Whamcloud - gitweb
LU-14997 tests: Register "stack_trap" for sanity/104c
[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-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
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         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_0e() { # LU-13417
257         (( $MDSCOUNT > 1 )) ||
258                 skip "We need at least 2 MDTs for this test"
259
260         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
261                 skip "Need server version at least 2.14.51"
262
263         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
264         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
265
266         [ $default_lmv_count -eq 1 ] ||
267                 error "$MOUNT default stripe count $default_lmv_count"
268
269         [ $default_lmv_index -eq -1 ] ||
270                 error "$MOUNT default stripe index $default_lmv_index"
271
272         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
273         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
274
275         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
276         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
277
278         [ $mdt_index1 -eq $mdt_index2 ] &&
279                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
280
281         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
282 }
283 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         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
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718         local devname=$(mdsdevname $mds_index)
719
720         echo "stop and checking mds${mds_index}:"
721         # e2fsck should not return error
722         stop mds${mds_index}
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 local devname=$(mdsdevname $mdt_index)
743                 # e2fsck should not return error
744                 stop mds${mdt_index}
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170 test_24t() {
1171         test_mkdir $DIR/R16a
1172         test_mkdir $DIR/R16a/b
1173         test_mkdir $DIR/R16a/b/c
1174         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1175         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1176         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1177 }
1178 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1179
1180 test_24u() { # bug12192
1181         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1182         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1183 }
1184 run_test 24u "create stripe file"
1185
1186 simple_cleanup_common() {
1187         local rc=0
1188         trap 0
1189         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1190
1191         local start=$SECONDS
1192         rm -rf $DIR/$tdir
1193         rc=$?
1194         wait_delete_completed
1195         echo "cleanup time $((SECONDS - start))"
1196         return $rc
1197 }
1198
1199 max_pages_per_rpc() {
1200         local mdtname="$(printf "MDT%04x" ${1:-0})"
1201         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1202 }
1203
1204 test_24v() {
1205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1206
1207         local nrfiles=${COUNT:-100000}
1208         local fname="$DIR/$tdir/$tfile"
1209
1210         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1211         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1212
1213         test_mkdir "$(dirname $fname)"
1214         # assume MDT0000 has the fewest inodes
1215         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1216         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1217         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1218
1219         trap simple_cleanup_common EXIT
1220
1221         createmany -m "$fname" $nrfiles
1222
1223         cancel_lru_locks mdc
1224         lctl set_param mdc.*.stats clear
1225
1226         # was previously test_24D: LU-6101
1227         # readdir() returns correct number of entries after cursor reload
1228         local num_ls=$(ls $DIR/$tdir | wc -l)
1229         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1230         local num_all=$(ls -a $DIR/$tdir | wc -l)
1231         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1232                 [ $num_all -ne $((nrfiles + 2)) ]; then
1233                         error "Expected $nrfiles files, got $num_ls " \
1234                                 "($num_uniq unique $num_all .&..)"
1235         fi
1236         # LU-5 large readdir
1237         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1238         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1239         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1240         # take into account of overhead in lu_dirpage header and end mark in
1241         # each page, plus one in rpc_num calculation.
1242         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1243         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1244         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1245         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1246         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1247         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1248         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1249         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1250                 error "large readdir doesn't take effect: " \
1251                       "$mds_readpage should be about $rpc_max"
1252
1253         simple_cleanup_common
1254 }
1255 run_test 24v "list large directory (test hash collision, b=17560)"
1256
1257 test_24w() { # bug21506
1258         SZ1=234852
1259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1260         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1261         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1262         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1263         [[ "$SZ1" -eq "$SZ2" ]] ||
1264                 error "Error reading at the end of the file $tfile"
1265 }
1266 run_test 24w "Reading a file larger than 4Gb"
1267
1268 test_24x() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1272                 skip "Need MDS version at least 2.7.56"
1273
1274         local MDTIDX=1
1275         local remote_dir=$DIR/$tdir/remote_dir
1276
1277         test_mkdir $DIR/$tdir
1278         $LFS mkdir -i $MDTIDX $remote_dir ||
1279                 error "create remote directory failed"
1280
1281         test_mkdir $DIR/$tdir/src_dir
1282         touch $DIR/$tdir/src_file
1283         test_mkdir $remote_dir/tgt_dir
1284         touch $remote_dir/tgt_file
1285
1286         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1287                 error "rename dir cross MDT failed!"
1288
1289         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1290                 error "rename file cross MDT failed!"
1291
1292         touch $DIR/$tdir/ln_file
1293         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1294                 error "ln file cross MDT failed"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24x "cross MDT rename/link"
1299
1300 test_24y() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1303
1304         local remote_dir=$DIR/$tdir/remote_dir
1305         local mdtidx=1
1306
1307         test_mkdir $DIR/$tdir
1308         $LFS mkdir -i $mdtidx $remote_dir ||
1309                 error "create remote directory failed"
1310
1311         test_mkdir $remote_dir/src_dir
1312         touch $remote_dir/src_file
1313         test_mkdir $remote_dir/tgt_dir
1314         touch $remote_dir/tgt_file
1315
1316         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1317                 error "rename subdir in the same remote dir failed!"
1318
1319         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1320                 error "rename files in the same remote dir failed!"
1321
1322         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1323                 error "link files in the same remote dir failed!"
1324
1325         rm -rf $DIR/$tdir || error "Can not delete directories"
1326 }
1327 run_test 24y "rename/link on the same dir should succeed"
1328
1329 test_24z() {
1330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1331         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1332                 skip "Need MDS version at least 2.12.51"
1333
1334         local index
1335
1336         for index in 0 1; do
1337                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1338                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1339         done
1340
1341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1344         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1345
1346         local mdts=$(comma_list $(mdts_nodes))
1347
1348         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1349         stack_trap "do_nodes $mdts $LCTL \
1350                 set_param mdt.*.enable_remote_rename=1" EXIT
1351
1352         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1353
1354         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1355         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1356 }
1357 run_test 24z "cross-MDT rename is done as cp"
1358
1359 test_24A() { # LU-3182
1360         local NFILES=5000
1361
1362         rm -rf $DIR/$tdir
1363         test_mkdir $DIR/$tdir
1364         trap simple_cleanup_common EXIT
1365         createmany -m $DIR/$tdir/$tfile $NFILES
1366         local t=$(ls $DIR/$tdir | wc -l)
1367         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1368         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1369         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1370            [ $v -ne $((NFILES + 2)) ] ; then
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372         fi
1373
1374         simple_cleanup_common || error "Can not delete directories"
1375 }
1376 run_test 24A "readdir() returns correct number of entries."
1377
1378 test_24B() { # LU-4805
1379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1380
1381         local count
1382
1383         test_mkdir $DIR/$tdir
1384         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1385                 error "create striped dir failed"
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 2 ] || error "Expected 2, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/a
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 3 ] || error "Expected 3, got $count"
1394
1395         touch $DIR/$tdir/striped_dir/.f
1396
1397         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1398         [ $count -eq 4 ] || error "Expected 4, got $count"
1399
1400         rm -rf $DIR/$tdir || error "Can not delete directories"
1401 }
1402 run_test 24B "readdir for striped dir return correct number of entries"
1403
1404 test_24C() {
1405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1406
1407         mkdir $DIR/$tdir
1408         mkdir $DIR/$tdir/d0
1409         mkdir $DIR/$tdir/d1
1410
1411         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1412                 error "create striped dir failed"
1413
1414         cd $DIR/$tdir/d0/striped_dir
1415
1416         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1417         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1418         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d0_ino" = "$parent_ino" ] ||
1421                 error ".. wrong, expect $d0_ino, get $parent_ino"
1422
1423         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1424                 error "mv striped dir failed"
1425
1426         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1427
1428         [ "$d1_ino" = "$parent_ino" ] ||
1429                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1430 }
1431 run_test 24C "check .. in striped dir"
1432
1433 test_24E() {
1434         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1436
1437         mkdir -p $DIR/$tdir
1438         mkdir $DIR/$tdir/src_dir
1439         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1440                 error "create remote source failed"
1441
1442         touch $DIR/$tdir/src_dir/src_child/a
1443
1444         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1445                 error "create remote target dir failed"
1446
1447         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "create remote target child failed"
1449
1450         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1451                 error "rename dir cross MDT failed!"
1452
1453         find $DIR/$tdir
1454
1455         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1456                 error "src_child still exists after rename"
1457
1458         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1459                 error "missing file(a) after rename"
1460
1461         rm -rf $DIR/$tdir || error "Can not delete directories"
1462 }
1463 run_test 24E "cross MDT rename/link"
1464
1465 test_24F () {
1466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1467
1468         local repeats=1000
1469         [ "$SLOW" = "no" ] && repeats=100
1470
1471         mkdir -p $DIR/$tdir
1472
1473         echo "$repeats repeats"
1474         for ((i = 0; i < repeats; i++)); do
1475                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1476                 touch $DIR/$tdir/test/a || error "touch fails"
1477                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1478                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1479         done
1480
1481         true
1482 }
1483 run_test 24F "hash order vs readdir (LU-11330)"
1484
1485 test_24G () {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487
1488         local ino1
1489         local ino2
1490
1491         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1492         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1493         touch $DIR/$tdir-0/f1 || error "touch f1"
1494         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1495         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1496         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1497         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1498         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1499 }
1500 run_test 24G "migrate symlink in rename"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27d() {
1724         test_mkdir $DIR/$tdir
1725         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1726                 error "setstripe failed"
1727         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1729 }
1730 run_test 27d "create file with default settings"
1731
1732 test_27e() {
1733         # LU-5839 adds check for existed layout before setting it
1734         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1735                 skip "Need MDS version at least 2.7.56"
1736
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741 }
1742 run_test 27e "setstripe existing file (should return error)"
1743
1744 test_27f() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1747                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1749                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1751         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1752 }
1753 run_test 27f "setstripe with bad stripe size (should return error)"
1754
1755 test_27g() {
1756         test_mkdir $DIR/$tdir
1757         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1758         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1759                 error "$DIR/$tdir/$tfile has object"
1760 }
1761 run_test 27g "$LFS getstripe with no objects"
1762
1763 test_27ga() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1767         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1768         local rc=$?
1769         (( rc == 2 )) || error "getstripe did not return ENOENT"
1770 }
1771 run_test 27ga "$LFS getstripe with missing file (should return error)"
1772
1773 test_27i() {
1774         test_mkdir $DIR/$tdir
1775         touch $DIR/$tdir/$tfile || error "touch failed"
1776         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1777                 error "missing objects"
1778 }
1779 run_test 27i "$LFS getstripe with some objects"
1780
1781 test_27j() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1784                 error "setstripe failed" || true
1785 }
1786 run_test 27j "setstripe with bad stripe offset (should return error)"
1787
1788 test_27k() { # bug 2844
1789         test_mkdir $DIR/$tdir
1790         local file=$DIR/$tdir/$tfile
1791         local ll_max_blksize=$((4 * 1024 * 1024))
1792         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1793         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1795         dd if=/dev/zero of=$file bs=4k count=1
1796         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1797         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1798 }
1799 run_test 27k "limit i_blksize for broken user apps"
1800
1801 test_27l() {
1802         mcreate $DIR/$tfile || error "creating file"
1803         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1804                 error "setstripe should have failed" || true
1805 }
1806 run_test 27l "check setstripe permissions (should return error)"
1807
1808 test_27m() {
1809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1810
1811         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1812                 skip_env "multiple clients -- skipping"
1813
1814         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1815                    head -n1)
1816         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1817                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1818         fi
1819         trap simple_cleanup_common EXIT
1820         test_mkdir $DIR/$tdir
1821         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1822         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1823                 error "dd should fill OST0"
1824         i=2
1825         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1826                 i=$((i + 1))
1827                 [ $i -gt 256 ] && break
1828         done
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it"
1834         i=$((i + 1))
1835         touch $DIR/$tdir/$tfile.$i
1836         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1837             awk '{print $1}'| grep -w "0") ] &&
1838                 error "OST0 was full but new created file still use it"
1839         simple_cleanup_common
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 __exhaust_precreations() {
1864         local OSTIDX=$1
1865         local FAILLOC=$2
1866         local FAILIDX=${3:-$OSTIDX}
1867         local ofacet=ost$((OSTIDX + 1))
1868
1869         mkdir_on_mdt0 $DIR/$tdir
1870         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1871         local mfacet=mds$((mdtidx + 1))
1872         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1873
1874         local OST=$(ostname_from_index $OSTIDX)
1875
1876         # on the mdt's osc
1877         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1878         local last_id=$(do_facet $mfacet lctl get_param -n \
1879                         osp.$mdtosc_proc1.prealloc_last_id)
1880         local next_id=$(do_facet $mfacet lctl get_param -n \
1881                         osp.$mdtosc_proc1.prealloc_next_id)
1882
1883         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1884         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1885
1886         test_mkdir -p $DIR/$tdir/${OST}
1887         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1888 #define OBD_FAIL_OST_ENOSPC              0x215
1889         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1890         echo "Creating to objid $last_id on ost $OST..."
1891         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1892         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1893         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1894 }
1895
1896 exhaust_precreations() {
1897         __exhaust_precreations $1 $2 $3
1898         sleep_maxage
1899 }
1900
1901 exhaust_all_precreations() {
1902         local i
1903         for (( i=0; i < OSTCOUNT; i++ )) ; do
1904                 __exhaust_precreations $i $1 -1
1905         done
1906         sleep_maxage
1907 }
1908
1909 test_27n() {
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         exhaust_precreations 0 0x80000215
1918         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1919         touch $DIR/$tdir/$tfile || error "touch failed"
1920         $LFS getstripe $DIR/$tdir/$tfile
1921         reset_enospc
1922 }
1923 run_test 27n "create file with some full OSTs"
1924
1925 test_27o() {
1926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930
1931         reset_enospc
1932         rm -f $DIR/$tdir/$tfile
1933         exhaust_all_precreations 0x215
1934
1935         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1936
1937         reset_enospc
1938         rm -rf $DIR/$tdir/*
1939 }
1940 run_test 27o "create file with all full OSTs (should error)"
1941
1942 function create_and_checktime() {
1943         local fname=$1
1944         local loops=$2
1945         local i
1946
1947         for ((i=0; i < $loops; i++)); do
1948                 local start=$SECONDS
1949                 multiop $fname-$i Oc
1950                 ((SECONDS-start < TIMEOUT)) ||
1951                         error "creation took " $((SECONDS-$start)) && return 1
1952         done
1953 }
1954
1955 test_27oo() {
1956         local mdts=$(comma_list $(mdts_nodes))
1957
1958         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1959                 skip "Need MDS version at least 2.13.57"
1960
1961         local f0=$DIR/${tfile}-0
1962         local f1=$DIR/${tfile}-1
1963
1964         wait_delete_completed
1965
1966         # refill precreated objects
1967         $LFS setstripe -i0 -c1 $f0
1968
1969         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1970         # force QoS allocation policy
1971         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1972         stack_trap "do_nodes $mdts $LCTL set_param \
1973                 lov.*.qos_threshold_rr=$saved" EXIT
1974         sleep_maxage
1975
1976         # one OST is unavailable, but still have few objects preallocated
1977         stop ost1
1978         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1979                 rm -rf $f1 $DIR/$tdir*" EXIT
1980
1981         for ((i=0; i < 7; i++)); do
1982                 mkdir $DIR/$tdir$i || error "can't create dir"
1983                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1984                         error "can't set striping"
1985         done
1986         for ((i=0; i < 7; i++)); do
1987                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1988         done
1989         wait
1990 }
1991 run_test 27oo "don't let few threads to reserve too many objects"
1992
1993 test_27p() {
1994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1996         remote_mds_nodsh && skip "remote MDS with nodsh"
1997         remote_ost_nodsh && skip "remote OST with nodsh"
1998
1999         reset_enospc
2000         rm -f $DIR/$tdir/$tfile
2001         test_mkdir $DIR/$tdir
2002
2003         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2004         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2005         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2006
2007         exhaust_precreations 0 0x80000215
2008         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2009         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2010         $LFS getstripe $DIR/$tdir/$tfile
2011
2012         reset_enospc
2013 }
2014 run_test 27p "append to a truncated file with some full OSTs"
2015
2016 test_27q() {
2017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2019         remote_mds_nodsh && skip "remote MDS with nodsh"
2020         remote_ost_nodsh && skip "remote OST with nodsh"
2021
2022         reset_enospc
2023         rm -f $DIR/$tdir/$tfile
2024
2025         mkdir_on_mdt0 $DIR/$tdir
2026         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2027         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2028                 error "truncate $DIR/$tdir/$tfile failed"
2029         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2030
2031         exhaust_all_precreations 0x215
2032
2033         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2034         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2035
2036         reset_enospc
2037 }
2038 run_test 27q "append to truncated file with all OSTs full (should error)"
2039
2040 test_27r() {
2041         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2043         remote_mds_nodsh && skip "remote MDS with nodsh"
2044         remote_ost_nodsh && skip "remote OST with nodsh"
2045
2046         reset_enospc
2047         rm -f $DIR/$tdir/$tfile
2048         exhaust_precreations 0 0x80000215
2049
2050         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2051
2052         reset_enospc
2053 }
2054 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2055
2056 test_27s() { # bug 10725
2057         test_mkdir $DIR/$tdir
2058         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2059         local stripe_count=0
2060         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2061         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2062                 error "stripe width >= 2^32 succeeded" || true
2063
2064 }
2065 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2066
2067 test_27t() { # bug 10864
2068         WDIR=$(pwd)
2069         WLFS=$(which lfs)
2070         cd $DIR
2071         touch $tfile
2072         $WLFS getstripe $tfile
2073         cd $WDIR
2074 }
2075 run_test 27t "check that utils parse path correctly"
2076
2077 test_27u() { # bug 4900
2078         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2079         remote_mds_nodsh && skip "remote MDS with nodsh"
2080
2081         local index
2082         local list=$(comma_list $(mdts_nodes))
2083
2084 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2085         do_nodes $list $LCTL set_param fail_loc=0x139
2086         test_mkdir -p $DIR/$tdir
2087         trap simple_cleanup_common EXIT
2088         createmany -o $DIR/$tdir/t- 1000
2089         do_nodes $list $LCTL set_param fail_loc=0
2090
2091         TLOG=$TMP/$tfile.getstripe
2092         $LFS getstripe $DIR/$tdir > $TLOG
2093         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2094         unlinkmany $DIR/$tdir/t- 1000
2095         trap 0
2096         [[ $OBJS -gt 0 ]] &&
2097                 error "$OBJS objects created on OST-0. See $TLOG" ||
2098                 rm -f $TLOG
2099 }
2100 run_test 27u "skip object creation on OSC w/o objects"
2101
2102 test_27v() { # bug 4900
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105         remote_mds_nodsh && skip "remote MDS with nodsh"
2106         remote_ost_nodsh && skip "remote OST with nodsh"
2107
2108         exhaust_all_precreations 0x215
2109         reset_enospc
2110
2111         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2112
2113         touch $DIR/$tdir/$tfile
2114         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2115         # all except ost1
2116         for (( i=1; i < OSTCOUNT; i++ )); do
2117                 do_facet ost$i lctl set_param fail_loc=0x705
2118         done
2119         local START=`date +%s`
2120         createmany -o $DIR/$tdir/$tfile 32
2121
2122         local FINISH=`date +%s`
2123         local TIMEOUT=`lctl get_param -n timeout`
2124         local PROCESS=$((FINISH - START))
2125         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2126                error "$FINISH - $START >= $TIMEOUT / 2"
2127         sleep $((TIMEOUT / 2 - PROCESS))
2128         reset_enospc
2129 }
2130 run_test 27v "skip object creation on slow OST"
2131
2132 test_27w() { # bug 10997
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2135         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2136                 error "stripe size $size != 65536" || true
2137         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2138                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2139 }
2140 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2141
2142 test_27wa() {
2143         [[ $OSTCOUNT -lt 2 ]] &&
2144                 skip_env "skipping multiple stripe count/offset test"
2145
2146         test_mkdir $DIR/$tdir
2147         for i in $(seq 1 $OSTCOUNT); do
2148                 offset=$((i - 1))
2149                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2150                         error "setstripe -c $i -i $offset failed"
2151                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2152                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2153                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2154                 [ $index -ne $offset ] &&
2155                         error "stripe offset $index != $offset" || true
2156         done
2157 }
2158 run_test 27wa "check $LFS setstripe -c -i options"
2159
2160 test_27x() {
2161         remote_ost_nodsh && skip "remote OST with nodsh"
2162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2164
2165         OFFSET=$(($OSTCOUNT - 1))
2166         OSTIDX=0
2167         local OST=$(ostname_from_index $OSTIDX)
2168
2169         test_mkdir $DIR/$tdir
2170         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2171         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2174         for i in $(seq 0 $OFFSET); do
2175                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2176                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2177                 error "OST0 was degraded but new created file still use it"
2178         done
2179         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2180 }
2181 run_test 27x "create files while OST0 is degraded"
2182
2183 test_27y() {
2184         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2185         remote_mds_nodsh && skip "remote MDS with nodsh"
2186         remote_ost_nodsh && skip "remote OST with nodsh"
2187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2188
2189         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2190         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2191                 osp.$mdtosc.prealloc_last_id)
2192         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2193                 osp.$mdtosc.prealloc_next_id)
2194         local fcount=$((last_id - next_id))
2195         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2196         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2197
2198         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2199                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2200         local OST_DEACTIVE_IDX=-1
2201         local OSC
2202         local OSTIDX
2203         local OST
2204
2205         for OSC in $MDS_OSCS; do
2206                 OST=$(osc_to_ost $OSC)
2207                 OSTIDX=$(index_from_ostuuid $OST)
2208                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2209                         OST_DEACTIVE_IDX=$OSTIDX
2210                 fi
2211                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2212                         echo $OSC "is Deactivated:"
2213                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2214                 fi
2215         done
2216
2217         OSTIDX=$(index_from_ostuuid $OST)
2218         test_mkdir $DIR/$tdir
2219         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2220
2221         for OSC in $MDS_OSCS; do
2222                 OST=$(osc_to_ost $OSC)
2223                 OSTIDX=$(index_from_ostuuid $OST)
2224                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2225                         echo $OST "is degraded:"
2226                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2227                                                 obdfilter.$OST.degraded=1
2228                 fi
2229         done
2230
2231         sleep_maxage
2232         createmany -o $DIR/$tdir/$tfile $fcount
2233
2234         for OSC in $MDS_OSCS; do
2235                 OST=$(osc_to_ost $OSC)
2236                 OSTIDX=$(index_from_ostuuid $OST)
2237                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2238                         echo $OST "is recovered from degraded:"
2239                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2240                                                 obdfilter.$OST.degraded=0
2241                 else
2242                         do_facet $SINGLEMDS lctl --device %$OSC activate
2243                 fi
2244         done
2245
2246         # all osp devices get activated, hence -1 stripe count restored
2247         local stripe_count=0
2248
2249         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2250         # devices get activated.
2251         sleep_maxage
2252         $LFS setstripe -c -1 $DIR/$tfile
2253         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2254         rm -f $DIR/$tfile
2255         [ $stripe_count -ne $OSTCOUNT ] &&
2256                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2257         return 0
2258 }
2259 run_test 27y "create files while OST0 is degraded and the rest inactive"
2260
2261 check_seq_oid()
2262 {
2263         log "check file $1"
2264
2265         lmm_count=$($LFS getstripe -c $1)
2266         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2267         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2268
2269         local old_ifs="$IFS"
2270         IFS=$'[:]'
2271         fid=($($LFS path2fid $1))
2272         IFS="$old_ifs"
2273
2274         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2275         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2276
2277         # compare lmm_seq and lu_fid->f_seq
2278         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2279         # compare lmm_object_id and lu_fid->oid
2280         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2281
2282         # check the trusted.fid attribute of the OST objects of the file
2283         local have_obdidx=false
2284         local stripe_nr=0
2285         $LFS getstripe $1 | while read obdidx oid hex seq; do
2286                 # skip lines up to and including "obdidx"
2287                 [ -z "$obdidx" ] && break
2288                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2289                 $have_obdidx || continue
2290
2291                 local ost=$((obdidx + 1))
2292                 local dev=$(ostdevname $ost)
2293                 local oid_hex
2294
2295                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2296
2297                 seq=$(echo $seq | sed -e "s/^0x//g")
2298                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2299                         oid_hex=$(echo $oid)
2300                 else
2301                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2302                 fi
2303                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2304
2305                 local ff=""
2306                 #
2307                 # Don't unmount/remount the OSTs if we don't need to do that.
2308                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2309                 # update too, until that use mount/ll_decode_filter_fid/mount.
2310                 # Re-enable when debugfs will understand new filter_fid.
2311                 #
2312                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2313                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2314                                 $dev 2>/dev/null" | grep "parent=")
2315                 fi
2316                 if [ -z "$ff" ]; then
2317                         stop ost$ost
2318                         mount_fstype ost$ost
2319                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2320                                 $(facet_mntpt ost$ost)/$obj_file)
2321                         unmount_fstype ost$ost
2322                         start ost$ost $dev $OST_MOUNT_OPTS
2323                         clients_up
2324                 fi
2325
2326                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2327
2328                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2329
2330                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2331                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2332                 #
2333                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2334                 #       stripe_size=1048576 component_id=1 component_start=0 \
2335                 #       component_end=33554432
2336                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2337                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2338                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2339                 local ff_pstripe
2340                 if grep -q 'stripe=' <<<$ff; then
2341                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2342                 else
2343                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2344                         # into f_ver in this case.  See comment on ff_parent.
2345                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2346                 fi
2347
2348                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2349                 [ $ff_pseq = $lmm_seq ] ||
2350                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2351                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2352                 [ $ff_poid = $lmm_oid ] ||
2353                         error "FF parent OID $ff_poid != $lmm_oid"
2354                 (($ff_pstripe == $stripe_nr)) ||
2355                         error "FF stripe $ff_pstripe != $stripe_nr"
2356
2357                 stripe_nr=$((stripe_nr + 1))
2358                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2359                         continue
2360                 if grep -q 'stripe_count=' <<<$ff; then
2361                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2362                                             -e 's/ .*//' <<<$ff)
2363                         [ $lmm_count = $ff_scnt ] ||
2364                                 error "FF stripe count $lmm_count != $ff_scnt"
2365                 fi
2366         done
2367 }
2368
2369 test_27z() {
2370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2371         remote_ost_nodsh && skip "remote OST with nodsh"
2372
2373         test_mkdir $DIR/$tdir
2374         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2375                 { error "setstripe -c -1 failed"; return 1; }
2376         # We need to send a write to every object to get parent FID info set.
2377         # This _should_ also work for setattr, but does not currently.
2378         # touch $DIR/$tdir/$tfile-1 ||
2379         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2380                 { error "dd $tfile-1 failed"; return 2; }
2381         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2382                 { error "setstripe -c -1 failed"; return 3; }
2383         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2384                 { error "dd $tfile-2 failed"; return 4; }
2385
2386         # make sure write RPCs have been sent to OSTs
2387         sync; sleep 5; sync
2388
2389         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2390         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2391 }
2392 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2393
2394 test_27A() { # b=19102
2395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2396
2397         save_layout_restore_at_exit $MOUNT
2398         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2399         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2400                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2401         local default_size=$($LFS getstripe -S $MOUNT)
2402         local default_offset=$($LFS getstripe -i $MOUNT)
2403         local dsize=$(do_facet $SINGLEMDS \
2404                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2405         [ $default_size -eq $dsize ] ||
2406                 error "stripe size $default_size != $dsize"
2407         [ $default_offset -eq -1 ] ||
2408                 error "stripe offset $default_offset != -1"
2409 }
2410 run_test 27A "check filesystem-wide default LOV EA values"
2411
2412 test_27B() { # LU-2523
2413         test_mkdir $DIR/$tdir
2414         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2415         touch $DIR/$tdir/f0
2416         # open f1 with O_LOV_DELAY_CREATE
2417         # rename f0 onto f1
2418         # call setstripe ioctl on open file descriptor for f1
2419         # close
2420         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2421                 $DIR/$tdir/f0
2422
2423         rm -f $DIR/$tdir/f1
2424         # open f1 with O_LOV_DELAY_CREATE
2425         # unlink f1
2426         # call setstripe ioctl on open file descriptor for f1
2427         # close
2428         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2429
2430         # Allow multiop to fail in imitation of NFS's busted semantics.
2431         true
2432 }
2433 run_test 27B "call setstripe on open unlinked file/rename victim"
2434
2435 # 27C family tests full striping and overstriping
2436 test_27Ca() { #LU-2871
2437         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2438
2439         declare -a ost_idx
2440         local index
2441         local found
2442         local i
2443         local j
2444
2445         test_mkdir $DIR/$tdir
2446         cd $DIR/$tdir
2447         for i in $(seq 0 $((OSTCOUNT - 1))); do
2448                 # set stripe across all OSTs starting from OST$i
2449                 $LFS setstripe -i $i -c -1 $tfile$i
2450                 # get striping information
2451                 ost_idx=($($LFS getstripe $tfile$i |
2452                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2453                 echo ${ost_idx[@]}
2454
2455                 # check the layout
2456                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2457                         error "${#ost_idx[@]} != $OSTCOUNT"
2458
2459                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2460                         found=0
2461                         for j in $(echo ${ost_idx[@]}); do
2462                                 if [ $index -eq $j ]; then
2463                                         found=1
2464                                         break
2465                                 fi
2466                         done
2467                         [ $found = 1 ] ||
2468                                 error "Can not find $index in ${ost_idx[@]}"
2469                 done
2470         done
2471 }
2472 run_test 27Ca "check full striping across all OSTs"
2473
2474 test_27Cb() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2478                 skip_env "too many osts, skipping"
2479
2480         test_mkdir -p $DIR/$tdir
2481         local setcount=$(($OSTCOUNT * 2))
2482         [ $setcount -lt 160 ] || large_xattr_enabled ||
2483                 skip_env "ea_inode feature disabled"
2484
2485         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2486                 error "setstripe failed"
2487
2488         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2489         [ $count -eq $setcount ] ||
2490                 error "stripe count $count, should be $setcount"
2491
2492         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2493                 error "overstriped should be set in pattern"
2494
2495         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2496                 error "dd failed"
2497 }
2498 run_test 27Cb "more stripes than OSTs with -C"
2499
2500 test_27Cc() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2504
2505         test_mkdir -p $DIR/$tdir
2506         local setcount=$(($OSTCOUNT - 1))
2507
2508         [ $setcount -lt 160 ] || large_xattr_enabled ||
2509                 skip_env "ea_inode feature disabled"
2510
2511         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2512                 error "setstripe failed"
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2519                 error "overstriped should not be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523 }
2524 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2525
2526 test_27Cd() {
2527         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2528                 skip "server does not support overstriping"
2529         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2530         large_xattr_enabled || skip_env "ea_inode feature disabled"
2531
2532         test_mkdir -p $DIR/$tdir
2533         local setcount=$LOV_MAX_STRIPE_COUNT
2534
2535         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2536                 error "setstripe failed"
2537
2538         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2539         [ $count -eq $setcount ] ||
2540                 error "stripe count $count, should be $setcount"
2541
2542         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2543                 error "overstriped should be set in pattern"
2544
2545         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2546                 error "dd failed"
2547
2548         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2549 }
2550 run_test 27Cd "test maximum stripe count"
2551
2552 test_27Ce() {
2553         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2554                 skip "server does not support overstriping"
2555         test_mkdir -p $DIR/$tdir
2556
2557         pool_add $TESTNAME || error "Pool creation failed"
2558         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2559
2560         local setcount=8
2561
2562         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2563                 error "setstripe failed"
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Ce "test pool with overstriping"
2578
2579 test_27Cf() {
2580         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2581                 skip "server does not support overstriping"
2582         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2583                 skip_env "too many osts, skipping"
2584
2585         test_mkdir -p $DIR/$tdir
2586
2587         local setcount=$(($OSTCOUNT * 2))
2588         [ $setcount -lt 160 ] || large_xattr_enabled ||
2589                 skip_env "ea_inode feature disabled"
2590
2591         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2592                 error "setstripe failed"
2593
2594         echo 1 > $DIR/$tdir/$tfile
2595
2596         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2597         [ $count -eq $setcount ] ||
2598                 error "stripe count $count, should be $setcount"
2599
2600         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2601                 error "overstriped should be set in pattern"
2602
2603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2604                 error "dd failed"
2605
2606         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2607 }
2608 run_test 27Cf "test default inheritance with overstriping"
2609
2610 test_27D() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2613         remote_mds_nodsh && skip "remote MDS with nodsh"
2614
2615         local POOL=${POOL:-testpool}
2616         local first_ost=0
2617         local last_ost=$(($OSTCOUNT - 1))
2618         local ost_step=1
2619         local ost_list=$(seq $first_ost $ost_step $last_ost)
2620         local ost_range="$first_ost $last_ost $ost_step"
2621
2622         test_mkdir $DIR/$tdir
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2625
2626         local skip27D
2627         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2628                 skip27D+="-s 29"
2629         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2630                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2631                         skip27D+=" -s 30,31"
2632         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2633           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2634                 skip27D+=" -s 32,33"
2635         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2636                 skip27D+=" -s 34"
2637         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2638                 error "llapi_layout_test failed"
2639
2640         destroy_test_pools || error "destroy test pools failed"
2641 }
2642 run_test 27D "validate llapi_layout API"
2643
2644 # Verify that default_easize is increased from its initial value after
2645 # accessing a widely striped file.
2646 test_27E() {
2647         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2648         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2649                 skip "client does not have LU-3338 fix"
2650
2651         # 72 bytes is the minimum space required to store striping
2652         # information for a file striped across one OST:
2653         # (sizeof(struct lov_user_md_v3) +
2654         #  sizeof(struct lov_user_ost_data_v1))
2655         local min_easize=72
2656         $LCTL set_param -n llite.*.default_easize $min_easize ||
2657                 error "lctl set_param failed"
2658         local easize=$($LCTL get_param -n llite.*.default_easize)
2659
2660         [ $easize -eq $min_easize ] ||
2661                 error "failed to set default_easize"
2662
2663         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2664                 error "setstripe failed"
2665         # In order to ensure stat() call actually talks to MDS we need to
2666         # do something drastic to this file to shake off all lock, e.g.
2667         # rename it (kills lookup lock forcing cache cleaning)
2668         mv $DIR/$tfile $DIR/${tfile}-1
2669         ls -l $DIR/${tfile}-1
2670         rm $DIR/${tfile}-1
2671
2672         easize=$($LCTL get_param -n llite.*.default_easize)
2673
2674         [ $easize -gt $min_easize ] ||
2675                 error "default_easize not updated"
2676 }
2677 run_test 27E "check that default extended attribute size properly increases"
2678
2679 test_27F() { # LU-5346/LU-7975
2680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2681         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2682         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2683                 skip "Need MDS version at least 2.8.51"
2684         remote_ost_nodsh && skip "remote OST with nodsh"
2685
2686         test_mkdir $DIR/$tdir
2687         rm -f $DIR/$tdir/f0
2688         $LFS setstripe -c 2 $DIR/$tdir
2689
2690         # stop all OSTs to reproduce situation for LU-7975 ticket
2691         for num in $(seq $OSTCOUNT); do
2692                 stop ost$num
2693         done
2694
2695         # open/create f0 with O_LOV_DELAY_CREATE
2696         # truncate f0 to a non-0 size
2697         # close
2698         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2699
2700         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2701         # open/write it again to force delayed layout creation
2702         cat /etc/hosts > $DIR/$tdir/f0 &
2703         catpid=$!
2704
2705         # restart OSTs
2706         for num in $(seq $OSTCOUNT); do
2707                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2708                         error "ost$num failed to start"
2709         done
2710
2711         wait $catpid || error "cat failed"
2712
2713         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2714         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2715                 error "wrong stripecount"
2716
2717 }
2718 run_test 27F "Client resend delayed layout creation with non-zero size"
2719
2720 test_27G() { #LU-10629
2721         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2722                 skip "Need MDS version at least 2.11.51"
2723         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2724         remote_mds_nodsh && skip "remote MDS with nodsh"
2725         local POOL=${POOL:-testpool}
2726         local ostrange="0 0 1"
2727
2728         test_mkdir $DIR/$tdir
2729         touch $DIR/$tdir/$tfile.nopool
2730         pool_add $POOL || error "pool_add failed"
2731         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2732         $LFS setstripe -p $POOL $DIR/$tdir
2733
2734         local pool=$($LFS getstripe -p $DIR/$tdir)
2735
2736         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2737         touch $DIR/$tdir/$tfile.default
2738         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2739         $LFS find $DIR/$tdir -type f --pool $POOL
2740         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2741         [[ "$found" == "2" ]] ||
2742                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2743
2744         $LFS setstripe -d $DIR/$tdir
2745
2746         pool=$($LFS getstripe -p -d $DIR/$tdir)
2747
2748         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2749 }
2750 run_test 27G "Clear OST pool from stripe"
2751
2752 test_27H() {
2753         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2754                 skip "Need MDS version newer than 2.11.54"
2755         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2756         test_mkdir $DIR/$tdir
2757         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2758         touch $DIR/$tdir/$tfile
2759         $LFS getstripe -c $DIR/$tdir/$tfile
2760         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2761                 error "two-stripe file doesn't have two stripes"
2762
2763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2764         $LFS getstripe -y $DIR/$tdir/$tfile
2765         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2766              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2767                 error "expected l_ost_idx: [02]$ not matched"
2768
2769         # make sure ost list has been cleared
2770         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2771         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2772                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2773         touch $DIR/$tdir/f3
2774         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2775 }
2776 run_test 27H "Set specific OSTs stripe"
2777
2778 test_27I() {
2779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2780         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2781         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2782                 skip "Need MDS version newer than 2.12.52"
2783         local pool=$TESTNAME
2784         local ostrange="1 1 1"
2785
2786         save_layout_restore_at_exit $MOUNT
2787         $LFS setstripe -c 2 -i 0 $MOUNT
2788         pool_add $pool || error "pool_add failed"
2789         pool_add_targets $pool $ostrange ||
2790                 error "pool_add_targets failed"
2791         test_mkdir $DIR/$tdir
2792         $LFS setstripe -p $pool $DIR/$tdir
2793         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2794         $LFS getstripe $DIR/$tdir/$tfile
2795 }
2796 run_test 27I "check that root dir striping does not break parent dir one"
2797
2798 test_27J() {
2799         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2800                 skip "Need MDS version newer than 2.12.51"
2801
2802         test_mkdir $DIR/$tdir
2803         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2804         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2805
2806         # create foreign file (raw way)
2807         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2808                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2809
2810         ! $LFS setstripe --foreign --flags foo \
2811                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2812                         error "creating $tfile with '--flags foo' should fail"
2813
2814         ! $LFS setstripe --foreign --flags 0xffffffff \
2815                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2816                         error "creating $tfile w/ 0xffffffff flags should fail"
2817
2818         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2819                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2820
2821         # verify foreign file (raw way)
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2825         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_size: 73" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2830         parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_type: 1" ||
2832                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2833         parse_foreign_file -f $DIR/$tdir/$tfile |
2834                 grep "lov_foreign_flags: 0x0000DA08" ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2836         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2837                 grep "lov_foreign_value: 0x" |
2838                 sed -e 's/lov_foreign_value: 0x//')
2839         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2840         [[ $lov = ${lov2// /} ]] ||
2841                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2842
2843         # create foreign file (lfs + API)
2844         $LFS setstripe --foreign=none --flags 0xda08 \
2845                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: create failed"
2847
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2849                 grep "lfm_magic:.*0x0BD70BD0" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2851         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2852         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2854         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2856         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2857                 grep "lfm_flags:.*0x0000DA08" ||
2858                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2859         $LFS getstripe $DIR/$tdir/${tfile}2 |
2860                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2861                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2862
2863         # modify striping should fail
2864         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2865                 error "$DIR/$tdir/$tfile: setstripe should fail"
2866         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2868
2869         # R/W should fail
2870         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2871         cat $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: read should fail"
2873         cat /etc/passwd > $DIR/$tdir/$tfile &&
2874                 error "$DIR/$tdir/$tfile: write should fail"
2875         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2876                 error "$DIR/$tdir/${tfile}2: write should fail"
2877
2878         # chmod should work
2879         chmod 222 $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chmod failed"
2881         chmod 222 $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chmod failed"
2883
2884         # chown should work
2885         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2886                 error "$DIR/$tdir/$tfile: chown failed"
2887         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2888                 error "$DIR/$tdir/${tfile}2: chown failed"
2889
2890         # rename should work
2891         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2893         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2895
2896         #remove foreign file
2897         rm $DIR/$tdir/${tfile}.new ||
2898                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2899         rm $DIR/$tdir/${tfile}2.new ||
2900                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2901 }
2902 run_test 27J "basic ops on file with foreign LOV"
2903
2904 test_27K() {
2905         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2906                 skip "Need MDS version newer than 2.12.49"
2907
2908         test_mkdir $DIR/$tdir
2909         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2910         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2911
2912         # create foreign dir (raw way)
2913         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2914                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2915
2916         ! $LFS setdirstripe --foreign --flags foo \
2917                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2918                         error "creating $tdir with '--flags foo' should fail"
2919
2920         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2921                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2922                         error "creating $tdir w/ 0xffffffff flags should fail"
2923
2924         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2925                 error "create_foreign_dir FAILED"
2926
2927         # verify foreign dir (raw way)
2928         parse_foreign_dir -d $DIR/$tdir/$tdir |
2929                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2930                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2931         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2933         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2934                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2935         parse_foreign_dir -d $DIR/$tdir/$tdir |
2936                 grep "lmv_foreign_flags: 55813$" ||
2937                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2938         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2939                 grep "lmv_foreign_value: 0x" |
2940                 sed 's/lmv_foreign_value: 0x//')
2941         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2942                 sed 's/ //g')
2943         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2944
2945         # create foreign dir (lfs + API)
2946         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2947                 $DIR/$tdir/${tdir}2 ||
2948                 error "$DIR/$tdir/${tdir}2: create failed"
2949
2950         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2951                 grep "lfm_magic:.*0x0CD50CD0" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2953         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2954         # - sizeof(lfm_type) - sizeof(lfm_flags)
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2956                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2959         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_flags:.*0x0000DA05" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2962         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2963                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2964                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2965
2966         # file create in dir should fail
2967         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2968         touch $DIR/$tdir/${tdir}2/$tfile &&
2969                 "$DIR/${tdir}2: file create should fail"
2970
2971         # chmod should work
2972         chmod 777 $DIR/$tdir/$tdir ||
2973                 error "$DIR/$tdir: chmod failed"
2974         chmod 777 $DIR/$tdir/${tdir}2 ||
2975                 error "$DIR/${tdir}2: chmod failed"
2976
2977         # chown should work
2978         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2979                 error "$DIR/$tdir: chown failed"
2980         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2981                 error "$DIR/${tdir}2: chown failed"
2982
2983         # rename should work
2984         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2985                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2986         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2987                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2988
2989         #remove foreign dir
2990         rmdir $DIR/$tdir/${tdir}.new ||
2991                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2992         rmdir $DIR/$tdir/${tdir}2.new ||
2993                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2994 }
2995 run_test 27K "basic ops on dir with foreign LMV"
2996
2997 test_27L() {
2998         remote_mds_nodsh && skip "remote MDS with nodsh"
2999
3000         local POOL=${POOL:-$TESTNAME}
3001
3002         pool_add $POOL || error "pool_add failed"
3003
3004         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3005                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3006                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3007 }
3008 run_test 27L "lfs pool_list gives correct pool name"
3009
3010 test_27M() {
3011         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3012                 skip "Need MDS version >= than 2.12.57"
3013         remote_mds_nodsh && skip "remote MDS with nodsh"
3014         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3015
3016         test_mkdir $DIR/$tdir
3017
3018         # Set default striping on directory
3019         local setcount=4
3020         local stripe_opt
3021
3022         # if we run against a 2.12 server which lacks overstring support
3023         # then the connect_flag will not report overstriping, even if client
3024         # is 2.14+
3025         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3026                 stripe_opt="-C $setcount"
3027         elif (( $OSTCOUNT >= $setcount )); then
3028                 stripe_opt="-c $setcount"
3029         else
3030                 skip "server does not support overstriping"
3031         fi
3032         $LFS setstripe $stripe_opt $DIR/$tdir
3033
3034         echo 1 > $DIR/$tdir/${tfile}.1
3035         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3036         [ $count -eq $setcount ] ||
3037                 error "(1) stripe count $count, should be $setcount"
3038
3039         # Capture existing append_stripe_count setting for restore
3040         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3041         local mdts=$(comma_list $(mdts_nodes))
3042         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3043
3044         local appendcount=$orig_count
3045         echo 1 >> $DIR/$tdir/${tfile}.2_append
3046         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3047         [ $count -eq $appendcount ] ||
3048                 error "(2)stripe count $count, should be $appendcount for append"
3049
3050         # Disable O_APPEND striping, verify it works
3051         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3052
3053         # Should now get the default striping, which is 4
3054         setcount=4
3055         echo 1 >> $DIR/$tdir/${tfile}.3_append
3056         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3057         [ $count -eq $setcount ] ||
3058                 error "(3) stripe count $count, should be $setcount"
3059
3060         # Try changing the stripe count for append files
3061         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3062
3063         # Append striping is now 2 (directory default is still 4)
3064         appendcount=2
3065         echo 1 >> $DIR/$tdir/${tfile}.4_append
3066         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3067         [ $count -eq $appendcount ] ||
3068                 error "(4) stripe count $count, should be $appendcount for append"
3069
3070         # Test append stripe count of -1
3071         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3072         appendcount=$OSTCOUNT
3073         echo 1 >> $DIR/$tdir/${tfile}.5
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3075         [ $count -eq $appendcount ] ||
3076                 error "(5) stripe count $count, should be $appendcount for append"
3077
3078         # Set append striping back to default of 1
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3080
3081         # Try a new default striping, PFL + DOM
3082         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3083
3084         # Create normal DOM file, DOM returns stripe count == 0
3085         setcount=0
3086         touch $DIR/$tdir/${tfile}.6
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3088         [ $count -eq $setcount ] ||
3089                 error "(6) stripe count $count, should be $setcount"
3090
3091         # Show
3092         appendcount=1
3093         echo 1 >> $DIR/$tdir/${tfile}.7_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3095         [ $count -eq $appendcount ] ||
3096                 error "(7) stripe count $count, should be $appendcount for append"
3097
3098         # Clean up DOM layout
3099         $LFS setstripe -d $DIR/$tdir
3100
3101         save_layout_restore_at_exit $MOUNT
3102         # Now test that append striping works when layout is from root
3103         $LFS setstripe -c 2 $MOUNT
3104         # Make a special directory for this
3105         mkdir $DIR/${tdir}/${tdir}.2
3106
3107         # Verify for normal file
3108         setcount=2
3109         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3110         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3111         [ $count -eq $setcount ] ||
3112                 error "(8) stripe count $count, should be $setcount"
3113
3114         appendcount=1
3115         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3116         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3117         [ $count -eq $appendcount ] ||
3118                 error "(9) stripe count $count, should be $appendcount for append"
3119
3120         # Now test O_APPEND striping with pools
3121         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3122         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3123
3124         # Create the pool
3125         pool_add $TESTNAME || error "pool creation failed"
3126         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3127
3128         echo 1 >> $DIR/$tdir/${tfile}.10_append
3129
3130         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3131         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3132
3133         # Check that count is still correct
3134         appendcount=1
3135         echo 1 >> $DIR/$tdir/${tfile}.11_append
3136         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3137         [ $count -eq $appendcount ] ||
3138                 error "(11) stripe count $count, should be $appendcount for append"
3139
3140         # Disable O_APPEND stripe count, verify pool works separately
3141         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3142
3143         echo 1 >> $DIR/$tdir/${tfile}.12_append
3144
3145         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3146         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3147
3148         # Remove pool setting, verify it's not applied
3149         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3150
3151         echo 1 >> $DIR/$tdir/${tfile}.13_append
3152
3153         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3154         [ "$pool" = "" ] || error "(13) pool found: $pool"
3155 }
3156 run_test 27M "test O_APPEND striping"
3157
3158 test_27N() {
3159         combined_mgs_mds && skip "needs separate MGS/MDT"
3160
3161         pool_add $TESTNAME || error "pool_add failed"
3162         do_facet mgs "$LCTL pool_list $FSNAME" |
3163                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3164                 error "lctl pool_list on MGS failed"
3165 }
3166 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3167
3168 clean_foreign_symlink() {
3169         trap 0
3170         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3171         for i in $DIR/$tdir/* ; do
3172                 $LFS unlink_foreign $i || true
3173         done
3174 }
3175
3176 test_27O() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3178                 skip "Need MDS version newer than 2.12.51"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LOV format is a partial path by default
3190
3191         # create foreign file (lfs + API)
3192         $LFS setstripe --foreign=symlink --flags 0xda05 \
3193                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3194                 error "$DIR/$tdir/${tfile}: create failed"
3195
3196         $LFS getstripe -v $DIR/$tdir/${tfile} |
3197                 grep "lfm_magic:.*0x0BD70BD0" ||
3198                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3199         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3204         $LFS getstripe $DIR/$tdir/${tfile} |
3205                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3207
3208         # modify striping should fail
3209         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3210                 error "$DIR/$tdir/$tfile: setstripe should fail"
3211
3212         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3213         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3214         cat /etc/passwd > $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: write should fail"
3216
3217         # rename should succeed
3218         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3219                 error "$DIR/$tdir/$tfile: rename has failed"
3220
3221         #remove foreign_symlink file should fail
3222         rm $DIR/$tdir/${tfile}.new &&
3223                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3224
3225         #test fake symlink
3226         mkdir /tmp/${uuid1} ||
3227                 error "/tmp/${uuid1}: mkdir has failed"
3228         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3229                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3231         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3232                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3233         #read should succeed now
3234         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3235                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3236         #write should succeed now
3237         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3239         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3240                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3241         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3242                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3243
3244         #check that getstripe still works
3245         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3247
3248         # chmod should still succeed
3249         chmod 644 $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3251
3252         # chown should still succeed
3253         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3254                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3255
3256         # rename should still succeed
3257         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3258                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3259
3260         #remove foreign_symlink file should still fail
3261         rm $DIR/$tdir/${tfile} &&
3262                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3263
3264         #use special ioctl() to unlink foreign_symlink file
3265         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3266                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3267
3268 }
3269 run_test 27O "basic ops on foreign file of symlink type"
3270
3271 test_27P() {
3272         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3273                 skip "Need MDS version newer than 2.12.49"
3274
3275         test_mkdir $DIR/$tdir
3276         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3277         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3278
3279         trap clean_foreign_symlink EXIT
3280
3281         # enable foreign_symlink behaviour
3282         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3283
3284         # foreign symlink LMV format is a partial path by default
3285
3286         # create foreign dir (lfs + API)
3287         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3288                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3289                 error "$DIR/$tdir/${tdir}: create failed"
3290
3291         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3292                 grep "lfm_magic:.*0x0CD50CD0" ||
3293                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3294         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3295                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3297                 grep "lfm_flags:.*0x0000DA05" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3299         $LFS getdirstripe $DIR/$tdir/${tdir} |
3300                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3302
3303         # file create in dir should fail
3304         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3305         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3306
3307         # rename should succeed
3308         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3309                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3310
3311         #remove foreign_symlink dir should fail
3312         rmdir $DIR/$tdir/${tdir}.new &&
3313                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3314
3315         #test fake symlink
3316         mkdir -p /tmp/${uuid1}/${uuid2} ||
3317                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3318         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3319                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3320         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3321         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3322                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3323         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3324                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3325
3326         #check that getstripe fails now that foreign_symlink enabled
3327         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3328                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3329
3330         # file create in dir should work now
3331         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3332                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3333         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3334                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3335         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3336                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3337
3338         # chmod should still succeed
3339         chmod 755 $DIR/$tdir/${tdir}.new ||
3340                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3341
3342         # chown should still succeed
3343         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3344                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3345
3346         # rename should still succeed
3347         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3348                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3349
3350         #remove foreign_symlink dir should still fail
3351         rmdir $DIR/$tdir/${tdir} &&
3352                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3353
3354         #use special ioctl() to unlink foreign_symlink file
3355         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3356                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3357
3358         #created file should still exist
3359         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3360                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3361         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3362                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3363 }
3364 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3365
3366 test_27Q() {
3367         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3368         stack_trap "rm -f $TMP/$tfile*"
3369
3370         test_mkdir $DIR/$tdir-1
3371         test_mkdir $DIR/$tdir-2
3372
3373         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3374         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3375
3376         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3377         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3378
3379         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3380         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3381
3382         # Create some bad symlinks and ensure that we don't loop
3383         # forever or something. These should return ELOOP (40) and
3384         # ENOENT (2) but I don't want to test for that because there's
3385         # always some weirdo architecture that needs to ruin
3386         # everything by defining these error numbers differently.
3387
3388         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3389         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3390
3391         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3392         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3393
3394         return 0
3395 }
3396 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3397
3398 # createtest also checks that device nodes are created and
3399 # then visible correctly (#2091)
3400 test_28() { # bug 2091
3401         test_mkdir $DIR/d28
3402         $CREATETEST $DIR/d28/ct || error "createtest failed"
3403 }
3404 run_test 28 "create/mknod/mkdir with bad file types ============"
3405
3406 test_29() {
3407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3408
3409         sync; sleep 1; sync # flush out any dirty pages from previous tests
3410         cancel_lru_locks
3411         test_mkdir $DIR/d29
3412         touch $DIR/d29/foo
3413         log 'first d29'
3414         ls -l $DIR/d29
3415
3416         declare -i LOCKCOUNTORIG=0
3417         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3418                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3419         done
3420         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3421
3422         declare -i LOCKUNUSEDCOUNTORIG=0
3423         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3424                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3425         done
3426
3427         log 'second d29'
3428         ls -l $DIR/d29
3429         log 'done'
3430
3431         declare -i LOCKCOUNTCURRENT=0
3432         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3433                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3434         done
3435
3436         declare -i LOCKUNUSEDCOUNTCURRENT=0
3437         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3438                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3439         done
3440
3441         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3442                 $LCTL set_param -n ldlm.dump_namespaces ""
3443                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3444                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3445                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3446                 return 2
3447         fi
3448         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3449                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3450                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3451                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3452                 return 3
3453         fi
3454 }
3455 run_test 29 "IT_GETATTR regression  ============================"
3456
3457 test_30a() { # was test_30
3458         cp $(which ls) $DIR || cp /bin/ls $DIR
3459         $DIR/ls / || error "Can't execute binary from lustre"
3460         rm $DIR/ls
3461 }
3462 run_test 30a "execute binary from Lustre (execve) =============="
3463
3464 test_30b() {
3465         cp `which ls` $DIR || cp /bin/ls $DIR
3466         chmod go+rx $DIR/ls
3467         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3468         rm $DIR/ls
3469 }
3470 run_test 30b "execute binary from Lustre as non-root ==========="
3471
3472 test_30c() { # b=22376
3473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3474
3475         cp $(which ls) $DIR || cp /bin/ls $DIR
3476         chmod a-rw $DIR/ls
3477         cancel_lru_locks mdc
3478         cancel_lru_locks osc
3479         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3480         rm -f $DIR/ls
3481 }
3482 run_test 30c "execute binary from Lustre without read perms ===="
3483
3484 test_30d() {
3485         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3486
3487         for i in {1..10}; do
3488                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3489                 local PID=$!
3490                 sleep 1
3491                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3492                 wait $PID || error "executing dd from Lustre failed"
3493                 rm -f $DIR/$tfile
3494         done
3495
3496         rm -f $DIR/dd
3497 }
3498 run_test 30d "execute binary from Lustre while clear locks"
3499
3500 test_31a() {
3501         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3502         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3503 }
3504 run_test 31a "open-unlink file =================================="
3505
3506 test_31b() {
3507         touch $DIR/f31 || error "touch $DIR/f31 failed"
3508         ln $DIR/f31 $DIR/f31b || error "ln failed"
3509         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3510         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3511 }
3512 run_test 31b "unlink file with multiple links while open ======="
3513
3514 test_31c() {
3515         touch $DIR/f31 || error "touch $DIR/f31 failed"
3516         ln $DIR/f31 $DIR/f31c || error "ln failed"
3517         multiop_bg_pause $DIR/f31 O_uc ||
3518                 error "multiop_bg_pause for $DIR/f31 failed"
3519         MULTIPID=$!
3520         $MULTIOP $DIR/f31c Ouc
3521         kill -USR1 $MULTIPID
3522         wait $MULTIPID
3523 }
3524 run_test 31c "open-unlink file with multiple links ============="
3525
3526 test_31d() {
3527         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3528         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3529 }
3530 run_test 31d "remove of open directory ========================="
3531
3532 test_31e() { # bug 2904
3533         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3534 }
3535 run_test 31e "remove of open non-empty directory ==============="
3536
3537 test_31f() { # bug 4554
3538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3539
3540         set -vx
3541         test_mkdir $DIR/d31f
3542         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3543         cp /etc/hosts $DIR/d31f
3544         ls -l $DIR/d31f
3545         $LFS getstripe $DIR/d31f/hosts
3546         multiop_bg_pause $DIR/d31f D_c || return 1
3547         MULTIPID=$!
3548
3549         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3550         test_mkdir $DIR/d31f
3551         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3552         cp /etc/hosts $DIR/d31f
3553         ls -l $DIR/d31f
3554         $LFS getstripe $DIR/d31f/hosts
3555         multiop_bg_pause $DIR/d31f D_c || return 1
3556         MULTIPID2=$!
3557
3558         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3559         wait $MULTIPID || error "first opendir $MULTIPID failed"
3560
3561         sleep 6
3562
3563         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3564         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3565         set +vx
3566 }
3567 run_test 31f "remove of open directory with open-unlink file ==="
3568
3569 test_31g() {
3570         echo "-- cross directory link --"
3571         test_mkdir -c1 $DIR/${tdir}ga
3572         test_mkdir -c1 $DIR/${tdir}gb
3573         touch $DIR/${tdir}ga/f
3574         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3575         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3576         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3577         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3578         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3579 }
3580 run_test 31g "cross directory link==============="
3581
3582 test_31h() {
3583         echo "-- cross directory link --"
3584         test_mkdir -c1 $DIR/${tdir}
3585         test_mkdir -c1 $DIR/${tdir}/dir
3586         touch $DIR/${tdir}/f
3587         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3588         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3589         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3590         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3591         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3592 }
3593 run_test 31h "cross directory link under child==============="
3594
3595 test_31i() {
3596         echo "-- cross directory link --"
3597         test_mkdir -c1 $DIR/$tdir
3598         test_mkdir -c1 $DIR/$tdir/dir
3599         touch $DIR/$tdir/dir/f
3600         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3601         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3602         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3603         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3604         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3605 }
3606 run_test 31i "cross directory link under parent==============="
3607
3608 test_31j() {
3609         test_mkdir -c1 -p $DIR/$tdir
3610         test_mkdir -c1 -p $DIR/$tdir/dir1
3611         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3612         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3613         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3614         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3615         return 0
3616 }
3617 run_test 31j "link for directory==============="
3618
3619 test_31k() {
3620         test_mkdir -c1 -p $DIR/$tdir
3621         touch $DIR/$tdir/s
3622         touch $DIR/$tdir/exist
3623         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3624         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3625         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3626         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3627         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3628         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3629         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3630         return 0
3631 }
3632 run_test 31k "link to file: the same, non-existing, dir==============="
3633
3634 test_31m() {
3635         mkdir $DIR/d31m
3636         touch $DIR/d31m/s
3637         mkdir $DIR/d31m2
3638         touch $DIR/d31m2/exist
3639         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3640         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3641         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3642         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3643         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3644         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3645         return 0
3646 }
3647 run_test 31m "link to file: the same, non-existing, dir==============="
3648
3649 test_31n() {
3650         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3651         nlink=$(stat --format=%h $DIR/$tfile)
3652         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3653         local fd=$(free_fd)
3654         local cmd="exec $fd<$DIR/$tfile"
3655         eval $cmd
3656         cmd="exec $fd<&-"
3657         trap "eval $cmd" EXIT
3658         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3659         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3660         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3661         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3662         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3663         eval $cmd
3664 }
3665 run_test 31n "check link count of unlinked file"
3666
3667 link_one() {
3668         local tempfile=$(mktemp $1_XXXXXX)
3669         mlink $tempfile $1 2> /dev/null &&
3670                 echo "$BASHPID: link $tempfile to $1 succeeded"
3671         munlink $tempfile
3672 }
3673
3674 test_31o() { # LU-2901
3675         test_mkdir $DIR/$tdir
3676         for LOOP in $(seq 100); do
3677                 rm -f $DIR/$tdir/$tfile*
3678                 for THREAD in $(seq 8); do
3679                         link_one $DIR/$tdir/$tfile.$LOOP &
3680                 done
3681                 wait
3682                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3683                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3684                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3685                         break || true
3686         done
3687 }
3688 run_test 31o "duplicate hard links with same filename"
3689
3690 test_31p() {
3691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3692
3693         test_mkdir $DIR/$tdir
3694         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3695         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3696
3697         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3698                 error "open unlink test1 failed"
3699         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3700                 error "open unlink test2 failed"
3701
3702         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3703                 error "test1 still exists"
3704         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3705                 error "test2 still exists"
3706 }
3707 run_test 31p "remove of open striped directory"
3708
3709 test_31q() {
3710         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3711
3712         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3713         index=$($LFS getdirstripe -i $DIR/$tdir)
3714         [ $index -eq 3 ] || error "first stripe index $index != 3"
3715         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3716         [ $index -eq 1 ] || error "second stripe index $index != 1"
3717
3718         # when "-c <stripe_count>" is set, the number of MDTs specified after
3719         # "-i" should equal to the stripe count
3720         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3721 }
3722 run_test 31q "create striped directory on specific MDTs"
3723
3724 #LU-14949
3725 test_31r() {
3726         touch $DIR/$tfile.target
3727         touch $DIR/$tfile.source
3728
3729         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3730         $LCTL set_param fail_loc=0x1419 fail_val=3
3731         cat $DIR/$tfile.target &
3732         CATPID=$!
3733
3734         # Guarantee open is waiting before we get here
3735         sleep 1
3736         mv $DIR/$tfile.source $DIR/$tfile.target
3737
3738         wait $CATPID
3739         RC=$?
3740         if [[ $RC -ne 0 ]]; then
3741                 error "open with cat failed, rc=$RC"
3742         fi
3743 }
3744 run_test 31r "open-rename(replace) race"
3745
3746 cleanup_test32_mount() {
3747         local rc=0
3748         trap 0
3749         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3750         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3751         losetup -d $loopdev || true
3752         rm -rf $DIR/$tdir
3753         return $rc
3754 }
3755
3756 test_32a() {
3757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3758
3759         echo "== more mountpoints and symlinks ================="
3760         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3761         trap cleanup_test32_mount EXIT
3762         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3763         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3764                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3765         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3766                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3767         cleanup_test32_mount
3768 }
3769 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3770
3771 test_32b() {
3772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3773
3774         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3775         trap cleanup_test32_mount EXIT
3776         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3777         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3778                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3779         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3780                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3781         cleanup_test32_mount
3782 }
3783 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3784
3785 test_32c() {
3786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3787
3788         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3789         trap cleanup_test32_mount EXIT
3790         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3791         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3792                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3793         test_mkdir -p $DIR/$tdir/d2/test_dir
3794         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3795                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3796         cleanup_test32_mount
3797 }
3798 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3799
3800 test_32d() {
3801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3802
3803         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3804         trap cleanup_test32_mount EXIT
3805         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3806         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3807                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3808         test_mkdir -p $DIR/$tdir/d2/test_dir
3809         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3810                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3811         cleanup_test32_mount
3812 }
3813 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3814
3815 test_32e() {
3816         rm -fr $DIR/$tdir
3817         test_mkdir -p $DIR/$tdir/tmp
3818         local tmp_dir=$DIR/$tdir/tmp
3819         ln -s $DIR/$tdir $tmp_dir/symlink11
3820         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3821         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3822         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3823 }
3824 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3825
3826 test_32f() {
3827         rm -fr $DIR/$tdir
3828         test_mkdir -p $DIR/$tdir/tmp
3829         local tmp_dir=$DIR/$tdir/tmp
3830         ln -s $DIR/$tdir $tmp_dir/symlink11
3831         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3832         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3833         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3834 }
3835 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3836
3837 test_32g() {
3838         local tmp_dir=$DIR/$tdir/tmp
3839         test_mkdir -p $tmp_dir
3840         test_mkdir $DIR/${tdir}2
3841         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3842         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3843         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3844         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3845         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3846         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3847 }
3848 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3849
3850 test_32h() {
3851         rm -fr $DIR/$tdir $DIR/${tdir}2
3852         tmp_dir=$DIR/$tdir/tmp
3853         test_mkdir -p $tmp_dir
3854         test_mkdir $DIR/${tdir}2
3855         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3856         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3857         ls $tmp_dir/symlink12 || error "listing symlink12"
3858         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3859 }
3860 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3861
3862 test_32i() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         touch $DIR/$tdir/test_file
3871         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3872                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3873         cleanup_test32_mount
3874 }
3875 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3876
3877 test_32j() {
3878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3879
3880         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3881         trap cleanup_test32_mount EXIT
3882         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3883         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3884                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3885         touch $DIR/$tdir/test_file
3886         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3887                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3888         cleanup_test32_mount
3889 }
3890 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3891
3892 test_32k() {
3893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3894
3895         rm -fr $DIR/$tdir
3896         trap cleanup_test32_mount EXIT
3897         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3898         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3899                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3900         test_mkdir -p $DIR/$tdir/d2
3901         touch $DIR/$tdir/d2/test_file || error "touch failed"
3902         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3903                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3904         cleanup_test32_mount
3905 }
3906 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3907
3908 test_32l() {
3909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3910
3911         rm -fr $DIR/$tdir
3912         trap cleanup_test32_mount EXIT
3913         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3914         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3915                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3916         test_mkdir -p $DIR/$tdir/d2
3917         touch $DIR/$tdir/d2/test_file || error "touch failed"
3918         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3919                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3920         cleanup_test32_mount
3921 }
3922 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3923
3924 test_32m() {
3925         rm -fr $DIR/d32m
3926         test_mkdir -p $DIR/d32m/tmp
3927         TMP_DIR=$DIR/d32m/tmp
3928         ln -s $DIR $TMP_DIR/symlink11
3929         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3930         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3931                 error "symlink11 not a link"
3932         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3933                 error "symlink01 not a link"
3934 }
3935 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3936
3937 test_32n() {
3938         rm -fr $DIR/d32n
3939         test_mkdir -p $DIR/d32n/tmp
3940         TMP_DIR=$DIR/d32n/tmp
3941         ln -s $DIR $TMP_DIR/symlink11
3942         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3943         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3944         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3945 }
3946 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3947
3948 test_32o() {
3949         touch $DIR/$tfile
3950         test_mkdir -p $DIR/d32o/tmp
3951         TMP_DIR=$DIR/d32o/tmp
3952         ln -s $DIR/$tfile $TMP_DIR/symlink12
3953         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3954         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3955                 error "symlink12 not a link"
3956         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3957         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3958                 error "$DIR/d32o/tmp/symlink12 not file type"
3959         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3960                 error "$DIR/d32o/symlink02 not file type"
3961 }
3962 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3963
3964 test_32p() {
3965         log 32p_1
3966         rm -fr $DIR/d32p
3967         log 32p_2
3968         rm -f $DIR/$tfile
3969         log 32p_3
3970         touch $DIR/$tfile
3971         log 32p_4
3972         test_mkdir -p $DIR/d32p/tmp
3973         log 32p_5
3974         TMP_DIR=$DIR/d32p/tmp
3975         log 32p_6
3976         ln -s $DIR/$tfile $TMP_DIR/symlink12
3977         log 32p_7
3978         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3979         log 32p_8
3980         cat $DIR/d32p/tmp/symlink12 ||
3981                 error "Can't open $DIR/d32p/tmp/symlink12"
3982         log 32p_9
3983         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3984         log 32p_10
3985 }
3986 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3987
3988 test_32q() {
3989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3990
3991         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3992         trap cleanup_test32_mount EXIT
3993         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3994         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3995         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3996                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3997         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3998         cleanup_test32_mount
3999 }
4000 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4001
4002 test_32r() {
4003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4004
4005         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4006         trap cleanup_test32_mount EXIT
4007         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4008         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4009         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4010                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4011         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4012         cleanup_test32_mount
4013 }
4014 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4015
4016 test_33aa() {
4017         rm -f $DIR/$tfile
4018         touch $DIR/$tfile
4019         chmod 444 $DIR/$tfile
4020         chown $RUNAS_ID $DIR/$tfile
4021         log 33_1
4022         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4023         log 33_2
4024 }
4025 run_test 33aa "write file with mode 444 (should return error)"
4026
4027 test_33a() {
4028         rm -fr $DIR/$tdir
4029         test_mkdir $DIR/$tdir
4030         chown $RUNAS_ID $DIR/$tdir
4031         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4032                 error "$RUNAS create $tdir/$tfile failed"
4033         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4034                 error "open RDWR" || true
4035 }
4036 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4037
4038 test_33b() {
4039         rm -fr $DIR/$tdir
4040         test_mkdir $DIR/$tdir
4041         chown $RUNAS_ID $DIR/$tdir
4042         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4043 }
4044 run_test 33b "test open file with malformed flags (No panic)"
4045
4046 test_33c() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048         remote_ost_nodsh && skip "remote OST with nodsh"
4049
4050         local ostnum
4051         local ostname
4052         local write_bytes
4053         local all_zeros
4054
4055         all_zeros=true
4056         test_mkdir $DIR/$tdir
4057         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4058
4059         sync
4060         for ostnum in $(seq $OSTCOUNT); do
4061                 # test-framework's OST numbering is one-based, while Lustre's
4062                 # is zero-based
4063                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4064                 # check if at least some write_bytes stats are counted
4065                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4066                               obdfilter.$ostname.stats |
4067                               awk '/^write_bytes/ {print $7}' )
4068                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4069                 if (( ${write_bytes:-0} > 0 )); then
4070                         all_zeros=false
4071                         break
4072                 fi
4073         done
4074
4075         $all_zeros || return 0
4076
4077         # Write four bytes
4078         echo foo > $DIR/$tdir/bar
4079         # Really write them
4080         sync
4081
4082         # Total up write_bytes after writing.  We'd better find non-zeros.
4083         for ostnum in $(seq $OSTCOUNT); do
4084                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4085                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4086                               obdfilter/$ostname/stats |
4087                               awk '/^write_bytes/ {print $7}' )
4088                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4089                 if (( ${write_bytes:-0} > 0 )); then
4090                         all_zeros=false
4091                         break
4092                 fi
4093         done
4094
4095         if $all_zeros; then
4096                 for ostnum in $(seq $OSTCOUNT); do
4097                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4098                         echo "Check write_bytes is in obdfilter.*.stats:"
4099                         do_facet ost$ostnum lctl get_param -n \
4100                                 obdfilter.$ostname.stats
4101                 done
4102                 error "OST not keeping write_bytes stats (b=22312)"
4103         fi
4104 }
4105 run_test 33c "test write_bytes stats"
4106
4107 test_33d() {
4108         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110
4111         local MDTIDX=1
4112         local remote_dir=$DIR/$tdir/remote_dir
4113
4114         test_mkdir $DIR/$tdir
4115         $LFS mkdir -i $MDTIDX $remote_dir ||
4116                 error "create remote directory failed"
4117
4118         touch $remote_dir/$tfile
4119         chmod 444 $remote_dir/$tfile
4120         chown $RUNAS_ID $remote_dir/$tfile
4121
4122         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4123
4124         chown $RUNAS_ID $remote_dir
4125         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4126                                         error "create" || true
4127         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4128                                     error "open RDWR" || true
4129         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4130 }
4131 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4132
4133 test_33e() {
4134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4135
4136         mkdir $DIR/$tdir
4137
4138         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4139         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4140         mkdir $DIR/$tdir/local_dir
4141
4142         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4143         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4144         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4145
4146         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4147                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4148
4149         rmdir $DIR/$tdir/* || error "rmdir failed"
4150
4151         umask 777
4152         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4153         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4154         mkdir $DIR/$tdir/local_dir
4155
4156         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4157         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4158         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4159
4160         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4161                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4162
4163         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4164
4165         umask 000
4166         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4167         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4168         mkdir $DIR/$tdir/local_dir
4169
4170         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4171         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4172         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4173
4174         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4175                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4176 }
4177 run_test 33e "mkdir and striped directory should have same mode"
4178
4179 cleanup_33f() {
4180         trap 0
4181         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4182 }
4183
4184 test_33f() {
4185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4186         remote_mds_nodsh && skip "remote MDS with nodsh"
4187
4188         mkdir $DIR/$tdir
4189         chmod go+rwx $DIR/$tdir
4190         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4191         trap cleanup_33f EXIT
4192
4193         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4194                 error "cannot create striped directory"
4195
4196         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4197                 error "cannot create files in striped directory"
4198
4199         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4200                 error "cannot remove files in striped directory"
4201
4202         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4203                 error "cannot remove striped directory"
4204
4205         cleanup_33f
4206 }
4207 run_test 33f "nonroot user can create, access, and remove a striped directory"
4208
4209 test_33g() {
4210         mkdir -p $DIR/$tdir/dir2
4211
4212         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4213         echo $err
4214         [[ $err =~ "exists" ]] || error "Not exists error"
4215 }
4216 run_test 33g "nonroot user create already existing root created file"
4217
4218 test_33h() {
4219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4220         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4221                 skip "Need MDS version at least 2.13.50"
4222
4223         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4224                 error "mkdir $tdir failed"
4225         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4226
4227         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4228         local index2
4229
4230         for fname in $DIR/$tdir/$tfile.bak \
4231                      $DIR/$tdir/$tfile.SAV \
4232                      $DIR/$tdir/$tfile.orig \
4233                      $DIR/$tdir/$tfile~; do
4234                 touch $fname  || error "touch $fname failed"
4235                 index2=$($LFS getstripe -m $fname)
4236                 [ $index -eq $index2 ] ||
4237                         error "$fname MDT index mismatch $index != $index2"
4238         done
4239
4240         local failed=0
4241         for i in {1..250}; do
4242                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4243                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4244                         touch $fname  || error "touch $fname failed"
4245                         index2=$($LFS getstripe -m $fname)
4246                         if [[ $index != $index2 ]]; then
4247                                 failed=$((failed + 1))
4248                                 echo "$fname MDT index mismatch $index != $index2"
4249                         fi
4250                 done
4251         done
4252         echo "$failed MDT index mismatches"
4253         (( failed < 20 )) || error "MDT index mismatch $failed times"
4254
4255 }
4256 run_test 33h "temp file is located on the same MDT as target"
4257
4258 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4259 test_34a() {
4260         rm -f $DIR/f34
4261         $MCREATE $DIR/f34 || error "mcreate failed"
4262         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4263                 error "getstripe failed"
4264         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4265         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4266                 error "getstripe failed"
4267         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4268                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4269 }
4270 run_test 34a "truncate file that has not been opened ==========="
4271
4272 test_34b() {
4273         [ ! -f $DIR/f34 ] && test_34a
4274         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4275                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4276         $OPENFILE -f O_RDONLY $DIR/f34
4277         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4278                 error "getstripe failed"
4279         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4280                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4281 }
4282 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4283
4284 test_34c() {
4285         [ ! -f $DIR/f34 ] && test_34a
4286         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4287                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4288         $OPENFILE -f O_RDWR $DIR/f34
4289         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4290                 error "$LFS getstripe failed"
4291         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4292                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4293 }
4294 run_test 34c "O_RDWR opening file-with-size works =============="
4295
4296 test_34d() {
4297         [ ! -f $DIR/f34 ] && test_34a
4298         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4299                 error "dd failed"
4300         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4301                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4302         rm $DIR/f34
4303 }
4304 run_test 34d "write to sparse file ============================="
4305
4306 test_34e() {
4307         rm -f $DIR/f34e
4308         $MCREATE $DIR/f34e || error "mcreate failed"
4309         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4310         $CHECKSTAT -s 1000 $DIR/f34e ||
4311                 error "Size of $DIR/f34e not equal to 1000 bytes"
4312         $OPENFILE -f O_RDWR $DIR/f34e
4313         $CHECKSTAT -s 1000 $DIR/f34e ||
4314                 error "Size of $DIR/f34e not equal to 1000 bytes"
4315 }
4316 run_test 34e "create objects, some with size and some without =="
4317
4318 test_34f() { # bug 6242, 6243
4319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4320
4321         SIZE34F=48000
4322         rm -f $DIR/f34f
4323         $MCREATE $DIR/f34f || error "mcreate failed"
4324         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4325         dd if=$DIR/f34f of=$TMP/f34f
4326         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4327         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4328         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4329         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4330         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4331 }
4332 run_test 34f "read from a file with no objects until EOF ======="
4333
4334 test_34g() {
4335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4336
4337         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4338                 error "dd failed"
4339         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4340         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4341                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4342         cancel_lru_locks osc
4343         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4344                 error "wrong size after lock cancel"
4345
4346         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4347         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4348                 error "expanding truncate failed"
4349         cancel_lru_locks osc
4350         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4351                 error "wrong expanded size after lock cancel"
4352 }
4353 run_test 34g "truncate long file ==============================="
4354
4355 test_34h() {
4356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4357
4358         local gid=10
4359         local sz=1000
4360
4361         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4362         sync # Flush the cache so that multiop below does not block on cache
4363              # flush when getting the group lock
4364         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4365         MULTIPID=$!
4366
4367         # Since just timed wait is not good enough, let's do a sync write
4368         # that way we are sure enough time for a roundtrip + processing
4369         # passed + 2 seconds of extra margin.
4370         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4371         rm $DIR/${tfile}-1
4372         sleep 2
4373
4374         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4375                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4376                 kill -9 $MULTIPID
4377         fi
4378         wait $MULTIPID
4379         local nsz=`stat -c %s $DIR/$tfile`
4380         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4381 }
4382 run_test 34h "ftruncate file under grouplock should not block"
4383
4384 test_35a() {
4385         cp /bin/sh $DIR/f35a
4386         chmod 444 $DIR/f35a
4387         chown $RUNAS_ID $DIR/f35a
4388         $RUNAS $DIR/f35a && error || true
4389         rm $DIR/f35a
4390 }
4391 run_test 35a "exec file with mode 444 (should return and not leak)"
4392
4393 test_36a() {
4394         rm -f $DIR/f36
4395         utime $DIR/f36 || error "utime failed for MDS"
4396 }
4397 run_test 36a "MDS utime check (mknod, utime)"
4398
4399 test_36b() {
4400         echo "" > $DIR/f36
4401         utime $DIR/f36 || error "utime failed for OST"
4402 }
4403 run_test 36b "OST utime check (open, utime)"
4404
4405 test_36c() {
4406         rm -f $DIR/d36/f36
4407         test_mkdir $DIR/d36
4408         chown $RUNAS_ID $DIR/d36
4409         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4410 }
4411 run_test 36c "non-root MDS utime check (mknod, utime)"
4412
4413 test_36d() {
4414         [ ! -d $DIR/d36 ] && test_36c
4415         echo "" > $DIR/d36/f36
4416         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4417 }
4418 run_test 36d "non-root OST utime check (open, utime)"
4419
4420 test_36e() {
4421         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4422
4423         test_mkdir $DIR/$tdir
4424         touch $DIR/$tdir/$tfile
4425         $RUNAS utime $DIR/$tdir/$tfile &&
4426                 error "utime worked, expected failure" || true
4427 }
4428 run_test 36e "utime on non-owned file (should return error)"
4429
4430 subr_36fh() {
4431         local fl="$1"
4432         local LANG_SAVE=$LANG
4433         local LC_LANG_SAVE=$LC_LANG
4434         export LANG=C LC_LANG=C # for date language
4435
4436         DATESTR="Dec 20  2000"
4437         test_mkdir $DIR/$tdir
4438         lctl set_param fail_loc=$fl
4439         date; date +%s
4440         cp /etc/hosts $DIR/$tdir/$tfile
4441         sync & # write RPC generated with "current" inode timestamp, but delayed
4442         sleep 1
4443         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4444         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4445         cancel_lru_locks $OSC
4446         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4447         date; date +%s
4448         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4449                 echo "BEFORE: $LS_BEFORE" && \
4450                 echo "AFTER : $LS_AFTER" && \
4451                 echo "WANT  : $DATESTR" && \
4452                 error "$DIR/$tdir/$tfile timestamps changed" || true
4453
4454         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4455 }
4456
4457 test_36f() {
4458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4459
4460         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4461         subr_36fh "0x80000214"
4462 }
4463 run_test 36f "utime on file racing with OST BRW write =========="
4464
4465 test_36g() {
4466         remote_ost_nodsh && skip "remote OST with nodsh"
4467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4468         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4469                 skip "Need MDS version at least 2.12.51"
4470
4471         local fmd_max_age
4472         local fmd
4473         local facet="ost1"
4474         local tgt="obdfilter"
4475
4476         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4477
4478         test_mkdir $DIR/$tdir
4479         fmd_max_age=$(do_facet $facet \
4480                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4481                 head -n 1")
4482
4483         echo "FMD max age: ${fmd_max_age}s"
4484         touch $DIR/$tdir/$tfile
4485         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4486                 gawk '{cnt=cnt+$1}  END{print cnt}')
4487         echo "FMD before: $fmd"
4488         [[ $fmd == 0 ]] &&
4489                 error "FMD wasn't create by touch"
4490         sleep $((fmd_max_age + 12))
4491         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4492                 gawk '{cnt=cnt+$1}  END{print cnt}')
4493         echo "FMD after: $fmd"
4494         [[ $fmd == 0 ]] ||
4495                 error "FMD wasn't expired by ping"
4496 }
4497 run_test 36g "FMD cache expiry ====================="
4498
4499 test_36h() {
4500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4501
4502         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4503         subr_36fh "0x80000227"
4504 }
4505 run_test 36h "utime on file racing with OST BRW write =========="
4506
4507 test_36i() {
4508         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4509
4510         test_mkdir $DIR/$tdir
4511         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4512
4513         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4514         local new_mtime=$((mtime + 200))
4515
4516         #change Modify time of striped dir
4517         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4518                         error "change mtime failed"
4519
4520         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4521
4522         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4523 }
4524 run_test 36i "change mtime on striped directory"
4525
4526 # test_37 - duplicate with tests 32q 32r
4527
4528 test_38() {
4529         local file=$DIR/$tfile
4530         touch $file
4531         openfile -f O_DIRECTORY $file
4532         local RC=$?
4533         local ENOTDIR=20
4534         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4535         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4536 }
4537 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4538
4539 test_39a() { # was test_39
4540         touch $DIR/$tfile
4541         touch $DIR/${tfile}2
4542 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4543 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4544 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4545         sleep 2
4546         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4547         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4548                 echo "mtime"
4549                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4550                 echo "atime"
4551                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4552                 echo "ctime"
4553                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4554                 error "O_TRUNC didn't change timestamps"
4555         fi
4556 }
4557 run_test 39a "mtime changed on create"
4558
4559 test_39b() {
4560         test_mkdir -c1 $DIR/$tdir
4561         cp -p /etc/passwd $DIR/$tdir/fopen
4562         cp -p /etc/passwd $DIR/$tdir/flink
4563         cp -p /etc/passwd $DIR/$tdir/funlink
4564         cp -p /etc/passwd $DIR/$tdir/frename
4565         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4566
4567         sleep 1
4568         echo "aaaaaa" >> $DIR/$tdir/fopen
4569         echo "aaaaaa" >> $DIR/$tdir/flink
4570         echo "aaaaaa" >> $DIR/$tdir/funlink
4571         echo "aaaaaa" >> $DIR/$tdir/frename
4572
4573         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4574         local link_new=`stat -c %Y $DIR/$tdir/flink`
4575         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4576         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4577
4578         cat $DIR/$tdir/fopen > /dev/null
4579         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4580         rm -f $DIR/$tdir/funlink2
4581         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4582
4583         for (( i=0; i < 2; i++ )) ; do
4584                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4585                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4586                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4587                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4588
4589                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4590                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4591                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4592                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4593
4594                 cancel_lru_locks $OSC
4595                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4596         done
4597 }
4598 run_test 39b "mtime change on open, link, unlink, rename  ======"
4599
4600 # this should be set to past
4601 TEST_39_MTIME=`date -d "1 year ago" +%s`
4602
4603 # bug 11063
4604 test_39c() {
4605         touch $DIR1/$tfile
4606         sleep 2
4607         local mtime0=`stat -c %Y $DIR1/$tfile`
4608
4609         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4610         local mtime1=`stat -c %Y $DIR1/$tfile`
4611         [ "$mtime1" = $TEST_39_MTIME ] || \
4612                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4613
4614         local d1=`date +%s`
4615         echo hello >> $DIR1/$tfile
4616         local d2=`date +%s`
4617         local mtime2=`stat -c %Y $DIR1/$tfile`
4618         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4619                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4620
4621         mv $DIR1/$tfile $DIR1/$tfile-1
4622
4623         for (( i=0; i < 2; i++ )) ; do
4624                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4625                 [ "$mtime2" = "$mtime3" ] || \
4626                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4627
4628                 cancel_lru_locks $OSC
4629                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4630         done
4631 }
4632 run_test 39c "mtime change on rename ==========================="
4633
4634 # bug 21114
4635 test_39d() {
4636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4637
4638         touch $DIR1/$tfile
4639         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4640
4641         for (( i=0; i < 2; i++ )) ; do
4642                 local mtime=`stat -c %Y $DIR1/$tfile`
4643                 [ $mtime = $TEST_39_MTIME ] || \
4644                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4645
4646                 cancel_lru_locks $OSC
4647                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4648         done
4649 }
4650 run_test 39d "create, utime, stat =============================="
4651
4652 # bug 21114
4653 test_39e() {
4654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4655
4656         touch $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4660
4661         for (( i=0; i < 2; i++ )) ; do
4662                 local mtime2=`stat -c %Y $DIR1/$tfile`
4663                 [ $mtime2 = $TEST_39_MTIME ] || \
4664                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4665
4666                 cancel_lru_locks $OSC
4667                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4668         done
4669 }
4670 run_test 39e "create, stat, utime, stat ========================"
4671
4672 # bug 21114
4673 test_39f() {
4674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4675
4676         touch $DIR1/$tfile
4677         mtime1=`stat -c %Y $DIR1/$tfile`
4678
4679         sleep 2
4680         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4681
4682         for (( i=0; i < 2; i++ )) ; do
4683                 local mtime2=`stat -c %Y $DIR1/$tfile`
4684                 [ $mtime2 = $TEST_39_MTIME ] || \
4685                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4686
4687                 cancel_lru_locks $OSC
4688                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4689         done
4690 }
4691 run_test 39f "create, stat, sleep, utime, stat ================="
4692
4693 # bug 11063
4694 test_39g() {
4695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4696
4697         echo hello >> $DIR1/$tfile
4698         local mtime1=`stat -c %Y $DIR1/$tfile`
4699
4700         sleep 2
4701         chmod o+r $DIR1/$tfile
4702
4703         for (( i=0; i < 2; i++ )) ; do
4704                 local mtime2=`stat -c %Y $DIR1/$tfile`
4705                 [ "$mtime1" = "$mtime2" ] || \
4706                         error "lost mtime: $mtime2, should be $mtime1"
4707
4708                 cancel_lru_locks $OSC
4709                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4710         done
4711 }
4712 run_test 39g "write, chmod, stat ==============================="
4713
4714 # bug 11063
4715 test_39h() {
4716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4717
4718         touch $DIR1/$tfile
4719         sleep 1
4720
4721         local d1=`date`
4722         echo hello >> $DIR1/$tfile
4723         local mtime1=`stat -c %Y $DIR1/$tfile`
4724
4725         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4726         local d2=`date`
4727         if [ "$d1" != "$d2" ]; then
4728                 echo "write and touch not within one second"
4729         else
4730                 for (( i=0; i < 2; i++ )) ; do
4731                         local mtime2=`stat -c %Y $DIR1/$tfile`
4732                         [ "$mtime2" = $TEST_39_MTIME ] || \
4733                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4734
4735                         cancel_lru_locks $OSC
4736                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4737                 done
4738         fi
4739 }
4740 run_test 39h "write, utime within one second, stat ============="
4741
4742 test_39i() {
4743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4744
4745         touch $DIR1/$tfile
4746         sleep 1
4747
4748         echo hello >> $DIR1/$tfile
4749         local mtime1=`stat -c %Y $DIR1/$tfile`
4750
4751         mv $DIR1/$tfile $DIR1/$tfile-1
4752
4753         for (( i=0; i < 2; i++ )) ; do
4754                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4755
4756                 [ "$mtime1" = "$mtime2" ] || \
4757                         error "lost mtime: $mtime2, should be $mtime1"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39i "write, rename, stat =============================="
4764
4765 test_39j() {
4766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4767
4768         start_full_debug_logging
4769         touch $DIR1/$tfile
4770         sleep 1
4771
4772         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4773         lctl set_param fail_loc=0x80000412
4774         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4775                 error "multiop failed"
4776         local multipid=$!
4777         local mtime1=`stat -c %Y $DIR1/$tfile`
4778
4779         mv $DIR1/$tfile $DIR1/$tfile-1
4780
4781         kill -USR1 $multipid
4782         wait $multipid || error "multiop close failed"
4783
4784         for (( i=0; i < 2; i++ )) ; do
4785                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4786                 [ "$mtime1" = "$mtime2" ] ||
4787                         error "mtime is lost on close: $mtime2, " \
4788                               "should be $mtime1"
4789
4790                 cancel_lru_locks
4791                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4792         done
4793         lctl set_param fail_loc=0
4794         stop_full_debug_logging
4795 }
4796 run_test 39j "write, rename, close, stat ======================="
4797
4798 test_39k() {
4799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4800
4801         touch $DIR1/$tfile
4802         sleep 1
4803
4804         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4805         local multipid=$!
4806         local mtime1=`stat -c %Y $DIR1/$tfile`
4807
4808         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4809
4810         kill -USR1 $multipid
4811         wait $multipid || error "multiop close failed"
4812
4813         for (( i=0; i < 2; i++ )) ; do
4814                 local mtime2=`stat -c %Y $DIR1/$tfile`
4815
4816                 [ "$mtime2" = $TEST_39_MTIME ] || \
4817                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4818
4819                 cancel_lru_locks
4820                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4821         done
4822 }
4823 run_test 39k "write, utime, close, stat ========================"
4824
4825 # this should be set to future
4826 TEST_39_ATIME=`date -d "1 year" +%s`
4827
4828 test_39l() {
4829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4830         remote_mds_nodsh && skip "remote MDS with nodsh"
4831
4832         local atime_diff=$(do_facet $SINGLEMDS \
4833                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4834         rm -rf $DIR/$tdir
4835         mkdir_on_mdt0 $DIR/$tdir
4836
4837         # test setting directory atime to future
4838         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4839         local atime=$(stat -c %X $DIR/$tdir)
4840         [ "$atime" = $TEST_39_ATIME ] ||
4841                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4842
4843         # test setting directory atime from future to now
4844         local now=$(date +%s)
4845         touch -a -d @$now $DIR/$tdir
4846
4847         atime=$(stat -c %X $DIR/$tdir)
4848         [ "$atime" -eq "$now"  ] ||
4849                 error "atime is not updated from future: $atime, $now"
4850
4851         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4852         sleep 3
4853
4854         # test setting directory atime when now > dir atime + atime_diff
4855         local d1=$(date +%s)
4856         ls $DIR/$tdir
4857         local d2=$(date +%s)
4858         cancel_lru_locks mdc
4859         atime=$(stat -c %X $DIR/$tdir)
4860         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4861                 error "atime is not updated  : $atime, should be $d2"
4862
4863         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4864         sleep 3
4865
4866         # test not setting directory atime when now < dir atime + atime_diff
4867         ls $DIR/$tdir
4868         cancel_lru_locks mdc
4869         atime=$(stat -c %X $DIR/$tdir)
4870         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4871                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4872
4873         do_facet $SINGLEMDS \
4874                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4875 }
4876 run_test 39l "directory atime update ==========================="
4877
4878 test_39m() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         touch $DIR1/$tfile
4882         sleep 2
4883         local far_past_mtime=$(date -d "May 29 1953" +%s)
4884         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4885
4886         touch -m -d @$far_past_mtime $DIR1/$tfile
4887         touch -a -d @$far_past_atime $DIR1/$tfile
4888
4889         for (( i=0; i < 2; i++ )) ; do
4890                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4891                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4892                         error "atime or mtime set incorrectly"
4893
4894                 cancel_lru_locks $OSC
4895                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4896         done
4897 }
4898 run_test 39m "test atime and mtime before 1970"
4899
4900 test_39n() { # LU-3832
4901         remote_mds_nodsh && skip "remote MDS with nodsh"
4902
4903         local atime_diff=$(do_facet $SINGLEMDS \
4904                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4905         local atime0
4906         local atime1
4907         local atime2
4908
4909         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4910
4911         rm -rf $DIR/$tfile
4912         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4913         atime0=$(stat -c %X $DIR/$tfile)
4914
4915         sleep 5
4916         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4917         atime1=$(stat -c %X $DIR/$tfile)
4918
4919         sleep 5
4920         cancel_lru_locks mdc
4921         cancel_lru_locks osc
4922         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4923         atime2=$(stat -c %X $DIR/$tfile)
4924
4925         do_facet $SINGLEMDS \
4926                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4927
4928         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4929         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4930 }
4931 run_test 39n "check that O_NOATIME is honored"
4932
4933 test_39o() {
4934         TESTDIR=$DIR/$tdir/$tfile
4935         [ -e $TESTDIR ] && rm -rf $TESTDIR
4936         mkdir -p $TESTDIR
4937         cd $TESTDIR
4938         links1=2
4939         ls
4940         mkdir a b
4941         ls
4942         links2=$(stat -c %h .)
4943         [ $(($links1 + 2)) != $links2 ] &&
4944                 error "wrong links count $(($links1 + 2)) != $links2"
4945         rmdir b
4946         links3=$(stat -c %h .)
4947         [ $(($links1 + 1)) != $links3 ] &&
4948                 error "wrong links count $links1 != $links3"
4949         return 0
4950 }
4951 run_test 39o "directory cached attributes updated after create"
4952
4953 test_39p() {
4954         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4955
4956         local MDTIDX=1
4957         TESTDIR=$DIR/$tdir/$tdir
4958         [ -e $TESTDIR ] && rm -rf $TESTDIR
4959         test_mkdir -p $TESTDIR
4960         cd $TESTDIR
4961         links1=2
4962         ls
4963         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4964         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4965         ls
4966         links2=$(stat -c %h .)
4967         [ $(($links1 + 2)) != $links2 ] &&
4968                 error "wrong links count $(($links1 + 2)) != $links2"
4969         rmdir remote_dir2
4970         links3=$(stat -c %h .)
4971         [ $(($links1 + 1)) != $links3 ] &&
4972                 error "wrong links count $links1 != $links3"
4973         return 0
4974 }
4975 run_test 39p "remote directory cached attributes updated after create ========"
4976
4977 test_39r() {
4978         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4979                 skip "no atime update on old OST"
4980         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4981                 skip_env "ldiskfs only test"
4982         fi
4983
4984         local saved_adiff
4985         saved_adiff=$(do_facet ost1 \
4986                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4987         stack_trap "do_facet ost1 \
4988                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4989
4990         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4991
4992         $LFS setstripe -i 0 $DIR/$tfile
4993         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4994                 error "can't write initial file"
4995         cancel_lru_locks osc
4996
4997         # exceed atime_diff and access file
4998         sleep 6
4999         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5000                 error "can't udpate atime"
5001
5002         local atime_cli=$(stat -c %X $DIR/$tfile)
5003         echo "client atime: $atime_cli"
5004         # allow atime update to be written to device
5005         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5006         sleep 5
5007
5008         local ostdev=$(ostdevname 1)
5009         local fid=($(lfs getstripe -y $DIR/$tfile |
5010                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5011         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5012         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5013
5014         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5015         local atime_ost=$(do_facet ost1 "$cmd" |&
5016                           awk -F'[: ]' '/atime:/ { print $4 }')
5017         (( atime_cli == atime_ost )) ||
5018                 error "atime on client $atime_cli != ost $atime_ost"
5019 }
5020 run_test 39r "lazy atime update on OST"
5021
5022 test_39q() { # LU-8041
5023         local testdir=$DIR/$tdir
5024         mkdir -p $testdir
5025         multiop_bg_pause $testdir D_c || error "multiop failed"
5026         local multipid=$!
5027         cancel_lru_locks mdc
5028         kill -USR1 $multipid
5029         local atime=$(stat -c %X $testdir)
5030         [ "$atime" -ne 0 ] || error "atime is zero"
5031 }
5032 run_test 39q "close won't zero out atime"
5033
5034 test_40() {
5035         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5036         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5037                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5038         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5039                 error "$tfile is not 4096 bytes in size"
5040 }
5041 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5042
5043 test_41() {
5044         # bug 1553
5045         small_write $DIR/f41 18
5046 }
5047 run_test 41 "test small file write + fstat ====================="
5048
5049 count_ost_writes() {
5050         lctl get_param -n ${OSC}.*.stats |
5051                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5052                         END { printf("%0.0f", writes) }'
5053 }
5054
5055 # decent default
5056 WRITEBACK_SAVE=500
5057 DIRTY_RATIO_SAVE=40
5058 MAX_DIRTY_RATIO=50
5059 BG_DIRTY_RATIO_SAVE=10
5060 MAX_BG_DIRTY_RATIO=25
5061
5062 start_writeback() {
5063         trap 0
5064         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5065         # dirty_ratio, dirty_background_ratio
5066         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5067                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5068                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5069                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5070         else
5071                 # if file not here, we are a 2.4 kernel
5072                 kill -CONT `pidof kupdated`
5073         fi
5074 }
5075
5076 stop_writeback() {
5077         # setup the trap first, so someone cannot exit the test at the
5078         # exact wrong time and mess up a machine
5079         trap start_writeback EXIT
5080         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5081         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5082                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5083                 sysctl -w vm.dirty_writeback_centisecs=0
5084                 sysctl -w vm.dirty_writeback_centisecs=0
5085                 # save and increase /proc/sys/vm/dirty_ratio
5086                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5087                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5088                 # save and increase /proc/sys/vm/dirty_background_ratio
5089                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5090                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5091         else
5092                 # if file not here, we are a 2.4 kernel
5093                 kill -STOP `pidof kupdated`
5094         fi
5095 }
5096
5097 # ensure that all stripes have some grant before we test client-side cache
5098 setup_test42() {
5099         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5100                 dd if=/dev/zero of=$i bs=4k count=1
5101                 rm $i
5102         done
5103 }
5104
5105 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5106 # file truncation, and file removal.
5107 test_42a() {
5108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5109
5110         setup_test42
5111         cancel_lru_locks $OSC
5112         stop_writeback
5113         sync; sleep 1; sync # just to be safe
5114         BEFOREWRITES=`count_ost_writes`
5115         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5116         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5117         AFTERWRITES=`count_ost_writes`
5118         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5119                 error "$BEFOREWRITES < $AFTERWRITES"
5120         start_writeback
5121 }
5122 run_test 42a "ensure that we don't flush on close"
5123
5124 test_42b() {
5125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5126
5127         setup_test42
5128         cancel_lru_locks $OSC
5129         stop_writeback
5130         sync
5131         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5132         BEFOREWRITES=$(count_ost_writes)
5133         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5134         AFTERWRITES=$(count_ost_writes)
5135         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5136                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5137         fi
5138         BEFOREWRITES=$(count_ost_writes)
5139         sync || error "sync: $?"
5140         AFTERWRITES=$(count_ost_writes)
5141         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5142                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5143         fi
5144         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5145         start_writeback
5146         return 0
5147 }
5148 run_test 42b "test destroy of file with cached dirty data ======"
5149
5150 # if these tests just want to test the effect of truncation,
5151 # they have to be very careful.  consider:
5152 # - the first open gets a {0,EOF}PR lock
5153 # - the first write conflicts and gets a {0, count-1}PW
5154 # - the rest of the writes are under {count,EOF}PW
5155 # - the open for truncate tries to match a {0,EOF}PR
5156 #   for the filesize and cancels the PWs.
5157 # any number of fixes (don't get {0,EOF} on open, match
5158 # composite locks, do smarter file size management) fix
5159 # this, but for now we want these tests to verify that
5160 # the cancellation with truncate intent works, so we
5161 # start the file with a full-file pw lock to match against
5162 # until the truncate.
5163 trunc_test() {
5164         test=$1
5165         file=$DIR/$test
5166         offset=$2
5167         cancel_lru_locks $OSC
5168         stop_writeback
5169         # prime the file with 0,EOF PW to match
5170         touch $file
5171         $TRUNCATE $file 0
5172         sync; sync
5173         # now the real test..
5174         dd if=/dev/zero of=$file bs=1024 count=100
5175         BEFOREWRITES=`count_ost_writes`
5176         $TRUNCATE $file $offset
5177         cancel_lru_locks $OSC
5178         AFTERWRITES=`count_ost_writes`
5179         start_writeback
5180 }
5181
5182 test_42c() {
5183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5184
5185         trunc_test 42c 1024
5186         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5187                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5188         rm $file
5189 }
5190 run_test 42c "test partial truncate of file with cached dirty data"
5191
5192 test_42d() {
5193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5194
5195         trunc_test 42d 0
5196         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5197                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5198         rm $file
5199 }
5200 run_test 42d "test complete truncate of file with cached dirty data"
5201
5202 test_42e() { # bug22074
5203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5204
5205         local TDIR=$DIR/${tdir}e
5206         local pages=16 # hardcoded 16 pages, don't change it.
5207         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5208         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5209         local max_dirty_mb
5210         local warmup_files
5211
5212         test_mkdir $DIR/${tdir}e
5213         $LFS setstripe -c 1 $TDIR
5214         createmany -o $TDIR/f $files
5215
5216         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5217
5218         # we assume that with $OSTCOUNT files, at least one of them will
5219         # be allocated on OST0.
5220         warmup_files=$((OSTCOUNT * max_dirty_mb))
5221         createmany -o $TDIR/w $warmup_files
5222
5223         # write a large amount of data into one file and sync, to get good
5224         # avail_grant number from OST.
5225         for ((i=0; i<$warmup_files; i++)); do
5226                 idx=$($LFS getstripe -i $TDIR/w$i)
5227                 [ $idx -ne 0 ] && continue
5228                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5229                 break
5230         done
5231         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5232         sync
5233         $LCTL get_param $proc_osc0/cur_dirty_bytes
5234         $LCTL get_param $proc_osc0/cur_grant_bytes
5235
5236         # create as much dirty pages as we can while not to trigger the actual
5237         # RPCs directly. but depends on the env, VFS may trigger flush during this
5238         # period, hopefully we are good.
5239         for ((i=0; i<$warmup_files; i++)); do
5240                 idx=$($LFS getstripe -i $TDIR/w$i)
5241                 [ $idx -ne 0 ] && continue
5242                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5243         done
5244         $LCTL get_param $proc_osc0/cur_dirty_bytes
5245         $LCTL get_param $proc_osc0/cur_grant_bytes
5246
5247         # perform the real test
5248         $LCTL set_param $proc_osc0/rpc_stats 0
5249         for ((;i<$files; i++)); do
5250                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5251                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5252         done
5253         sync
5254         $LCTL get_param $proc_osc0/rpc_stats
5255
5256         local percent=0
5257         local have_ppr=false
5258         $LCTL get_param $proc_osc0/rpc_stats |
5259                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5260                         # skip lines until we are at the RPC histogram data
5261                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5262                         $have_ppr || continue
5263
5264                         # we only want the percent stat for < 16 pages
5265                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5266
5267                         percent=$((percent + WPCT))
5268                         if [[ $percent -gt 15 ]]; then
5269                                 error "less than 16-pages write RPCs" \
5270                                       "$percent% > 15%"
5271                                 break
5272                         fi
5273                 done
5274         rm -rf $TDIR
5275 }
5276 run_test 42e "verify sub-RPC writes are not done synchronously"
5277
5278 test_43A() { # was test_43
5279         test_mkdir $DIR/$tdir
5280         cp -p /bin/ls $DIR/$tdir/$tfile
5281         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5282         pid=$!
5283         # give multiop a chance to open
5284         sleep 1
5285
5286         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5287         kill -USR1 $pid
5288         # Wait for multiop to exit
5289         wait $pid
5290 }
5291 run_test 43A "execution of file opened for write should return -ETXTBSY"
5292
5293 test_43a() {
5294         test_mkdir $DIR/$tdir
5295         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5296         $DIR/$tdir/sleep 60 &
5297         SLEEP_PID=$!
5298         # Make sure exec of $tdir/sleep wins race with truncate
5299         sleep 1
5300         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5301         kill $SLEEP_PID
5302 }
5303 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5304
5305 test_43b() {
5306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5307
5308         test_mkdir $DIR/$tdir
5309         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5310         $DIR/$tdir/sleep 60 &
5311         SLEEP_PID=$!
5312         # Make sure exec of $tdir/sleep wins race with truncate
5313         sleep 1
5314         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5315         kill $SLEEP_PID
5316 }
5317 run_test 43b "truncate of file being executed should return -ETXTBSY"
5318
5319 test_43c() {
5320         local testdir="$DIR/$tdir"
5321         test_mkdir $testdir
5322         cp $SHELL $testdir/
5323         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5324                 ( cd $testdir && md5sum -c )
5325 }
5326 run_test 43c "md5sum of copy into lustre"
5327
5328 test_44A() { # was test_44
5329         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5330
5331         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5332         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5333 }
5334 run_test 44A "zero length read from a sparse stripe"
5335
5336 test_44a() {
5337         local nstripe=$($LFS getstripe -c -d $DIR)
5338         [ -z "$nstripe" ] && skip "can't get stripe info"
5339         [[ $nstripe -gt $OSTCOUNT ]] &&
5340                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5341
5342         local stride=$($LFS getstripe -S -d $DIR)
5343         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5344                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5345         fi
5346
5347         OFFSETS="0 $((stride/2)) $((stride-1))"
5348         for offset in $OFFSETS; do
5349                 for i in $(seq 0 $((nstripe-1))); do
5350                         local GLOBALOFFSETS=""
5351                         # size in Bytes
5352                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5353                         local myfn=$DIR/d44a-$size
5354                         echo "--------writing $myfn at $size"
5355                         ll_sparseness_write $myfn $size ||
5356                                 error "ll_sparseness_write"
5357                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5358                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5359                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5360
5361                         for j in $(seq 0 $((nstripe-1))); do
5362                                 # size in Bytes
5363                                 size=$((((j + $nstripe )*$stride + $offset)))
5364                                 ll_sparseness_write $myfn $size ||
5365                                         error "ll_sparseness_write"
5366                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5367                         done
5368                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5369                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5370                         rm -f $myfn
5371                 done
5372         done
5373 }
5374 run_test 44a "test sparse pwrite ==============================="
5375
5376 dirty_osc_total() {
5377         tot=0
5378         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5379                 tot=$(($tot + $d))
5380         done
5381         echo $tot
5382 }
5383 do_dirty_record() {
5384         before=`dirty_osc_total`
5385         echo executing "\"$*\""
5386         eval $*
5387         after=`dirty_osc_total`
5388         echo before $before, after $after
5389 }
5390 test_45() {
5391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5392
5393         f="$DIR/f45"
5394         # Obtain grants from OST if it supports it
5395         echo blah > ${f}_grant
5396         stop_writeback
5397         sync
5398         do_dirty_record "echo blah > $f"
5399         [[ $before -eq $after ]] && error "write wasn't cached"
5400         do_dirty_record "> $f"
5401         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5402         do_dirty_record "echo blah > $f"
5403         [[ $before -eq $after ]] && error "write wasn't cached"
5404         do_dirty_record "sync"
5405         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5406         do_dirty_record "echo blah > $f"
5407         [[ $before -eq $after ]] && error "write wasn't cached"
5408         do_dirty_record "cancel_lru_locks osc"
5409         [[ $before -gt $after ]] ||
5410                 error "lock cancellation didn't lower dirty count"
5411         start_writeback
5412 }
5413 run_test 45 "osc io page accounting ============================"
5414
5415 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5416 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5417 # objects offset and an assert hit when an rpc was built with 1023's mapped
5418 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5419 test_46() {
5420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5421
5422         f="$DIR/f46"
5423         stop_writeback
5424         sync
5425         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5426         sync
5427         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5428         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5429         sync
5430         start_writeback
5431 }
5432 run_test 46 "dirtying a previously written page ================"
5433
5434 # test_47 is removed "Device nodes check" is moved to test_28
5435
5436 test_48a() { # bug 2399
5437         [ "$mds1_FSTYPE" = "zfs" ] &&
5438         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5439                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5440
5441         test_mkdir $DIR/$tdir
5442         cd $DIR/$tdir
5443         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5444         test_mkdir $DIR/$tdir
5445         touch foo || error "'touch foo' failed after recreating cwd"
5446         test_mkdir bar
5447         touch .foo || error "'touch .foo' failed after recreating cwd"
5448         test_mkdir .bar
5449         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5450         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5451         cd . || error "'cd .' failed after recreating cwd"
5452         mkdir . && error "'mkdir .' worked after recreating cwd"
5453         rmdir . && error "'rmdir .' worked after recreating cwd"
5454         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5455         cd .. || error "'cd ..' failed after recreating cwd"
5456 }
5457 run_test 48a "Access renamed working dir (should return errors)="
5458
5459 test_48b() { # bug 2399
5460         rm -rf $DIR/$tdir
5461         test_mkdir $DIR/$tdir
5462         cd $DIR/$tdir
5463         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5464         touch foo && error "'touch foo' worked after removing cwd"
5465         mkdir foo && error "'mkdir foo' worked after removing cwd"
5466         touch .foo && error "'touch .foo' worked after removing cwd"
5467         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5468         ls . > /dev/null && error "'ls .' worked after removing cwd"
5469         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5470         mkdir . && error "'mkdir .' worked after removing cwd"
5471         rmdir . && error "'rmdir .' worked after removing cwd"
5472         ln -s . foo && error "'ln -s .' worked after removing cwd"
5473         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5474 }
5475 run_test 48b "Access removed working dir (should return errors)="
5476
5477 test_48c() { # bug 2350
5478         #lctl set_param debug=-1
5479         #set -vx
5480         rm -rf $DIR/$tdir
5481         test_mkdir -p $DIR/$tdir/dir
5482         cd $DIR/$tdir/dir
5483         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5484         $TRACE touch foo && error "touch foo worked after removing cwd"
5485         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5486         touch .foo && error "touch .foo worked after removing cwd"
5487         mkdir .foo && error "mkdir .foo worked after removing cwd"
5488         $TRACE ls . && error "'ls .' worked after removing cwd"
5489         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5490         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5491         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5492         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5493         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5494 }
5495 run_test 48c "Access removed working subdir (should return errors)"
5496
5497 test_48d() { # bug 2350
5498         #lctl set_param debug=-1
5499         #set -vx
5500         rm -rf $DIR/$tdir
5501         test_mkdir -p $DIR/$tdir/dir
5502         cd $DIR/$tdir/dir
5503         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5504         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5505         $TRACE touch foo && error "'touch foo' worked after removing parent"
5506         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5507         touch .foo && error "'touch .foo' worked after removing parent"
5508         mkdir .foo && error "mkdir .foo worked after removing parent"
5509         $TRACE ls . && error "'ls .' worked after removing parent"
5510         $TRACE ls .. && error "'ls ..' worked after removing parent"
5511         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5512         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5513         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5514         true
5515 }
5516 run_test 48d "Access removed parent subdir (should return errors)"
5517
5518 test_48e() { # bug 4134
5519         #lctl set_param debug=-1
5520         #set -vx
5521         rm -rf $DIR/$tdir
5522         test_mkdir -p $DIR/$tdir/dir
5523         cd $DIR/$tdir/dir
5524         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5525         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5526         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5527         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5528         # On a buggy kernel addition of "touch foo" after cd .. will
5529         # produce kernel oops in lookup_hash_it
5530         touch ../foo && error "'cd ..' worked after recreate parent"
5531         cd $DIR
5532         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5533 }
5534 run_test 48e "Access to recreated parent subdir (should return errors)"
5535
5536 test_48f() {
5537         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5538                 skip "need MDS >= 2.13.55"
5539         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5540         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5541                 skip "needs different host for mdt1 mdt2"
5542         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5543
5544         $LFS mkdir -i0 $DIR/$tdir
5545         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5546
5547         for d in sub1 sub2 sub3; do
5548                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5549                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5550                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5551         done
5552
5553         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5554 }
5555 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5556
5557 test_49() { # LU-1030
5558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5559         remote_ost_nodsh && skip "remote OST with nodsh"
5560
5561         # get ost1 size - $FSNAME-OST0000
5562         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5563                 awk '{ print $4 }')
5564         # write 800M at maximum
5565         [[ $ost1_size -lt 2 ]] && ost1_size=2
5566         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5567
5568         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5569         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5570         local dd_pid=$!
5571
5572         # change max_pages_per_rpc while writing the file
5573         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5574         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5575         # loop until dd process exits
5576         while ps ax -opid | grep -wq $dd_pid; do
5577                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5578                 sleep $((RANDOM % 5 + 1))
5579         done
5580         # restore original max_pages_per_rpc
5581         $LCTL set_param $osc1_mppc=$orig_mppc
5582         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5583 }
5584 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5585
5586 test_50() {
5587         # bug 1485
5588         test_mkdir $DIR/$tdir
5589         cd $DIR/$tdir
5590         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5591 }
5592 run_test 50 "special situations: /proc symlinks  ==============="
5593
5594 test_51a() {    # was test_51
5595         # bug 1516 - create an empty entry right after ".." then split dir
5596         test_mkdir -c1 $DIR/$tdir
5597         touch $DIR/$tdir/foo
5598         $MCREATE $DIR/$tdir/bar
5599         rm $DIR/$tdir/foo
5600         createmany -m $DIR/$tdir/longfile 201
5601         FNUM=202
5602         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5603                 $MCREATE $DIR/$tdir/longfile$FNUM
5604                 FNUM=$(($FNUM + 1))
5605                 echo -n "+"
5606         done
5607         echo
5608         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5609 }
5610 run_test 51a "special situations: split htree with empty entry =="
5611
5612 cleanup_print_lfs_df () {
5613         trap 0
5614         $LFS df
5615         $LFS df -i
5616 }
5617
5618 test_51b() {
5619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5620
5621         local dir=$DIR/$tdir
5622         local nrdirs=$((65536 + 100))
5623
5624         # cleanup the directory
5625         rm -fr $dir
5626
5627         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5628
5629         $LFS df
5630         $LFS df -i
5631         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5632         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5633         [[ $numfree -lt $nrdirs ]] &&
5634                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5635
5636         # need to check free space for the directories as well
5637         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5638         numfree=$(( blkfree / $(fs_inode_ksize) ))
5639         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5640
5641         trap cleanup_print_lfs_df EXIT
5642
5643         # create files
5644         createmany -d $dir/d $nrdirs || {
5645                 unlinkmany $dir/d $nrdirs
5646                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5647         }
5648
5649         # really created :
5650         nrdirs=$(ls -U $dir | wc -l)
5651
5652         # unlink all but 100 subdirectories, then check it still works
5653         local left=100
5654         local delete=$((nrdirs - left))
5655
5656         $LFS df
5657         $LFS df -i
5658
5659         # for ldiskfs the nlink count should be 1, but this is OSD specific
5660         # and so this is listed for informational purposes only
5661         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5662         unlinkmany -d $dir/d $delete ||
5663                 error "unlink of first $delete subdirs failed"
5664
5665         echo "nlink between: $(stat -c %h $dir)"
5666         local found=$(ls -U $dir | wc -l)
5667         [ $found -ne $left ] &&
5668                 error "can't find subdirs: found only $found, expected $left"
5669
5670         unlinkmany -d $dir/d $delete $left ||
5671                 error "unlink of second $left subdirs failed"
5672         # regardless of whether the backing filesystem tracks nlink accurately
5673         # or not, the nlink count shouldn't be more than "." and ".." here
5674         local after=$(stat -c %h $dir)
5675         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5676                 echo "nlink after: $after"
5677
5678         cleanup_print_lfs_df
5679 }
5680 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5681
5682 test_51d() {
5683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5684         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5685
5686         test_mkdir $DIR/$tdir
5687         createmany -o $DIR/$tdir/t- 1000
5688         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5689         for N in $(seq 0 $((OSTCOUNT - 1))); do
5690                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5691                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5692                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5693                         '($1 == '$N') { objs += 1 } \
5694                         END { printf("%0.0f", objs) }')
5695                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5696         done
5697         unlinkmany $DIR/$tdir/t- 1000
5698
5699         NLAST=0
5700         for N in $(seq 1 $((OSTCOUNT - 1))); do
5701                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5702                         error "OST $N has less objects vs OST $NLAST" \
5703                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5704                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5705                         error "OST $N has less objects vs OST $NLAST" \
5706                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5707
5708                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5709                         error "OST $N has less #0 objects vs OST $NLAST" \
5710                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5711                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5712                         error "OST $N has less #0 objects vs OST $NLAST" \
5713                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5714                 NLAST=$N
5715         done
5716         rm -f $TMP/$tfile
5717 }
5718 run_test 51d "check object distribution"
5719
5720 test_51e() {
5721         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5722                 skip_env "ldiskfs only test"
5723         fi
5724
5725         test_mkdir -c1 $DIR/$tdir
5726         test_mkdir -c1 $DIR/$tdir/d0
5727
5728         touch $DIR/$tdir/d0/foo
5729         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5730                 error "file exceed 65000 nlink limit!"
5731         unlinkmany $DIR/$tdir/d0/f- 65001
5732         return 0
5733 }
5734 run_test 51e "check file nlink limit"
5735
5736 test_51f() {
5737         test_mkdir $DIR/$tdir
5738
5739         local max=100000
5740         local ulimit_old=$(ulimit -n)
5741         local spare=20 # number of spare fd's for scripts/libraries, etc.
5742         local mdt=$($LFS getstripe -m $DIR/$tdir)
5743         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5744
5745         echo "MDT$mdt numfree=$numfree, max=$max"
5746         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5747         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5748                 while ! ulimit -n $((numfree + spare)); do
5749                         numfree=$((numfree * 3 / 4))
5750                 done
5751                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5752         else
5753                 echo "left ulimit at $ulimit_old"
5754         fi
5755
5756         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5757                 unlinkmany $DIR/$tdir/f $numfree
5758                 error "create+open $numfree files in $DIR/$tdir failed"
5759         }
5760         ulimit -n $ulimit_old
5761
5762         # if createmany exits at 120s there will be fewer than $numfree files
5763         unlinkmany $DIR/$tdir/f $numfree || true
5764 }
5765 run_test 51f "check many open files limit"
5766
5767 test_52a() {
5768         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5769         test_mkdir $DIR/$tdir
5770         touch $DIR/$tdir/foo
5771         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5772         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5773         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5774         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5775         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5776                                         error "link worked"
5777         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5778         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5779         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5780                                                      error "lsattr"
5781         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5782         cp -r $DIR/$tdir $TMP/
5783         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5784 }
5785 run_test 52a "append-only flag test (should return errors)"
5786
5787 test_52b() {
5788         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5789         test_mkdir $DIR/$tdir
5790         touch $DIR/$tdir/foo
5791         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5792         cat test > $DIR/$tdir/foo && error "cat test worked"
5793         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5794         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5795         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5796                                         error "link worked"
5797         echo foo >> $DIR/$tdir/foo && error "echo worked"
5798         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5799         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5800         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5801         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5802                                                         error "lsattr"
5803         chattr -i $DIR/$tdir/foo || error "chattr failed"
5804
5805         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5806 }
5807 run_test 52b "immutable flag test (should return errors) ======="
5808
5809 test_53() {
5810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5811         remote_mds_nodsh && skip "remote MDS with nodsh"
5812         remote_ost_nodsh && skip "remote OST with nodsh"
5813
5814         local param
5815         local param_seq
5816         local ostname
5817         local mds_last
5818         local mds_last_seq
5819         local ost_last
5820         local ost_last_seq
5821         local ost_last_id
5822         local ostnum
5823         local node
5824         local found=false
5825         local support_last_seq=true
5826
5827         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5828                 support_last_seq=false
5829
5830         # only test MDT0000
5831         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5832         local value
5833         for value in $(do_facet $SINGLEMDS \
5834                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5835                 param=$(echo ${value[0]} | cut -d "=" -f1)
5836                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5837
5838                 if $support_last_seq; then
5839                         param_seq=$(echo $param |
5840                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5841                         mds_last_seq=$(do_facet $SINGLEMDS \
5842                                        $LCTL get_param -n $param_seq)
5843                 fi
5844                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5845
5846                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5847                 node=$(facet_active_host ost$((ostnum+1)))
5848                 param="obdfilter.$ostname.last_id"
5849                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5850                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5851                         ost_last_id=$ost_last
5852
5853                         if $support_last_seq; then
5854                                 ost_last_id=$(echo $ost_last |
5855                                               awk -F':' '{print $2}' |
5856                                               sed -e "s/^0x//g")
5857                                 ost_last_seq=$(echo $ost_last |
5858                                                awk -F':' '{print $1}')
5859                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5860                         fi
5861
5862                         if [[ $ost_last_id != $mds_last ]]; then
5863                                 error "$ost_last_id != $mds_last"
5864                         else
5865                                 found=true
5866                                 break
5867                         fi
5868                 done
5869         done
5870         $found || error "can not match last_seq/last_id for $mdtosc"
5871         return 0
5872 }
5873 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5874
5875 test_54a() {
5876         perl -MSocket -e ';' || skip "no Socket perl module installed"
5877
5878         $SOCKETSERVER $DIR/socket ||
5879                 error "$SOCKETSERVER $DIR/socket failed: $?"
5880         $SOCKETCLIENT $DIR/socket ||
5881                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5882         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5883 }
5884 run_test 54a "unix domain socket test =========================="
5885
5886 test_54b() {
5887         f="$DIR/f54b"
5888         mknod $f c 1 3
5889         chmod 0666 $f
5890         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5891 }
5892 run_test 54b "char device works in lustre ======================"
5893
5894 find_loop_dev() {
5895         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5896         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5897         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5898
5899         for i in $(seq 3 7); do
5900                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5901                 LOOPDEV=$LOOPBASE$i
5902                 LOOPNUM=$i
5903                 break
5904         done
5905 }
5906
5907 cleanup_54c() {
5908         local rc=0
5909         loopdev="$DIR/loop54c"
5910
5911         trap 0
5912         $UMOUNT $DIR/$tdir || rc=$?
5913         losetup -d $loopdev || true
5914         losetup -d $LOOPDEV || true
5915         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5916         return $rc
5917 }
5918
5919 test_54c() {
5920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5921
5922         loopdev="$DIR/loop54c"
5923
5924         find_loop_dev
5925         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5926         trap cleanup_54c EXIT
5927         mknod $loopdev b 7 $LOOPNUM
5928         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5929         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5930         losetup $loopdev $DIR/$tfile ||
5931                 error "can't set up $loopdev for $DIR/$tfile"
5932         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5933         test_mkdir $DIR/$tdir
5934         mount -t ext2 $loopdev $DIR/$tdir ||
5935                 error "error mounting $loopdev on $DIR/$tdir"
5936         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5937                 error "dd write"
5938         df $DIR/$tdir
5939         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5940                 error "dd read"
5941         cleanup_54c
5942 }
5943 run_test 54c "block device works in lustre ====================="
5944
5945 test_54d() {
5946         f="$DIR/f54d"
5947         string="aaaaaa"
5948         mknod $f p
5949         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5950 }
5951 run_test 54d "fifo device works in lustre ======================"
5952
5953 test_54e() {
5954         f="$DIR/f54e"
5955         string="aaaaaa"
5956         cp -aL /dev/console $f
5957         echo $string > $f || error "echo $string to $f failed"
5958 }
5959 run_test 54e "console/tty device works in lustre ======================"
5960
5961 test_56a() {
5962         local numfiles=3
5963         local numdirs=2
5964         local dir=$DIR/$tdir
5965
5966         rm -rf $dir
5967         test_mkdir -p $dir/dir
5968         for i in $(seq $numfiles); do
5969                 touch $dir/file$i
5970                 touch $dir/dir/file$i
5971         done
5972
5973         local numcomp=$($LFS getstripe --component-count $dir)
5974
5975         [[ $numcomp == 0 ]] && numcomp=1
5976
5977         # test lfs getstripe with --recursive
5978         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5979
5980         [[ $filenum -eq $((numfiles * 2)) ]] ||
5981                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5982         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5983         [[ $filenum -eq $numfiles ]] ||
5984                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5985         echo "$LFS getstripe showed obdidx or l_ost_idx"
5986
5987         # test lfs getstripe with file instead of dir
5988         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5989         [[ $filenum -eq 1 ]] ||
5990                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5991         echo "$LFS getstripe file1 passed"
5992
5993         #test lfs getstripe with --verbose
5994         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5995         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5996                 error "$LFS getstripe --verbose $dir: "\
5997                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5998         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5999                 error "$LFS getstripe $dir: showed lmm_magic"
6000
6001         #test lfs getstripe with -v prints lmm_fid
6002         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6003         local countfids=$((numdirs + numfiles * numcomp))
6004         [[ $filenum -eq $countfids ]] ||
6005                 error "$LFS getstripe -v $dir: "\
6006                       "got $filenum want $countfids lmm_fid"
6007         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6008                 error "$LFS getstripe $dir: showed lmm_fid by default"
6009         echo "$LFS getstripe --verbose passed"
6010
6011         #check for FID information
6012         local fid1=$($LFS getstripe --fid $dir/file1)
6013         local fid2=$($LFS getstripe --verbose $dir/file1 |
6014                      awk '/lmm_fid: / { print $2; exit; }')
6015         local fid3=$($LFS path2fid $dir/file1)
6016
6017         [ "$fid1" != "$fid2" ] &&
6018                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6019         [ "$fid1" != "$fid3" ] &&
6020                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6021         echo "$LFS getstripe --fid passed"
6022
6023         #test lfs getstripe with --obd
6024         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6025                 error "$LFS getstripe --obd wrong_uuid: should return error"
6026
6027         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6028
6029         local ostidx=1
6030         local obduuid=$(ostuuid_from_index $ostidx)
6031         local found=$($LFS getstripe -r --obd $obduuid $dir |
6032                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6033
6034         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6035         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6036                 ((filenum--))
6037         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6038                 ((filenum--))
6039
6040         [[ $found -eq $filenum ]] ||
6041                 error "$LFS getstripe --obd: found $found expect $filenum"
6042         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6043                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6044                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6045                 error "$LFS getstripe --obd: should not show file on other obd"
6046         echo "$LFS getstripe --obd passed"
6047 }
6048 run_test 56a "check $LFS getstripe"
6049
6050 test_56b() {
6051         local dir=$DIR/$tdir
6052         local numdirs=3
6053
6054         test_mkdir $dir
6055         for i in $(seq $numdirs); do
6056                 test_mkdir $dir/dir$i
6057         done
6058
6059         # test lfs getdirstripe default mode is non-recursion, which is
6060         # different from lfs getstripe
6061         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6062
6063         [[ $dircnt -eq 1 ]] ||
6064                 error "$LFS getdirstripe: found $dircnt, not 1"
6065         dircnt=$($LFS getdirstripe --recursive $dir |
6066                 grep -c lmv_stripe_count)
6067         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6068                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6069 }
6070 run_test 56b "check $LFS getdirstripe"
6071
6072 test_56c() {
6073         remote_ost_nodsh && skip "remote OST with nodsh"
6074
6075         local ost_idx=0
6076         local ost_name=$(ostname_from_index $ost_idx)
6077         local old_status=$(ost_dev_status $ost_idx)
6078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6079
6080         [[ -z "$old_status" ]] ||
6081                 skip_env "OST $ost_name is in $old_status status"
6082
6083         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6084         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6085                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6086         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6087                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6088                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6089         fi
6090
6091         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6092                 error "$LFS df -v showing inactive devices"
6093         sleep_maxage
6094
6095         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6096
6097         [[ "$new_status" =~ "D" ]] ||
6098                 error "$ost_name status is '$new_status', missing 'D'"
6099         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6100                 [[ "$new_status" =~ "N" ]] ||
6101                         error "$ost_name status is '$new_status', missing 'N'"
6102         fi
6103         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6104                 [[ "$new_status" =~ "f" ]] ||
6105                         error "$ost_name status is '$new_status', missing 'f'"
6106         fi
6107
6108         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6109         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6110                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6111         [[ -z "$p" ]] && restore_lustre_params < $p || true
6112         sleep_maxage
6113
6114         new_status=$(ost_dev_status $ost_idx)
6115         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6116                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6117         # can't check 'f' as devices may actually be on flash
6118 }
6119 run_test 56c "check 'lfs df' showing device status"
6120
6121 test_56d() {
6122         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6123         local osts=$($LFS df -v $MOUNT | grep -c OST)
6124
6125         $LFS df $MOUNT
6126
6127         (( mdts == MDSCOUNT )) ||
6128                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6129         (( osts == OSTCOUNT )) ||
6130                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6131 }
6132 run_test 56d "'lfs df -v' prints only configured devices"
6133
6134 NUMFILES=3
6135 NUMDIRS=3
6136 setup_56() {
6137         local local_tdir="$1"
6138         local local_numfiles="$2"
6139         local local_numdirs="$3"
6140         local dir_params="$4"
6141         local dir_stripe_params="$5"
6142
6143         if [ ! -d "$local_tdir" ] ; then
6144                 test_mkdir -p $dir_stripe_params $local_tdir
6145                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6146                 for i in $(seq $local_numfiles) ; do
6147                         touch $local_tdir/file$i
6148                 done
6149                 for i in $(seq $local_numdirs) ; do
6150                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6151                         for j in $(seq $local_numfiles) ; do
6152                                 touch $local_tdir/dir$i/file$j
6153                         done
6154                 done
6155         fi
6156 }
6157
6158 setup_56_special() {
6159         local local_tdir=$1
6160         local local_numfiles=$2
6161         local local_numdirs=$3
6162
6163         setup_56 $local_tdir $local_numfiles $local_numdirs
6164
6165         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6166                 for i in $(seq $local_numfiles) ; do
6167                         mknod $local_tdir/loop${i}b b 7 $i
6168                         mknod $local_tdir/null${i}c c 1 3
6169                         ln -s $local_tdir/file1 $local_tdir/link${i}
6170                 done
6171                 for i in $(seq $local_numdirs) ; do
6172                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6173                         mknod $local_tdir/dir$i/null${i}c c 1 3
6174                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6175                 done
6176         fi
6177 }
6178
6179 test_56g() {
6180         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6181         local expected=$(($NUMDIRS + 2))
6182
6183         setup_56 $dir $NUMFILES $NUMDIRS
6184
6185         # test lfs find with -name
6186         for i in $(seq $NUMFILES) ; do
6187                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6188
6189                 [ $nums -eq $expected ] ||
6190                         error "lfs find -name '*$i' $dir wrong: "\
6191                               "found $nums, expected $expected"
6192         done
6193 }
6194 run_test 56g "check lfs find -name"
6195
6196 test_56h() {
6197         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6198         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6199
6200         setup_56 $dir $NUMFILES $NUMDIRS
6201
6202         # test lfs find with ! -name
6203         for i in $(seq $NUMFILES) ; do
6204                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6205
6206                 [ $nums -eq $expected ] ||
6207                         error "lfs find ! -name '*$i' $dir wrong: "\
6208                               "found $nums, expected $expected"
6209         done
6210 }
6211 run_test 56h "check lfs find ! -name"
6212
6213 test_56i() {
6214         local dir=$DIR/$tdir
6215
6216         test_mkdir $dir
6217
6218         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6219         local out=$($cmd)
6220
6221         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6222 }
6223 run_test 56i "check 'lfs find -ost UUID' skips directories"
6224
6225 test_56j() {
6226         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6227
6228         setup_56_special $dir $NUMFILES $NUMDIRS
6229
6230         local expected=$((NUMDIRS + 1))
6231         local cmd="$LFS find -type d $dir"
6232         local nums=$($cmd | wc -l)
6233
6234         [ $nums -eq $expected ] ||
6235                 error "'$cmd' wrong: found $nums, expected $expected"
6236 }
6237 run_test 56j "check lfs find -type d"
6238
6239 test_56k() {
6240         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6241
6242         setup_56_special $dir $NUMFILES $NUMDIRS
6243
6244         local expected=$(((NUMDIRS + 1) * NUMFILES))
6245         local cmd="$LFS find -type f $dir"
6246         local nums=$($cmd | wc -l)
6247
6248         [ $nums -eq $expected ] ||
6249                 error "'$cmd' wrong: found $nums, expected $expected"
6250 }
6251 run_test 56k "check lfs find -type f"
6252
6253 test_56l() {
6254         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6255
6256         setup_56_special $dir $NUMFILES $NUMDIRS
6257
6258         local expected=$((NUMDIRS + NUMFILES))
6259         local cmd="$LFS find -type b $dir"
6260         local nums=$($cmd | wc -l)
6261
6262         [ $nums -eq $expected ] ||
6263                 error "'$cmd' wrong: found $nums, expected $expected"
6264 }
6265 run_test 56l "check lfs find -type b"
6266
6267 test_56m() {
6268         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6269
6270         setup_56_special $dir $NUMFILES $NUMDIRS
6271
6272         local expected=$((NUMDIRS + NUMFILES))
6273         local cmd="$LFS find -type c $dir"
6274         local nums=$($cmd | wc -l)
6275         [ $nums -eq $expected ] ||
6276                 error "'$cmd' wrong: found $nums, expected $expected"
6277 }
6278 run_test 56m "check lfs find -type c"
6279
6280 test_56n() {
6281         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6282         setup_56_special $dir $NUMFILES $NUMDIRS
6283
6284         local expected=$((NUMDIRS + NUMFILES))
6285         local cmd="$LFS find -type l $dir"
6286         local nums=$($cmd | wc -l)
6287
6288         [ $nums -eq $expected ] ||
6289                 error "'$cmd' wrong: found $nums, expected $expected"
6290 }
6291 run_test 56n "check lfs find -type l"
6292
6293 test_56o() {
6294         local dir=$DIR/$tdir
6295
6296         setup_56 $dir $NUMFILES $NUMDIRS
6297         utime $dir/file1 > /dev/null || error "utime (1)"
6298         utime $dir/file2 > /dev/null || error "utime (2)"
6299         utime $dir/dir1 > /dev/null || error "utime (3)"
6300         utime $dir/dir2 > /dev/null || error "utime (4)"
6301         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6302         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6303
6304         local expected=4
6305         local nums=$($LFS find -mtime +0 $dir | wc -l)
6306
6307         [ $nums -eq $expected ] ||
6308                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6309
6310         expected=12
6311         cmd="$LFS find -mtime 0 $dir"
6312         nums=$($cmd | wc -l)
6313         [ $nums -eq $expected ] ||
6314                 error "'$cmd' wrong: found $nums, expected $expected"
6315 }
6316 run_test 56o "check lfs find -mtime for old files"
6317
6318 test_56ob() {
6319         local dir=$DIR/$tdir
6320         local expected=1
6321         local count=0
6322
6323         # just to make sure there is something that won't be found
6324         test_mkdir $dir
6325         touch $dir/$tfile.now
6326
6327         for age in year week day hour min; do
6328                 count=$((count + 1))
6329
6330                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6331                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6332                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6333
6334                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6335                 local nums=$($cmd | wc -l)
6336                 [ $nums -eq $expected ] ||
6337                         error "'$cmd' wrong: found $nums, expected $expected"
6338
6339                 cmd="$LFS find $dir -atime $count${age:0:1}"
6340                 nums=$($cmd | wc -l)
6341                 [ $nums -eq $expected ] ||
6342                         error "'$cmd' wrong: found $nums, expected $expected"
6343         done
6344
6345         sleep 2
6346         cmd="$LFS find $dir -ctime +1s -type f"
6347         nums=$($cmd | wc -l)
6348         (( $nums == $count * 2 + 1)) ||
6349                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6350 }
6351 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6352
6353 test_newerXY_base() {
6354         local x=$1
6355         local y=$2
6356         local dir=$DIR/$tdir
6357         local ref
6358         local negref
6359
6360         if [ $y == "t" ]; then
6361                 if [ $x == "b" ]; then
6362                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6363                 else
6364                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6365                 fi
6366         else
6367                 ref=$DIR/$tfile.newer.$x$y
6368                 touch $ref || error "touch $ref failed"
6369         fi
6370
6371         echo "before = $ref"
6372         sleep 2
6373         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6374         sleep 2
6375         if [ $y == "t" ]; then
6376                 if [ $x == "b" ]; then
6377                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6378                 else
6379                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6380                 fi
6381         else
6382                 negref=$DIR/$tfile.negnewer.$x$y
6383                 touch $negref || error "touch $negref failed"
6384         fi
6385
6386         echo "after = $negref"
6387         local cmd="$LFS find $dir -newer$x$y $ref"
6388         local nums=$(eval $cmd | wc -l)
6389         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6390
6391         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6392                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6393
6394         cmd="$LFS find $dir ! -newer$x$y $negref"
6395         nums=$(eval $cmd | wc -l)
6396         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6397                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6398
6399         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6400         nums=$(eval $cmd | wc -l)
6401         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6402                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6403
6404         rm -rf $DIR/*
6405 }
6406
6407 test_56oc() {
6408         test_newerXY_base "a" "a"
6409         test_newerXY_base "a" "m"
6410         test_newerXY_base "a" "c"
6411         test_newerXY_base "m" "a"
6412         test_newerXY_base "m" "m"
6413         test_newerXY_base "m" "c"
6414         test_newerXY_base "c" "a"
6415         test_newerXY_base "c" "m"
6416         test_newerXY_base "c" "c"
6417
6418         [[ -n "$sles_version" ]] &&
6419                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6420
6421         test_newerXY_base "a" "t"
6422         test_newerXY_base "m" "t"
6423         test_newerXY_base "c" "t"
6424
6425         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6426            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6427                 ! btime_supported && echo "btime unsupported" && return 0
6428
6429         test_newerXY_base "b" "b"
6430         test_newerXY_base "b" "t"
6431 }
6432 run_test 56oc "check lfs find -newerXY work"
6433
6434 btime_supported() {
6435         local dir=$DIR/$tdir
6436         local rc
6437
6438         mkdir -p $dir
6439         touch $dir/$tfile
6440         $LFS find $dir -btime -1d -type f
6441         rc=$?
6442         rm -rf $dir
6443         return $rc
6444 }
6445
6446 test_56od() {
6447         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6448                 ! btime_supported && skip "btime unsupported on MDS"
6449
6450         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6451                 ! btime_supported && skip "btime unsupported on clients"
6452
6453         local dir=$DIR/$tdir
6454         local ref=$DIR/$tfile.ref
6455         local negref=$DIR/$tfile.negref
6456
6457         mkdir $dir || error "mkdir $dir failed"
6458         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6459         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6460         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6461         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6462         touch $ref || error "touch $ref failed"
6463         # sleep 3 seconds at least
6464         sleep 3
6465
6466         local before=$(do_facet mds1 date +%s)
6467         local skew=$(($(date +%s) - before + 1))
6468
6469         if (( skew < 0 && skew > -5 )); then
6470                 sleep $((0 - skew + 1))
6471                 skew=0
6472         fi
6473
6474         # Set the dir stripe params to limit files all on MDT0,
6475         # otherwise we need to calc the max clock skew between
6476         # the client and MDTs.
6477         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6478         sleep 2
6479         touch $negref || error "touch $negref failed"
6480
6481         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6482         local nums=$($cmd | wc -l)
6483         local expected=$(((NUMFILES + 1) * NUMDIRS))
6484
6485         [ $nums -eq $expected ] ||
6486                 error "'$cmd' wrong: found $nums, expected $expected"
6487
6488         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6489         nums=$($cmd | wc -l)
6490         expected=$((NUMFILES + 1))
6491         [ $nums -eq $expected ] ||
6492                 error "'$cmd' wrong: found $nums, expected $expected"
6493
6494         [ $skew -lt 0 ] && return
6495
6496         local after=$(do_facet mds1 date +%s)
6497         local age=$((after - before + 1 + skew))
6498
6499         cmd="$LFS find $dir -btime -${age}s -type f"
6500         nums=$($cmd | wc -l)
6501         expected=$(((NUMFILES + 1) * NUMDIRS))
6502
6503         echo "Clock skew between client and server: $skew, age:$age"
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506
6507         expected=$(($NUMDIRS + 1))
6508         cmd="$LFS find $dir -btime -${age}s -type d"
6509         nums=$($cmd | wc -l)
6510         [ $nums -eq $expected ] ||
6511                 error "'$cmd' wrong: found $nums, expected $expected"
6512         rm -f $ref $negref || error "Failed to remove $ref $negref"
6513 }
6514 run_test 56od "check lfs find -btime with units"
6515
6516 test_56p() {
6517         [ $RUNAS_ID -eq $UID ] &&
6518                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6519
6520         local dir=$DIR/$tdir
6521
6522         setup_56 $dir $NUMFILES $NUMDIRS
6523         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6524
6525         local expected=$NUMFILES
6526         local cmd="$LFS find -uid $RUNAS_ID $dir"
6527         local nums=$($cmd | wc -l)
6528
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6533         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537 }
6538 run_test 56p "check lfs find -uid and ! -uid"
6539
6540 test_56q() {
6541         [ $RUNAS_ID -eq $UID ] &&
6542                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6543
6544         local dir=$DIR/$tdir
6545
6546         setup_56 $dir $NUMFILES $NUMDIRS
6547         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6548
6549         local expected=$NUMFILES
6550         local cmd="$LFS find -gid $RUNAS_GID $dir"
6551         local nums=$($cmd | wc -l)
6552
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555
6556         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6557         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6558         nums=$($cmd | wc -l)
6559         [ $nums -eq $expected ] ||
6560                 error "'$cmd' wrong: found $nums, expected $expected"
6561 }
6562 run_test 56q "check lfs find -gid and ! -gid"
6563
6564 test_56r() {
6565         local dir=$DIR/$tdir
6566
6567         setup_56 $dir $NUMFILES $NUMDIRS
6568
6569         local expected=12
6570         local cmd="$LFS find -size 0 -type f -lazy $dir"
6571         local nums=$($cmd | wc -l)
6572
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575         cmd="$LFS find -size 0 -type f $dir"
6576         nums=$($cmd | wc -l)
6577         [ $nums -eq $expected ] ||
6578                 error "'$cmd' wrong: found $nums, expected $expected"
6579
6580         expected=0
6581         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6582         nums=$($cmd | wc -l)
6583         [ $nums -eq $expected ] ||
6584                 error "'$cmd' wrong: found $nums, expected $expected"
6585         cmd="$LFS find ! -size 0 -type f $dir"
6586         nums=$($cmd | wc -l)
6587         [ $nums -eq $expected ] ||
6588                 error "'$cmd' wrong: found $nums, expected $expected"
6589
6590         echo "test" > $dir/$tfile
6591         echo "test2" > $dir/$tfile.2 && sync
6592         expected=1
6593         cmd="$LFS find -size 5 -type f -lazy $dir"
6594         nums=$($cmd | wc -l)
6595         [ $nums -eq $expected ] ||
6596                 error "'$cmd' wrong: found $nums, expected $expected"
6597         cmd="$LFS find -size 5 -type f $dir"
6598         nums=$($cmd | wc -l)
6599         [ $nums -eq $expected ] ||
6600                 error "'$cmd' wrong: found $nums, expected $expected"
6601
6602         expected=1
6603         cmd="$LFS find -size +5 -type f -lazy $dir"
6604         nums=$($cmd | wc -l)
6605         [ $nums -eq $expected ] ||
6606                 error "'$cmd' wrong: found $nums, expected $expected"
6607         cmd="$LFS find -size +5 -type f $dir"
6608         nums=$($cmd | wc -l)
6609         [ $nums -eq $expected ] ||
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611
6612         expected=2
6613         cmd="$LFS find -size +0 -type f -lazy $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617         cmd="$LFS find -size +0 -type f $dir"
6618         nums=$($cmd | wc -l)
6619         [ $nums -eq $expected ] ||
6620                 error "'$cmd' wrong: found $nums, expected $expected"
6621
6622         expected=2
6623         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6624         nums=$($cmd | wc -l)
6625         [ $nums -eq $expected ] ||
6626                 error "'$cmd' wrong: found $nums, expected $expected"
6627         cmd="$LFS find ! -size -5 -type f $dir"
6628         nums=$($cmd | wc -l)
6629         [ $nums -eq $expected ] ||
6630                 error "'$cmd' wrong: found $nums, expected $expected"
6631
6632         expected=12
6633         cmd="$LFS find -size -5 -type f -lazy $dir"
6634         nums=$($cmd | wc -l)
6635         [ $nums -eq $expected ] ||
6636                 error "'$cmd' wrong: found $nums, expected $expected"
6637         cmd="$LFS find -size -5 -type f $dir"
6638         nums=$($cmd | wc -l)
6639         [ $nums -eq $expected ] ||
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641 }
6642 run_test 56r "check lfs find -size works"
6643
6644 test_56ra_sub() {
6645         local expected=$1
6646         local glimpses=$2
6647         local cmd="$3"
6648
6649         cancel_lru_locks $OSC
6650
6651         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6652         local nums=$($cmd | wc -l)
6653
6654         [ $nums -eq $expected ] ||
6655                 error "'$cmd' wrong: found $nums, expected $expected"
6656
6657         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6658
6659         if (( rpcs_before + glimpses != rpcs_after )); then
6660                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6661                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6662
6663                 if [[ $glimpses == 0 ]]; then
6664                         error "'$cmd' should not send glimpse RPCs to OST"
6665                 else
6666                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6667                 fi
6668         fi
6669 }
6670
6671 test_56ra() {
6672         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6673                 skip "MDS < 2.12.58 doesn't return LSOM data"
6674         local dir=$DIR/$tdir
6675         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6676
6677         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6678
6679         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6680         $LCTL set_param -n llite.*.statahead_agl=0
6681         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6682
6683         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6684         # open and close all files to ensure LSOM is updated
6685         cancel_lru_locks $OSC
6686         find $dir -type f | xargs cat > /dev/null
6687
6688         #   expect_found  glimpse_rpcs  command_to_run
6689         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6690         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6691         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6692         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6693
6694         echo "test" > $dir/$tfile
6695         echo "test2" > $dir/$tfile.2 && sync
6696         cancel_lru_locks $OSC
6697         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6698
6699         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6700         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6701         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6702         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6703
6704         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6705         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6706         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6707         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6708         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6709         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6710 }
6711 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6712
6713 test_56rb() {
6714         local dir=$DIR/$tdir
6715         local tmp=$TMP/$tfile.log
6716         local mdt_idx;
6717
6718         test_mkdir -p $dir || error "failed to mkdir $dir"
6719         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6720                 error "failed to setstripe $dir/$tfile"
6721         mdt_idx=$($LFS getdirstripe -i $dir)
6722         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6723
6724         stack_trap "rm -f $tmp" EXIT
6725         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6726         ! grep -q obd_uuid $tmp ||
6727                 error "failed to find --size +100K --ost 0 $dir"
6728         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6729         ! grep -q obd_uuid $tmp ||
6730                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6731 }
6732 run_test 56rb "check lfs find --size --ost/--mdt works"
6733
6734 test_56rc() {
6735         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6736         local dir=$DIR/$tdir
6737         local found
6738
6739         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6740         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6741         (( $MDSCOUNT > 2 )) &&
6742                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6743         mkdir $dir/$tdir-{1..10}
6744         touch $dir/$tfile-{1..10}
6745
6746         found=$($LFS find $dir --mdt-count 2 | wc -l)
6747         expect=11
6748         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6749
6750         found=$($LFS find $dir -T +1 | wc -l)
6751         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6752         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6753
6754         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6755         expect=11
6756         (( $found == $expect )) || error "found $found all_char, expect $expect"
6757
6758         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6759         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6760         (( $found == $expect )) || error "found $found all_char, expect $expect"
6761 }
6762 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6763
6764 test_56s() { # LU-611 #LU-9369
6765         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6766
6767         local dir=$DIR/$tdir
6768         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6771         for i in $(seq $NUMDIRS); do
6772                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6773         done
6774
6775         local expected=$NUMDIRS
6776         local cmd="$LFS find -c $OSTCOUNT $dir"
6777         local nums=$($cmd | wc -l)
6778
6779         [ $nums -eq $expected ] || {
6780                 $LFS getstripe -R $dir
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782         }
6783
6784         expected=$((NUMDIRS + onestripe))
6785         cmd="$LFS find -stripe-count +0 -type f $dir"
6786         nums=$($cmd | wc -l)
6787         [ $nums -eq $expected ] || {
6788                 $LFS getstripe -R $dir
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790         }
6791
6792         expected=$onestripe
6793         cmd="$LFS find -stripe-count 1 -type f $dir"
6794         nums=$($cmd | wc -l)
6795         [ $nums -eq $expected ] || {
6796                 $LFS getstripe -R $dir
6797                 error "'$cmd' wrong: found $nums, expected $expected"
6798         }
6799
6800         cmd="$LFS find -stripe-count -2 -type f $dir"
6801         nums=$($cmd | wc -l)
6802         [ $nums -eq $expected ] || {
6803                 $LFS getstripe -R $dir
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805         }
6806
6807         expected=0
6808         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] || {
6811                 $LFS getstripe -R $dir
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813         }
6814 }
6815 run_test 56s "check lfs find -stripe-count works"
6816
6817 test_56t() { # LU-611 #LU-9369
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir 0 $NUMDIRS
6821         for i in $(seq $NUMDIRS); do
6822                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6823         done
6824
6825         local expected=$NUMDIRS
6826         local cmd="$LFS find -S 8M $dir"
6827         local nums=$($cmd | wc -l)
6828
6829         [ $nums -eq $expected ] || {
6830                 $LFS getstripe -R $dir
6831                 error "'$cmd' wrong: found $nums, expected $expected"
6832         }
6833         rm -rf $dir
6834
6835         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6836
6837         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6838
6839         expected=$(((NUMDIRS + 1) * NUMFILES))
6840         cmd="$LFS find -stripe-size 512k -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         cmd="$LFS find -stripe-size +320k -type f $dir"
6846         nums=$($cmd | wc -l)
6847         [ $nums -eq $expected ] ||
6848                 error "'$cmd' wrong: found $nums, expected $expected"
6849
6850         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6851         cmd="$LFS find -stripe-size +200k -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855
6856         cmd="$LFS find -stripe-size -640k -type f $dir"
6857         nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860
6861         expected=4
6862         cmd="$LFS find -stripe-size 256k -type f $dir"
6863         nums=$($cmd | wc -l)
6864         [ $nums -eq $expected ] ||
6865                 error "'$cmd' wrong: found $nums, expected $expected"
6866
6867         cmd="$LFS find -stripe-size -320k -type f $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871
6872         expected=0
6873         cmd="$LFS find -stripe-size 1024k -type f $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877 }
6878 run_test 56t "check lfs find -stripe-size works"
6879
6880 test_56u() { # LU-611
6881         local dir=$DIR/$tdir
6882
6883         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6884
6885         if [[ $OSTCOUNT -gt 1 ]]; then
6886                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6887                 onestripe=4
6888         else
6889                 onestripe=0
6890         fi
6891
6892         local expected=$(((NUMDIRS + 1) * NUMFILES))
6893         local cmd="$LFS find -stripe-index 0 -type f $dir"
6894         local nums=$($cmd | wc -l)
6895
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898
6899         expected=$onestripe
6900         cmd="$LFS find -stripe-index 1 -type f $dir"
6901         nums=$($cmd | wc -l)
6902         [ $nums -eq $expected ] ||
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904
6905         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         expected=0
6911         # This should produce an error and not return any files
6912         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6913         nums=$($cmd 2>/dev/null | wc -l)
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916
6917         if [[ $OSTCOUNT -gt 1 ]]; then
6918                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6919                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6920                 nums=$($cmd | wc -l)
6921                 [ $nums -eq $expected ] ||
6922                         error "'$cmd' wrong: found $nums, expected $expected"
6923         fi
6924 }
6925 run_test 56u "check lfs find -stripe-index works"
6926
6927 test_56v() {
6928         local mdt_idx=0
6929         local dir=$DIR/$tdir
6930
6931         setup_56 $dir $NUMFILES $NUMDIRS
6932
6933         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6934         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6935
6936         for file in $($LFS find -m $UUID $dir); do
6937                 file_midx=$($LFS getstripe -m $file)
6938                 [ $file_midx -eq $mdt_idx ] ||
6939                         error "lfs find -m $UUID != getstripe -m $file_midx"
6940         done
6941 }
6942 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6943
6944 test_56w() {
6945         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6947
6948         local dir=$DIR/$tdir
6949
6950         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6951
6952         local stripe_size=$($LFS getstripe -S -d $dir) ||
6953                 error "$LFS getstripe -S -d $dir failed"
6954         stripe_size=${stripe_size%% *}
6955
6956         local file_size=$((stripe_size * OSTCOUNT))
6957         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6958         local required_space=$((file_num * file_size))
6959         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6960                            head -n1)
6961         [[ $free_space -le $((required_space / 1024)) ]] &&
6962                 skip_env "need $required_space, have $free_space kbytes"
6963
6964         local dd_bs=65536
6965         local dd_count=$((file_size / dd_bs))
6966
6967         # write data into the files
6968         local i
6969         local j
6970         local file
6971
6972         for i in $(seq $NUMFILES); do
6973                 file=$dir/file$i
6974                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6975                         error "write data into $file failed"
6976         done
6977         for i in $(seq $NUMDIRS); do
6978                 for j in $(seq $NUMFILES); do
6979                         file=$dir/dir$i/file$j
6980                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6981                                 error "write data into $file failed"
6982                 done
6983         done
6984
6985         # $LFS_MIGRATE will fail if hard link migration is unsupported
6986         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6987                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6988                         error "creating links to $dir/dir1/file1 failed"
6989         fi
6990
6991         local expected=-1
6992
6993         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6994
6995         # lfs_migrate file
6996         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6997
6998         echo "$cmd"
6999         eval $cmd || error "$cmd failed"
7000
7001         check_stripe_count $dir/file1 $expected
7002
7003         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7004         then
7005                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7006                 # OST 1 if it is on OST 0. This file is small enough to
7007                 # be on only one stripe.
7008                 file=$dir/migr_1_ost
7009                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7010                         error "write data into $file failed"
7011                 local obdidx=$($LFS getstripe -i $file)
7012                 local oldmd5=$(md5sum $file)
7013                 local newobdidx=0
7014
7015                 [[ $obdidx -eq 0 ]] && newobdidx=1
7016                 cmd="$LFS migrate -i $newobdidx $file"
7017                 echo $cmd
7018                 eval $cmd || error "$cmd failed"
7019
7020                 local realobdix=$($LFS getstripe -i $file)
7021                 local newmd5=$(md5sum $file)
7022
7023                 [[ $newobdidx -ne $realobdix ]] &&
7024                         error "new OST is different (was=$obdidx, "\
7025                               "wanted=$newobdidx, got=$realobdix)"
7026                 [[ "$oldmd5" != "$newmd5" ]] &&
7027                         error "md5sum differ: $oldmd5, $newmd5"
7028         fi
7029
7030         # lfs_migrate dir
7031         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7032         echo "$cmd"
7033         eval $cmd || error "$cmd failed"
7034
7035         for j in $(seq $NUMFILES); do
7036                 check_stripe_count $dir/dir1/file$j $expected
7037         done
7038
7039         # lfs_migrate works with lfs find
7040         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7041              $LFS_MIGRATE -y -c $expected"
7042         echo "$cmd"
7043         eval $cmd || error "$cmd failed"
7044
7045         for i in $(seq 2 $NUMFILES); do
7046                 check_stripe_count $dir/file$i $expected
7047         done
7048         for i in $(seq 2 $NUMDIRS); do
7049                 for j in $(seq $NUMFILES); do
7050                 check_stripe_count $dir/dir$i/file$j $expected
7051                 done
7052         done
7053 }
7054 run_test 56w "check lfs_migrate -c stripe_count works"
7055
7056 test_56wb() {
7057         local file1=$DIR/$tdir/file1
7058         local create_pool=false
7059         local initial_pool=$($LFS getstripe -p $DIR)
7060         local pool_list=()
7061         local pool=""
7062
7063         echo -n "Creating test dir..."
7064         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7065         echo "done."
7066
7067         echo -n "Creating test file..."
7068         touch $file1 || error "cannot create file"
7069         echo "done."
7070
7071         echo -n "Detecting existing pools..."
7072         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7073
7074         if [ ${#pool_list[@]} -gt 0 ]; then
7075                 echo "${pool_list[@]}"
7076                 for thispool in "${pool_list[@]}"; do
7077                         if [[ -z "$initial_pool" ||
7078                               "$initial_pool" != "$thispool" ]]; then
7079                                 pool="$thispool"
7080                                 echo "Using existing pool '$pool'"
7081                                 break
7082                         fi
7083                 done
7084         else
7085                 echo "none detected."
7086         fi
7087         if [ -z "$pool" ]; then
7088                 pool=${POOL:-testpool}
7089                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7090                 echo -n "Creating pool '$pool'..."
7091                 create_pool=true
7092                 pool_add $pool &> /dev/null ||
7093                         error "pool_add failed"
7094                 echo "done."
7095
7096                 echo -n "Adding target to pool..."
7097                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7098                         error "pool_add_targets failed"
7099                 echo "done."
7100         fi
7101
7102         echo -n "Setting pool using -p option..."
7103         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7104                 error "migrate failed rc = $?"
7105         echo "done."
7106
7107         echo -n "Verifying test file is in pool after migrating..."
7108         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7109                 error "file was not migrated to pool $pool"
7110         echo "done."
7111
7112         echo -n "Removing test file from pool '$pool'..."
7113         # "lfs migrate $file" won't remove the file from the pool
7114         # until some striping information is changed.
7115         $LFS migrate -c 1 $file1 &> /dev/null ||
7116                 error "cannot remove from pool"
7117         [ "$($LFS getstripe -p $file1)" ] &&
7118                 error "pool still set"
7119         echo "done."
7120
7121         echo -n "Setting pool using --pool option..."
7122         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7123                 error "migrate failed rc = $?"
7124         echo "done."
7125
7126         # Clean up
7127         rm -f $file1
7128         if $create_pool; then
7129                 destroy_test_pools 2> /dev/null ||
7130                         error "destroy test pools failed"
7131         fi
7132 }
7133 run_test 56wb "check lfs_migrate pool support"
7134
7135 test_56wc() {
7136         local file1="$DIR/$tdir/file1"
7137         local parent_ssize
7138         local parent_scount
7139         local cur_ssize
7140         local cur_scount
7141         local orig_ssize
7142
7143         echo -n "Creating test dir..."
7144         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7145         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7146                 error "cannot set stripe by '-S 1M -c 1'"
7147         echo "done"
7148
7149         echo -n "Setting initial stripe for test file..."
7150         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7151                 error "cannot set stripe"
7152         cur_ssize=$($LFS getstripe -S "$file1")
7153         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7154         echo "done."
7155
7156         # File currently set to -S 512K -c 1
7157
7158         # Ensure -c and -S options are rejected when -R is set
7159         echo -n "Verifying incompatible options are detected..."
7160         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7161                 error "incompatible -c and -R options not detected"
7162         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7163                 error "incompatible -S and -R options not detected"
7164         echo "done."
7165
7166         # Ensure unrecognized options are passed through to 'lfs migrate'
7167         echo -n "Verifying -S option is passed through to lfs migrate..."
7168         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7169                 error "migration failed"
7170         cur_ssize=$($LFS getstripe -S "$file1")
7171         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7172         echo "done."
7173
7174         # File currently set to -S 1M -c 1
7175
7176         # Ensure long options are supported
7177         echo -n "Verifying long options supported..."
7178         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7179                 error "long option without argument not supported"
7180         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7181                 error "long option with argument not supported"
7182         cur_ssize=$($LFS getstripe -S "$file1")
7183         [ $cur_ssize -eq 524288 ] ||
7184                 error "migrate --stripe-size $cur_ssize != 524288"
7185         echo "done."
7186
7187         # File currently set to -S 512K -c 1
7188
7189         if [ "$OSTCOUNT" -gt 1 ]; then
7190                 echo -n "Verifying explicit stripe count can be set..."
7191                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7192                         error "migrate failed"
7193                 cur_scount=$($LFS getstripe -c "$file1")
7194                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7195                 echo "done."
7196         fi
7197
7198         # File currently set to -S 512K -c 1 or -S 512K -c 2
7199
7200         # Ensure parent striping is used if -R is set, and no stripe
7201         # count or size is specified
7202         echo -n "Setting stripe for parent directory..."
7203         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7204                 error "cannot set stripe '-S 2M -c 1'"
7205         echo "done."
7206
7207         echo -n "Verifying restripe option uses parent stripe settings..."
7208         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7209         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7210         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7211                 error "migrate failed"
7212         cur_ssize=$($LFS getstripe -S "$file1")
7213         [ $cur_ssize -eq $parent_ssize ] ||
7214                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7215         cur_scount=$($LFS getstripe -c "$file1")
7216         [ $cur_scount -eq $parent_scount ] ||
7217                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7218         echo "done."
7219
7220         # File currently set to -S 1M -c 1
7221
7222         # Ensure striping is preserved if -R is not set, and no stripe
7223         # count or size is specified
7224         echo -n "Verifying striping size preserved when not specified..."
7225         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7226         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7227                 error "cannot set stripe on parent directory"
7228         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7229                 error "migrate failed"
7230         cur_ssize=$($LFS getstripe -S "$file1")
7231         [ $cur_ssize -eq $orig_ssize ] ||
7232                 error "migrate by default $cur_ssize != $orig_ssize"
7233         echo "done."
7234
7235         # Ensure file name properly detected when final option has no argument
7236         echo -n "Verifying file name properly detected..."
7237         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7238                 error "file name interpreted as option argument"
7239         echo "done."
7240
7241         # Clean up
7242         rm -f "$file1"
7243 }
7244 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7245
7246 test_56wd() {
7247         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7248
7249         local file1=$DIR/$tdir/file1
7250
7251         echo -n "Creating test dir..."
7252         test_mkdir $DIR/$tdir || error "cannot create dir"
7253         echo "done."
7254
7255         echo -n "Creating test file..."
7256         touch $file1
7257         echo "done."
7258
7259         # Ensure 'lfs migrate' will fail by using a non-existent option,
7260         # and make sure rsync is not called to recover
7261         echo -n "Make sure --no-rsync option works..."
7262         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7263                 grep -q 'refusing to fall back to rsync' ||
7264                 error "rsync was called with --no-rsync set"
7265         echo "done."
7266
7267         # Ensure rsync is called without trying 'lfs migrate' first
7268         echo -n "Make sure --rsync option works..."
7269         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7270                 grep -q 'falling back to rsync' &&
7271                 error "lfs migrate was called with --rsync set"
7272         echo "done."
7273
7274         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7275         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7276                 grep -q 'at the same time' ||
7277                 error "--rsync and --no-rsync accepted concurrently"
7278         echo "done."
7279
7280         # Clean up
7281         rm -f $file1
7282 }
7283 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7284
7285 test_56we() {
7286         local td=$DIR/$tdir
7287         local tf=$td/$tfile
7288
7289         test_mkdir $td || error "cannot create $td"
7290         touch $tf || error "cannot touch $tf"
7291
7292         echo -n "Make sure --non-direct|-D works..."
7293         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7294                 grep -q "lfs migrate --non-direct" ||
7295                 error "--non-direct option cannot work correctly"
7296         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7297                 grep -q "lfs migrate -D" ||
7298                 error "-D option cannot work correctly"
7299         echo "done."
7300 }
7301 run_test 56we "check lfs_migrate --non-direct|-D support"
7302
7303 test_56x() {
7304         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7305         check_swap_layouts_support
7306
7307         local dir=$DIR/$tdir
7308         local ref1=/etc/passwd
7309         local file1=$dir/file1
7310
7311         test_mkdir $dir || error "creating dir $dir"
7312         $LFS setstripe -c 2 $file1
7313         cp $ref1 $file1
7314         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7315         stripe=$($LFS getstripe -c $file1)
7316         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7317         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7318
7319         # clean up
7320         rm -f $file1
7321 }
7322 run_test 56x "lfs migration support"
7323
7324 test_56xa() {
7325         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7326         check_swap_layouts_support
7327
7328         local dir=$DIR/$tdir/$testnum
7329
7330         test_mkdir -p $dir
7331
7332         local ref1=/etc/passwd
7333         local file1=$dir/file1
7334
7335         $LFS setstripe -c 2 $file1
7336         cp $ref1 $file1
7337         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7338
7339         local stripe=$($LFS getstripe -c $file1)
7340
7341         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7342         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7343
7344         # clean up
7345         rm -f $file1
7346 }
7347 run_test 56xa "lfs migration --block support"
7348
7349 check_migrate_links() {
7350         local dir="$1"
7351         local file1="$dir/file1"
7352         local begin="$2"
7353         local count="$3"
7354         local runas="$4"
7355         local total_count=$(($begin + $count - 1))
7356         local symlink_count=10
7357         local uniq_count=10
7358
7359         if [ ! -f "$file1" ]; then
7360                 echo -n "creating initial file..."
7361                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7362                         error "cannot setstripe initial file"
7363                 echo "done"
7364
7365                 echo -n "creating symlinks..."
7366                 for s in $(seq 1 $symlink_count); do
7367                         ln -s "$file1" "$dir/slink$s" ||
7368                                 error "cannot create symlinks"
7369                 done
7370                 echo "done"
7371
7372                 echo -n "creating nonlinked files..."
7373                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7374                         error "cannot create nonlinked files"
7375                 echo "done"
7376         fi
7377
7378         # create hard links
7379         if [ ! -f "$dir/file$total_count" ]; then
7380                 echo -n "creating hard links $begin:$total_count..."
7381                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7382                         /dev/null || error "cannot create hard links"
7383                 echo "done"
7384         fi
7385
7386         echo -n "checking number of hard links listed in xattrs..."
7387         local fid=$($LFS getstripe -F "$file1")
7388         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7389
7390         echo "${#paths[*]}"
7391         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7392                         skip "hard link list has unexpected size, skipping test"
7393         fi
7394         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7395                         error "link names should exceed xattrs size"
7396         fi
7397
7398         echo -n "migrating files..."
7399         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7400         local rc=$?
7401         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7402         echo "done"
7403
7404         # make sure all links have been properly migrated
7405         echo -n "verifying files..."
7406         fid=$($LFS getstripe -F "$file1") ||
7407                 error "cannot get fid for file $file1"
7408         for i in $(seq 2 $total_count); do
7409                 local fid2=$($LFS getstripe -F $dir/file$i)
7410
7411                 [ "$fid2" == "$fid" ] ||
7412                         error "migrated hard link has mismatched FID"
7413         done
7414
7415         # make sure hard links were properly detected, and migration was
7416         # performed only once for the entire link set; nonlinked files should
7417         # also be migrated
7418         local actual=$(grep -c 'done' <<< "$migrate_out")
7419         local expected=$(($uniq_count + 1))
7420
7421         [ "$actual" -eq  "$expected" ] ||
7422                 error "hard links individually migrated ($actual != $expected)"
7423
7424         # make sure the correct number of hard links are present
7425         local hardlinks=$(stat -c '%h' "$file1")
7426
7427         [ $hardlinks -eq $total_count ] ||
7428                 error "num hard links $hardlinks != $total_count"
7429         echo "done"
7430
7431         return 0
7432 }
7433
7434 test_56xb() {
7435         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7436                 skip "Need MDS version at least 2.10.55"
7437
7438         local dir="$DIR/$tdir"
7439
7440         test_mkdir "$dir" || error "cannot create dir $dir"
7441
7442         echo "testing lfs migrate mode when all links fit within xattrs"
7443         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7444
7445         echo "testing rsync mode when all links fit within xattrs"
7446         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7447
7448         echo "testing lfs migrate mode when all links do not fit within xattrs"
7449         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7450
7451         echo "testing rsync mode when all links do not fit within xattrs"
7452         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7453
7454         chown -R $RUNAS_ID $dir
7455         echo "testing non-root lfs migrate mode when not all links are in xattr"
7456         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7457
7458         # clean up
7459         rm -rf $dir
7460 }
7461 run_test 56xb "lfs migration hard link support"
7462
7463 test_56xc() {
7464         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7465
7466         local dir="$DIR/$tdir"
7467
7468         test_mkdir "$dir" || error "cannot create dir $dir"
7469
7470         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7471         echo -n "Setting initial stripe for 20MB test file..."
7472         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7473                 error "cannot setstripe 20MB file"
7474         echo "done"
7475         echo -n "Sizing 20MB test file..."
7476         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7477         echo "done"
7478         echo -n "Verifying small file autostripe count is 1..."
7479         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7480                 error "cannot migrate 20MB file"
7481         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7482                 error "cannot get stripe for $dir/20mb"
7483         [ $stripe_count -eq 1 ] ||
7484                 error "unexpected stripe count $stripe_count for 20MB file"
7485         rm -f "$dir/20mb"
7486         echo "done"
7487
7488         # Test 2: File is small enough to fit within the available space on
7489         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7490         # have at least an additional 1KB for each desired stripe for test 3
7491         echo -n "Setting stripe for 1GB test file..."
7492         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7493         echo "done"
7494         echo -n "Sizing 1GB test file..."
7495         # File size is 1GB + 3KB
7496         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7497         echo "done"
7498
7499         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7500         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7501         if (( avail > 524288 * OSTCOUNT )); then
7502                 echo -n "Migrating 1GB file..."
7503                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7504                         error "cannot migrate 1GB file"
7505                 echo "done"
7506                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7507                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7508                         error "cannot getstripe for 1GB file"
7509                 [ $stripe_count -eq 2 ] ||
7510                         error "unexpected stripe count $stripe_count != 2"
7511                 echo "done"
7512         fi
7513
7514         # Test 3: File is too large to fit within the available space on
7515         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7516         if [ $OSTCOUNT -ge 3 ]; then
7517                 # The required available space is calculated as
7518                 # file size (1GB + 3KB) / OST count (3).
7519                 local kb_per_ost=349526
7520
7521                 echo -n "Migrating 1GB file with limit..."
7522                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7523                         error "cannot migrate 1GB file with limit"
7524                 echo "done"
7525
7526                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7527                 echo -n "Verifying 1GB autostripe count with limited space..."
7528                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7529                         error "unexpected stripe count $stripe_count (min 3)"
7530                 echo "done"
7531         fi
7532
7533         # clean up
7534         rm -rf $dir
7535 }
7536 run_test 56xc "lfs migration autostripe"
7537
7538 test_56xd() {
7539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7540
7541         local dir=$DIR/$tdir
7542         local f_mgrt=$dir/$tfile.mgrt
7543         local f_yaml=$dir/$tfile.yaml
7544         local f_copy=$dir/$tfile.copy
7545         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7546         local layout_copy="-c 2 -S 2M -i 1"
7547         local yamlfile=$dir/yamlfile
7548         local layout_before;
7549         local layout_after;
7550
7551         test_mkdir "$dir" || error "cannot create dir $dir"
7552         $LFS setstripe $layout_yaml $f_yaml ||
7553                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7554         $LFS getstripe --yaml $f_yaml > $yamlfile
7555         $LFS setstripe $layout_copy $f_copy ||
7556                 error "cannot setstripe $f_copy with layout $layout_copy"
7557         touch $f_mgrt
7558         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7559
7560         # 1. test option --yaml
7561         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7562                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7563         layout_before=$(get_layout_param $f_yaml)
7564         layout_after=$(get_layout_param $f_mgrt)
7565         [ "$layout_after" == "$layout_before" ] ||
7566                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7567
7568         # 2. test option --copy
7569         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7570                 error "cannot migrate $f_mgrt with --copy $f_copy"
7571         layout_before=$(get_layout_param $f_copy)
7572         layout_after=$(get_layout_param $f_mgrt)
7573         [ "$layout_after" == "$layout_before" ] ||
7574                 error "lfs_migrate --copy: $layout_after != $layout_before"
7575 }
7576 run_test 56xd "check lfs_migrate --yaml and --copy support"
7577
7578 test_56xe() {
7579         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7580
7581         local dir=$DIR/$tdir
7582         local f_comp=$dir/$tfile
7583         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7584         local layout_before=""
7585         local layout_after=""
7586
7587         test_mkdir "$dir" || error "cannot create dir $dir"
7588         $LFS setstripe $layout $f_comp ||
7589                 error "cannot setstripe $f_comp with layout $layout"
7590         layout_before=$(get_layout_param $f_comp)
7591         dd if=/dev/zero of=$f_comp bs=1M count=4
7592
7593         # 1. migrate a comp layout file by lfs_migrate
7594         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7595         layout_after=$(get_layout_param $f_comp)
7596         [ "$layout_before" == "$layout_after" ] ||
7597                 error "lfs_migrate: $layout_before != $layout_after"
7598
7599         # 2. migrate a comp layout file by lfs migrate
7600         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7601         layout_after=$(get_layout_param $f_comp)
7602         [ "$layout_before" == "$layout_after" ] ||
7603                 error "lfs migrate: $layout_before != $layout_after"
7604 }
7605 run_test 56xe "migrate a composite layout file"
7606
7607 test_56xf() {
7608         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7609
7610         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7611                 skip "Need server version at least 2.13.53"
7612
7613         local dir=$DIR/$tdir
7614         local f_comp=$dir/$tfile
7615         local layout="-E 1M -c1 -E -1 -c2"
7616         local fid_before=""
7617         local fid_after=""
7618
7619         test_mkdir "$dir" || error "cannot create dir $dir"
7620         $LFS setstripe $layout $f_comp ||
7621                 error "cannot setstripe $f_comp with layout $layout"
7622         fid_before=$($LFS getstripe --fid $f_comp)
7623         dd if=/dev/zero of=$f_comp bs=1M count=4
7624
7625         # 1. migrate a comp layout file to a comp layout
7626         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7627         fid_after=$($LFS getstripe --fid $f_comp)
7628         [ "$fid_before" == "$fid_after" ] ||
7629                 error "comp-to-comp migrate: $fid_before != $fid_after"
7630
7631         # 2. migrate a comp layout file to a plain layout
7632         $LFS migrate -c2 $f_comp ||
7633                 error "cannot migrate $f_comp by lfs migrate"
7634         fid_after=$($LFS getstripe --fid $f_comp)
7635         [ "$fid_before" == "$fid_after" ] ||
7636                 error "comp-to-plain migrate: $fid_before != $fid_after"
7637
7638         # 3. migrate a plain layout file to a comp layout
7639         $LFS migrate $layout $f_comp ||
7640                 error "cannot migrate $f_comp by lfs migrate"
7641         fid_after=$($LFS getstripe --fid $f_comp)
7642         [ "$fid_before" == "$fid_after" ] ||
7643                 error "plain-to-comp migrate: $fid_before != $fid_after"
7644 }
7645 run_test 56xf "FID is not lost during migration of a composite layout file"
7646
7647 check_file_ost_range() {
7648         local file="$1"
7649         shift
7650         local range="$*"
7651         local -a file_range
7652         local idx
7653
7654         file_range=($($LFS getstripe -y "$file" |
7655                 awk '/l_ost_idx:/ { print $NF }'))
7656
7657         if [[ "${#file_range[@]}" = 0 ]]; then
7658                 echo "No osts found for $file"
7659                 return 1
7660         fi
7661
7662         for idx in "${file_range[@]}"; do
7663                 [[ " $range " =~ " $idx " ]] ||
7664                         return 1
7665         done
7666
7667         return 0
7668 }
7669
7670 sub_test_56xg() {
7671         local stripe_opt="$1"
7672         local pool="$2"
7673         shift 2
7674         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7675
7676         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7677                 error "Fail to migrate $tfile on $pool"
7678         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7679                 error "$tfile is not in pool $pool"
7680         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7681                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7682 }
7683
7684 test_56xg() {
7685         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7686         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7687         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7688                 skip "Need MDS version newer than 2.14.52"
7689
7690         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7691         local -a pool_ranges=("0 0" "1 1" "0 1")
7692
7693         # init pools
7694         for i in "${!pool_names[@]}"; do
7695                 pool_add ${pool_names[$i]} ||
7696                         error "pool_add failed (pool: ${pool_names[$i]})"
7697                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7698                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7699         done
7700
7701         # init the file to migrate
7702         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7703                 error "Unable to create $tfile on OST1"
7704         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7705                 error "Unable to write on $tfile"
7706
7707         echo "1. migrate $tfile on pool ${pool_names[0]}"
7708         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7709
7710         echo "2. migrate $tfile on pool ${pool_names[2]}"
7711         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7712
7713         echo "3. migrate $tfile on pool ${pool_names[1]}"
7714         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7715
7716         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7717         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7718         echo
7719
7720         # Clean pools
7721         destroy_test_pools ||
7722                 error "pool_destroy failed"
7723 }
7724 run_test 56xg "lfs migrate pool support"
7725
7726 test_56y() {
7727         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7728                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7729
7730         local res=""
7731         local dir=$DIR/$tdir
7732         local f1=$dir/file1
7733         local f2=$dir/file2
7734
7735         test_mkdir -p $dir || error "creating dir $dir"
7736         touch $f1 || error "creating std file $f1"
7737         $MULTIOP $f2 H2c || error "creating released file $f2"
7738
7739         # a directory can be raid0, so ask only for files
7740         res=$($LFS find $dir -L raid0 -type f | wc -l)
7741         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7742
7743         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7744         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7745
7746         # only files can be released, so no need to force file search
7747         res=$($LFS find $dir -L released)
7748         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7749
7750         res=$($LFS find $dir -type f \! -L released)
7751         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7752 }
7753 run_test 56y "lfs find -L raid0|released"
7754
7755 test_56z() { # LU-4824
7756         # This checks to make sure 'lfs find' continues after errors
7757         # There are two classes of errors that should be caught:
7758         # - If multiple paths are provided, all should be searched even if one
7759         #   errors out
7760         # - If errors are encountered during the search, it should not terminate
7761         #   early
7762         local dir=$DIR/$tdir
7763         local i
7764
7765         test_mkdir $dir
7766         for i in d{0..9}; do
7767                 test_mkdir $dir/$i
7768                 touch $dir/$i/$tfile
7769         done
7770         $LFS find $DIR/non_existent_dir $dir &&
7771                 error "$LFS find did not return an error"
7772         # Make a directory unsearchable. This should NOT be the last entry in
7773         # directory order.  Arbitrarily pick the 6th entry
7774         chmod 700 $($LFS find $dir -type d | sed '6!d')
7775
7776         $RUNAS $LFS find $DIR/non_existent $dir
7777         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7778
7779         # The user should be able to see 10 directories and 9 files
7780         (( count == 19 )) ||
7781                 error "$LFS find found $count != 19 entries after error"
7782 }
7783 run_test 56z "lfs find should continue after an error"
7784
7785 test_56aa() { # LU-5937
7786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7787
7788         local dir=$DIR/$tdir
7789
7790         mkdir $dir
7791         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7792
7793         createmany -o $dir/striped_dir/${tfile}- 1024
7794         local dirs=$($LFS find --size +8k $dir/)
7795
7796         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7797 }
7798 run_test 56aa "lfs find --size under striped dir"
7799
7800 test_56ab() { # LU-10705
7801         test_mkdir $DIR/$tdir
7802         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7803         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7804         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7805         # Flush writes to ensure valid blocks.  Need to be more thorough for
7806         # ZFS, since blocks are not allocated/returned to client immediately.
7807         sync_all_data
7808         wait_zfs_commit ost1 2
7809         cancel_lru_locks osc
7810         ls -ls $DIR/$tdir
7811
7812         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7813
7814         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7815
7816         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7817         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7818
7819         rm -f $DIR/$tdir/$tfile.[123]
7820 }
7821 run_test 56ab "lfs find --blocks"
7822
7823 # LU-11188
7824 test_56aca() {
7825         local dir="$DIR/$tdir"
7826         local perms=(001 002 003 004 005 006 007
7827                      010 020 030 040 050 060 070
7828                      100 200 300 400 500 600 700
7829                      111 222 333 444 555 666 777)
7830         local perm_minus=(8 8 4 8 4 4 2
7831                           8 8 4 8 4 4 2
7832                           8 8 4 8 4 4 2
7833                           4 4 2 4 2 2 1)
7834         local perm_slash=(8  8 12  8 12 12 14
7835                           8  8 12  8 12 12 14
7836                           8  8 12  8 12 12 14
7837                          16 16 24 16 24 24 28)
7838
7839         test_mkdir "$dir"
7840         for perm in ${perms[*]}; do
7841                 touch "$dir/$tfile.$perm"
7842                 chmod $perm "$dir/$tfile.$perm"
7843         done
7844
7845         for ((i = 0; i < ${#perms[*]}; i++)); do
7846                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7847                 (( $num == 1 )) ||
7848                         error "lfs find -perm ${perms[i]}:"\
7849                               "$num != 1"
7850
7851                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7852                 (( $num == ${perm_minus[i]} )) ||
7853                         error "lfs find -perm -${perms[i]}:"\
7854                               "$num != ${perm_minus[i]}"
7855
7856                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7857                 (( $num == ${perm_slash[i]} )) ||
7858                         error "lfs find -perm /${perms[i]}:"\
7859                               "$num != ${perm_slash[i]}"
7860         done
7861 }
7862 run_test 56aca "check lfs find -perm with octal representation"
7863
7864 test_56acb() {
7865         local dir=$DIR/$tdir
7866         # p is the permission of write and execute for user, group and other
7867         # without the umask. It is used to test +wx.
7868         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7869         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7870         local symbolic=(+t  a+t u+t g+t o+t
7871                         g+s u+s o+s +s o+sr
7872                         o=r,ug+o,u+w
7873                         u+ g+ o+ a+ ugo+
7874                         u- g- o- a- ugo-
7875                         u= g= o= a= ugo=
7876                         o=r,ug+o,u+w u=r,a+u,u+w
7877                         g=r,ugo=g,u+w u+x,+X +X
7878                         u+x,u+X u+X u+x,g+X o+r,+X
7879                         u+x,go+X +wx +rwx)
7880
7881         test_mkdir $dir
7882         for perm in ${perms[*]}; do
7883                 touch "$dir/$tfile.$perm"
7884                 chmod $perm "$dir/$tfile.$perm"
7885         done
7886
7887         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7888                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7889
7890                 (( $num == 1 )) ||
7891                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7892         done
7893 }
7894 run_test 56acb "check lfs find -perm with symbolic representation"
7895
7896 test_56acc() {
7897         local dir=$DIR/$tdir
7898         local tests="17777 787 789 abcd
7899                 ug=uu ug=a ug=gu uo=ou urw
7900                 u+xg+x a=r,u+x,"
7901
7902         test_mkdir $dir
7903         for err in $tests; do
7904                 if $LFS find $dir -perm $err 2>/dev/null; then
7905                         error "lfs find -perm $err: parsing should have failed"
7906                 fi
7907         done
7908 }
7909 run_test 56acc "check parsing error for lfs find -perm"
7910
7911 test_56ba() {
7912         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7913                 skip "Need MDS version at least 2.10.50"
7914
7915         # Create composite files with one component
7916         local dir=$DIR/$tdir
7917
7918         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7919         # Create composite files with three components
7920         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7921         # Create non-composite files
7922         createmany -o $dir/${tfile}- 10
7923
7924         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7925
7926         [[ $nfiles == 10 ]] ||
7927                 error "lfs find -E 1M found $nfiles != 10 files"
7928
7929         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7930         [[ $nfiles == 25 ]] ||
7931                 error "lfs find ! -E 1M found $nfiles != 25 files"
7932
7933         # All files have a component that starts at 0
7934         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7935         [[ $nfiles == 35 ]] ||
7936                 error "lfs find --component-start 0 - $nfiles != 35 files"
7937
7938         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7939         [[ $nfiles == 15 ]] ||
7940                 error "lfs find --component-start 2M - $nfiles != 15 files"
7941
7942         # All files created here have a componenet that does not starts at 2M
7943         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7944         [[ $nfiles == 35 ]] ||
7945                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7946
7947         # Find files with a specified number of components
7948         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7949         [[ $nfiles == 15 ]] ||
7950                 error "lfs find --component-count 3 - $nfiles != 15 files"
7951
7952         # Remember non-composite files have a component count of zero
7953         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7954         [[ $nfiles == 10 ]] ||
7955                 error "lfs find --component-count 0 - $nfiles != 10 files"
7956
7957         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7958         [[ $nfiles == 20 ]] ||
7959                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7960
7961         # All files have a flag called "init"
7962         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7963         [[ $nfiles == 35 ]] ||
7964                 error "lfs find --component-flags init - $nfiles != 35 files"
7965
7966         # Multi-component files will have a component not initialized
7967         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7968         [[ $nfiles == 15 ]] ||
7969                 error "lfs find !--component-flags init - $nfiles != 15 files"
7970
7971         rm -rf $dir
7972
7973 }
7974 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7975
7976 test_56ca() {
7977         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7978                 skip "Need MDS version at least 2.10.57"
7979
7980         local td=$DIR/$tdir
7981         local tf=$td/$tfile
7982         local dir
7983         local nfiles
7984         local cmd
7985         local i
7986         local j
7987
7988         # create mirrored directories and mirrored files
7989         mkdir $td || error "mkdir $td failed"
7990         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7991         createmany -o $tf- 10 || error "create $tf- failed"
7992
7993         for i in $(seq 2); do
7994                 dir=$td/dir$i
7995                 mkdir $dir || error "mkdir $dir failed"
7996                 $LFS mirror create -N$((3 + i)) $dir ||
7997                         error "create mirrored dir $dir failed"
7998                 createmany -o $dir/$tfile- 10 ||
7999                         error "create $dir/$tfile- failed"
8000         done
8001
8002         # change the states of some mirrored files
8003         echo foo > $tf-6
8004         for i in $(seq 2); do
8005                 dir=$td/dir$i
8006                 for j in $(seq 4 9); do
8007                         echo foo > $dir/$tfile-$j
8008                 done
8009         done
8010
8011         # find mirrored files with specific mirror count
8012         cmd="$LFS find --mirror-count 3 --type f $td"
8013         nfiles=$($cmd | wc -l)
8014         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8015
8016         cmd="$LFS find ! --mirror-count 3 --type f $td"
8017         nfiles=$($cmd | wc -l)
8018         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8019
8020         cmd="$LFS find --mirror-count +2 --type f $td"
8021         nfiles=$($cmd | wc -l)
8022         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8023
8024         cmd="$LFS find --mirror-count -6 --type f $td"
8025         nfiles=$($cmd | wc -l)
8026         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8027
8028         # find mirrored files with specific file state
8029         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8030         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8031
8032         cmd="$LFS find --mirror-state=ro --type f $td"
8033         nfiles=$($cmd | wc -l)
8034         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8035
8036         cmd="$LFS find ! --mirror-state=ro --type f $td"
8037         nfiles=$($cmd | wc -l)
8038         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8039
8040         cmd="$LFS find --mirror-state=wp --type f $td"
8041         nfiles=$($cmd | wc -l)
8042         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8043
8044         cmd="$LFS find ! --mirror-state=sp --type f $td"
8045         nfiles=$($cmd | wc -l)
8046         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8047 }
8048 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8049
8050 test_56da() { # LU-14179
8051         local path=$DIR/$tdir
8052
8053         test_mkdir $path
8054         cd $path
8055
8056         local longdir=$(str_repeat 'a' 255)
8057
8058         for i in {1..15}; do
8059                 path=$path/$longdir
8060                 test_mkdir $longdir
8061                 cd $longdir
8062         done
8063
8064         local len=${#path}
8065         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8066
8067         test_mkdir $lastdir
8068         cd $lastdir
8069         # PATH_MAX-1
8070         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8071
8072         # NAME_MAX
8073         touch $(str_repeat 'f' 255)
8074
8075         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8076                 error "lfs find reported an error"
8077
8078         rm -rf $DIR/$tdir
8079 }
8080 run_test 56da "test lfs find with long paths"
8081
8082 test_57a() {
8083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8084         # note test will not do anything if MDS is not local
8085         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8086                 skip_env "ldiskfs only test"
8087         fi
8088         remote_mds_nodsh && skip "remote MDS with nodsh"
8089
8090         local MNTDEV="osd*.*MDT*.mntdev"
8091         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8092         [ -z "$DEV" ] && error "can't access $MNTDEV"
8093         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8094                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8095                         error "can't access $DEV"
8096                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8097                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8098                 rm $TMP/t57a.dump
8099         done
8100 }
8101 run_test 57a "verify MDS filesystem created with large inodes =="
8102
8103 test_57b() {
8104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8105         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8106                 skip_env "ldiskfs only test"
8107         fi
8108         remote_mds_nodsh && skip "remote MDS with nodsh"
8109
8110         local dir=$DIR/$tdir
8111         local filecount=100
8112         local file1=$dir/f1
8113         local fileN=$dir/f$filecount
8114
8115         rm -rf $dir || error "removing $dir"
8116         test_mkdir -c1 $dir
8117         local mdtidx=$($LFS getstripe -m $dir)
8118         local mdtname=MDT$(printf %04x $mdtidx)
8119         local facet=mds$((mdtidx + 1))
8120
8121         echo "mcreating $filecount files"
8122         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8123
8124         # verify that files do not have EAs yet
8125         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8126                 error "$file1 has an EA"
8127         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8128                 error "$fileN has an EA"
8129
8130         sync
8131         sleep 1
8132         df $dir  #make sure we get new statfs data
8133         local mdsfree=$(do_facet $facet \
8134                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8135         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8136         local file
8137
8138         echo "opening files to create objects/EAs"
8139         for file in $(seq -f $dir/f%g 1 $filecount); do
8140                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8141                         error "opening $file"
8142         done
8143
8144         # verify that files have EAs now
8145         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8146         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8147
8148         sleep 1  #make sure we get new statfs data
8149         df $dir
8150         local mdsfree2=$(do_facet $facet \
8151                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8152         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8153
8154         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8155                 if [ "$mdsfree" != "$mdsfree2" ]; then
8156                         error "MDC before $mdcfree != after $mdcfree2"
8157                 else
8158                         echo "MDC before $mdcfree != after $mdcfree2"
8159                         echo "unable to confirm if MDS has large inodes"
8160                 fi
8161         fi
8162         rm -rf $dir
8163 }
8164 run_test 57b "default LOV EAs are stored inside large inodes ==="
8165
8166 test_58() {
8167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8168         [ -z "$(which wiretest 2>/dev/null)" ] &&
8169                         skip_env "could not find wiretest"
8170
8171         wiretest
8172 }
8173 run_test 58 "verify cross-platform wire constants =============="
8174
8175 test_59() {
8176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8177
8178         echo "touch 130 files"
8179         createmany -o $DIR/f59- 130
8180         echo "rm 130 files"
8181         unlinkmany $DIR/f59- 130
8182         sync
8183         # wait for commitment of removal
8184         wait_delete_completed
8185 }
8186 run_test 59 "verify cancellation of llog records async ========="
8187
8188 TEST60_HEAD="test_60 run $RANDOM"
8189 test_60a() {
8190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8191         remote_mgs_nodsh && skip "remote MGS with nodsh"
8192         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8193                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8194                         skip_env "missing subtest run-llog.sh"
8195
8196         log "$TEST60_HEAD - from kernel mode"
8197         do_facet mgs "$LCTL dk > /dev/null"
8198         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8199         do_facet mgs $LCTL dk > $TMP/$tfile
8200
8201         # LU-6388: test llog_reader
8202         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8203         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8204         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8205                         skip_env "missing llog_reader"
8206         local fstype=$(facet_fstype mgs)
8207         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8208                 skip_env "Only for ldiskfs or zfs type mgs"
8209
8210         local mntpt=$(facet_mntpt mgs)
8211         local mgsdev=$(mgsdevname 1)
8212         local fid_list
8213         local fid
8214         local rec_list
8215         local rec
8216         local rec_type
8217         local obj_file
8218         local path
8219         local seq
8220         local oid
8221         local pass=true
8222
8223         #get fid and record list
8224         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8225                 tail -n 4))
8226         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8227                 tail -n 4))
8228         #remount mgs as ldiskfs or zfs type
8229         stop mgs || error "stop mgs failed"
8230         mount_fstype mgs || error "remount mgs failed"
8231         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8232                 fid=${fid_list[i]}
8233                 rec=${rec_list[i]}
8234                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8235                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8236                 oid=$((16#$oid))
8237
8238                 case $fstype in
8239                         ldiskfs )
8240                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8241                         zfs )
8242                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8243                 esac
8244                 echo "obj_file is $obj_file"
8245                 do_facet mgs $llog_reader $obj_file
8246
8247                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8248                         awk '{ print $3 }' | sed -e "s/^type=//g")
8249                 if [ $rec_type != $rec ]; then
8250                         echo "FAILED test_60a wrong record type $rec_type," \
8251                               "should be $rec"
8252                         pass=false
8253                         break
8254                 fi
8255
8256                 #check obj path if record type is LLOG_LOGID_MAGIC
8257                 if [ "$rec" == "1064553b" ]; then
8258                         path=$(do_facet mgs $llog_reader $obj_file |
8259                                 grep "path=" | awk '{ print $NF }' |
8260                                 sed -e "s/^path=//g")
8261                         if [ $obj_file != $mntpt/$path ]; then
8262                                 echo "FAILED test_60a wrong obj path" \
8263                                       "$montpt/$path, should be $obj_file"
8264                                 pass=false
8265                                 break
8266                         fi
8267                 fi
8268         done
8269         rm -f $TMP/$tfile
8270         #restart mgs before "error", otherwise it will block the next test
8271         stop mgs || error "stop mgs failed"
8272         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8273         $pass || error "test failed, see FAILED test_60a messages for specifics"
8274 }
8275 run_test 60a "llog_test run from kernel module and test llog_reader"
8276
8277 test_60b() { # bug 6411
8278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8279
8280         dmesg > $DIR/$tfile
8281         LLOG_COUNT=$(do_facet mgs dmesg |
8282                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8283                           /llog_[a-z]*.c:[0-9]/ {
8284                                 if (marker)
8285                                         from_marker++
8286                                 from_begin++
8287                           }
8288                           END {
8289                                 if (marker)
8290                                         print from_marker
8291                                 else
8292                                         print from_begin
8293                           }")
8294
8295         [[ $LLOG_COUNT -gt 120 ]] &&
8296                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8297 }
8298 run_test 60b "limit repeated messages from CERROR/CWARN"
8299
8300 test_60c() {
8301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8302
8303         echo "create 5000 files"
8304         createmany -o $DIR/f60c- 5000
8305 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8306         lctl set_param fail_loc=0x80000137
8307         unlinkmany $DIR/f60c- 5000
8308         lctl set_param fail_loc=0
8309 }
8310 run_test 60c "unlink file when mds full"
8311
8312 test_60d() {
8313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8314
8315         SAVEPRINTK=$(lctl get_param -n printk)
8316         # verify "lctl mark" is even working"
8317         MESSAGE="test message ID $RANDOM $$"
8318         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8319         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8320
8321         lctl set_param printk=0 || error "set lnet.printk failed"
8322         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8323         MESSAGE="new test message ID $RANDOM $$"
8324         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8325         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8326         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8327
8328         lctl set_param -n printk="$SAVEPRINTK"
8329 }
8330 run_test 60d "test printk console message masking"
8331
8332 test_60e() {
8333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8334         remote_mds_nodsh && skip "remote MDS with nodsh"
8335
8336         touch $DIR/$tfile
8337 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8338         do_facet mds1 lctl set_param fail_loc=0x15b
8339         rm $DIR/$tfile
8340 }
8341 run_test 60e "no space while new llog is being created"
8342
8343 test_60f() {
8344         local old_path=$($LCTL get_param -n debug_path)
8345
8346         stack_trap "$LCTL set_param debug_path=$old_path"
8347         stack_trap "rm -f $TMP/$tfile*"
8348         rm -f $TMP/$tfile* 2> /dev/null
8349         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8350         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8351         test_mkdir $DIR/$tdir
8352         # retry in case the open is cached and not released
8353         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8354                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8355                 sleep 0.1
8356         done
8357         ls $TMP/$tfile*
8358         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8359 }
8360 run_test 60f "change debug_path works"
8361
8362 test_60g() {
8363         local pid
8364         local i
8365
8366         test_mkdir -c $MDSCOUNT $DIR/$tdir
8367
8368         (
8369                 local index=0
8370                 while true; do
8371                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8372                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8373                                 2>/dev/null
8374                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8375                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8376                         index=$((index + 1))
8377                 done
8378         ) &
8379
8380         pid=$!
8381
8382         for i in {0..100}; do
8383                 # define OBD_FAIL_OSD_TXN_START    0x19a
8384                 local index=$((i % MDSCOUNT + 1))
8385
8386                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8387                         > /dev/null
8388                 sleep 0.01
8389         done
8390
8391         kill -9 $pid
8392
8393         for i in $(seq $MDSCOUNT); do
8394                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8395         done
8396
8397         mkdir $DIR/$tdir/new || error "mkdir failed"
8398         rmdir $DIR/$tdir/new || error "rmdir failed"
8399
8400         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8401                 -t namespace
8402         for i in $(seq $MDSCOUNT); do
8403                 wait_update_facet mds$i "$LCTL get_param -n \
8404                         mdd.$(facet_svc mds$i).lfsck_namespace |
8405                         awk '/^status/ { print \\\$2 }'" "completed"
8406         done
8407
8408         ls -R $DIR/$tdir || error "ls failed"
8409         rm -rf $DIR/$tdir || error "rmdir failed"
8410 }
8411 run_test 60g "transaction abort won't cause MDT hung"
8412
8413 test_60h() {
8414         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8415                 skip "Need MDS version at least 2.12.52"
8416         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8417
8418         local f
8419
8420         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8421         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8422         for fail_loc in 0x80000188 0x80000189; do
8423                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8424                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8425                         error "mkdir $dir-$fail_loc failed"
8426                 for i in {0..10}; do
8427                         # create may fail on missing stripe
8428                         echo $i > $DIR/$tdir-$fail_loc/$i
8429                 done
8430                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8431                         error "getdirstripe $tdir-$fail_loc failed"
8432                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8433                         error "migrate $tdir-$fail_loc failed"
8434                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8435                         error "getdirstripe $tdir-$fail_loc failed"
8436                 pushd $DIR/$tdir-$fail_loc
8437                 for f in *; do
8438                         echo $f | cmp $f - || error "$f data mismatch"
8439                 done
8440                 popd
8441                 rm -rf $DIR/$tdir-$fail_loc
8442         done
8443 }
8444 run_test 60h "striped directory with missing stripes can be accessed"
8445
8446 function t60i_load() {
8447         mkdir $DIR/$tdir
8448         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8449         $LCTL set_param fail_loc=0x131c fail_val=1
8450         for ((i=0; i<5000; i++)); do
8451                 touch $DIR/$tdir/f$i
8452         done
8453 }
8454
8455 test_60i() {
8456         changelog_register || error "changelog_register failed"
8457         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8458         changelog_users $SINGLEMDS | grep -q $cl_user ||
8459                 error "User $cl_user not found in changelog_users"
8460         changelog_chmask "ALL"
8461         t60i_load &
8462         local PID=$!
8463         for((i=0; i<100; i++)); do
8464                 changelog_dump >/dev/null ||
8465                         error "can't read changelog"
8466         done
8467         kill $PID
8468         wait $PID
8469         changelog_deregister || error "changelog_deregister failed"
8470         $LCTL set_param fail_loc=0
8471 }
8472 run_test 60i "llog: new record vs reader race"
8473
8474 test_61a() {
8475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8476
8477         f="$DIR/f61"
8478         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8479         cancel_lru_locks osc
8480         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8481         sync
8482 }
8483 run_test 61a "mmap() writes don't make sync hang ================"
8484
8485 test_61b() {
8486         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8487 }
8488 run_test 61b "mmap() of unstriped file is successful"
8489
8490 # bug 2330 - insufficient obd_match error checking causes LBUG
8491 test_62() {
8492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8493
8494         f="$DIR/f62"
8495         echo foo > $f
8496         cancel_lru_locks osc
8497         lctl set_param fail_loc=0x405
8498         cat $f && error "cat succeeded, expect -EIO"
8499         lctl set_param fail_loc=0
8500 }
8501 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8502 # match every page all of the time.
8503 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8504
8505 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8506 # Though this test is irrelevant anymore, it helped to reveal some
8507 # other grant bugs (LU-4482), let's keep it.
8508 test_63a() {   # was test_63
8509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8510
8511         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8512
8513         for i in `seq 10` ; do
8514                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8515                 sleep 5
8516                 kill $!
8517                 sleep 1
8518         done
8519
8520         rm -f $DIR/f63 || true
8521 }
8522 run_test 63a "Verify oig_wait interruption does not crash ======="
8523
8524 # bug 2248 - async write errors didn't return to application on sync
8525 # bug 3677 - async write errors left page locked
8526 test_63b() {
8527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8528
8529         debugsave
8530         lctl set_param debug=-1
8531
8532         # ensure we have a grant to do async writes
8533         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8534         rm $DIR/$tfile
8535
8536         sync    # sync lest earlier test intercept the fail_loc
8537
8538         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8539         lctl set_param fail_loc=0x80000406
8540         $MULTIOP $DIR/$tfile Owy && \
8541                 error "sync didn't return ENOMEM"
8542         sync; sleep 2; sync     # do a real sync this time to flush page
8543         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8544                 error "locked page left in cache after async error" || true
8545         debugrestore
8546 }
8547 run_test 63b "async write errors should be returned to fsync ==="
8548
8549 test_64a () {
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551
8552         lfs df $DIR
8553         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8554 }
8555 run_test 64a "verify filter grant calculations (in kernel) ====="
8556
8557 test_64b () {
8558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8559
8560         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8561 }
8562 run_test 64b "check out-of-space detection on client"
8563
8564 test_64c() {
8565         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8566 }
8567 run_test 64c "verify grant shrink"
8568
8569 import_param() {
8570         local tgt=$1
8571         local param=$2
8572
8573         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8574 }
8575
8576 # this does exactly what osc_request.c:osc_announce_cached() does in
8577 # order to calculate max amount of grants to ask from server
8578 want_grant() {
8579         local tgt=$1
8580
8581         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8582         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8583
8584         ((rpc_in_flight++));
8585         nrpages=$((nrpages * rpc_in_flight))
8586
8587         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8588
8589         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8590
8591         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8592         local undirty=$((nrpages * PAGE_SIZE))
8593
8594         local max_extent_pages
8595         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8596         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8597         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8598         local grant_extent_tax
8599         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8600
8601         undirty=$((undirty + nrextents * grant_extent_tax))
8602
8603         echo $undirty
8604 }
8605
8606 # this is size of unit for grant allocation. It should be equal to
8607 # what tgt_grant.c:tgt_grant_chunk() calculates
8608 grant_chunk() {
8609         local tgt=$1
8610         local max_brw_size
8611         local grant_extent_tax
8612
8613         max_brw_size=$(import_param $tgt max_brw_size)
8614
8615         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8616
8617         echo $(((max_brw_size + grant_extent_tax) * 2))
8618 }
8619
8620 test_64d() {
8621         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8622                 skip "OST < 2.10.55 doesn't limit grants enough"
8623
8624         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8625
8626         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8627                 skip "no grant_param connect flag"
8628
8629         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8630
8631         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8632         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8633
8634
8635         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8636         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8637
8638         $LFS setstripe $DIR/$tfile -i 0 -c 1
8639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8640         ddpid=$!
8641
8642         while kill -0 $ddpid; do
8643                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8644
8645                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8646                         kill $ddpid
8647                         error "cur_grant $cur_grant > $max_cur_granted"
8648                 fi
8649
8650                 sleep 1
8651         done
8652 }
8653 run_test 64d "check grant limit exceed"
8654
8655 check_grants() {
8656         local tgt=$1
8657         local expected=$2
8658         local msg=$3
8659         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8660
8661         ((cur_grants == expected)) ||
8662                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8663 }
8664
8665 round_up_p2() {
8666         echo $((($1 + $2 - 1) & ~($2 - 1)))
8667 }
8668
8669 test_64e() {
8670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8671         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8672                 skip "Need OSS version at least 2.11.56"
8673
8674         # Remount client to reset grant
8675         remount_client $MOUNT || error "failed to remount client"
8676         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8677
8678         local init_grants=$(import_param $osc_tgt initial_grant)
8679
8680         check_grants $osc_tgt $init_grants "init grants"
8681
8682         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8683         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8684         local gbs=$(import_param $osc_tgt grant_block_size)
8685
8686         # write random number of bytes from max_brw_size / 4 to max_brw_size
8687         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8688         # align for direct io
8689         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8690         # round to grant consumption unit
8691         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8692
8693         local grants=$((wb_round_up + extent_tax))
8694
8695         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8696
8697         # define OBD_FAIL_TGT_NO_GRANT 0x725
8698         # make the server not grant more back
8699         do_facet ost1 $LCTL set_param fail_loc=0x725
8700         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8701
8702         do_facet ost1 $LCTL set_param fail_loc=0
8703
8704         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8705
8706         rm -f $DIR/$tfile || error "rm failed"
8707
8708         # Remount client to reset grant
8709         remount_client $MOUNT || error "failed to remount client"
8710         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8711
8712         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8713
8714         # define OBD_FAIL_TGT_NO_GRANT 0x725
8715         # make the server not grant more back
8716         do_facet ost1 $LCTL set_param fail_loc=0x725
8717         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8718         do_facet ost1 $LCTL set_param fail_loc=0
8719
8720         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8721 }
8722 run_test 64e "check grant consumption (no grant allocation)"
8723
8724 test_64f() {
8725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8726
8727         # Remount client to reset grant
8728         remount_client $MOUNT || error "failed to remount client"
8729         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8730
8731         local init_grants=$(import_param $osc_tgt initial_grant)
8732         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8733         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8734         local gbs=$(import_param $osc_tgt grant_block_size)
8735         local chunk=$(grant_chunk $osc_tgt)
8736
8737         # write random number of bytes from max_brw_size / 4 to max_brw_size
8738         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8739         # align for direct io
8740         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8741         # round to grant consumption unit
8742         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8743
8744         local grants=$((wb_round_up + extent_tax))
8745
8746         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8747         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8748                 error "error writing to $DIR/$tfile"
8749
8750         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8751                 "direct io with grant allocation"
8752
8753         rm -f $DIR/$tfile || error "rm failed"
8754
8755         # Remount client to reset grant
8756         remount_client $MOUNT || error "failed to remount client"
8757         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8758
8759         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8760
8761         local cmd="oO_WRONLY:w${write_bytes}_yc"
8762
8763         $MULTIOP $DIR/$tfile $cmd &
8764         MULTIPID=$!
8765         sleep 1
8766
8767         check_grants $osc_tgt $((init_grants - grants)) \
8768                 "buffered io, not write rpc"
8769
8770         kill -USR1 $MULTIPID
8771         wait
8772
8773         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8774                 "buffered io, one RPC"
8775 }
8776 run_test 64f "check grant consumption (with grant allocation)"
8777
8778 # bug 1414 - set/get directories' stripe info
8779 test_65a() {
8780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8781
8782         test_mkdir $DIR/$tdir
8783         touch $DIR/$tdir/f1
8784         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8785 }
8786 run_test 65a "directory with no stripe info"
8787
8788 test_65b() {
8789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8790
8791         test_mkdir $DIR/$tdir
8792         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8793
8794         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8795                                                 error "setstripe"
8796         touch $DIR/$tdir/f2
8797         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8798 }
8799 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8800
8801 test_65c() {
8802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8803         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8804
8805         test_mkdir $DIR/$tdir
8806         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8807
8808         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8809                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8810         touch $DIR/$tdir/f3
8811         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8812 }
8813 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8814
8815 test_65d() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817
8818         test_mkdir $DIR/$tdir
8819         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8820         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8821
8822         if [[ $STRIPECOUNT -le 0 ]]; then
8823                 sc=1
8824         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8825                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8826                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8827         else
8828                 sc=$(($STRIPECOUNT - 1))
8829         fi
8830         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8831         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8832         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8833                 error "lverify failed"
8834 }
8835 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8836
8837 test_65e() {
8838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8839
8840         test_mkdir $DIR/$tdir
8841
8842         $LFS setstripe $DIR/$tdir || error "setstripe"
8843         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8844                                         error "no stripe info failed"
8845         touch $DIR/$tdir/f6
8846         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8847 }
8848 run_test 65e "directory setstripe defaults"
8849
8850 test_65f() {
8851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8852
8853         test_mkdir $DIR/${tdir}f
8854         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8855                 error "setstripe succeeded" || true
8856 }
8857 run_test 65f "dir setstripe permission (should return error) ==="
8858
8859 test_65g() {
8860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8861
8862         test_mkdir $DIR/$tdir
8863         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8864
8865         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8866                 error "setstripe -S failed"
8867         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8868         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8869                 error "delete default stripe failed"
8870 }
8871 run_test 65g "directory setstripe -d"
8872
8873 test_65h() {
8874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8875
8876         test_mkdir $DIR/$tdir
8877         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8878
8879         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8880                 error "setstripe -S failed"
8881         test_mkdir $DIR/$tdir/dd1
8882         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8883                 error "stripe info inherit failed"
8884 }
8885 run_test 65h "directory stripe info inherit ===================="
8886
8887 test_65i() {
8888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8889
8890         save_layout_restore_at_exit $MOUNT
8891
8892         # bug6367: set non-default striping on root directory
8893         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8894
8895         # bug12836: getstripe on -1 default directory striping
8896         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8897
8898         # bug12836: getstripe -v on -1 default directory striping
8899         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8900
8901         # bug12836: new find on -1 default directory striping
8902         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8903 }
8904 run_test 65i "various tests to set root directory striping"
8905
8906 test_65j() { # bug6367
8907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8908
8909         sync; sleep 1
8910
8911         # if we aren't already remounting for each test, do so for this test
8912         if [ "$I_MOUNTED" = "yes" ]; then
8913                 cleanup || error "failed to unmount"
8914                 setup
8915         fi
8916
8917         save_layout_restore_at_exit $MOUNT
8918
8919         $LFS setstripe -d $MOUNT || error "setstripe failed"
8920 }
8921 run_test 65j "set default striping on root directory (bug 6367)="
8922
8923 cleanup_65k() {
8924         rm -rf $DIR/$tdir
8925         wait_delete_completed
8926         do_facet $SINGLEMDS "lctl set_param -n \
8927                 osp.$ost*MDT0000.max_create_count=$max_count"
8928         do_facet $SINGLEMDS "lctl set_param -n \
8929                 osp.$ost*MDT0000.create_count=$count"
8930         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8931         echo $INACTIVE_OSC "is Activate"
8932
8933         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8934 }
8935
8936 test_65k() { # bug11679
8937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8939         remote_mds_nodsh && skip "remote MDS with nodsh"
8940
8941         local disable_precreate=true
8942         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8943                 disable_precreate=false
8944
8945         echo "Check OST status: "
8946         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8947                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8948
8949         for OSC in $MDS_OSCS; do
8950                 echo $OSC "is active"
8951                 do_facet $SINGLEMDS lctl --device %$OSC activate
8952         done
8953
8954         for INACTIVE_OSC in $MDS_OSCS; do
8955                 local ost=$(osc_to_ost $INACTIVE_OSC)
8956                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8957                                lov.*md*.target_obd |
8958                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8959
8960                 mkdir -p $DIR/$tdir
8961                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8962                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8963
8964                 echo "Deactivate: " $INACTIVE_OSC
8965                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8966
8967                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8968                               osp.$ost*MDT0000.create_count")
8969                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8970                                   osp.$ost*MDT0000.max_create_count")
8971                 $disable_precreate &&
8972                         do_facet $SINGLEMDS "lctl set_param -n \
8973                                 osp.$ost*MDT0000.max_create_count=0"
8974
8975                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8976                         [ -f $DIR/$tdir/$idx ] && continue
8977                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8978                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8979                                 { cleanup_65k;
8980                                   error "setstripe $idx should succeed"; }
8981                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8982                 done
8983                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8984                 rmdir $DIR/$tdir
8985
8986                 do_facet $SINGLEMDS "lctl set_param -n \
8987                         osp.$ost*MDT0000.max_create_count=$max_count"
8988                 do_facet $SINGLEMDS "lctl set_param -n \
8989                         osp.$ost*MDT0000.create_count=$count"
8990                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8991                 echo $INACTIVE_OSC "is Activate"
8992
8993                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8994         done
8995 }
8996 run_test 65k "validate manual striping works properly with deactivated OSCs"
8997
8998 test_65l() { # bug 12836
8999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9000
9001         test_mkdir -p $DIR/$tdir/test_dir
9002         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9003         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9004 }
9005 run_test 65l "lfs find on -1 stripe dir ========================"
9006
9007 test_65m() {
9008         local layout=$(save_layout $MOUNT)
9009         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9010                 restore_layout $MOUNT $layout
9011                 error "setstripe should fail by non-root users"
9012         }
9013         true
9014 }
9015 run_test 65m "normal user can't set filesystem default stripe"
9016
9017 test_65n() {
9018         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9019         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9020                 skip "Need MDS version at least 2.12.50"
9021         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9022
9023         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9024         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9025         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9026
9027         save_layout_restore_at_exit $MOUNT
9028
9029         # new subdirectory under root directory should not inherit
9030         # the default layout from root
9031         local dir1=$MOUNT/$tdir-1
9032         mkdir $dir1 || error "mkdir $dir1 failed"
9033         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9034                 error "$dir1 shouldn't have LOV EA"
9035
9036         # delete the default layout on root directory
9037         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9038
9039         local dir2=$MOUNT/$tdir-2
9040         mkdir $dir2 || error "mkdir $dir2 failed"
9041         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9042                 error "$dir2 shouldn't have LOV EA"
9043
9044         # set a new striping pattern on root directory
9045         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9046         local new_def_stripe_size=$((def_stripe_size * 2))
9047         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9048                 error "set stripe size on $MOUNT failed"
9049
9050         # new file created in $dir2 should inherit the new stripe size from
9051         # the filesystem default
9052         local file2=$dir2/$tfile-2
9053         touch $file2 || error "touch $file2 failed"
9054
9055         local file2_stripe_size=$($LFS getstripe -S $file2)
9056         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9057         {
9058                 echo "file2_stripe_size: '$file2_stripe_size'"
9059                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9060                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9061         }
9062
9063         local dir3=$MOUNT/$tdir-3
9064         mkdir $dir3 || error "mkdir $dir3 failed"
9065         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9066         # the root layout, which is the actual default layout that will be used
9067         # when new files are created in $dir3.
9068         local dir3_layout=$(get_layout_param $dir3)
9069         local root_dir_layout=$(get_layout_param $MOUNT)
9070         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9071         {
9072                 echo "dir3_layout: '$dir3_layout'"
9073                 echo "root_dir_layout: '$root_dir_layout'"
9074                 error "$dir3 should show the default layout from $MOUNT"
9075         }
9076
9077         # set OST pool on root directory
9078         local pool=$TESTNAME
9079         pool_add $pool || error "add $pool failed"
9080         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9081                 error "add targets to $pool failed"
9082
9083         $LFS setstripe -p $pool $MOUNT ||
9084                 error "set OST pool on $MOUNT failed"
9085
9086         # new file created in $dir3 should inherit the pool from
9087         # the filesystem default
9088         local file3=$dir3/$tfile-3
9089         touch $file3 || error "touch $file3 failed"
9090
9091         local file3_pool=$($LFS getstripe -p $file3)
9092         [[ "$file3_pool" = "$pool" ]] ||
9093                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9094
9095         local dir4=$MOUNT/$tdir-4
9096         mkdir $dir4 || error "mkdir $dir4 failed"
9097         local dir4_layout=$(get_layout_param $dir4)
9098         root_dir_layout=$(get_layout_param $MOUNT)
9099         echo "$LFS getstripe -d $dir4"
9100         $LFS getstripe -d $dir4
9101         echo "$LFS getstripe -d $MOUNT"
9102         $LFS getstripe -d $MOUNT
9103         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9104         {
9105                 echo "dir4_layout: '$dir4_layout'"
9106                 echo "root_dir_layout: '$root_dir_layout'"
9107                 error "$dir4 should show the default layout from $MOUNT"
9108         }
9109
9110         # new file created in $dir4 should inherit the pool from
9111         # the filesystem default
9112         local file4=$dir4/$tfile-4
9113         touch $file4 || error "touch $file4 failed"
9114
9115         local file4_pool=$($LFS getstripe -p $file4)
9116         [[ "$file4_pool" = "$pool" ]] ||
9117                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9118
9119         # new subdirectory under non-root directory should inherit
9120         # the default layout from its parent directory
9121         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9122                 error "set directory layout on $dir4 failed"
9123
9124         local dir5=$dir4/$tdir-5
9125         mkdir $dir5 || error "mkdir $dir5 failed"
9126
9127         dir4_layout=$(get_layout_param $dir4)
9128         local dir5_layout=$(get_layout_param $dir5)
9129         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9130         {
9131                 echo "dir4_layout: '$dir4_layout'"
9132                 echo "dir5_layout: '$dir5_layout'"
9133                 error "$dir5 should inherit the default layout from $dir4"
9134         }
9135
9136         # though subdir under ROOT doesn't inherit default layout, but
9137         # its sub dir/file should be created with default layout.
9138         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9139         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9140                 skip "Need MDS version at least 2.12.59"
9141
9142         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9143         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9144         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9145
9146         if [ $default_lmv_hash == "none" ]; then
9147                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9148         else
9149                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9150                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9151         fi
9152
9153         $LFS setdirstripe -D -c 2 $MOUNT ||
9154                 error "setdirstripe -D -c 2 failed"
9155         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9156         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9157         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9158 }
9159 run_test 65n "don't inherit default layout from root for new subdirectories"
9160
9161 # bug 2543 - update blocks count on client
9162 test_66() {
9163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9164
9165         COUNT=${COUNT:-8}
9166         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9167         sync; sync_all_data; sync; sync_all_data
9168         cancel_lru_locks osc
9169         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9170         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9171 }
9172 run_test 66 "update inode blocks count on client ==============="
9173
9174 meminfo() {
9175         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9176 }
9177
9178 swap_used() {
9179         swapon -s | awk '($1 == "'$1'") { print $4 }'
9180 }
9181
9182 # bug5265, obdfilter oa2dentry return -ENOENT
9183 # #define OBD_FAIL_SRV_ENOENT 0x217
9184 test_69() {
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186         remote_ost_nodsh && skip "remote OST with nodsh"
9187
9188         f="$DIR/$tfile"
9189         $LFS setstripe -c 1 -i 0 $f
9190
9191         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9192
9193         do_facet ost1 lctl set_param fail_loc=0x217
9194         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9195         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9196
9197         do_facet ost1 lctl set_param fail_loc=0
9198         $DIRECTIO write $f 0 2 || error "write error"
9199
9200         cancel_lru_locks osc
9201         $DIRECTIO read $f 0 1 || error "read error"
9202
9203         do_facet ost1 lctl set_param fail_loc=0x217
9204         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9205
9206         do_facet ost1 lctl set_param fail_loc=0
9207         rm -f $f
9208 }
9209 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9210
9211 test_71() {
9212         test_mkdir $DIR/$tdir
9213         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9214         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9215 }
9216 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9217
9218 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9220         [ "$RUNAS_ID" = "$UID" ] &&
9221                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9222         # Check that testing environment is properly set up. Skip if not
9223         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9224                 skip_env "User $RUNAS_ID does not exist - skipping"
9225
9226         touch $DIR/$tfile
9227         chmod 777 $DIR/$tfile
9228         chmod ug+s $DIR/$tfile
9229         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9230                 error "$RUNAS dd $DIR/$tfile failed"
9231         # See if we are still setuid/sgid
9232         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9233                 error "S/gid is not dropped on write"
9234         # Now test that MDS is updated too
9235         cancel_lru_locks mdc
9236         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9237                 error "S/gid is not dropped on MDS"
9238         rm -f $DIR/$tfile
9239 }
9240 run_test 72a "Test that remove suid works properly (bug5695) ===="
9241
9242 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9243         local perm
9244
9245         [ "$RUNAS_ID" = "$UID" ] &&
9246                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9247         [ "$RUNAS_ID" -eq 0 ] &&
9248                 skip_env "RUNAS_ID = 0 -- skipping"
9249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9250         # Check that testing environment is properly set up. Skip if not
9251         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9252                 skip_env "User $RUNAS_ID does not exist - skipping"
9253
9254         touch $DIR/${tfile}-f{g,u}
9255         test_mkdir $DIR/${tfile}-dg
9256         test_mkdir $DIR/${tfile}-du
9257         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9258         chmod g+s $DIR/${tfile}-{f,d}g
9259         chmod u+s $DIR/${tfile}-{f,d}u
9260         for perm in 777 2777 4777; do
9261                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9262                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9263                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9264                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9265         done
9266         true
9267 }
9268 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9269
9270 # bug 3462 - multiple simultaneous MDC requests
9271 test_73() {
9272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9273
9274         test_mkdir $DIR/d73-1
9275         test_mkdir $DIR/d73-2
9276         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9277         pid1=$!
9278
9279         lctl set_param fail_loc=0x80000129
9280         $MULTIOP $DIR/d73-1/f73-2 Oc &
9281         sleep 1
9282         lctl set_param fail_loc=0
9283
9284         $MULTIOP $DIR/d73-2/f73-3 Oc &
9285         pid3=$!
9286
9287         kill -USR1 $pid1
9288         wait $pid1 || return 1
9289
9290         sleep 25
9291
9292         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9293         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9294         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9295
9296         rm -rf $DIR/d73-*
9297 }
9298 run_test 73 "multiple MDC requests (should not deadlock)"
9299
9300 test_74a() { # bug 6149, 6184
9301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9302
9303         touch $DIR/f74a
9304         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9305         #
9306         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9307         # will spin in a tight reconnection loop
9308         $LCTL set_param fail_loc=0x8000030e
9309         # get any lock that won't be difficult - lookup works.
9310         ls $DIR/f74a
9311         $LCTL set_param fail_loc=0
9312         rm -f $DIR/f74a
9313         true
9314 }
9315 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9316
9317 test_74b() { # bug 13310
9318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9319
9320         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9321         #
9322         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9323         # will spin in a tight reconnection loop
9324         $LCTL set_param fail_loc=0x8000030e
9325         # get a "difficult" lock
9326         touch $DIR/f74b
9327         $LCTL set_param fail_loc=0
9328         rm -f $DIR/f74b
9329         true
9330 }
9331 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9332
9333 test_74c() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         #define OBD_FAIL_LDLM_NEW_LOCK
9337         $LCTL set_param fail_loc=0x319
9338         touch $DIR/$tfile && error "touch successful"
9339         $LCTL set_param fail_loc=0
9340         true
9341 }
9342 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9343
9344 slab_lic=/sys/kernel/slab/lustre_inode_cache
9345 num_objects() {
9346         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9347         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9348                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9349 }
9350
9351 test_76a() { # Now for b=20433, added originally in b=1443
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         cancel_lru_locks osc
9355         # there may be some slab objects cached per core
9356         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9357         local before=$(num_objects)
9358         local count=$((512 * cpus))
9359         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9360         local margin=$((count / 10))
9361         if [[ -f $slab_lic/aliases ]]; then
9362                 local aliases=$(cat $slab_lic/aliases)
9363                 (( aliases > 0 )) && margin=$((margin * aliases))
9364         fi
9365
9366         echo "before slab objects: $before"
9367         for i in $(seq $count); do
9368                 touch $DIR/$tfile
9369                 rm -f $DIR/$tfile
9370         done
9371         cancel_lru_locks osc
9372         local after=$(num_objects)
9373         echo "created: $count, after slab objects: $after"
9374         # shared slab counts are not very accurate, allow significant margin
9375         # the main goal is that the cache growth is not permanently > $count
9376         while (( after > before + margin )); do
9377                 sleep 1
9378                 after=$(num_objects)
9379                 wait=$((wait + 1))
9380                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9381                 if (( wait > 60 )); then
9382                         error "inode slab grew from $before+$margin to $after"
9383                 fi
9384         done
9385 }
9386 run_test 76a "confirm clients recycle inodes properly ===="
9387
9388 test_76b() {
9389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9390         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9391
9392         local count=512
9393         local before=$(num_objects)
9394
9395         for i in $(seq $count); do
9396                 mkdir $DIR/$tdir
9397                 rmdir $DIR/$tdir
9398         done
9399
9400         local after=$(num_objects)
9401         local wait=0
9402
9403         while (( after > before )); do
9404                 sleep 1
9405                 after=$(num_objects)
9406                 wait=$((wait + 1))
9407                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9408                 if (( wait > 60 )); then
9409                         error "inode slab grew from $before to $after"
9410                 fi
9411         done
9412
9413         echo "slab objects before: $before, after: $after"
9414 }
9415 run_test 76b "confirm clients recycle directory inodes properly ===="
9416
9417 export ORIG_CSUM=""
9418 set_checksums()
9419 {
9420         # Note: in sptlrpc modes which enable its own bulk checksum, the
9421         # original crc32_le bulk checksum will be automatically disabled,
9422         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9423         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9424         # In this case set_checksums() will not be no-op, because sptlrpc
9425         # bulk checksum will be enabled all through the test.
9426
9427         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9428         lctl set_param -n osc.*.checksums $1
9429         return 0
9430 }
9431
9432 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9433                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9434 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9435                              tr -d [] | head -n1)}
9436 set_checksum_type()
9437 {
9438         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9439         rc=$?
9440         log "set checksum type to $1, rc = $rc"
9441         return $rc
9442 }
9443
9444 get_osc_checksum_type()
9445 {
9446         # arugment 1: OST name, like OST0000
9447         ost=$1
9448         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9449                         sed 's/.*\[\(.*\)\].*/\1/g')
9450         rc=$?
9451         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9452         echo $checksum_type
9453 }
9454
9455 F77_TMP=$TMP/f77-temp
9456 F77SZ=8
9457 setup_f77() {
9458         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9459                 error "error writing to $F77_TMP"
9460 }
9461
9462 test_77a() { # bug 10889
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464         $GSS && skip_env "could not run with gss"
9465
9466         [ ! -f $F77_TMP ] && setup_f77
9467         set_checksums 1
9468         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9469         set_checksums 0
9470         rm -f $DIR/$tfile
9471 }
9472 run_test 77a "normal checksum read/write operation"
9473
9474 test_77b() { # bug 10889
9475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9476         $GSS && skip_env "could not run with gss"
9477
9478         [ ! -f $F77_TMP ] && setup_f77
9479         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9480         $LCTL set_param fail_loc=0x80000409
9481         set_checksums 1
9482
9483         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9484                 error "dd error: $?"
9485         $LCTL set_param fail_loc=0
9486
9487         for algo in $CKSUM_TYPES; do
9488                 cancel_lru_locks osc
9489                 set_checksum_type $algo
9490                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9491                 $LCTL set_param fail_loc=0x80000408
9492                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9493                 $LCTL set_param fail_loc=0
9494         done
9495         set_checksums 0
9496         set_checksum_type $ORIG_CSUM_TYPE
9497         rm -f $DIR/$tfile
9498 }
9499 run_test 77b "checksum error on client write, read"
9500
9501 cleanup_77c() {
9502         trap 0
9503         set_checksums 0
9504         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9505         $check_ost &&
9506                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9507         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9508         $check_ost && [ -n "$ost_file_prefix" ] &&
9509                 do_facet ost1 rm -f ${ost_file_prefix}\*
9510 }
9511
9512 test_77c() {
9513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9514         $GSS && skip_env "could not run with gss"
9515         remote_ost_nodsh && skip "remote OST with nodsh"
9516
9517         local bad1
9518         local osc_file_prefix
9519         local osc_file
9520         local check_ost=false
9521         local ost_file_prefix
9522         local ost_file
9523         local orig_cksum
9524         local dump_cksum
9525         local fid
9526
9527         # ensure corruption will occur on first OSS/OST
9528         $LFS setstripe -i 0 $DIR/$tfile
9529
9530         [ ! -f $F77_TMP ] && setup_f77
9531         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9532                 error "dd write error: $?"
9533         fid=$($LFS path2fid $DIR/$tfile)
9534
9535         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9536         then
9537                 check_ost=true
9538                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9539                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9540         else
9541                 echo "OSS do not support bulk pages dump upon error"
9542         fi
9543
9544         osc_file_prefix=$($LCTL get_param -n debug_path)
9545         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9546
9547         trap cleanup_77c EXIT
9548
9549         set_checksums 1
9550         # enable bulk pages dump upon error on Client
9551         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9552         # enable bulk pages dump upon error on OSS
9553         $check_ost &&
9554                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9555
9556         # flush Client cache to allow next read to reach OSS
9557         cancel_lru_locks osc
9558
9559         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9560         $LCTL set_param fail_loc=0x80000408
9561         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9562         $LCTL set_param fail_loc=0
9563
9564         rm -f $DIR/$tfile
9565
9566         # check cksum dump on Client
9567         osc_file=$(ls ${osc_file_prefix}*)
9568         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9569         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9570         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9571         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9572         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9573                      cksum)
9574         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9575         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9576                 error "dump content does not match on Client"
9577
9578         $check_ost || skip "No need to check cksum dump on OSS"
9579
9580         # check cksum dump on OSS
9581         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9582         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9583         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9584         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9585         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9586                 error "dump content does not match on OSS"
9587
9588         cleanup_77c
9589 }
9590 run_test 77c "checksum error on client read with debug"
9591
9592 test_77d() { # bug 10889
9593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9594         $GSS && skip_env "could not run with gss"
9595
9596         stack_trap "rm -f $DIR/$tfile"
9597         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9598         $LCTL set_param fail_loc=0x80000409
9599         set_checksums 1
9600         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9601                 error "direct write: rc=$?"
9602         $LCTL set_param fail_loc=0
9603         set_checksums 0
9604
9605         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9606         $LCTL set_param fail_loc=0x80000408
9607         set_checksums 1
9608         cancel_lru_locks osc
9609         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9610                 error "direct read: rc=$?"
9611         $LCTL set_param fail_loc=0
9612         set_checksums 0
9613 }
9614 run_test 77d "checksum error on OST direct write, read"
9615
9616 test_77f() { # bug 10889
9617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9618         $GSS && skip_env "could not run with gss"
9619
9620         set_checksums 1
9621         stack_trap "rm -f $DIR/$tfile"
9622         for algo in $CKSUM_TYPES; do
9623                 cancel_lru_locks osc
9624                 set_checksum_type $algo
9625                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9626                 $LCTL set_param fail_loc=0x409
9627                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9628                         error "direct write succeeded"
9629                 $LCTL set_param fail_loc=0
9630         done
9631         set_checksum_type $ORIG_CSUM_TYPE
9632         set_checksums 0
9633 }
9634 run_test 77f "repeat checksum error on write (expect error)"
9635
9636 test_77g() { # bug 10889
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638         $GSS && skip_env "could not run with gss"
9639         remote_ost_nodsh && skip "remote OST with nodsh"
9640
9641         [ ! -f $F77_TMP ] && setup_f77
9642
9643         local file=$DIR/$tfile
9644         stack_trap "rm -f $file" EXIT
9645
9646         $LFS setstripe -c 1 -i 0 $file
9647         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9648         do_facet ost1 lctl set_param fail_loc=0x8000021a
9649         set_checksums 1
9650         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9651                 error "write error: rc=$?"
9652         do_facet ost1 lctl set_param fail_loc=0
9653         set_checksums 0
9654
9655         cancel_lru_locks osc
9656         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9657         do_facet ost1 lctl set_param fail_loc=0x8000021b
9658         set_checksums 1
9659         cmp $F77_TMP $file || error "file compare failed"
9660         do_facet ost1 lctl set_param fail_loc=0
9661         set_checksums 0
9662 }
9663 run_test 77g "checksum error on OST write, read"
9664
9665 test_77k() { # LU-10906
9666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9667         $GSS && skip_env "could not run with gss"
9668
9669         local cksum_param="osc.$FSNAME*.checksums"
9670         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9671         local checksum
9672         local i
9673
9674         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9675         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9676         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9677
9678         for i in 0 1; do
9679                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9680                         error "failed to set checksum=$i on MGS"
9681                 wait_update $HOSTNAME "$get_checksum" $i
9682                 #remount
9683                 echo "remount client, checksum should be $i"
9684                 remount_client $MOUNT || error "failed to remount client"
9685                 checksum=$(eval $get_checksum)
9686                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9687         done
9688         # remove persistent param to avoid races with checksum mountopt below
9689         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9690                 error "failed to delete checksum on MGS"
9691
9692         for opt in "checksum" "nochecksum"; do
9693                 #remount with mount option
9694                 echo "remount client with option $opt, checksum should be $i"
9695                 umount_client $MOUNT || error "failed to umount client"
9696                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9697                         error "failed to mount client with option '$opt'"
9698                 checksum=$(eval $get_checksum)
9699                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9700                 i=$((i - 1))
9701         done
9702
9703         remount_client $MOUNT || error "failed to remount client"
9704 }
9705 run_test 77k "enable/disable checksum correctly"
9706
9707 test_77l() {
9708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9709         $GSS && skip_env "could not run with gss"
9710
9711         set_checksums 1
9712         stack_trap "set_checksums $ORIG_CSUM" EXIT
9713         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9714
9715         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9716
9717         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9718         for algo in $CKSUM_TYPES; do
9719                 set_checksum_type $algo || error "fail to set checksum type $algo"
9720                 osc_algo=$(get_osc_checksum_type OST0000)
9721                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9722
9723                 # no locks, no reqs to let the connection idle
9724                 cancel_lru_locks osc
9725                 lru_resize_disable osc
9726                 wait_osc_import_state client ost1 IDLE
9727
9728                 # ensure ost1 is connected
9729                 stat $DIR/$tfile >/dev/null || error "can't stat"
9730                 wait_osc_import_state client ost1 FULL
9731
9732                 osc_algo=$(get_osc_checksum_type OST0000)
9733                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9734         done
9735         return 0
9736 }
9737 run_test 77l "preferred checksum type is remembered after reconnected"
9738
9739 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9740 rm -f $F77_TMP
9741 unset F77_TMP
9742
9743 test_77m() {
9744         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9745                 skip "Need at least version 2.14.52"
9746         local param=checksum_speed
9747
9748         $LCTL get_param $param || error "reading $param failed"
9749
9750         csum_speeds=$($LCTL get_param -n $param)
9751
9752         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9753                 error "known checksum types are missing"
9754 }
9755 run_test 77m "Verify checksum_speed is correctly read"
9756
9757 check_filefrag_77n() {
9758         local nr_ext=0
9759         local starts=()
9760         local ends=()
9761
9762         while read extidx a b start end rest; do
9763                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9764                         nr_ext=$(( $nr_ext + 1 ))
9765                         starts+=( ${start%..} )
9766                         ends+=( ${end%:} )
9767                 fi
9768         done < <( filefrag -sv $1 )
9769
9770         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9771         return 1
9772 }
9773
9774 test_77n() {
9775         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9776
9777         touch $DIR/$tfile
9778         $TRUNCATE $DIR/$tfile 0
9779         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9780         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9781         check_filefrag_77n $DIR/$tfile ||
9782                 skip "$tfile blocks not contiguous around hole"
9783
9784         set_checksums 1
9785         stack_trap "set_checksums $ORIG_CSUM" EXIT
9786         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9787         stack_trap "rm -f $DIR/$tfile"
9788
9789         for algo in $CKSUM_TYPES; do
9790                 if [[ "$algo" =~ ^t10 ]]; then
9791                         set_checksum_type $algo ||
9792                                 error "fail to set checksum type $algo"
9793                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9794                                 error "fail to read $tfile with $algo"
9795                 fi
9796         done
9797         rm -f $DIR/$tfile
9798         return 0
9799 }
9800 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9801
9802 cleanup_test_78() {
9803         trap 0
9804         rm -f $DIR/$tfile
9805 }
9806
9807 test_78() { # bug 10901
9808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9809         remote_ost || skip_env "local OST"
9810
9811         NSEQ=5
9812         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9813         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9814         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9815         echo "MemTotal: $MEMTOTAL"
9816
9817         # reserve 256MB of memory for the kernel and other running processes,
9818         # and then take 1/2 of the remaining memory for the read/write buffers.
9819         if [ $MEMTOTAL -gt 512 ] ;then
9820                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9821         else
9822                 # for those poor memory-starved high-end clusters...
9823                 MEMTOTAL=$((MEMTOTAL / 2))
9824         fi
9825         echo "Mem to use for directio: $MEMTOTAL"
9826
9827         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9828         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9829         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9830         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9831                 head -n1)
9832         echo "Smallest OST: $SMALLESTOST"
9833         [[ $SMALLESTOST -lt 10240 ]] &&
9834                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9835
9836         trap cleanup_test_78 EXIT
9837
9838         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9839                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9840
9841         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9842         echo "File size: $F78SIZE"
9843         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9844         for i in $(seq 1 $NSEQ); do
9845                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9846                 echo directIO rdwr round $i of $NSEQ
9847                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9848         done
9849
9850         cleanup_test_78
9851 }
9852 run_test 78 "handle large O_DIRECT writes correctly ============"
9853
9854 test_79() { # bug 12743
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856
9857         wait_delete_completed
9858
9859         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9860         BKFREE=$(calc_osc_kbytes kbytesfree)
9861         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9862
9863         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9864         DFTOTAL=`echo $STRING | cut -d, -f1`
9865         DFUSED=`echo $STRING  | cut -d, -f2`
9866         DFAVAIL=`echo $STRING | cut -d, -f3`
9867         DFFREE=$(($DFTOTAL - $DFUSED))
9868
9869         ALLOWANCE=$((64 * $OSTCOUNT))
9870
9871         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9872            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9873                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9874         fi
9875         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9876            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9877                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9878         fi
9879         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9880            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9881                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9882         fi
9883 }
9884 run_test 79 "df report consistency check ======================="
9885
9886 test_80() { # bug 10718
9887         remote_ost_nodsh && skip "remote OST with nodsh"
9888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9889
9890         # relax strong synchronous semantics for slow backends like ZFS
9891         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9892                 local soc="obdfilter.*.sync_lock_cancel"
9893                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9894
9895                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9896                 if [ -z "$save" ]; then
9897                         soc="obdfilter.*.sync_on_lock_cancel"
9898                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9899                 fi
9900
9901                 if [ "$save" != "never" ]; then
9902                         local hosts=$(comma_list $(osts_nodes))
9903
9904                         do_nodes $hosts $LCTL set_param $soc=never
9905                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9906                 fi
9907         fi
9908
9909         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9910         sync; sleep 1; sync
9911         local before=$(date +%s)
9912         cancel_lru_locks osc
9913         local after=$(date +%s)
9914         local diff=$((after - before))
9915         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9916
9917         rm -f $DIR/$tfile
9918 }
9919 run_test 80 "Page eviction is equally fast at high offsets too"
9920
9921 test_81a() { # LU-456
9922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9923         remote_ost_nodsh && skip "remote OST with nodsh"
9924
9925         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9926         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9927         do_facet ost1 lctl set_param fail_loc=0x80000228
9928
9929         # write should trigger a retry and success
9930         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9931         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9932         RC=$?
9933         if [ $RC -ne 0 ] ; then
9934                 error "write should success, but failed for $RC"
9935         fi
9936 }
9937 run_test 81a "OST should retry write when get -ENOSPC ==============="
9938
9939 test_81b() { # LU-456
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941         remote_ost_nodsh && skip "remote OST with nodsh"
9942
9943         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9944         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9945         do_facet ost1 lctl set_param fail_loc=0x228
9946
9947         # write should retry several times and return -ENOSPC finally
9948         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9949         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9950         RC=$?
9951         ENOSPC=28
9952         if [ $RC -ne $ENOSPC ] ; then
9953                 error "dd should fail for -ENOSPC, but succeed."
9954         fi
9955 }
9956 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9957
9958 test_99() {
9959         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9960
9961         test_mkdir $DIR/$tdir.cvsroot
9962         chown $RUNAS_ID $DIR/$tdir.cvsroot
9963
9964         cd $TMP
9965         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9966
9967         cd /etc/init.d
9968         # some versions of cvs import exit(1) when asked to import links or
9969         # files they can't read.  ignore those files.
9970         local toignore=$(find . -type l -printf '-I %f\n' -o \
9971                          ! -perm /4 -printf '-I %f\n')
9972         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9973                 $tdir.reposname vtag rtag
9974
9975         cd $DIR
9976         test_mkdir $DIR/$tdir.reposname
9977         chown $RUNAS_ID $DIR/$tdir.reposname
9978         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9979
9980         cd $DIR/$tdir.reposname
9981         $RUNAS touch foo99
9982         $RUNAS cvs add -m 'addmsg' foo99
9983         $RUNAS cvs update
9984         $RUNAS cvs commit -m 'nomsg' foo99
9985         rm -fr $DIR/$tdir.cvsroot
9986 }
9987 run_test 99 "cvs strange file/directory operations"
9988
9989 test_100() {
9990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9991         [[ "$NETTYPE" =~ tcp ]] ||
9992                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9993         remote_ost_nodsh && skip "remote OST with nodsh"
9994         remote_mds_nodsh && skip "remote MDS with nodsh"
9995         remote_servers ||
9996                 skip "useless for local single node setup"
9997
9998         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9999                 [ "$PROT" != "tcp" ] && continue
10000                 RPORT=$(echo $REMOTE | cut -d: -f2)
10001                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10002
10003                 rc=0
10004                 LPORT=`echo $LOCAL | cut -d: -f2`
10005                 if [ $LPORT -ge 1024 ]; then
10006                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10007                         netstat -tna
10008                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10009                 fi
10010         done
10011         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10012 }
10013 run_test 100 "check local port using privileged port ==========="
10014
10015 function get_named_value()
10016 {
10017     local tag=$1
10018
10019     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10020 }
10021
10022 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10023                    awk '/^max_cached_mb/ { print $2 }')
10024
10025 cleanup_101a() {
10026         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10027         trap 0
10028 }
10029
10030 test_101a() {
10031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10032
10033         local s
10034         local discard
10035         local nreads=10000
10036         local cache_limit=32
10037
10038         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10039         trap cleanup_101a EXIT
10040         $LCTL set_param -n llite.*.read_ahead_stats=0
10041         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10042
10043         #
10044         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10045         #
10046         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10047         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10048
10049         discard=0
10050         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10051                    get_named_value 'read.but.discarded'); do
10052                         discard=$(($discard + $s))
10053         done
10054         cleanup_101a
10055
10056         $LCTL get_param osc.*-osc*.rpc_stats
10057         $LCTL get_param llite.*.read_ahead_stats
10058
10059         # Discard is generally zero, but sometimes a few random reads line up
10060         # and trigger larger readahead, which is wasted & leads to discards.
10061         if [[ $(($discard)) -gt $nreads ]]; then
10062                 error "too many ($discard) discarded pages"
10063         fi
10064         rm -f $DIR/$tfile || true
10065 }
10066 run_test 101a "check read-ahead for random reads"
10067
10068 setup_test101bc() {
10069         test_mkdir $DIR/$tdir
10070         local ssize=$1
10071         local FILE_LENGTH=$2
10072         STRIPE_OFFSET=0
10073
10074         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10075
10076         local list=$(comma_list $(osts_nodes))
10077         set_osd_param $list '' read_cache_enable 0
10078         set_osd_param $list '' writethrough_cache_enable 0
10079
10080         trap cleanup_test101bc EXIT
10081         # prepare the read-ahead file
10082         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10083
10084         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10085                                 count=$FILE_SIZE_MB 2> /dev/null
10086
10087 }
10088
10089 cleanup_test101bc() {
10090         trap 0
10091         rm -rf $DIR/$tdir
10092         rm -f $DIR/$tfile
10093
10094         local list=$(comma_list $(osts_nodes))
10095         set_osd_param $list '' read_cache_enable 1
10096         set_osd_param $list '' writethrough_cache_enable 1
10097 }
10098
10099 calc_total() {
10100         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10101 }
10102
10103 ra_check_101() {
10104         local READ_SIZE=$1
10105         local STRIPE_SIZE=$2
10106         local FILE_LENGTH=$3
10107         local RA_INC=1048576
10108         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10109         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10110                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10111         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10112                   get_named_value 'read.but.discarded' | calc_total)
10113         if [[ $DISCARD -gt $discard_limit ]]; then
10114                 $LCTL get_param llite.*.read_ahead_stats
10115                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10116         else
10117                 echo "Read-ahead success for size ${READ_SIZE}"
10118         fi
10119 }
10120
10121 test_101b() {
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10124
10125         local STRIPE_SIZE=1048576
10126         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10127
10128         if [ $SLOW == "yes" ]; then
10129                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10130         else
10131                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10132         fi
10133
10134         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10135
10136         # prepare the read-ahead file
10137         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10138         cancel_lru_locks osc
10139         for BIDX in 2 4 8 16 32 64 128 256
10140         do
10141                 local BSIZE=$((BIDX*4096))
10142                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10143                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10144                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10145                 $LCTL set_param -n llite.*.read_ahead_stats=0
10146                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10147                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10148                 cancel_lru_locks osc
10149                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10150         done
10151         cleanup_test101bc
10152         true
10153 }
10154 run_test 101b "check stride-io mode read-ahead ================="
10155
10156 test_101c() {
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10158
10159         local STRIPE_SIZE=1048576
10160         local FILE_LENGTH=$((STRIPE_SIZE*100))
10161         local nreads=10000
10162         local rsize=65536
10163         local osc_rpc_stats
10164
10165         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10166
10167         cancel_lru_locks osc
10168         $LCTL set_param osc.*.rpc_stats=0
10169         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10170         $LCTL get_param osc.*.rpc_stats
10171         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10172                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10173                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10174                 local size
10175
10176                 if [ $lines -le 20 ]; then
10177                         echo "continue debug"
10178                         continue
10179                 fi
10180                 for size in 1 2 4 8; do
10181                         local rpc=$(echo "$stats" |
10182                                     awk '($1 == "'$size':") {print $2; exit; }')
10183                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10184                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10185                 done
10186                 echo "$osc_rpc_stats check passed!"
10187         done
10188         cleanup_test101bc
10189         true
10190 }
10191 run_test 101c "check stripe_size aligned read-ahead"
10192
10193 test_101d() {
10194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10195
10196         local file=$DIR/$tfile
10197         local sz_MB=${FILESIZE_101d:-80}
10198         local ra_MB=${READAHEAD_MB:-40}
10199
10200         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10201         [ $free_MB -lt $sz_MB ] &&
10202                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10203
10204         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10205         $LFS setstripe -c -1 $file || error "setstripe failed"
10206
10207         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10208         echo Cancel LRU locks on lustre client to flush the client cache
10209         cancel_lru_locks osc
10210
10211         echo Disable read-ahead
10212         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10213         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10214         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10215         $LCTL get_param -n llite.*.max_read_ahead_mb
10216
10217         echo "Reading the test file $file with read-ahead disabled"
10218         local sz_KB=$((sz_MB * 1024 / 4))
10219         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10220         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10221         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10222                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10223
10224         echo "Cancel LRU locks on lustre client to flush the client cache"
10225         cancel_lru_locks osc
10226         echo Enable read-ahead with ${ra_MB}MB
10227         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10228
10229         echo "Reading the test file $file with read-ahead enabled"
10230         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10231                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10232
10233         echo "read-ahead disabled time read $raOFF"
10234         echo "read-ahead enabled time read $raON"
10235
10236         rm -f $file
10237         wait_delete_completed
10238
10239         # use awk for this check instead of bash because it handles decimals
10240         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10241                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10242 }
10243 run_test 101d "file read with and without read-ahead enabled"
10244
10245 test_101e() {
10246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10247
10248         local file=$DIR/$tfile
10249         local size_KB=500  #KB
10250         local count=100
10251         local bsize=1024
10252
10253         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10254         local need_KB=$((count * size_KB))
10255         [[ $free_KB -le $need_KB ]] &&
10256                 skip_env "Need free space $need_KB, have $free_KB"
10257
10258         echo "Creating $count ${size_KB}K test files"
10259         for ((i = 0; i < $count; i++)); do
10260                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10261         done
10262
10263         echo "Cancel LRU locks on lustre client to flush the client cache"
10264         cancel_lru_locks $OSC
10265
10266         echo "Reset readahead stats"
10267         $LCTL set_param -n llite.*.read_ahead_stats=0
10268
10269         for ((i = 0; i < $count; i++)); do
10270                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10271         done
10272
10273         $LCTL get_param llite.*.max_cached_mb
10274         $LCTL get_param llite.*.read_ahead_stats
10275         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10276                      get_named_value 'misses' | calc_total)
10277
10278         for ((i = 0; i < $count; i++)); do
10279                 rm -rf $file.$i 2>/dev/null
10280         done
10281
10282         #10000 means 20% reads are missing in readahead
10283         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10284 }
10285 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10286
10287 test_101f() {
10288         which iozone || skip_env "no iozone installed"
10289
10290         local old_debug=$($LCTL get_param debug)
10291         old_debug=${old_debug#*=}
10292         $LCTL set_param debug="reada mmap"
10293
10294         # create a test file
10295         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10296
10297         echo Cancel LRU locks on lustre client to flush the client cache
10298         cancel_lru_locks osc
10299
10300         echo Reset readahead stats
10301         $LCTL set_param -n llite.*.read_ahead_stats=0
10302
10303         echo mmap read the file with small block size
10304         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10305                 > /dev/null 2>&1
10306
10307         echo checking missing pages
10308         $LCTL get_param llite.*.read_ahead_stats
10309         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10310                         get_named_value 'misses' | calc_total)
10311
10312         $LCTL set_param debug="$old_debug"
10313         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10314         rm -f $DIR/$tfile
10315 }
10316 run_test 101f "check mmap read performance"
10317
10318 test_101g_brw_size_test() {
10319         local mb=$1
10320         local pages=$((mb * 1048576 / PAGE_SIZE))
10321         local file=$DIR/$tfile
10322
10323         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10324                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10325         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10326                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10327                         return 2
10328         done
10329
10330         stack_trap "rm -f $file" EXIT
10331         $LCTL set_param -n osc.*.rpc_stats=0
10332
10333         # 10 RPCs should be enough for the test
10334         local count=10
10335         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10336                 { error "dd write ${mb} MB blocks failed"; return 3; }
10337         cancel_lru_locks osc
10338         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10339                 { error "dd write ${mb} MB blocks failed"; return 4; }
10340
10341         # calculate number of full-sized read and write RPCs
10342         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10343                 sed -n '/pages per rpc/,/^$/p' |
10344                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10345                 END { print reads,writes }'))
10346         # allow one extra full-sized read RPC for async readahead
10347         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10348                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10349         [[ ${rpcs[1]} == $count ]] ||
10350                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10351 }
10352
10353 test_101g() {
10354         remote_ost_nodsh && skip "remote OST with nodsh"
10355
10356         local rpcs
10357         local osts=$(get_facets OST)
10358         local list=$(comma_list $(osts_nodes))
10359         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10360         local brw_size="obdfilter.*.brw_size"
10361
10362         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10363
10364         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10365
10366         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10367                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10368                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10369            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10370                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10371                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10372
10373                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10374                         suffix="M"
10375
10376                 if [[ $orig_mb -lt 16 ]]; then
10377                         save_lustre_params $osts "$brw_size" > $p
10378                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10379                                 error "set 16MB RPC size failed"
10380
10381                         echo "remount client to enable new RPC size"
10382                         remount_client $MOUNT || error "remount_client failed"
10383                 fi
10384
10385                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10386                 # should be able to set brw_size=12, but no rpc_stats for that
10387                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10388         fi
10389
10390         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10391
10392         if [[ $orig_mb -lt 16 ]]; then
10393                 restore_lustre_params < $p
10394                 remount_client $MOUNT || error "remount_client restore failed"
10395         fi
10396
10397         rm -f $p $DIR/$tfile
10398 }
10399 run_test 101g "Big bulk(4/16 MiB) readahead"
10400
10401 test_101h() {
10402         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10403
10404         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10405                 error "dd 70M file failed"
10406         echo Cancel LRU locks on lustre client to flush the client cache
10407         cancel_lru_locks osc
10408
10409         echo "Reset readahead stats"
10410         $LCTL set_param -n llite.*.read_ahead_stats 0
10411
10412         echo "Read 10M of data but cross 64M bundary"
10413         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10414         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10415                      get_named_value 'misses' | calc_total)
10416         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10417         rm -f $p $DIR/$tfile
10418 }
10419 run_test 101h "Readahead should cover current read window"
10420
10421 test_101i() {
10422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10423                 error "dd 10M file failed"
10424
10425         local max_per_file_mb=$($LCTL get_param -n \
10426                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10427         cancel_lru_locks osc
10428         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10429         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10430                 error "set max_read_ahead_per_file_mb to 1 failed"
10431
10432         echo "Reset readahead stats"
10433         $LCTL set_param llite.*.read_ahead_stats=0
10434
10435         dd if=$DIR/$tfile of=/dev/null bs=2M
10436
10437         $LCTL get_param llite.*.read_ahead_stats
10438         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10439                      awk '/misses/ { print $2 }')
10440         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10441         rm -f $DIR/$tfile
10442 }
10443 run_test 101i "allow current readahead to exceed reservation"
10444
10445 test_101j() {
10446         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10447                 error "setstripe $DIR/$tfile failed"
10448         local file_size=$((1048576 * 16))
10449         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10450         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10451
10452         echo Disable read-ahead
10453         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10454
10455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10456         for blk in $PAGE_SIZE 1048576 $file_size; do
10457                 cancel_lru_locks osc
10458                 echo "Reset readahead stats"
10459                 $LCTL set_param -n llite.*.read_ahead_stats=0
10460                 local count=$(($file_size / $blk))
10461                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10462                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10463                              get_named_value 'failed.to.fast.read' | calc_total)
10464                 $LCTL get_param -n llite.*.read_ahead_stats
10465                 [ $miss -eq $count ] || error "expected $count got $miss"
10466         done
10467
10468         rm -f $p $DIR/$tfile
10469 }
10470 run_test 101j "A complete read block should be submitted when no RA"
10471
10472 setup_test102() {
10473         test_mkdir $DIR/$tdir
10474         chown $RUNAS_ID $DIR/$tdir
10475         STRIPE_SIZE=65536
10476         STRIPE_OFFSET=1
10477         STRIPE_COUNT=$OSTCOUNT
10478         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10479
10480         trap cleanup_test102 EXIT
10481         cd $DIR
10482         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10483         cd $DIR/$tdir
10484         for num in 1 2 3 4; do
10485                 for count in $(seq 1 $STRIPE_COUNT); do
10486                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10487                                 local size=`expr $STRIPE_SIZE \* $num`
10488                                 local file=file"$num-$idx-$count"
10489                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10490                         done
10491                 done
10492         done
10493
10494         cd $DIR
10495         $1 tar cf $TMP/f102.tar $tdir --xattrs
10496 }
10497
10498 cleanup_test102() {
10499         trap 0
10500         rm -f $TMP/f102.tar
10501         rm -rf $DIR/d0.sanity/d102
10502 }
10503
10504 test_102a() {
10505         [ "$UID" != 0 ] && skip "must run as root"
10506         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10507                 skip_env "must have user_xattr"
10508
10509         [ -z "$(which setfattr 2>/dev/null)" ] &&
10510                 skip_env "could not find setfattr"
10511
10512         local testfile=$DIR/$tfile
10513
10514         touch $testfile
10515         echo "set/get xattr..."
10516         setfattr -n trusted.name1 -v value1 $testfile ||
10517                 error "setfattr -n trusted.name1=value1 $testfile failed"
10518         getfattr -n trusted.name1 $testfile 2> /dev/null |
10519           grep "trusted.name1=.value1" ||
10520                 error "$testfile missing trusted.name1=value1"
10521
10522         setfattr -n user.author1 -v author1 $testfile ||
10523                 error "setfattr -n user.author1=author1 $testfile failed"
10524         getfattr -n user.author1 $testfile 2> /dev/null |
10525           grep "user.author1=.author1" ||
10526                 error "$testfile missing trusted.author1=author1"
10527
10528         echo "listxattr..."
10529         setfattr -n trusted.name2 -v value2 $testfile ||
10530                 error "$testfile unable to set trusted.name2"
10531         setfattr -n trusted.name3 -v value3 $testfile ||
10532                 error "$testfile unable to set trusted.name3"
10533         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10534             grep "trusted.name" | wc -l) -eq 3 ] ||
10535                 error "$testfile missing 3 trusted.name xattrs"
10536
10537         setfattr -n user.author2 -v author2 $testfile ||
10538                 error "$testfile unable to set user.author2"
10539         setfattr -n user.author3 -v author3 $testfile ||
10540                 error "$testfile unable to set user.author3"
10541         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10542             grep "user.author" | wc -l) -eq 3 ] ||
10543                 error "$testfile missing 3 user.author xattrs"
10544
10545         echo "remove xattr..."
10546         setfattr -x trusted.name1 $testfile ||
10547                 error "$testfile error deleting trusted.name1"
10548         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10549                 error "$testfile did not delete trusted.name1 xattr"
10550
10551         setfattr -x user.author1 $testfile ||
10552                 error "$testfile error deleting user.author1"
10553         echo "set lustre special xattr ..."
10554         $LFS setstripe -c1 $testfile
10555         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10556                 awk -F "=" '/trusted.lov/ { print $2 }' )
10557         setfattr -n "trusted.lov" -v $lovea $testfile ||
10558                 error "$testfile doesn't ignore setting trusted.lov again"
10559         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10560                 error "$testfile allow setting invalid trusted.lov"
10561         rm -f $testfile
10562 }
10563 run_test 102a "user xattr test =================================="
10564
10565 check_102b_layout() {
10566         local layout="$*"
10567         local testfile=$DIR/$tfile
10568
10569         echo "test layout '$layout'"
10570         $LFS setstripe $layout $testfile || error "setstripe failed"
10571         $LFS getstripe -y $testfile
10572
10573         echo "get/set/list trusted.lov xattr ..." # b=10930
10574         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10575         [[ "$value" =~ "trusted.lov" ]] ||
10576                 error "can't get trusted.lov from $testfile"
10577         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10578                 error "getstripe failed"
10579
10580         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10581
10582         value=$(cut -d= -f2 <<<$value)
10583         # LU-13168: truncated xattr should fail if short lov_user_md header
10584         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10585                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10586         for len in $lens; do
10587                 echo "setfattr $len $testfile.2"
10588                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10589                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10590         done
10591         local stripe_size=$($LFS getstripe -S $testfile.2)
10592         local stripe_count=$($LFS getstripe -c $testfile.2)
10593         [[ $stripe_size -eq 65536 ]] ||
10594                 error "stripe size $stripe_size != 65536"
10595         [[ $stripe_count -eq $stripe_count_orig ]] ||
10596                 error "stripe count $stripe_count != $stripe_count_orig"
10597         rm $testfile $testfile.2
10598 }
10599
10600 test_102b() {
10601         [ -z "$(which setfattr 2>/dev/null)" ] &&
10602                 skip_env "could not find setfattr"
10603         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10604
10605         # check plain layout
10606         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10607
10608         # and also check composite layout
10609         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10610
10611 }
10612 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10613
10614 test_102c() {
10615         [ -z "$(which setfattr 2>/dev/null)" ] &&
10616                 skip_env "could not find setfattr"
10617         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10618
10619         # b10930: get/set/list lustre.lov xattr
10620         echo "get/set/list lustre.lov xattr ..."
10621         test_mkdir $DIR/$tdir
10622         chown $RUNAS_ID $DIR/$tdir
10623         local testfile=$DIR/$tdir/$tfile
10624         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10625                 error "setstripe failed"
10626         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10627                 error "getstripe failed"
10628         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10629         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10630
10631         local testfile2=${testfile}2
10632         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10633                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10634
10635         $RUNAS $MCREATE $testfile2
10636         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10637         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10638         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10639         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10640         [ $stripe_count -eq $STRIPECOUNT ] ||
10641                 error "stripe count $stripe_count != $STRIPECOUNT"
10642 }
10643 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10644
10645 compare_stripe_info1() {
10646         local stripe_index_all_zero=true
10647
10648         for num in 1 2 3 4; do
10649                 for count in $(seq 1 $STRIPE_COUNT); do
10650                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10651                                 local size=$((STRIPE_SIZE * num))
10652                                 local file=file"$num-$offset-$count"
10653                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10654                                 [[ $stripe_size -ne $size ]] &&
10655                                     error "$file: size $stripe_size != $size"
10656                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10657                                 # allow fewer stripes to be created, ORI-601
10658                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10659                                     error "$file: count $stripe_count != $count"
10660                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10661                                 [[ $stripe_index -ne 0 ]] &&
10662                                         stripe_index_all_zero=false
10663                         done
10664                 done
10665         done
10666         $stripe_index_all_zero &&
10667                 error "all files are being extracted starting from OST index 0"
10668         return 0
10669 }
10670
10671 have_xattrs_include() {
10672         tar --help | grep -q xattrs-include &&
10673                 echo --xattrs-include="lustre.*"
10674 }
10675
10676 test_102d() {
10677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10678         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10679
10680         XINC=$(have_xattrs_include)
10681         setup_test102
10682         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10683         cd $DIR/$tdir/$tdir
10684         compare_stripe_info1
10685 }
10686 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10687
10688 test_102f() {
10689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10690         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10691
10692         XINC=$(have_xattrs_include)
10693         setup_test102
10694         test_mkdir $DIR/$tdir.restore
10695         cd $DIR
10696         tar cf - --xattrs $tdir | tar xf - \
10697                 -C $DIR/$tdir.restore --xattrs $XINC
10698         cd $DIR/$tdir.restore/$tdir
10699         compare_stripe_info1
10700 }
10701 run_test 102f "tar copy files, not keep osts"
10702
10703 grow_xattr() {
10704         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10705                 skip "must have user_xattr"
10706         [ -z "$(which setfattr 2>/dev/null)" ] &&
10707                 skip_env "could not find setfattr"
10708         [ -z "$(which getfattr 2>/dev/null)" ] &&
10709                 skip_env "could not find getfattr"
10710
10711         local xsize=${1:-1024}  # in bytes
10712         local file=$DIR/$tfile
10713         local value="$(generate_string $xsize)"
10714         local xbig=trusted.big
10715         local toobig=$2
10716
10717         touch $file
10718         log "save $xbig on $file"
10719         if [ -z "$toobig" ]
10720         then
10721                 setfattr -n $xbig -v $value $file ||
10722                         error "saving $xbig on $file failed"
10723         else
10724                 setfattr -n $xbig -v $value $file &&
10725                         error "saving $xbig on $file succeeded"
10726                 return 0
10727         fi
10728
10729         local orig=$(get_xattr_value $xbig $file)
10730         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10731
10732         local xsml=trusted.sml
10733         log "save $xsml on $file"
10734         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10735
10736         local new=$(get_xattr_value $xbig $file)
10737         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10738
10739         log "grow $xsml on $file"
10740         setfattr -n $xsml -v "$value" $file ||
10741                 error "growing $xsml on $file failed"
10742
10743         new=$(get_xattr_value $xbig $file)
10744         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10745         log "$xbig still valid after growing $xsml"
10746
10747         rm -f $file
10748 }
10749
10750 test_102h() { # bug 15777
10751         grow_xattr 1024
10752 }
10753 run_test 102h "grow xattr from inside inode to external block"
10754
10755 test_102ha() {
10756         large_xattr_enabled || skip_env "ea_inode feature disabled"
10757
10758         echo "setting xattr of max xattr size: $(max_xattr_size)"
10759         grow_xattr $(max_xattr_size)
10760
10761         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10762         echo "This should fail:"
10763         grow_xattr $(($(max_xattr_size) + 10)) 1
10764 }
10765 run_test 102ha "grow xattr from inside inode to external inode"
10766
10767 test_102i() { # bug 17038
10768         [ -z "$(which getfattr 2>/dev/null)" ] &&
10769                 skip "could not find getfattr"
10770
10771         touch $DIR/$tfile
10772         ln -s $DIR/$tfile $DIR/${tfile}link
10773         getfattr -n trusted.lov $DIR/$tfile ||
10774                 error "lgetxattr on $DIR/$tfile failed"
10775         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10776                 grep -i "no such attr" ||
10777                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10778         rm -f $DIR/$tfile $DIR/${tfile}link
10779 }
10780 run_test 102i "lgetxattr test on symbolic link ============"
10781
10782 test_102j() {
10783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10785
10786         XINC=$(have_xattrs_include)
10787         setup_test102 "$RUNAS"
10788         chown $RUNAS_ID $DIR/$tdir
10789         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10790         cd $DIR/$tdir/$tdir
10791         compare_stripe_info1 "$RUNAS"
10792 }
10793 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10794
10795 test_102k() {
10796         [ -z "$(which setfattr 2>/dev/null)" ] &&
10797                 skip "could not find setfattr"
10798
10799         touch $DIR/$tfile
10800         # b22187 just check that does not crash for regular file.
10801         setfattr -n trusted.lov $DIR/$tfile
10802         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10803         local test_kdir=$DIR/$tdir
10804         test_mkdir $test_kdir
10805         local default_size=$($LFS getstripe -S $test_kdir)
10806         local default_count=$($LFS getstripe -c $test_kdir)
10807         local default_offset=$($LFS getstripe -i $test_kdir)
10808         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10809                 error 'dir setstripe failed'
10810         setfattr -n trusted.lov $test_kdir
10811         local stripe_size=$($LFS getstripe -S $test_kdir)
10812         local stripe_count=$($LFS getstripe -c $test_kdir)
10813         local stripe_offset=$($LFS getstripe -i $test_kdir)
10814         [ $stripe_size -eq $default_size ] ||
10815                 error "stripe size $stripe_size != $default_size"
10816         [ $stripe_count -eq $default_count ] ||
10817                 error "stripe count $stripe_count != $default_count"
10818         [ $stripe_offset -eq $default_offset ] ||
10819                 error "stripe offset $stripe_offset != $default_offset"
10820         rm -rf $DIR/$tfile $test_kdir
10821 }
10822 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10823
10824 test_102l() {
10825         [ -z "$(which getfattr 2>/dev/null)" ] &&
10826                 skip "could not find getfattr"
10827
10828         # LU-532 trusted. xattr is invisible to non-root
10829         local testfile=$DIR/$tfile
10830
10831         touch $testfile
10832
10833         echo "listxattr as user..."
10834         chown $RUNAS_ID $testfile
10835         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10836             grep -q "trusted" &&
10837                 error "$testfile trusted xattrs are user visible"
10838
10839         return 0;
10840 }
10841 run_test 102l "listxattr size test =================================="
10842
10843 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10844         local path=$DIR/$tfile
10845         touch $path
10846
10847         listxattr_size_check $path || error "listattr_size_check $path failed"
10848 }
10849 run_test 102m "Ensure listxattr fails on small bufffer ========"
10850
10851 cleanup_test102
10852
10853 getxattr() { # getxattr path name
10854         # Return the base64 encoding of the value of xattr name on path.
10855         local path=$1
10856         local name=$2
10857
10858         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10859         # file: $path
10860         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10861         #
10862         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10863
10864         getfattr --absolute-names --encoding=base64 --name=$name $path |
10865                 awk -F= -v name=$name '$1 == name {
10866                         print substr($0, index($0, "=") + 1);
10867         }'
10868 }
10869
10870 test_102n() { # LU-4101 mdt: protect internal xattrs
10871         [ -z "$(which setfattr 2>/dev/null)" ] &&
10872                 skip "could not find setfattr"
10873         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10874         then
10875                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10876         fi
10877
10878         local file0=$DIR/$tfile.0
10879         local file1=$DIR/$tfile.1
10880         local xattr0=$TMP/$tfile.0
10881         local xattr1=$TMP/$tfile.1
10882         local namelist="lov lma lmv link fid version som hsm"
10883         local name
10884         local value
10885
10886         rm -rf $file0 $file1 $xattr0 $xattr1
10887         touch $file0 $file1
10888
10889         # Get 'before' xattrs of $file1.
10890         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10891
10892         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10893                 namelist+=" lfsck_namespace"
10894         for name in $namelist; do
10895                 # Try to copy xattr from $file0 to $file1.
10896                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10897
10898                 setfattr --name=trusted.$name --value="$value" $file1 ||
10899                         error "setxattr 'trusted.$name' failed"
10900
10901                 # Try to set a garbage xattr.
10902                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10903
10904                 if [[ x$name == "xlov" ]]; then
10905                         setfattr --name=trusted.lov --value="$value" $file1 &&
10906                         error "setxattr invalid 'trusted.lov' success"
10907                 else
10908                         setfattr --name=trusted.$name --value="$value" $file1 ||
10909                                 error "setxattr invalid 'trusted.$name' failed"
10910                 fi
10911
10912                 # Try to remove the xattr from $file1. We don't care if this
10913                 # appears to succeed or fail, we just don't want there to be
10914                 # any changes or crashes.
10915                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10916         done
10917
10918         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10919         then
10920                 name="lfsck_ns"
10921                 # Try to copy xattr from $file0 to $file1.
10922                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10923
10924                 setfattr --name=trusted.$name --value="$value" $file1 ||
10925                         error "setxattr 'trusted.$name' failed"
10926
10927                 # Try to set a garbage xattr.
10928                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10929
10930                 setfattr --name=trusted.$name --value="$value" $file1 ||
10931                         error "setxattr 'trusted.$name' failed"
10932
10933                 # Try to remove the xattr from $file1. We don't care if this
10934                 # appears to succeed or fail, we just don't want there to be
10935                 # any changes or crashes.
10936                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10937         fi
10938
10939         # Get 'after' xattrs of file1.
10940         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10941
10942         if ! diff $xattr0 $xattr1; then
10943                 error "before and after xattrs of '$file1' differ"
10944         fi
10945
10946         rm -rf $file0 $file1 $xattr0 $xattr1
10947
10948         return 0
10949 }
10950 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10951
10952 test_102p() { # LU-4703 setxattr did not check ownership
10953         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10954                 skip "MDS needs to be at least 2.5.56"
10955
10956         local testfile=$DIR/$tfile
10957
10958         touch $testfile
10959
10960         echo "setfacl as user..."
10961         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10962         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10963
10964         echo "setfattr as user..."
10965         setfacl -m "u:$RUNAS_ID:---" $testfile
10966         $RUNAS setfattr -x system.posix_acl_access $testfile
10967         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10968 }
10969 run_test 102p "check setxattr(2) correctly fails without permission"
10970
10971 test_102q() {
10972         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10973                 skip "MDS needs to be at least 2.6.92"
10974
10975         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10976 }
10977 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10978
10979 test_102r() {
10980         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10981                 skip "MDS needs to be at least 2.6.93"
10982
10983         touch $DIR/$tfile || error "touch"
10984         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10985         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10986         rm $DIR/$tfile || error "rm"
10987
10988         #normal directory
10989         mkdir -p $DIR/$tdir || error "mkdir"
10990         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10991         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10992         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10993                 error "$testfile error deleting user.author1"
10994         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10995                 grep "user.$(basename $tdir)" &&
10996                 error "$tdir did not delete user.$(basename $tdir)"
10997         rmdir $DIR/$tdir || error "rmdir"
10998
10999         #striped directory
11000         test_mkdir $DIR/$tdir
11001         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11002         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11003         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11004                 error "$testfile error deleting user.author1"
11005         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11006                 grep "user.$(basename $tdir)" &&
11007                 error "$tdir did not delete user.$(basename $tdir)"
11008         rmdir $DIR/$tdir || error "rm striped dir"
11009 }
11010 run_test 102r "set EAs with empty values"
11011
11012 test_102s() {
11013         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11014                 skip "MDS needs to be at least 2.11.52"
11015
11016         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11017
11018         save_lustre_params client "llite.*.xattr_cache" > $save
11019
11020         for cache in 0 1; do
11021                 lctl set_param llite.*.xattr_cache=$cache
11022
11023                 rm -f $DIR/$tfile
11024                 touch $DIR/$tfile || error "touch"
11025                 for prefix in lustre security system trusted user; do
11026                         # Note getxattr() may fail with 'Operation not
11027                         # supported' or 'No such attribute' depending
11028                         # on prefix and cache.
11029                         getfattr -n $prefix.n102s $DIR/$tfile &&
11030                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11031                 done
11032         done
11033
11034         restore_lustre_params < $save
11035 }
11036 run_test 102s "getting nonexistent xattrs should fail"
11037
11038 test_102t() {
11039         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11040                 skip "MDS needs to be at least 2.11.52"
11041
11042         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11043
11044         save_lustre_params client "llite.*.xattr_cache" > $save
11045
11046         for cache in 0 1; do
11047                 lctl set_param llite.*.xattr_cache=$cache
11048
11049                 for buf_size in 0 256; do
11050                         rm -f $DIR/$tfile
11051                         touch $DIR/$tfile || error "touch"
11052                         setfattr -n user.multiop $DIR/$tfile
11053                         $MULTIOP $DIR/$tfile oa$buf_size ||
11054                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11055                 done
11056         done
11057
11058         restore_lustre_params < $save
11059 }
11060 run_test 102t "zero length xattr values handled correctly"
11061
11062 run_acl_subtest()
11063 {
11064     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11065     return $?
11066 }
11067
11068 test_103a() {
11069         [ "$UID" != 0 ] && skip "must run as root"
11070         $GSS && skip_env "could not run under gss"
11071         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11072                 skip_env "must have acl enabled"
11073         [ -z "$(which setfacl 2>/dev/null)" ] &&
11074                 skip_env "could not find setfacl"
11075         remote_mds_nodsh && skip "remote MDS with nodsh"
11076
11077         gpasswd -a daemon bin                           # LU-5641
11078         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11079
11080         declare -a identity_old
11081
11082         for num in $(seq $MDSCOUNT); do
11083                 switch_identity $num true || identity_old[$num]=$?
11084         done
11085
11086         SAVE_UMASK=$(umask)
11087         umask 0022
11088         mkdir -p $DIR/$tdir
11089         cd $DIR/$tdir
11090
11091         echo "performing cp ..."
11092         run_acl_subtest cp || error "run_acl_subtest cp failed"
11093         echo "performing getfacl-noacl..."
11094         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11095         echo "performing misc..."
11096         run_acl_subtest misc || error  "misc test failed"
11097         echo "performing permissions..."
11098         run_acl_subtest permissions || error "permissions failed"
11099         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11100         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11101                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11102                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11103         then
11104                 echo "performing permissions xattr..."
11105                 run_acl_subtest permissions_xattr ||
11106                         error "permissions_xattr failed"
11107         fi
11108         echo "performing setfacl..."
11109         run_acl_subtest setfacl || error  "setfacl test failed"
11110
11111         # inheritance test got from HP
11112         echo "performing inheritance..."
11113         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11114         chmod +x make-tree || error "chmod +x failed"
11115         run_acl_subtest inheritance || error "inheritance test failed"
11116         rm -f make-tree
11117
11118         echo "LU-974 ignore umask when acl is enabled..."
11119         run_acl_subtest 974 || error "LU-974 umask test failed"
11120         if [ $MDSCOUNT -ge 2 ]; then
11121                 run_acl_subtest 974_remote ||
11122                         error "LU-974 umask test failed under remote dir"
11123         fi
11124
11125         echo "LU-2561 newly created file is same size as directory..."
11126         if [ "$mds1_FSTYPE" != "zfs" ]; then
11127                 run_acl_subtest 2561 || error "LU-2561 test failed"
11128         else
11129                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11130         fi
11131
11132         run_acl_subtest 4924 || error "LU-4924 test failed"
11133
11134         cd $SAVE_PWD
11135         umask $SAVE_UMASK
11136
11137         for num in $(seq $MDSCOUNT); do
11138                 if [ "${identity_old[$num]}" = 1 ]; then
11139                         switch_identity $num false || identity_old[$num]=$?
11140                 fi
11141         done
11142 }
11143 run_test 103a "acl test"
11144
11145 test_103b() {
11146         declare -a pids
11147         local U
11148
11149         for U in {0..511}; do
11150                 {
11151                 local O=$(printf "%04o" $U)
11152
11153                 umask $(printf "%04o" $((511 ^ $O)))
11154                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11155                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11156
11157                 (( $S == ($O & 0666) )) ||
11158                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11159
11160                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11161                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11162                 (( $S == ($O & 0666) )) ||
11163                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11164
11165                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11166                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11167                 (( $S == ($O & 0666) )) ||
11168                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11169                 rm -f $DIR/$tfile.[smp]$0
11170                 } &
11171                 local pid=$!
11172
11173                 # limit the concurrently running threads to 64. LU-11878
11174                 local idx=$((U % 64))
11175                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11176                 pids[idx]=$pid
11177         done
11178         wait
11179 }
11180 run_test 103b "umask lfs setstripe"
11181
11182 test_103c() {
11183         mkdir -p $DIR/$tdir
11184         cp -rp $DIR/$tdir $DIR/$tdir.bak
11185
11186         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11187                 error "$DIR/$tdir shouldn't contain default ACL"
11188         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11189                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11190         true
11191 }
11192 run_test 103c "'cp -rp' won't set empty acl"
11193
11194 test_103e() {
11195         local numacl
11196         local fileacl
11197         local saved_debug=$($LCTL get_param -n debug)
11198
11199         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11200                 skip "MDS needs to be at least 2.14.0"
11201
11202         large_xattr_enabled || skip_env "ea_inode feature disabled"
11203
11204         mkdir -p $DIR/$tdir
11205         # add big LOV EA to cause reply buffer overflow earlier
11206         $LFS setstripe -C 1000 $DIR/$tdir
11207         lctl set_param mdc.*-mdc*.stats=clear
11208
11209         $LCTL set_param debug=0
11210         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11211         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11212
11213         # add a large number of default ACLs (expect 8000+ for 2.13+)
11214         for U in {2..7000}; do
11215                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11216                         error "Able to add just $U default ACLs"
11217         done
11218         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11219         echo "$numacl default ACLs created"
11220
11221         stat $DIR/$tdir || error "Cannot stat directory"
11222         # check file creation
11223         touch $DIR/$tdir/$tfile ||
11224                 error "failed to create $tfile with $numacl default ACLs"
11225         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11226         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11227         echo "$fileacl ACLs were inherited"
11228         (( $fileacl == $numacl )) ||
11229                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11230         # check that new ACLs creation adds new ACLs to inherited ACLs
11231         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11232                 error "Cannot set new ACL"
11233         numacl=$((numacl + 1))
11234         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11235         (( $fileacl == $numacl )) ||
11236                 error "failed to add new ACL: $fileacl != $numacl as expected"
11237         # adds more ACLs to a file to reach their maximum at 8000+
11238         numacl=0
11239         for U in {20000..25000}; do
11240                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11241                 numacl=$((numacl + 1))
11242         done
11243         echo "Added $numacl more ACLs to the file"
11244         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11245         echo "Total $fileacl ACLs in file"
11246         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11247         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11248         rmdir $DIR/$tdir || error "Cannot remove directory"
11249 }
11250 run_test 103e "inheritance of big amount of default ACLs"
11251
11252 test_103f() {
11253         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11254                 skip "MDS needs to be at least 2.14.51"
11255
11256         large_xattr_enabled || skip_env "ea_inode feature disabled"
11257
11258         # enable changelog to consume more internal MDD buffers
11259         changelog_register
11260
11261         mkdir -p $DIR/$tdir
11262         # add big LOV EA
11263         $LFS setstripe -C 1000 $DIR/$tdir
11264         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11265         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11266         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11267         rmdir $DIR/$tdir || error "Cannot remove directory"
11268 }
11269 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11270
11271 test_104a() {
11272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11273
11274         touch $DIR/$tfile
11275         lfs df || error "lfs df failed"
11276         lfs df -ih || error "lfs df -ih failed"
11277         lfs df -h $DIR || error "lfs df -h $DIR failed"
11278         lfs df -i $DIR || error "lfs df -i $DIR failed"
11279         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11280         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11281
11282         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11283         lctl --device %$OSC deactivate
11284         lfs df || error "lfs df with deactivated OSC failed"
11285         lctl --device %$OSC activate
11286         # wait the osc back to normal
11287         wait_osc_import_ready client ost
11288
11289         lfs df || error "lfs df with reactivated OSC failed"
11290         rm -f $DIR/$tfile
11291 }
11292 run_test 104a "lfs df [-ih] [path] test ========================="
11293
11294 test_104b() {
11295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11296         [ $RUNAS_ID -eq $UID ] &&
11297                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11298
11299         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11300                         grep "Permission denied" | wc -l)))
11301         if [ $denied_cnt -ne 0 ]; then
11302                 error "lfs check servers test failed"
11303         fi
11304 }
11305 run_test 104b "$RUNAS lfs check servers test ===================="
11306
11307 cleanup_104c() {
11308         local facets=$1
11309         local param=$2
11310         local saved_blocks=$3
11311
11312         for facet in ${facets//,/ }; do
11313                 osd=$(do_facet $facet $LCTL get_param -n $param.mntdev)
11314                 do_facet $facet zfs set recordsize=$saved_blocks $osd
11315         done
11316 }
11317
11318 #
11319 # Verify $1 is within range of $2.
11320 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11321 # $1 is <= 2% of $2. Else Fail.
11322 #
11323 value_in_range() {
11324         # Strip all units (M, G, T)
11325         actual=$(echo ${1/[a-zA-Z]*/})
11326         expect=$(echo ${2/[a-zA-Z]*/})
11327
11328         expect_lo=$(($expect * 98 / 100)) # 2% below
11329         expect_hi=$(($expect * 102 / 100)) # 2% above
11330
11331         # permit 2% drift above and below
11332         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11333 }
11334
11335 test_104c() {
11336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11337         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11338
11339         local ost_param="osd-zfs.$FSNAME-OST0000."
11340         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11341         local ofacets=$(get_facets OST)
11342         local mfacets=$(get_facets MDS)
11343         local saved_ost_blocks=
11344         local saved_mdt_blocks=
11345
11346         echo "Before recordsize change"
11347         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11348         df=($(df -h | grep "/mnt/lustre"$))
11349
11350         # For checking.
11351         echo "lfs output : ${lfs_df[*]}"
11352         echo "df  output : ${df[*]}"
11353
11354         for facet in ${ofacets//,/ }; do
11355                 if [ -z $saved_ost_blocks ]; then
11356                         saved_ost_blocks=$(do_facet $facet \
11357                                 lctl get_param -n $ost_param.blocksize)
11358                         echo "OST Blocksize: $saved_ost_blocks"
11359                 fi
11360                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11361                 do_facet $facet zfs set recordsize=32768 $ost
11362         done
11363
11364         # BS too small. Sufficient for functional testing.
11365         for facet in ${mfacets//,/ }; do
11366                 if [ -z $saved_mdt_blocks ]; then
11367                         saved_mdt_blocks=$(do_facet $facet \
11368                                 lctl get_param -n $mdt_param.blocksize)
11369                         echo "MDT Blocksize: $saved_mdt_blocks"
11370                 fi
11371                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11372                 do_facet $facet zfs set recordsize=32768 $mdt
11373         done
11374
11375         # Restore OST recordize back to original
11376         stack_trap "cleanup_104c $ofacets $ost_param $saved_ost_blocks"
11377         # Restore MDT recordize back to original
11378         stack_trap "cleanup_104c $mfacets $mdt_param $saved_mdt_blocks"
11379
11380         # Give new values chance to reflect change
11381         sleep 2
11382
11383         echo "After recordsize change"
11384         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11385         df_after=($(df -h | grep "/mnt/lustre"$))
11386
11387         # For checking.
11388         echo "lfs output : ${lfs_df_after[*]}"
11389         echo "df  output : ${df_after[*]}"
11390
11391         # Verify lfs df
11392         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11393                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11394         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11395                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11396         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11397                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11398
11399         # Verify df
11400         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11401                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11402         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11403                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11404         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11405                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11406
11407         return 0
11408 }
11409 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11410
11411 test_105a() {
11412         # doesn't work on 2.4 kernels
11413         touch $DIR/$tfile
11414         if $(flock_is_enabled); then
11415                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11416         else
11417                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11418         fi
11419         rm -f $DIR/$tfile
11420 }
11421 run_test 105a "flock when mounted without -o flock test ========"
11422
11423 test_105b() {
11424         touch $DIR/$tfile
11425         if $(flock_is_enabled); then
11426                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11427         else
11428                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11429         fi
11430         rm -f $DIR/$tfile
11431 }
11432 run_test 105b "fcntl when mounted without -o flock test ========"
11433
11434 test_105c() {
11435         touch $DIR/$tfile
11436         if $(flock_is_enabled); then
11437                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11438         else
11439                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11440         fi
11441         rm -f $DIR/$tfile
11442 }
11443 run_test 105c "lockf when mounted without -o flock test"
11444
11445 test_105d() { # bug 15924
11446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11447
11448         test_mkdir $DIR/$tdir
11449         flock_is_enabled || skip_env "mount w/o flock enabled"
11450         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11451         $LCTL set_param fail_loc=0x80000315
11452         flocks_test 2 $DIR/$tdir
11453 }
11454 run_test 105d "flock race (should not freeze) ========"
11455
11456 test_105e() { # bug 22660 && 22040
11457         flock_is_enabled || skip_env "mount w/o flock enabled"
11458
11459         touch $DIR/$tfile
11460         flocks_test 3 $DIR/$tfile
11461 }
11462 run_test 105e "Two conflicting flocks from same process"
11463
11464 test_106() { #bug 10921
11465         test_mkdir $DIR/$tdir
11466         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11467         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11468 }
11469 run_test 106 "attempt exec of dir followed by chown of that dir"
11470
11471 test_107() {
11472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11473
11474         CDIR=`pwd`
11475         local file=core
11476
11477         cd $DIR
11478         rm -f $file
11479
11480         local save_pattern=$(sysctl -n kernel.core_pattern)
11481         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11482         sysctl -w kernel.core_pattern=$file
11483         sysctl -w kernel.core_uses_pid=0
11484
11485         ulimit -c unlimited
11486         sleep 60 &
11487         SLEEPPID=$!
11488
11489         sleep 1
11490
11491         kill -s 11 $SLEEPPID
11492         wait $SLEEPPID
11493         if [ -e $file ]; then
11494                 size=`stat -c%s $file`
11495                 [ $size -eq 0 ] && error "Fail to create core file $file"
11496         else
11497                 error "Fail to create core file $file"
11498         fi
11499         rm -f $file
11500         sysctl -w kernel.core_pattern=$save_pattern
11501         sysctl -w kernel.core_uses_pid=$save_uses_pid
11502         cd $CDIR
11503 }
11504 run_test 107 "Coredump on SIG"
11505
11506 test_110() {
11507         test_mkdir $DIR/$tdir
11508         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11509         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11510                 error "mkdir with 256 char should fail, but did not"
11511         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11512                 error "create with 255 char failed"
11513         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11514                 error "create with 256 char should fail, but did not"
11515
11516         ls -l $DIR/$tdir
11517         rm -rf $DIR/$tdir
11518 }
11519 run_test 110 "filename length checking"
11520
11521 #
11522 # Purpose: To verify dynamic thread (OSS) creation.
11523 #
11524 test_115() {
11525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11526         remote_ost_nodsh && skip "remote OST with nodsh"
11527
11528         # Lustre does not stop service threads once they are started.
11529         # Reset number of running threads to default.
11530         stopall
11531         setupall
11532
11533         local OSTIO_pre
11534         local save_params="$TMP/sanity-$TESTNAME.parameters"
11535
11536         # Get ll_ost_io count before I/O
11537         OSTIO_pre=$(do_facet ost1 \
11538                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11539         # Exit if lustre is not running (ll_ost_io not running).
11540         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11541
11542         echo "Starting with $OSTIO_pre threads"
11543         local thread_max=$((OSTIO_pre * 2))
11544         local rpc_in_flight=$((thread_max * 2))
11545         # Number of I/O Process proposed to be started.
11546         local nfiles
11547         local facets=$(get_facets OST)
11548
11549         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11550         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11551
11552         # Set in_flight to $rpc_in_flight
11553         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11554                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11555         nfiles=${rpc_in_flight}
11556         # Set ost thread_max to $thread_max
11557         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11558
11559         # 5 Minutes should be sufficient for max number of OSS
11560         # threads(thread_max) to be created.
11561         local timeout=300
11562
11563         # Start I/O.
11564         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11565         test_mkdir $DIR/$tdir
11566         for i in $(seq $nfiles); do
11567                 local file=$DIR/$tdir/${tfile}-$i
11568                 $LFS setstripe -c -1 -i 0 $file
11569                 ($WTL $file $timeout)&
11570         done
11571
11572         # I/O Started - Wait for thread_started to reach thread_max or report
11573         # error if thread_started is more than thread_max.
11574         echo "Waiting for thread_started to reach thread_max"
11575         local thread_started=0
11576         local end_time=$((SECONDS + timeout))
11577
11578         while [ $SECONDS -le $end_time ] ; do
11579                 echo -n "."
11580                 # Get ost i/o thread_started count.
11581                 thread_started=$(do_facet ost1 \
11582                         "$LCTL get_param \
11583                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11584                 # Break out if thread_started is equal/greater than thread_max
11585                 if [[ $thread_started -ge $thread_max ]]; then
11586                         echo ll_ost_io thread_started $thread_started, \
11587                                 equal/greater than thread_max $thread_max
11588                         break
11589                 fi
11590                 sleep 1
11591         done
11592
11593         # Cleanup - We have the numbers, Kill i/o jobs if running.
11594         jobcount=($(jobs -p))
11595         for i in $(seq 0 $((${#jobcount[@]}-1)))
11596         do
11597                 kill -9 ${jobcount[$i]}
11598                 if [ $? -ne 0 ] ; then
11599                         echo Warning: \
11600                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11601                 fi
11602         done
11603
11604         # Cleanup files left by WTL binary.
11605         for i in $(seq $nfiles); do
11606                 local file=$DIR/$tdir/${tfile}-$i
11607                 rm -rf $file
11608                 if [ $? -ne 0 ] ; then
11609                         echo "Warning: Failed to delete file $file"
11610                 fi
11611         done
11612
11613         restore_lustre_params <$save_params
11614         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11615
11616         # Error out if no new thread has started or Thread started is greater
11617         # than thread max.
11618         if [[ $thread_started -le $OSTIO_pre ||
11619                         $thread_started -gt $thread_max ]]; then
11620                 error "ll_ost_io: thread_started $thread_started" \
11621                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11622                       "No new thread started or thread started greater " \
11623                       "than thread_max."
11624         fi
11625 }
11626 run_test 115 "verify dynamic thread creation===================="
11627
11628 free_min_max () {
11629         wait_delete_completed
11630         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11631         echo "OST kbytes available: ${AVAIL[@]}"
11632         MAXV=${AVAIL[0]}
11633         MAXI=0
11634         MINV=${AVAIL[0]}
11635         MINI=0
11636         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11637                 #echo OST $i: ${AVAIL[i]}kb
11638                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11639                         MAXV=${AVAIL[i]}
11640                         MAXI=$i
11641                 fi
11642                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11643                         MINV=${AVAIL[i]}
11644                         MINI=$i
11645                 fi
11646         done
11647         echo "Min free space: OST $MINI: $MINV"
11648         echo "Max free space: OST $MAXI: $MAXV"
11649 }
11650
11651 test_116a() { # was previously test_116()
11652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11653         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11654         remote_mds_nodsh && skip "remote MDS with nodsh"
11655
11656         echo -n "Free space priority "
11657         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11658                 head -n1
11659         declare -a AVAIL
11660         free_min_max
11661
11662         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11663         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11664         trap simple_cleanup_common EXIT
11665
11666         # Check if we need to generate uneven OSTs
11667         test_mkdir -p $DIR/$tdir/OST${MINI}
11668         local FILL=$((MINV / 4))
11669         local DIFF=$((MAXV - MINV))
11670         local DIFF2=$((DIFF * 100 / MINV))
11671
11672         local threshold=$(do_facet $SINGLEMDS \
11673                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11674         threshold=${threshold%%%}
11675         echo -n "Check for uneven OSTs: "
11676         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11677
11678         if [[ $DIFF2 -gt $threshold ]]; then
11679                 echo "ok"
11680                 echo "Don't need to fill OST$MINI"
11681         else
11682                 # generate uneven OSTs. Write 2% over the QOS threshold value
11683                 echo "no"
11684                 DIFF=$((threshold - DIFF2 + 2))
11685                 DIFF2=$((MINV * DIFF / 100))
11686                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11687                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11688                         error "setstripe failed"
11689                 DIFF=$((DIFF2 / 2048))
11690                 i=0
11691                 while [ $i -lt $DIFF ]; do
11692                         i=$((i + 1))
11693                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11694                                 bs=2M count=1 2>/dev/null
11695                         echo -n .
11696                 done
11697                 echo .
11698                 sync
11699                 sleep_maxage
11700                 free_min_max
11701         fi
11702
11703         DIFF=$((MAXV - MINV))
11704         DIFF2=$((DIFF * 100 / MINV))
11705         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11706         if [ $DIFF2 -gt $threshold ]; then
11707                 echo "ok"
11708         else
11709                 echo "failed - QOS mode won't be used"
11710                 simple_cleanup_common
11711                 skip "QOS imbalance criteria not met"
11712         fi
11713
11714         MINI1=$MINI
11715         MINV1=$MINV
11716         MAXI1=$MAXI
11717         MAXV1=$MAXV
11718
11719         # now fill using QOS
11720         $LFS setstripe -c 1 $DIR/$tdir
11721         FILL=$((FILL / 200))
11722         if [ $FILL -gt 600 ]; then
11723                 FILL=600
11724         fi
11725         echo "writing $FILL files to QOS-assigned OSTs"
11726         i=0
11727         while [ $i -lt $FILL ]; do
11728                 i=$((i + 1))
11729                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11730                         count=1 2>/dev/null
11731                 echo -n .
11732         done
11733         echo "wrote $i 200k files"
11734         sync
11735         sleep_maxage
11736
11737         echo "Note: free space may not be updated, so measurements might be off"
11738         free_min_max
11739         DIFF2=$((MAXV - MINV))
11740         echo "free space delta: orig $DIFF final $DIFF2"
11741         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11742         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11743         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11744         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11745         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11746         if [[ $DIFF -gt 0 ]]; then
11747                 FILL=$((DIFF2 * 100 / DIFF - 100))
11748                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11749         fi
11750
11751         # Figure out which files were written where
11752         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11753                awk '/'$MINI1': / {print $2; exit}')
11754         echo $UUID
11755         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11756         echo "$MINC files created on smaller OST $MINI1"
11757         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11758                awk '/'$MAXI1': / {print $2; exit}')
11759         echo $UUID
11760         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11761         echo "$MAXC files created on larger OST $MAXI1"
11762         if [[ $MINC -gt 0 ]]; then
11763                 FILL=$((MAXC * 100 / MINC - 100))
11764                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11765         fi
11766         [[ $MAXC -gt $MINC ]] ||
11767                 error_ignore LU-9 "stripe QOS didn't balance free space"
11768         simple_cleanup_common
11769 }
11770 run_test 116a "stripe QOS: free space balance ==================="
11771
11772 test_116b() { # LU-2093
11773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11774         remote_mds_nodsh && skip "remote MDS with nodsh"
11775
11776 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11777         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11778                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11779         [ -z "$old_rr" ] && skip "no QOS"
11780         do_facet $SINGLEMDS lctl set_param \
11781                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11782         mkdir -p $DIR/$tdir
11783         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11784         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11785         do_facet $SINGLEMDS lctl set_param fail_loc=0
11786         rm -rf $DIR/$tdir
11787         do_facet $SINGLEMDS lctl set_param \
11788                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11789 }
11790 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11791
11792 test_117() # bug 10891
11793 {
11794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11795
11796         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11797         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11798         lctl set_param fail_loc=0x21e
11799         > $DIR/$tfile || error "truncate failed"
11800         lctl set_param fail_loc=0
11801         echo "Truncate succeeded."
11802         rm -f $DIR/$tfile
11803 }
11804 run_test 117 "verify osd extend =========="
11805
11806 NO_SLOW_RESENDCOUNT=4
11807 export OLD_RESENDCOUNT=""
11808 set_resend_count () {
11809         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11810         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11811         lctl set_param -n $PROC_RESENDCOUNT $1
11812         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11813 }
11814
11815 # for reduce test_118* time (b=14842)
11816 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11817
11818 # Reset async IO behavior after error case
11819 reset_async() {
11820         FILE=$DIR/reset_async
11821
11822         # Ensure all OSCs are cleared
11823         $LFS setstripe -c -1 $FILE
11824         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11825         sync
11826         rm $FILE
11827 }
11828
11829 test_118a() #bug 11710
11830 {
11831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11832
11833         reset_async
11834
11835         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11836         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11837         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11838
11839         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11840                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11841                 return 1;
11842         fi
11843         rm -f $DIR/$tfile
11844 }
11845 run_test 118a "verify O_SYNC works =========="
11846
11847 test_118b()
11848 {
11849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11850         remote_ost_nodsh && skip "remote OST with nodsh"
11851
11852         reset_async
11853
11854         #define OBD_FAIL_SRV_ENOENT 0x217
11855         set_nodes_failloc "$(osts_nodes)" 0x217
11856         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11857         RC=$?
11858         set_nodes_failloc "$(osts_nodes)" 0
11859         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11860         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11861                     grep -c writeback)
11862
11863         if [[ $RC -eq 0 ]]; then
11864                 error "Must return error due to dropped pages, rc=$RC"
11865                 return 1;
11866         fi
11867
11868         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11869                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11870                 return 1;
11871         fi
11872
11873         echo "Dirty pages not leaked on ENOENT"
11874
11875         # Due to the above error the OSC will issue all RPCs syncronously
11876         # until a subsequent RPC completes successfully without error.
11877         $MULTIOP $DIR/$tfile Ow4096yc
11878         rm -f $DIR/$tfile
11879
11880         return 0
11881 }
11882 run_test 118b "Reclaim dirty pages on fatal error =========="
11883
11884 test_118c()
11885 {
11886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11887
11888         # for 118c, restore the original resend count, LU-1940
11889         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11890                                 set_resend_count $OLD_RESENDCOUNT
11891         remote_ost_nodsh && skip "remote OST with nodsh"
11892
11893         reset_async
11894
11895         #define OBD_FAIL_OST_EROFS               0x216
11896         set_nodes_failloc "$(osts_nodes)" 0x216
11897
11898         # multiop should block due to fsync until pages are written
11899         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11900         MULTIPID=$!
11901         sleep 1
11902
11903         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11904                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11905         fi
11906
11907         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11908                     grep -c writeback)
11909         if [[ $WRITEBACK -eq 0 ]]; then
11910                 error "No page in writeback, writeback=$WRITEBACK"
11911         fi
11912
11913         set_nodes_failloc "$(osts_nodes)" 0
11914         wait $MULTIPID
11915         RC=$?
11916         if [[ $RC -ne 0 ]]; then
11917                 error "Multiop fsync failed, rc=$RC"
11918         fi
11919
11920         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11921         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11922                     grep -c writeback)
11923         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11924                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11925         fi
11926
11927         rm -f $DIR/$tfile
11928         echo "Dirty pages flushed via fsync on EROFS"
11929         return 0
11930 }
11931 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11932
11933 # continue to use small resend count to reduce test_118* time (b=14842)
11934 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11935
11936 test_118d()
11937 {
11938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11939         remote_ost_nodsh && skip "remote OST with nodsh"
11940
11941         reset_async
11942
11943         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11944         set_nodes_failloc "$(osts_nodes)" 0x214
11945         # multiop should block due to fsync until pages are written
11946         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11947         MULTIPID=$!
11948         sleep 1
11949
11950         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11951                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11952         fi
11953
11954         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11955                     grep -c writeback)
11956         if [[ $WRITEBACK -eq 0 ]]; then
11957                 error "No page in writeback, writeback=$WRITEBACK"
11958         fi
11959
11960         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11961         set_nodes_failloc "$(osts_nodes)" 0
11962
11963         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11964         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11965                     grep -c writeback)
11966         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11967                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11968         fi
11969
11970         rm -f $DIR/$tfile
11971         echo "Dirty pages gaurenteed flushed via fsync"
11972         return 0
11973 }
11974 run_test 118d "Fsync validation inject a delay of the bulk =========="
11975
11976 test_118f() {
11977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11978
11979         reset_async
11980
11981         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11982         lctl set_param fail_loc=0x8000040a
11983
11984         # Should simulate EINVAL error which is fatal
11985         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11986         RC=$?
11987         if [[ $RC -eq 0 ]]; then
11988                 error "Must return error due to dropped pages, rc=$RC"
11989         fi
11990
11991         lctl set_param fail_loc=0x0
11992
11993         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11994         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11995         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11996                     grep -c writeback)
11997         if [[ $LOCKED -ne 0 ]]; then
11998                 error "Locked pages remain in cache, locked=$LOCKED"
11999         fi
12000
12001         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12002                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12003         fi
12004
12005         rm -f $DIR/$tfile
12006         echo "No pages locked after fsync"
12007
12008         reset_async
12009         return 0
12010 }
12011 run_test 118f "Simulate unrecoverable OSC side error =========="
12012
12013 test_118g() {
12014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12015
12016         reset_async
12017
12018         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12019         lctl set_param fail_loc=0x406
12020
12021         # simulate local -ENOMEM
12022         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12023         RC=$?
12024
12025         lctl set_param fail_loc=0
12026         if [[ $RC -eq 0 ]]; then
12027                 error "Must return error due to dropped pages, rc=$RC"
12028         fi
12029
12030         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12031         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12032         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12033                         grep -c writeback)
12034         if [[ $LOCKED -ne 0 ]]; then
12035                 error "Locked pages remain in cache, locked=$LOCKED"
12036         fi
12037
12038         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12039                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12040         fi
12041
12042         rm -f $DIR/$tfile
12043         echo "No pages locked after fsync"
12044
12045         reset_async
12046         return 0
12047 }
12048 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12049
12050 test_118h() {
12051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12052         remote_ost_nodsh && skip "remote OST with nodsh"
12053
12054         reset_async
12055
12056         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12057         set_nodes_failloc "$(osts_nodes)" 0x20e
12058         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12059         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12060         RC=$?
12061
12062         set_nodes_failloc "$(osts_nodes)" 0
12063         if [[ $RC -eq 0 ]]; then
12064                 error "Must return error due to dropped pages, rc=$RC"
12065         fi
12066
12067         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12068         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12069         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12070                     grep -c writeback)
12071         if [[ $LOCKED -ne 0 ]]; then
12072                 error "Locked pages remain in cache, locked=$LOCKED"
12073         fi
12074
12075         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12076                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12077         fi
12078
12079         rm -f $DIR/$tfile
12080         echo "No pages locked after fsync"
12081
12082         return 0
12083 }
12084 run_test 118h "Verify timeout in handling recoverables errors  =========="
12085
12086 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12087
12088 test_118i() {
12089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12090         remote_ost_nodsh && skip "remote OST with nodsh"
12091
12092         reset_async
12093
12094         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12095         set_nodes_failloc "$(osts_nodes)" 0x20e
12096
12097         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12098         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12099         PID=$!
12100         sleep 5
12101         set_nodes_failloc "$(osts_nodes)" 0
12102
12103         wait $PID
12104         RC=$?
12105         if [[ $RC -ne 0 ]]; then
12106                 error "got error, but should be not, rc=$RC"
12107         fi
12108
12109         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12110         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12111         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12112         if [[ $LOCKED -ne 0 ]]; then
12113                 error "Locked pages remain in cache, locked=$LOCKED"
12114         fi
12115
12116         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12117                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12118         fi
12119
12120         rm -f $DIR/$tfile
12121         echo "No pages locked after fsync"
12122
12123         return 0
12124 }
12125 run_test 118i "Fix error before timeout in recoverable error  =========="
12126
12127 [ "$SLOW" = "no" ] && set_resend_count 4
12128
12129 test_118j() {
12130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12131         remote_ost_nodsh && skip "remote OST with nodsh"
12132
12133         reset_async
12134
12135         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12136         set_nodes_failloc "$(osts_nodes)" 0x220
12137
12138         # return -EIO from OST
12139         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12140         RC=$?
12141         set_nodes_failloc "$(osts_nodes)" 0x0
12142         if [[ $RC -eq 0 ]]; then
12143                 error "Must return error due to dropped pages, rc=$RC"
12144         fi
12145
12146         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12147         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12148         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12149         if [[ $LOCKED -ne 0 ]]; then
12150                 error "Locked pages remain in cache, locked=$LOCKED"
12151         fi
12152
12153         # in recoverable error on OST we want resend and stay until it finished
12154         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12155                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12156         fi
12157
12158         rm -f $DIR/$tfile
12159         echo "No pages locked after fsync"
12160
12161         return 0
12162 }
12163 run_test 118j "Simulate unrecoverable OST side error =========="
12164
12165 test_118k()
12166 {
12167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12168         remote_ost_nodsh && skip "remote OSTs with nodsh"
12169
12170         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12171         set_nodes_failloc "$(osts_nodes)" 0x20e
12172         test_mkdir $DIR/$tdir
12173
12174         for ((i=0;i<10;i++)); do
12175                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12176                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12177                 SLEEPPID=$!
12178                 sleep 0.500s
12179                 kill $SLEEPPID
12180                 wait $SLEEPPID
12181         done
12182
12183         set_nodes_failloc "$(osts_nodes)" 0
12184         rm -rf $DIR/$tdir
12185 }
12186 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12187
12188 test_118l() # LU-646
12189 {
12190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12191
12192         test_mkdir $DIR/$tdir
12193         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12194         rm -rf $DIR/$tdir
12195 }
12196 run_test 118l "fsync dir"
12197
12198 test_118m() # LU-3066
12199 {
12200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12201
12202         test_mkdir $DIR/$tdir
12203         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12204         rm -rf $DIR/$tdir
12205 }
12206 run_test 118m "fdatasync dir ========="
12207
12208 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12209
12210 test_118n()
12211 {
12212         local begin
12213         local end
12214
12215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12216         remote_ost_nodsh && skip "remote OSTs with nodsh"
12217
12218         # Sleep to avoid a cached response.
12219         #define OBD_STATFS_CACHE_SECONDS 1
12220         sleep 2
12221
12222         # Inject a 10 second delay in the OST_STATFS handler.
12223         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12224         set_nodes_failloc "$(osts_nodes)" 0x242
12225
12226         begin=$SECONDS
12227         stat --file-system $MOUNT > /dev/null
12228         end=$SECONDS
12229
12230         set_nodes_failloc "$(osts_nodes)" 0
12231
12232         if ((end - begin > 20)); then
12233             error "statfs took $((end - begin)) seconds, expected 10"
12234         fi
12235 }
12236 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12237
12238 test_119a() # bug 11737
12239 {
12240         BSIZE=$((512 * 1024))
12241         directio write $DIR/$tfile 0 1 $BSIZE
12242         # We ask to read two blocks, which is more than a file size.
12243         # directio will indicate an error when requested and actual
12244         # sizes aren't equeal (a normal situation in this case) and
12245         # print actual read amount.
12246         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12247         if [ "$NOB" != "$BSIZE" ]; then
12248                 error "read $NOB bytes instead of $BSIZE"
12249         fi
12250         rm -f $DIR/$tfile
12251 }
12252 run_test 119a "Short directIO read must return actual read amount"
12253
12254 test_119b() # bug 11737
12255 {
12256         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12257
12258         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12260         sync
12261         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12262                 error "direct read failed"
12263         rm -f $DIR/$tfile
12264 }
12265 run_test 119b "Sparse directIO read must return actual read amount"
12266
12267 test_119c() # bug 13099
12268 {
12269         BSIZE=1048576
12270         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12271         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12272         rm -f $DIR/$tfile
12273 }
12274 run_test 119c "Testing for direct read hitting hole"
12275
12276 test_119d() # bug 15950
12277 {
12278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12279
12280         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12281         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12282         BSIZE=1048576
12283         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12284         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12285         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12286         lctl set_param fail_loc=0x40d
12287         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12288         pid_dio=$!
12289         sleep 1
12290         cat $DIR/$tfile > /dev/null &
12291         lctl set_param fail_loc=0
12292         pid_reads=$!
12293         wait $pid_dio
12294         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12295         sleep 2
12296         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12297         error "the read rpcs have not completed in 2s"
12298         rm -f $DIR/$tfile
12299         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12300 }
12301 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12302
12303 test_120a() {
12304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12305         remote_mds_nodsh && skip "remote MDS with nodsh"
12306         test_mkdir -i0 -c1 $DIR/$tdir
12307         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12308                 skip_env "no early lock cancel on server"
12309
12310         lru_resize_disable mdc
12311         lru_resize_disable osc
12312         cancel_lru_locks mdc
12313         # asynchronous object destroy at MDT could cause bl ast to client
12314         cancel_lru_locks osc
12315
12316         stat $DIR/$tdir > /dev/null
12317         can1=$(do_facet mds1 \
12318                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12319                awk '/ldlm_cancel/ {print $2}')
12320         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12321                awk '/ldlm_bl_callback/ {print $2}')
12322         test_mkdir -i0 -c1 $DIR/$tdir/d1
12323         can2=$(do_facet mds1 \
12324                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12325                awk '/ldlm_cancel/ {print $2}')
12326         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12327                awk '/ldlm_bl_callback/ {print $2}')
12328         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12329         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12330         lru_resize_enable mdc
12331         lru_resize_enable osc
12332 }
12333 run_test 120a "Early Lock Cancel: mkdir test"
12334
12335 test_120b() {
12336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12337         remote_mds_nodsh && skip "remote MDS with nodsh"
12338         test_mkdir $DIR/$tdir
12339         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12340                 skip_env "no early lock cancel on server"
12341
12342         lru_resize_disable mdc
12343         lru_resize_disable osc
12344         cancel_lru_locks mdc
12345         stat $DIR/$tdir > /dev/null
12346         can1=$(do_facet $SINGLEMDS \
12347                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12348                awk '/ldlm_cancel/ {print $2}')
12349         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12350                awk '/ldlm_bl_callback/ {print $2}')
12351         touch $DIR/$tdir/f1
12352         can2=$(do_facet $SINGLEMDS \
12353                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12354                awk '/ldlm_cancel/ {print $2}')
12355         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12356                awk '/ldlm_bl_callback/ {print $2}')
12357         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12358         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12359         lru_resize_enable mdc
12360         lru_resize_enable osc
12361 }
12362 run_test 120b "Early Lock Cancel: create test"
12363
12364 test_120c() {
12365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12366         remote_mds_nodsh && skip "remote MDS with nodsh"
12367         test_mkdir -i0 -c1 $DIR/$tdir
12368         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12369                 skip "no early lock cancel on server"
12370
12371         lru_resize_disable mdc
12372         lru_resize_disable osc
12373         test_mkdir -i0 -c1 $DIR/$tdir/d1
12374         test_mkdir -i0 -c1 $DIR/$tdir/d2
12375         touch $DIR/$tdir/d1/f1
12376         cancel_lru_locks mdc
12377         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12378         can1=$(do_facet mds1 \
12379                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12380                awk '/ldlm_cancel/ {print $2}')
12381         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12382                awk '/ldlm_bl_callback/ {print $2}')
12383         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12384         can2=$(do_facet mds1 \
12385                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12386                awk '/ldlm_cancel/ {print $2}')
12387         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12388                awk '/ldlm_bl_callback/ {print $2}')
12389         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12390         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12391         lru_resize_enable mdc
12392         lru_resize_enable osc
12393 }
12394 run_test 120c "Early Lock Cancel: link test"
12395
12396 test_120d() {
12397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12398         remote_mds_nodsh && skip "remote MDS with nodsh"
12399         test_mkdir -i0 -c1 $DIR/$tdir
12400         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12401                 skip_env "no early lock cancel on server"
12402
12403         lru_resize_disable mdc
12404         lru_resize_disable osc
12405         touch $DIR/$tdir
12406         cancel_lru_locks mdc
12407         stat $DIR/$tdir > /dev/null
12408         can1=$(do_facet mds1 \
12409                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12410                awk '/ldlm_cancel/ {print $2}')
12411         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12412                awk '/ldlm_bl_callback/ {print $2}')
12413         chmod a+x $DIR/$tdir
12414         can2=$(do_facet mds1 \
12415                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12416                awk '/ldlm_cancel/ {print $2}')
12417         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12418                awk '/ldlm_bl_callback/ {print $2}')
12419         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12420         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12421         lru_resize_enable mdc
12422         lru_resize_enable osc
12423 }
12424 run_test 120d "Early Lock Cancel: setattr test"
12425
12426 test_120e() {
12427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12428         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12429                 skip_env "no early lock cancel on server"
12430         remote_mds_nodsh && skip "remote MDS with nodsh"
12431
12432         local dlmtrace_set=false
12433
12434         test_mkdir -i0 -c1 $DIR/$tdir
12435         lru_resize_disable mdc
12436         lru_resize_disable osc
12437         ! $LCTL get_param debug | grep -q dlmtrace &&
12438                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12439         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12440         cancel_lru_locks mdc
12441         cancel_lru_locks osc
12442         dd if=$DIR/$tdir/f1 of=/dev/null
12443         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12444         # XXX client can not do early lock cancel of OST lock
12445         # during unlink (LU-4206), so cancel osc lock now.
12446         sleep 2
12447         cancel_lru_locks osc
12448         can1=$(do_facet mds1 \
12449                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12450                awk '/ldlm_cancel/ {print $2}')
12451         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12452                awk '/ldlm_bl_callback/ {print $2}')
12453         unlink $DIR/$tdir/f1
12454         sleep 5
12455         can2=$(do_facet mds1 \
12456                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12457                awk '/ldlm_cancel/ {print $2}')
12458         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12459                awk '/ldlm_bl_callback/ {print $2}')
12460         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12461                 $LCTL dk $TMP/cancel.debug.txt
12462         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12463                 $LCTL dk $TMP/blocking.debug.txt
12464         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12465         lru_resize_enable mdc
12466         lru_resize_enable osc
12467 }
12468 run_test 120e "Early Lock Cancel: unlink test"
12469
12470 test_120f() {
12471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12472         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12473                 skip_env "no early lock cancel on server"
12474         remote_mds_nodsh && skip "remote MDS with nodsh"
12475
12476         test_mkdir -i0 -c1 $DIR/$tdir
12477         lru_resize_disable mdc
12478         lru_resize_disable osc
12479         test_mkdir -i0 -c1 $DIR/$tdir/d1
12480         test_mkdir -i0 -c1 $DIR/$tdir/d2
12481         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12482         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12483         cancel_lru_locks mdc
12484         cancel_lru_locks osc
12485         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12486         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12487         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12488         # XXX client can not do early lock cancel of OST lock
12489         # during rename (LU-4206), so cancel osc lock now.
12490         sleep 2
12491         cancel_lru_locks osc
12492         can1=$(do_facet mds1 \
12493                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12494                awk '/ldlm_cancel/ {print $2}')
12495         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12496                awk '/ldlm_bl_callback/ {print $2}')
12497         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12498         sleep 5
12499         can2=$(do_facet mds1 \
12500                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12501                awk '/ldlm_cancel/ {print $2}')
12502         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12503                awk '/ldlm_bl_callback/ {print $2}')
12504         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12505         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12506         lru_resize_enable mdc
12507         lru_resize_enable osc
12508 }
12509 run_test 120f "Early Lock Cancel: rename test"
12510
12511 test_120g() {
12512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12513         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12514                 skip_env "no early lock cancel on server"
12515         remote_mds_nodsh && skip "remote MDS with nodsh"
12516
12517         lru_resize_disable mdc
12518         lru_resize_disable osc
12519         count=10000
12520         echo create $count files
12521         test_mkdir $DIR/$tdir
12522         cancel_lru_locks mdc
12523         cancel_lru_locks osc
12524         t0=$(date +%s)
12525
12526         can0=$(do_facet $SINGLEMDS \
12527                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12528                awk '/ldlm_cancel/ {print $2}')
12529         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12530                awk '/ldlm_bl_callback/ {print $2}')
12531         createmany -o $DIR/$tdir/f $count
12532         sync
12533         can1=$(do_facet $SINGLEMDS \
12534                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12535                awk '/ldlm_cancel/ {print $2}')
12536         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12537                awk '/ldlm_bl_callback/ {print $2}')
12538         t1=$(date +%s)
12539         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12540         echo rm $count files
12541         rm -r $DIR/$tdir
12542         sync
12543         can2=$(do_facet $SINGLEMDS \
12544                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12545                awk '/ldlm_cancel/ {print $2}')
12546         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12547                awk '/ldlm_bl_callback/ {print $2}')
12548         t2=$(date +%s)
12549         echo total: $count removes in $((t2-t1))
12550         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12551         sleep 2
12552         # wait for commitment of removal
12553         lru_resize_enable mdc
12554         lru_resize_enable osc
12555 }
12556 run_test 120g "Early Lock Cancel: performance test"
12557
12558 test_121() { #bug #10589
12559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12560
12561         rm -rf $DIR/$tfile
12562         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12563 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12564         lctl set_param fail_loc=0x310
12565         cancel_lru_locks osc > /dev/null
12566         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12567         lctl set_param fail_loc=0
12568         [[ $reads -eq $writes ]] ||
12569                 error "read $reads blocks, must be $writes blocks"
12570 }
12571 run_test 121 "read cancel race ========="
12572
12573 test_123a_base() { # was test 123, statahead(bug 11401)
12574         local lsx="$1"
12575
12576         SLOWOK=0
12577         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12578                 log "testing UP system. Performance may be lower than expected."
12579                 SLOWOK=1
12580         fi
12581
12582         rm -rf $DIR/$tdir
12583         test_mkdir $DIR/$tdir
12584         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12585         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12586         MULT=10
12587         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12588                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12589
12590                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12591                 lctl set_param -n llite.*.statahead_max 0
12592                 lctl get_param llite.*.statahead_max
12593                 cancel_lru_locks mdc
12594                 cancel_lru_locks osc
12595                 stime=$(date +%s)
12596                 time $lsx $DIR/$tdir | wc -l
12597                 etime=$(date +%s)
12598                 delta=$((etime - stime))
12599                 log "$lsx $i files without statahead: $delta sec"
12600                 lctl set_param llite.*.statahead_max=$max
12601
12602                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12603                         grep "statahead wrong:" | awk '{print $3}')
12604                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12605                 cancel_lru_locks mdc
12606                 cancel_lru_locks osc
12607                 stime=$(date +%s)
12608                 time $lsx $DIR/$tdir | wc -l
12609                 etime=$(date +%s)
12610                 delta_sa=$((etime - stime))
12611                 log "$lsx $i files with statahead: $delta_sa sec"
12612                 lctl get_param -n llite.*.statahead_stats
12613                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12614                         grep "statahead wrong:" | awk '{print $3}')
12615
12616                 [[ $swrong -lt $ewrong ]] &&
12617                         log "statahead was stopped, maybe too many locks held!"
12618                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12619
12620                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12621                         max=$(lctl get_param -n llite.*.statahead_max |
12622                                 head -n 1)
12623                         lctl set_param -n llite.*.statahead_max 0
12624                         lctl get_param llite.*.statahead_max
12625                         cancel_lru_locks mdc
12626                         cancel_lru_locks osc
12627                         stime=$(date +%s)
12628                         time $lsx $DIR/$tdir | wc -l
12629                         etime=$(date +%s)
12630                         delta=$((etime - stime))
12631                         log "$lsx $i files again without statahead: $delta sec"
12632                         lctl set_param llite.*.statahead_max=$max
12633                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12634                                 if [  $SLOWOK -eq 0 ]; then
12635                                         error "$lsx $i files is slower with statahead!"
12636                                 else
12637                                         log "$lsx $i files is slower with statahead!"
12638                                 fi
12639                                 break
12640                         fi
12641                 fi
12642
12643                 [ $delta -gt 20 ] && break
12644                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12645                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12646         done
12647         log "$lsx done"
12648
12649         stime=$(date +%s)
12650         rm -r $DIR/$tdir
12651         sync
12652         etime=$(date +%s)
12653         delta=$((etime - stime))
12654         log "rm -r $DIR/$tdir/: $delta seconds"
12655         log "rm done"
12656         lctl get_param -n llite.*.statahead_stats
12657 }
12658
12659 test_123aa() {
12660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12661
12662         test_123a_base "ls -l"
12663 }
12664 run_test 123aa "verify statahead work"
12665
12666 test_123ab() {
12667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12668
12669         statx_supported || skip_env "Test must be statx() syscall supported"
12670
12671         test_123a_base "$STATX -l"
12672 }
12673 run_test 123ab "verify statahead work by using statx"
12674
12675 test_123ac() {
12676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12677
12678         statx_supported || skip_env "Test must be statx() syscall supported"
12679
12680         local rpcs_before
12681         local rpcs_after
12682         local agl_before
12683         local agl_after
12684
12685         cancel_lru_locks $OSC
12686         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12687         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12688                 awk '/agl.total:/ {print $3}')
12689         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12690         test_123a_base "$STATX --cached=always -D"
12691         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12692                 awk '/agl.total:/ {print $3}')
12693         [ $agl_before -eq $agl_after ] ||
12694                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12695         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12696         [ $rpcs_after -eq $rpcs_before ] ||
12697                 error "$STATX should not send glimpse RPCs to $OSC"
12698 }
12699 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12700
12701 test_123b () { # statahead(bug 15027)
12702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12703
12704         test_mkdir $DIR/$tdir
12705         createmany -o $DIR/$tdir/$tfile-%d 1000
12706
12707         cancel_lru_locks mdc
12708         cancel_lru_locks osc
12709
12710 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12711         lctl set_param fail_loc=0x80000803
12712         ls -lR $DIR/$tdir > /dev/null
12713         log "ls done"
12714         lctl set_param fail_loc=0x0
12715         lctl get_param -n llite.*.statahead_stats
12716         rm -r $DIR/$tdir
12717         sync
12718
12719 }
12720 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12721
12722 test_123c() {
12723         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12724
12725         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12726         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12727         touch $DIR/$tdir.1/{1..3}
12728         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12729
12730         remount_client $MOUNT
12731
12732         $MULTIOP $DIR/$tdir.0 Q
12733
12734         # let statahead to complete
12735         ls -l $DIR/$tdir.0 > /dev/null
12736
12737         testid=$(echo $TESTNAME | tr '_' ' ')
12738         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12739                 error "statahead warning" || true
12740 }
12741 run_test 123c "Can not initialize inode warning on DNE statahead"
12742
12743 test_124a() {
12744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12745         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12746                 skip_env "no lru resize on server"
12747
12748         local NR=2000
12749
12750         test_mkdir $DIR/$tdir
12751
12752         log "create $NR files at $DIR/$tdir"
12753         createmany -o $DIR/$tdir/f $NR ||
12754                 error "failed to create $NR files in $DIR/$tdir"
12755
12756         cancel_lru_locks mdc
12757         ls -l $DIR/$tdir > /dev/null
12758
12759         local NSDIR=""
12760         local LRU_SIZE=0
12761         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12762                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12763                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12764                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12765                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12766                         log "NSDIR=$NSDIR"
12767                         log "NS=$(basename $NSDIR)"
12768                         break
12769                 fi
12770         done
12771
12772         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12773                 skip "Not enough cached locks created!"
12774         fi
12775         log "LRU=$LRU_SIZE"
12776
12777         local SLEEP=30
12778
12779         # We know that lru resize allows one client to hold $LIMIT locks
12780         # for 10h. After that locks begin to be killed by client.
12781         local MAX_HRS=10
12782         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12783         log "LIMIT=$LIMIT"
12784         if [ $LIMIT -lt $LRU_SIZE ]; then
12785                 skip "Limit is too small $LIMIT"
12786         fi
12787
12788         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12789         # killing locks. Some time was spent for creating locks. This means
12790         # that up to the moment of sleep finish we must have killed some of
12791         # them (10-100 locks). This depends on how fast ther were created.
12792         # Many of them were touched in almost the same moment and thus will
12793         # be killed in groups.
12794         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12795
12796         # Use $LRU_SIZE_B here to take into account real number of locks
12797         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12798         local LRU_SIZE_B=$LRU_SIZE
12799         log "LVF=$LVF"
12800         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12801         log "OLD_LVF=$OLD_LVF"
12802         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12803
12804         # Let's make sure that we really have some margin. Client checks
12805         # cached locks every 10 sec.
12806         SLEEP=$((SLEEP+20))
12807         log "Sleep ${SLEEP} sec"
12808         local SEC=0
12809         while ((SEC<$SLEEP)); do
12810                 echo -n "..."
12811                 sleep 5
12812                 SEC=$((SEC+5))
12813                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12814                 echo -n "$LRU_SIZE"
12815         done
12816         echo ""
12817         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12818         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12819
12820         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12821                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12822                 unlinkmany $DIR/$tdir/f $NR
12823                 return
12824         }
12825
12826         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12827         log "unlink $NR files at $DIR/$tdir"
12828         unlinkmany $DIR/$tdir/f $NR
12829 }
12830 run_test 124a "lru resize ======================================="
12831
12832 get_max_pool_limit()
12833 {
12834         local limit=$($LCTL get_param \
12835                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12836         local max=0
12837         for l in $limit; do
12838                 if [[ $l -gt $max ]]; then
12839                         max=$l
12840                 fi
12841         done
12842         echo $max
12843 }
12844
12845 test_124b() {
12846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12847         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12848                 skip_env "no lru resize on server"
12849
12850         LIMIT=$(get_max_pool_limit)
12851
12852         NR=$(($(default_lru_size)*20))
12853         if [[ $NR -gt $LIMIT ]]; then
12854                 log "Limit lock number by $LIMIT locks"
12855                 NR=$LIMIT
12856         fi
12857
12858         IFree=$(mdsrate_inodes_available)
12859         if [ $IFree -lt $NR ]; then
12860                 log "Limit lock number by $IFree inodes"
12861                 NR=$IFree
12862         fi
12863
12864         lru_resize_disable mdc
12865         test_mkdir -p $DIR/$tdir/disable_lru_resize
12866
12867         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12868         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12869         cancel_lru_locks mdc
12870         stime=`date +%s`
12871         PID=""
12872         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12873         PID="$PID $!"
12874         sleep 2
12875         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12876         PID="$PID $!"
12877         sleep 2
12878         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12879         PID="$PID $!"
12880         wait $PID
12881         etime=`date +%s`
12882         nolruresize_delta=$((etime-stime))
12883         log "ls -la time: $nolruresize_delta seconds"
12884         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12885         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12886
12887         lru_resize_enable mdc
12888         test_mkdir -p $DIR/$tdir/enable_lru_resize
12889
12890         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12891         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12892         cancel_lru_locks mdc
12893         stime=`date +%s`
12894         PID=""
12895         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12896         PID="$PID $!"
12897         sleep 2
12898         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12899         PID="$PID $!"
12900         sleep 2
12901         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12902         PID="$PID $!"
12903         wait $PID
12904         etime=`date +%s`
12905         lruresize_delta=$((etime-stime))
12906         log "ls -la time: $lruresize_delta seconds"
12907         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12908
12909         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12910                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12911         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12912                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12913         else
12914                 log "lru resize performs the same with no lru resize"
12915         fi
12916         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12917 }
12918 run_test 124b "lru resize (performance test) ======================="
12919
12920 test_124c() {
12921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12922         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12923                 skip_env "no lru resize on server"
12924
12925         # cache ununsed locks on client
12926         local nr=100
12927         cancel_lru_locks mdc
12928         test_mkdir $DIR/$tdir
12929         createmany -o $DIR/$tdir/f $nr ||
12930                 error "failed to create $nr files in $DIR/$tdir"
12931         ls -l $DIR/$tdir > /dev/null
12932
12933         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12934         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12935         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12936         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12937         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12938
12939         # set lru_max_age to 1 sec
12940         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12941         echo "sleep $((recalc_p * 2)) seconds..."
12942         sleep $((recalc_p * 2))
12943
12944         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12945         # restore lru_max_age
12946         $LCTL set_param -n $nsdir.lru_max_age $max_age
12947         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12948         unlinkmany $DIR/$tdir/f $nr
12949 }
12950 run_test 124c "LRUR cancel very aged locks"
12951
12952 test_124d() {
12953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12954         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12955                 skip_env "no lru resize on server"
12956
12957         # cache ununsed locks on client
12958         local nr=100
12959
12960         lru_resize_disable mdc
12961         stack_trap "lru_resize_enable mdc" EXIT
12962
12963         cancel_lru_locks mdc
12964
12965         # asynchronous object destroy at MDT could cause bl ast to client
12966         test_mkdir $DIR/$tdir
12967         createmany -o $DIR/$tdir/f $nr ||
12968                 error "failed to create $nr files in $DIR/$tdir"
12969         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12970
12971         ls -l $DIR/$tdir > /dev/null
12972
12973         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12974         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12975         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12976         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12977
12978         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12979
12980         # set lru_max_age to 1 sec
12981         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12982         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12983
12984         echo "sleep $((recalc_p * 2)) seconds..."
12985         sleep $((recalc_p * 2))
12986
12987         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12988
12989         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12990 }
12991 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12992
12993 test_125() { # 13358
12994         $LCTL get_param -n llite.*.client_type | grep -q local ||
12995                 skip "must run as local client"
12996         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12997                 skip_env "must have acl enabled"
12998         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12999
13000         test_mkdir $DIR/$tdir
13001         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13002         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13003         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13004 }
13005 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13006
13007 test_126() { # bug 12829/13455
13008         $GSS && skip_env "must run as gss disabled"
13009         $LCTL get_param -n llite.*.client_type | grep -q local ||
13010                 skip "must run as local client"
13011         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13012
13013         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13014         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13015         rm -f $DIR/$tfile
13016         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13017 }
13018 run_test 126 "check that the fsgid provided by the client is taken into account"
13019
13020 test_127a() { # bug 15521
13021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13022         local name count samp unit min max sum sumsq
13023
13024         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13025         echo "stats before reset"
13026         $LCTL get_param osc.*.stats
13027         $LCTL set_param osc.*.stats=0
13028         local fsize=$((2048 * 1024))
13029
13030         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13031         cancel_lru_locks osc
13032         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13033
13034         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13035         stack_trap "rm -f $TMP/$tfile.tmp"
13036         while read name count samp unit min max sum sumsq; do
13037                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13038                 [ ! $min ] && error "Missing min value for $name proc entry"
13039                 eval $name=$count || error "Wrong proc format"
13040
13041                 case $name in
13042                 read_bytes|write_bytes)
13043                         [[ "$unit" =~ "bytes" ]] ||
13044                                 error "unit is not 'bytes': $unit"
13045                         (( $min >= 4096 )) || error "min is too small: $min"
13046                         (( $min <= $fsize )) || error "min is too big: $min"
13047                         (( $max >= 4096 )) || error "max is too small: $max"
13048                         (( $max <= $fsize )) || error "max is too big: $max"
13049                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13050                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13051                                 error "sumsquare is too small: $sumsq"
13052                         (( $sumsq <= $fsize * $fsize )) ||
13053                                 error "sumsquare is too big: $sumsq"
13054                         ;;
13055                 ost_read|ost_write)
13056                         [[ "$unit" =~ "usec" ]] ||
13057                                 error "unit is not 'usec': $unit"
13058                         ;;
13059                 *)      ;;
13060                 esac
13061         done < $DIR/$tfile.tmp
13062
13063         #check that we actually got some stats
13064         [ "$read_bytes" ] || error "Missing read_bytes stats"
13065         [ "$write_bytes" ] || error "Missing write_bytes stats"
13066         [ "$read_bytes" != 0 ] || error "no read done"
13067         [ "$write_bytes" != 0 ] || error "no write done"
13068 }
13069 run_test 127a "verify the client stats are sane"
13070
13071 test_127b() { # bug LU-333
13072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13073         local name count samp unit min max sum sumsq
13074
13075         echo "stats before reset"
13076         $LCTL get_param llite.*.stats
13077         $LCTL set_param llite.*.stats=0
13078
13079         # perform 2 reads and writes so MAX is different from SUM.
13080         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13081         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13082         cancel_lru_locks osc
13083         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13084         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13085
13086         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13087         stack_trap "rm -f $TMP/$tfile.tmp"
13088         while read name count samp unit min max sum sumsq; do
13089                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13090                 eval $name=$count || error "Wrong proc format"
13091
13092                 case $name in
13093                 read_bytes|write_bytes)
13094                         [[ "$unit" =~ "bytes" ]] ||
13095                                 error "unit is not 'bytes': $unit"
13096                         (( $count == 2 )) || error "count is not 2: $count"
13097                         (( $min == $PAGE_SIZE )) ||
13098                                 error "min is not $PAGE_SIZE: $min"
13099                         (( $max == $PAGE_SIZE )) ||
13100                                 error "max is not $PAGE_SIZE: $max"
13101                         (( $sum == $PAGE_SIZE * 2 )) ||
13102                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13103                         ;;
13104                 read|write)
13105                         [[ "$unit" =~ "usec" ]] ||
13106                                 error "unit is not 'usec': $unit"
13107                         ;;
13108                 *)      ;;
13109                 esac
13110         done < $TMP/$tfile.tmp
13111
13112         #check that we actually got some stats
13113         [ "$read_bytes" ] || error "Missing read_bytes stats"
13114         [ "$write_bytes" ] || error "Missing write_bytes stats"
13115         [ "$read_bytes" != 0 ] || error "no read done"
13116         [ "$write_bytes" != 0 ] || error "no write done"
13117 }
13118 run_test 127b "verify the llite client stats are sane"
13119
13120 test_127c() { # LU-12394
13121         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13122         local size
13123         local bsize
13124         local reads
13125         local writes
13126         local count
13127
13128         $LCTL set_param llite.*.extents_stats=1
13129         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13130
13131         # Use two stripes so there is enough space in default config
13132         $LFS setstripe -c 2 $DIR/$tfile
13133
13134         # Extent stats start at 0-4K and go in power of two buckets
13135         # LL_HIST_START = 12 --> 2^12 = 4K
13136         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13137         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13138         # small configs
13139         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13140                 do
13141                 # Write and read, 2x each, second time at a non-zero offset
13142                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13143                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13144                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13145                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13146                 rm -f $DIR/$tfile
13147         done
13148
13149         $LCTL get_param llite.*.extents_stats
13150
13151         count=2
13152         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13153                 do
13154                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13155                                 grep -m 1 $bsize)
13156                 reads=$(echo $bucket | awk '{print $5}')
13157                 writes=$(echo $bucket | awk '{print $9}')
13158                 [ "$reads" -eq $count ] ||
13159                         error "$reads reads in < $bsize bucket, expect $count"
13160                 [ "$writes" -eq $count ] ||
13161                         error "$writes writes in < $bsize bucket, expect $count"
13162         done
13163
13164         # Test mmap write and read
13165         $LCTL set_param llite.*.extents_stats=c
13166         size=512
13167         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13168         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13169         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13170
13171         $LCTL get_param llite.*.extents_stats
13172
13173         count=$(((size*1024) / PAGE_SIZE))
13174
13175         bsize=$((2 * PAGE_SIZE / 1024))K
13176
13177         bucket=$($LCTL get_param -n llite.*.extents_stats |
13178                         grep -m 1 $bsize)
13179         reads=$(echo $bucket | awk '{print $5}')
13180         writes=$(echo $bucket | awk '{print $9}')
13181         # mmap writes fault in the page first, creating an additonal read
13182         [ "$reads" -eq $((2 * count)) ] ||
13183                 error "$reads reads in < $bsize bucket, expect $count"
13184         [ "$writes" -eq $count ] ||
13185                 error "$writes writes in < $bsize bucket, expect $count"
13186 }
13187 run_test 127c "test llite extent stats with regular & mmap i/o"
13188
13189 test_128() { # bug 15212
13190         touch $DIR/$tfile
13191         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13192                 find $DIR/$tfile
13193                 find $DIR/$tfile
13194         EOF
13195
13196         result=$(grep error $TMP/$tfile.log)
13197         rm -f $DIR/$tfile $TMP/$tfile.log
13198         [ -z "$result" ] ||
13199                 error "consecutive find's under interactive lfs failed"
13200 }
13201 run_test 128 "interactive lfs for 2 consecutive find's"
13202
13203 set_dir_limits () {
13204         local mntdev
13205         local canondev
13206         local node
13207
13208         local ldproc=/proc/fs/ldiskfs
13209         local facets=$(get_facets MDS)
13210
13211         for facet in ${facets//,/ }; do
13212                 canondev=$(ldiskfs_canon \
13213                            *.$(convert_facet2label $facet).mntdev $facet)
13214                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13215                         ldproc=/sys/fs/ldiskfs
13216                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13217                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13218         done
13219 }
13220
13221 check_mds_dmesg() {
13222         local facets=$(get_facets MDS)
13223         for facet in ${facets//,/ }; do
13224                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13225         done
13226         return 1
13227 }
13228
13229 test_129() {
13230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13231         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13232                 skip "Need MDS version with at least 2.5.56"
13233         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13234                 skip_env "ldiskfs only test"
13235         fi
13236         remote_mds_nodsh && skip "remote MDS with nodsh"
13237
13238         local ENOSPC=28
13239         local has_warning=false
13240
13241         rm -rf $DIR/$tdir
13242         mkdir -p $DIR/$tdir
13243
13244         # block size of mds1
13245         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13246         set_dir_limits $maxsize $((maxsize * 6 / 8))
13247         stack_trap "set_dir_limits 0 0"
13248         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13249         local dirsize=$(stat -c%s "$DIR/$tdir")
13250         local nfiles=0
13251         while (( $dirsize <= $maxsize )); do
13252                 $MCREATE $DIR/$tdir/file_base_$nfiles
13253                 rc=$?
13254                 # check two errors:
13255                 # ENOSPC for ext4 max_dir_size, which has been used since
13256                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13257                 if (( rc == ENOSPC )); then
13258                         set_dir_limits 0 0
13259                         echo "rc=$rc returned as expected after $nfiles files"
13260
13261                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13262                                 error "create failed w/o dir size limit"
13263
13264                         # messages may be rate limited if test is run repeatedly
13265                         check_mds_dmesg '"is approaching max"' ||
13266                                 echo "warning message should be output"
13267                         check_mds_dmesg '"has reached max"' ||
13268                                 echo "reached message should be output"
13269
13270                         dirsize=$(stat -c%s "$DIR/$tdir")
13271
13272                         [[ $dirsize -ge $maxsize ]] && return 0
13273                         error "dirsize $dirsize < $maxsize after $nfiles files"
13274                 elif (( rc != 0 )); then
13275                         break
13276                 fi
13277                 nfiles=$((nfiles + 1))
13278                 dirsize=$(stat -c%s "$DIR/$tdir")
13279         done
13280
13281         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13282 }
13283 run_test 129 "test directory size limit ========================"
13284
13285 OLDIFS="$IFS"
13286 cleanup_130() {
13287         trap 0
13288         IFS="$OLDIFS"
13289 }
13290
13291 test_130a() {
13292         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13293         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13294
13295         trap cleanup_130 EXIT RETURN
13296
13297         local fm_file=$DIR/$tfile
13298         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13299         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13300                 error "dd failed for $fm_file"
13301
13302         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13303         filefrag -ves $fm_file
13304         RC=$?
13305         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13306                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13307         [ $RC != 0 ] && error "filefrag $fm_file failed"
13308
13309         filefrag_op=$(filefrag -ve -k $fm_file |
13310                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13311         lun=$($LFS getstripe -i $fm_file)
13312
13313         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13314         IFS=$'\n'
13315         tot_len=0
13316         for line in $filefrag_op
13317         do
13318                 frag_lun=`echo $line | cut -d: -f5`
13319                 ext_len=`echo $line | cut -d: -f4`
13320                 if (( $frag_lun != $lun )); then
13321                         cleanup_130
13322                         error "FIEMAP on 1-stripe file($fm_file) failed"
13323                         return
13324                 fi
13325                 (( tot_len += ext_len ))
13326         done
13327
13328         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13329                 cleanup_130
13330                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13331                 return
13332         fi
13333
13334         cleanup_130
13335
13336         echo "FIEMAP on single striped file succeeded"
13337 }
13338 run_test 130a "FIEMAP (1-stripe file)"
13339
13340 test_130b() {
13341         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13342
13343         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13344         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13345
13346         trap cleanup_130 EXIT RETURN
13347
13348         local fm_file=$DIR/$tfile
13349         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13350                         error "setstripe on $fm_file"
13351         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13352                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13353
13354         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13355                 error "dd failed on $fm_file"
13356
13357         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13358         filefrag_op=$(filefrag -ve -k $fm_file |
13359                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13360
13361         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13362                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13363
13364         IFS=$'\n'
13365         tot_len=0
13366         num_luns=1
13367         for line in $filefrag_op
13368         do
13369                 frag_lun=$(echo $line | cut -d: -f5 |
13370                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13371                 ext_len=$(echo $line | cut -d: -f4)
13372                 if (( $frag_lun != $last_lun )); then
13373                         if (( tot_len != 1024 )); then
13374                                 cleanup_130
13375                                 error "FIEMAP on $fm_file failed; returned " \
13376                                 "len $tot_len for OST $last_lun instead of 1024"
13377                                 return
13378                         else
13379                                 (( num_luns += 1 ))
13380                                 tot_len=0
13381                         fi
13382                 fi
13383                 (( tot_len += ext_len ))
13384                 last_lun=$frag_lun
13385         done
13386         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13387                 cleanup_130
13388                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13389                         "luns or wrong len for OST $last_lun"
13390                 return
13391         fi
13392
13393         cleanup_130
13394
13395         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13396 }
13397 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13398
13399 test_130c() {
13400         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13401
13402         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13403         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13404
13405         trap cleanup_130 EXIT RETURN
13406
13407         local fm_file=$DIR/$tfile
13408         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13409         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13410                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13411
13412         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13413                         error "dd failed on $fm_file"
13414
13415         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13416         filefrag_op=$(filefrag -ve -k $fm_file |
13417                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13418
13419         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13420                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13421
13422         IFS=$'\n'
13423         tot_len=0
13424         num_luns=1
13425         for line in $filefrag_op
13426         do
13427                 frag_lun=$(echo $line | cut -d: -f5 |
13428                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13429                 ext_len=$(echo $line | cut -d: -f4)
13430                 if (( $frag_lun != $last_lun )); then
13431                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13432                         if (( logical != 512 )); then
13433                                 cleanup_130
13434                                 error "FIEMAP on $fm_file failed; returned " \
13435                                 "logical start for lun $logical instead of 512"
13436                                 return
13437                         fi
13438                         if (( tot_len != 512 )); then
13439                                 cleanup_130
13440                                 error "FIEMAP on $fm_file failed; returned " \
13441                                 "len $tot_len for OST $last_lun instead of 1024"
13442                                 return
13443                         else
13444                                 (( num_luns += 1 ))
13445                                 tot_len=0
13446                         fi
13447                 fi
13448                 (( tot_len += ext_len ))
13449                 last_lun=$frag_lun
13450         done
13451         if (( num_luns != 2 || tot_len != 512 )); then
13452                 cleanup_130
13453                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13454                         "luns or wrong len for OST $last_lun"
13455                 return
13456         fi
13457
13458         cleanup_130
13459
13460         echo "FIEMAP on 2-stripe file with hole succeeded"
13461 }
13462 run_test 130c "FIEMAP (2-stripe file with hole)"
13463
13464 test_130d() {
13465         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13466
13467         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13468         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13469
13470         trap cleanup_130 EXIT RETURN
13471
13472         local fm_file=$DIR/$tfile
13473         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13474                         error "setstripe on $fm_file"
13475         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13476                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13477
13478         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13479         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13480                 error "dd failed on $fm_file"
13481
13482         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13483         filefrag_op=$(filefrag -ve -k $fm_file |
13484                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13485
13486         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13487                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13488
13489         IFS=$'\n'
13490         tot_len=0
13491         num_luns=1
13492         for line in $filefrag_op
13493         do
13494                 frag_lun=$(echo $line | cut -d: -f5 |
13495                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13496                 ext_len=$(echo $line | cut -d: -f4)
13497                 if (( $frag_lun != $last_lun )); then
13498                         if (( tot_len != 1024 )); then
13499                                 cleanup_130
13500                                 error "FIEMAP on $fm_file failed; returned " \
13501                                 "len $tot_len for OST $last_lun instead of 1024"
13502                                 return
13503                         else
13504                                 (( num_luns += 1 ))
13505                                 tot_len=0
13506                         fi
13507                 fi
13508                 (( tot_len += ext_len ))
13509                 last_lun=$frag_lun
13510         done
13511         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13512                 cleanup_130
13513                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13514                         "luns or wrong len for OST $last_lun"
13515                 return
13516         fi
13517
13518         cleanup_130
13519
13520         echo "FIEMAP on N-stripe file succeeded"
13521 }
13522 run_test 130d "FIEMAP (N-stripe file)"
13523
13524 test_130e() {
13525         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13526
13527         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13528         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13529
13530         trap cleanup_130 EXIT RETURN
13531
13532         local fm_file=$DIR/$tfile
13533         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13534
13535         NUM_BLKS=512
13536         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13537         for ((i = 0; i < $NUM_BLKS; i++)); do
13538                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13539                         conv=notrunc > /dev/null 2>&1
13540         done
13541
13542         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13543         filefrag_op=$(filefrag -ve -k $fm_file |
13544                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13545
13546         last_lun=$(echo $filefrag_op | cut -d: -f5)
13547
13548         IFS=$'\n'
13549         tot_len=0
13550         num_luns=1
13551         for line in $filefrag_op; do
13552                 frag_lun=$(echo $line | cut -d: -f5)
13553                 ext_len=$(echo $line | cut -d: -f4)
13554                 if [[ "$frag_lun" != "$last_lun" ]]; then
13555                         if (( tot_len != $EXPECTED_LEN )); then
13556                                 cleanup_130
13557                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13558                         else
13559                                 (( num_luns += 1 ))
13560                                 tot_len=0
13561                         fi
13562                 fi
13563                 (( tot_len += ext_len ))
13564                 last_lun=$frag_lun
13565         done
13566         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13567                 cleanup_130
13568                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13569         fi
13570
13571         echo "FIEMAP with continuation calls succeeded"
13572 }
13573 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13574
13575 test_130f() {
13576         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13577         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13578
13579         local fm_file=$DIR/$tfile
13580         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13581                 error "multiop create with lov_delay_create on $fm_file"
13582
13583         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13584         filefrag_extents=$(filefrag -vek $fm_file |
13585                            awk '/extents? found/ { print $2 }')
13586         if [[ "$filefrag_extents" != "0" ]]; then
13587                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13588         fi
13589
13590         rm -f $fm_file
13591 }
13592 run_test 130f "FIEMAP (unstriped file)"
13593
13594 test_130g() {
13595         local file=$DIR/$tfile
13596         local nr=$((OSTCOUNT * 100))
13597
13598         $LFS setstripe -C $nr $file ||
13599                 error "failed to setstripe -C $nr $file"
13600
13601         dd if=/dev/zero of=$file count=$nr bs=1M
13602         sync
13603         nr=$($LFS getstripe -c $file)
13604
13605         local extents=$(filefrag -v $file |
13606                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13607
13608         echo "filefrag list $extents extents in file with stripecount $nr"
13609         if (( extents < nr )); then
13610                 $LFS getstripe $file
13611                 filefrag -v $file
13612                 error "filefrag printed $extents < $nr extents"
13613         fi
13614
13615         rm -f $file
13616 }
13617 run_test 130g "FIEMAP (overstripe file)"
13618
13619 # Test for writev/readv
13620 test_131a() {
13621         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13622                 error "writev test failed"
13623         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13624                 error "readv failed"
13625         rm -f $DIR/$tfile
13626 }
13627 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13628
13629 test_131b() {
13630         local fsize=$((524288 + 1048576 + 1572864))
13631         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13632                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13633                         error "append writev test failed"
13634
13635         ((fsize += 1572864 + 1048576))
13636         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13637                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13638                         error "append writev test failed"
13639         rm -f $DIR/$tfile
13640 }
13641 run_test 131b "test append writev"
13642
13643 test_131c() {
13644         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13645         error "NOT PASS"
13646 }
13647 run_test 131c "test read/write on file w/o objects"
13648
13649 test_131d() {
13650         rwv -f $DIR/$tfile -w -n 1 1572864
13651         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13652         if [ "$NOB" != 1572864 ]; then
13653                 error "Short read filed: read $NOB bytes instead of 1572864"
13654         fi
13655         rm -f $DIR/$tfile
13656 }
13657 run_test 131d "test short read"
13658
13659 test_131e() {
13660         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13661         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13662         error "read hitting hole failed"
13663         rm -f $DIR/$tfile
13664 }
13665 run_test 131e "test read hitting hole"
13666
13667 check_stats() {
13668         local facet=$1
13669         local op=$2
13670         local want=${3:-0}
13671         local res
13672
13673         case $facet in
13674         mds*) res=$(do_facet $facet \
13675                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13676                  ;;
13677         ost*) res=$(do_facet $facet \
13678                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13679                  ;;
13680         *) error "Wrong facet '$facet'" ;;
13681         esac
13682         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13683         # if the argument $3 is zero, it means any stat increment is ok.
13684         if [[ $want -gt 0 ]]; then
13685                 local count=$(echo $res | awk '{ print $2 }')
13686                 [[ $count -ne $want ]] &&
13687                         error "The $op counter on $facet is $count, not $want"
13688         fi
13689 }
13690
13691 test_133a() {
13692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13693         remote_ost_nodsh && skip "remote OST with nodsh"
13694         remote_mds_nodsh && skip "remote MDS with nodsh"
13695         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13696                 skip_env "MDS doesn't support rename stats"
13697
13698         local testdir=$DIR/${tdir}/stats_testdir
13699
13700         mkdir -p $DIR/${tdir}
13701
13702         # clear stats.
13703         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13704         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13705
13706         # verify mdt stats first.
13707         mkdir ${testdir} || error "mkdir failed"
13708         check_stats $SINGLEMDS "mkdir" 1
13709         touch ${testdir}/${tfile} || error "touch failed"
13710         check_stats $SINGLEMDS "open" 1
13711         check_stats $SINGLEMDS "close" 1
13712         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13713                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13714                 check_stats $SINGLEMDS "mknod" 2
13715         }
13716         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13717         check_stats $SINGLEMDS "unlink" 1
13718         rm -f ${testdir}/${tfile} || error "file remove failed"
13719         check_stats $SINGLEMDS "unlink" 2
13720
13721         # remove working dir and check mdt stats again.
13722         rmdir ${testdir} || error "rmdir failed"
13723         check_stats $SINGLEMDS "rmdir" 1
13724
13725         local testdir1=$DIR/${tdir}/stats_testdir1
13726         mkdir -p ${testdir}
13727         mkdir -p ${testdir1}
13728         touch ${testdir1}/test1
13729         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13730         check_stats $SINGLEMDS "crossdir_rename" 1
13731
13732         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13733         check_stats $SINGLEMDS "samedir_rename" 1
13734
13735         rm -rf $DIR/${tdir}
13736 }
13737 run_test 133a "Verifying MDT stats ========================================"
13738
13739 test_133b() {
13740         local res
13741
13742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13743         remote_ost_nodsh && skip "remote OST with nodsh"
13744         remote_mds_nodsh && skip "remote MDS with nodsh"
13745
13746         local testdir=$DIR/${tdir}/stats_testdir
13747
13748         mkdir -p ${testdir} || error "mkdir failed"
13749         touch ${testdir}/${tfile} || error "touch failed"
13750         cancel_lru_locks mdc
13751
13752         # clear stats.
13753         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13754         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13755
13756         # extra mdt stats verification.
13757         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13758         check_stats $SINGLEMDS "setattr" 1
13759         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13760         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13761         then            # LU-1740
13762                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13763                 check_stats $SINGLEMDS "getattr" 1
13764         fi
13765         rm -rf $DIR/${tdir}
13766
13767         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13768         # so the check below is not reliable
13769         [ $MDSCOUNT -eq 1 ] || return 0
13770
13771         # Sleep to avoid a cached response.
13772         #define OBD_STATFS_CACHE_SECONDS 1
13773         sleep 2
13774         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13775         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13776         $LFS df || error "lfs failed"
13777         check_stats $SINGLEMDS "statfs" 1
13778
13779         # check aggregated statfs (LU-10018)
13780         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13781                 return 0
13782         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13783                 return 0
13784         sleep 2
13785         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13786         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13787         df $DIR
13788         check_stats $SINGLEMDS "statfs" 1
13789
13790         # We want to check that the client didn't send OST_STATFS to
13791         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13792         # extra care is needed here.
13793         if remote_mds; then
13794                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13795                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13796
13797                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13798                 [ "$res" ] && error "OST got STATFS"
13799         fi
13800
13801         return 0
13802 }
13803 run_test 133b "Verifying extra MDT stats =================================="
13804
13805 test_133c() {
13806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13807         remote_ost_nodsh && skip "remote OST with nodsh"
13808         remote_mds_nodsh && skip "remote MDS with nodsh"
13809
13810         local testdir=$DIR/$tdir/stats_testdir
13811
13812         test_mkdir -p $testdir
13813
13814         # verify obdfilter stats.
13815         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13816         sync
13817         cancel_lru_locks osc
13818         wait_delete_completed
13819
13820         # clear stats.
13821         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13822         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13823
13824         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13825                 error "dd failed"
13826         sync
13827         cancel_lru_locks osc
13828         check_stats ost1 "write" 1
13829
13830         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13831         check_stats ost1 "read" 1
13832
13833         > $testdir/$tfile || error "truncate failed"
13834         check_stats ost1 "punch" 1
13835
13836         rm -f $testdir/$tfile || error "file remove failed"
13837         wait_delete_completed
13838         check_stats ost1 "destroy" 1
13839
13840         rm -rf $DIR/$tdir
13841 }
13842 run_test 133c "Verifying OST stats ========================================"
13843
13844 order_2() {
13845         local value=$1
13846         local orig=$value
13847         local order=1
13848
13849         while [ $value -ge 2 ]; do
13850                 order=$((order*2))
13851                 value=$((value/2))
13852         done
13853
13854         if [ $orig -gt $order ]; then
13855                 order=$((order*2))
13856         fi
13857         echo $order
13858 }
13859
13860 size_in_KMGT() {
13861     local value=$1
13862     local size=('K' 'M' 'G' 'T');
13863     local i=0
13864     local size_string=$value
13865
13866     while [ $value -ge 1024 ]; do
13867         if [ $i -gt 3 ]; then
13868             #T is the biggest unit we get here, if that is bigger,
13869             #just return XXXT
13870             size_string=${value}T
13871             break
13872         fi
13873         value=$((value >> 10))
13874         if [ $value -lt 1024 ]; then
13875             size_string=${value}${size[$i]}
13876             break
13877         fi
13878         i=$((i + 1))
13879     done
13880
13881     echo $size_string
13882 }
13883
13884 get_rename_size() {
13885         local size=$1
13886         local context=${2:-.}
13887         local sample=$(do_facet $SINGLEMDS $LCTL \
13888                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13889                 grep -A1 $context |
13890                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13891         echo $sample
13892 }
13893
13894 test_133d() {
13895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13896         remote_ost_nodsh && skip "remote OST with nodsh"
13897         remote_mds_nodsh && skip "remote MDS with nodsh"
13898         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13899                 skip_env "MDS doesn't support rename stats"
13900
13901         local testdir1=$DIR/${tdir}/stats_testdir1
13902         local testdir2=$DIR/${tdir}/stats_testdir2
13903         mkdir -p $DIR/${tdir}
13904
13905         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13906
13907         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13908         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13909
13910         createmany -o $testdir1/test 512 || error "createmany failed"
13911
13912         # check samedir rename size
13913         mv ${testdir1}/test0 ${testdir1}/test_0
13914
13915         local testdir1_size=$(ls -l $DIR/${tdir} |
13916                 awk '/stats_testdir1/ {print $5}')
13917         local testdir2_size=$(ls -l $DIR/${tdir} |
13918                 awk '/stats_testdir2/ {print $5}')
13919
13920         testdir1_size=$(order_2 $testdir1_size)
13921         testdir2_size=$(order_2 $testdir2_size)
13922
13923         testdir1_size=$(size_in_KMGT $testdir1_size)
13924         testdir2_size=$(size_in_KMGT $testdir2_size)
13925
13926         echo "source rename dir size: ${testdir1_size}"
13927         echo "target rename dir size: ${testdir2_size}"
13928
13929         local cmd="do_facet $SINGLEMDS $LCTL "
13930         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13931
13932         eval $cmd || error "$cmd failed"
13933         local samedir=$($cmd | grep 'same_dir')
13934         local same_sample=$(get_rename_size $testdir1_size)
13935         [ -z "$samedir" ] && error "samedir_rename_size count error"
13936         [[ $same_sample -eq 1 ]] ||
13937                 error "samedir_rename_size error $same_sample"
13938         echo "Check same dir rename stats success"
13939
13940         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13941
13942         # check crossdir rename size
13943         mv ${testdir1}/test_0 ${testdir2}/test_0
13944
13945         testdir1_size=$(ls -l $DIR/${tdir} |
13946                 awk '/stats_testdir1/ {print $5}')
13947         testdir2_size=$(ls -l $DIR/${tdir} |
13948                 awk '/stats_testdir2/ {print $5}')
13949
13950         testdir1_size=$(order_2 $testdir1_size)
13951         testdir2_size=$(order_2 $testdir2_size)
13952
13953         testdir1_size=$(size_in_KMGT $testdir1_size)
13954         testdir2_size=$(size_in_KMGT $testdir2_size)
13955
13956         echo "source rename dir size: ${testdir1_size}"
13957         echo "target rename dir size: ${testdir2_size}"
13958
13959         eval $cmd || error "$cmd failed"
13960         local crossdir=$($cmd | grep 'crossdir')
13961         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13962         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13963         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13964         [[ $src_sample -eq 1 ]] ||
13965                 error "crossdir_rename_size error $src_sample"
13966         [[ $tgt_sample -eq 1 ]] ||
13967                 error "crossdir_rename_size error $tgt_sample"
13968         echo "Check cross dir rename stats success"
13969         rm -rf $DIR/${tdir}
13970 }
13971 run_test 133d "Verifying rename_stats ========================================"
13972
13973 test_133e() {
13974         remote_mds_nodsh && skip "remote MDS with nodsh"
13975         remote_ost_nodsh && skip "remote OST with nodsh"
13976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13977
13978         local testdir=$DIR/${tdir}/stats_testdir
13979         local ctr f0 f1 bs=32768 count=42 sum
13980
13981         mkdir -p ${testdir} || error "mkdir failed"
13982
13983         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13984
13985         for ctr in {write,read}_bytes; do
13986                 sync
13987                 cancel_lru_locks osc
13988
13989                 do_facet ost1 $LCTL set_param -n \
13990                         "obdfilter.*.exports.clear=clear"
13991
13992                 if [ $ctr = write_bytes ]; then
13993                         f0=/dev/zero
13994                         f1=${testdir}/${tfile}
13995                 else
13996                         f0=${testdir}/${tfile}
13997                         f1=/dev/null
13998                 fi
13999
14000                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14001                         error "dd failed"
14002                 sync
14003                 cancel_lru_locks osc
14004
14005                 sum=$(do_facet ost1 $LCTL get_param \
14006                         "obdfilter.*.exports.*.stats" |
14007                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14008                                 $1 == ctr { sum += $7 }
14009                                 END { printf("%0.0f", sum) }')
14010
14011                 if ((sum != bs * count)); then
14012                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14013                 fi
14014         done
14015
14016         rm -rf $DIR/${tdir}
14017 }
14018 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14019
14020 test_133f() {
14021         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14022                 skip "too old lustre for get_param -R ($facet_ver)"
14023
14024         # verifying readability.
14025         $LCTL get_param -R '*' &> /dev/null
14026
14027         # Verifing writability with badarea_io.
14028         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14029         local skipped_params='force_lbug|changelog_mask|daemon_file'
14030         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14031                 egrep -v "$skipped_params" |
14032                 xargs -n 1 find $proc_dirs -name |
14033                 xargs -n 1 badarea_io ||
14034                 error "client badarea_io failed"
14035
14036         # remount the FS in case writes/reads /proc break the FS
14037         cleanup || error "failed to unmount"
14038         setup || error "failed to setup"
14039 }
14040 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14041
14042 test_133g() {
14043         remote_mds_nodsh && skip "remote MDS with nodsh"
14044         remote_ost_nodsh && skip "remote OST with nodsh"
14045
14046         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14047         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14048         local facet
14049         for facet in mds1 ost1; do
14050                 local facet_ver=$(lustre_version_code $facet)
14051                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14052                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14053                 else
14054                         log "$facet: too old lustre for get_param -R"
14055                 fi
14056                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14057                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14058                                 tr -d = | egrep -v $skipped_params |
14059                                 xargs -n 1 find $proc_dirs -name |
14060                                 xargs -n 1 badarea_io" ||
14061                                         error "$facet badarea_io failed"
14062                 else
14063                         skip_noexit "$facet: too old lustre for get_param -R"
14064                 fi
14065         done
14066
14067         # remount the FS in case writes/reads /proc break the FS
14068         cleanup || error "failed to unmount"
14069         setup || error "failed to setup"
14070 }
14071 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14072
14073 test_133h() {
14074         remote_mds_nodsh && skip "remote MDS with nodsh"
14075         remote_ost_nodsh && skip "remote OST with nodsh"
14076         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14077                 skip "Need MDS version at least 2.9.54"
14078
14079         local facet
14080         for facet in client mds1 ost1; do
14081                 # Get the list of files that are missing the terminating newline
14082                 local plist=$(do_facet $facet
14083                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14084                 local ent
14085                 for ent in $plist; do
14086                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14087                                 awk -v FS='\v' -v RS='\v\v' \
14088                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14089                                         print FILENAME}'" 2>/dev/null)
14090                         [ -z $missing ] || {
14091                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14092                                 error "file does not end with newline: $facet-$ent"
14093                         }
14094                 done
14095         done
14096 }
14097 run_test 133h "Proc files should end with newlines"
14098
14099 test_134a() {
14100         remote_mds_nodsh && skip "remote MDS with nodsh"
14101         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14102                 skip "Need MDS version at least 2.7.54"
14103
14104         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14105         cancel_lru_locks mdc
14106
14107         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14108         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14109         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14110
14111         local nr=1000
14112         createmany -o $DIR/$tdir/f $nr ||
14113                 error "failed to create $nr files in $DIR/$tdir"
14114         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14115
14116         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14117         do_facet mds1 $LCTL set_param fail_loc=0x327
14118         do_facet mds1 $LCTL set_param fail_val=500
14119         touch $DIR/$tdir/m
14120
14121         echo "sleep 10 seconds ..."
14122         sleep 10
14123         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14124
14125         do_facet mds1 $LCTL set_param fail_loc=0
14126         do_facet mds1 $LCTL set_param fail_val=0
14127         [ $lck_cnt -lt $unused ] ||
14128                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14129
14130         rm $DIR/$tdir/m
14131         unlinkmany $DIR/$tdir/f $nr
14132 }
14133 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14134
14135 test_134b() {
14136         remote_mds_nodsh && skip "remote MDS with nodsh"
14137         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14138                 skip "Need MDS version at least 2.7.54"
14139
14140         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14141         cancel_lru_locks mdc
14142
14143         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14144                         ldlm.lock_reclaim_threshold_mb)
14145         # disable reclaim temporarily
14146         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14147
14148         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14149         do_facet mds1 $LCTL set_param fail_loc=0x328
14150         do_facet mds1 $LCTL set_param fail_val=500
14151
14152         $LCTL set_param debug=+trace
14153
14154         local nr=600
14155         createmany -o $DIR/$tdir/f $nr &
14156         local create_pid=$!
14157
14158         echo "Sleep $TIMEOUT seconds ..."
14159         sleep $TIMEOUT
14160         if ! ps -p $create_pid  > /dev/null 2>&1; then
14161                 do_facet mds1 $LCTL set_param fail_loc=0
14162                 do_facet mds1 $LCTL set_param fail_val=0
14163                 do_facet mds1 $LCTL set_param \
14164                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14165                 error "createmany finished incorrectly!"
14166         fi
14167         do_facet mds1 $LCTL set_param fail_loc=0
14168         do_facet mds1 $LCTL set_param fail_val=0
14169         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14170         wait $create_pid || return 1
14171
14172         unlinkmany $DIR/$tdir/f $nr
14173 }
14174 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14175
14176 test_135() {
14177         remote_mds_nodsh && skip "remote MDS with nodsh"
14178         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14179                 skip "Need MDS version at least 2.13.50"
14180         local fname
14181
14182         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14183
14184 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14185         #set only one record at plain llog
14186         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14187
14188         #fill already existed plain llog each 64767
14189         #wrapping whole catalog
14190         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14191
14192         createmany -o $DIR/$tdir/$tfile_ 64700
14193         for (( i = 0; i < 64700; i = i + 2 ))
14194         do
14195                 rm $DIR/$tdir/$tfile_$i &
14196                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14197                 local pid=$!
14198                 wait $pid
14199         done
14200
14201         #waiting osp synchronization
14202         wait_delete_completed
14203 }
14204 run_test 135 "Race catalog processing"
14205
14206 test_136() {
14207         remote_mds_nodsh && skip "remote MDS with nodsh"
14208         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14209                 skip "Need MDS version at least 2.13.50"
14210         local fname
14211
14212         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14213         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14214         #set only one record at plain llog
14215 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14216         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14217
14218         #fill already existed 2 plain llogs each 64767
14219         #wrapping whole catalog
14220         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14221         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14222         wait_delete_completed
14223
14224         createmany -o $DIR/$tdir/$tfile_ 10
14225         sleep 25
14226
14227         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14228         for (( i = 0; i < 10; i = i + 3 ))
14229         do
14230                 rm $DIR/$tdir/$tfile_$i &
14231                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14232                 local pid=$!
14233                 wait $pid
14234                 sleep 7
14235                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14236         done
14237
14238         #waiting osp synchronization
14239         wait_delete_completed
14240 }
14241 run_test 136 "Race catalog processing 2"
14242
14243 test_140() { #bug-17379
14244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14245
14246         test_mkdir $DIR/$tdir
14247         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14248         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14249
14250         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14251         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14252         local i=0
14253         while i=$((i + 1)); do
14254                 test_mkdir $i
14255                 cd $i || error "Changing to $i"
14256                 ln -s ../stat stat || error "Creating stat symlink"
14257                 # Read the symlink until ELOOP present,
14258                 # not LBUGing the system is considered success,
14259                 # we didn't overrun the stack.
14260                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14261                 if [ $ret -ne 0 ]; then
14262                         if [ $ret -eq 40 ]; then
14263                                 break  # -ELOOP
14264                         else
14265                                 error "Open stat symlink"
14266                                         return
14267                         fi
14268                 fi
14269         done
14270         i=$((i - 1))
14271         echo "The symlink depth = $i"
14272         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14273                 error "Invalid symlink depth"
14274
14275         # Test recursive symlink
14276         ln -s symlink_self symlink_self
14277         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14278         echo "open symlink_self returns $ret"
14279         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14280 }
14281 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14282
14283 test_150a() {
14284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14285
14286         local TF="$TMP/$tfile"
14287
14288         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14289         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14290         cp $TF $DIR/$tfile
14291         cancel_lru_locks $OSC
14292         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14293         remount_client $MOUNT
14294         df -P $MOUNT
14295         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14296
14297         $TRUNCATE $TF 6000
14298         $TRUNCATE $DIR/$tfile 6000
14299         cancel_lru_locks $OSC
14300         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14301
14302         echo "12345" >>$TF
14303         echo "12345" >>$DIR/$tfile
14304         cancel_lru_locks $OSC
14305         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14306
14307         echo "12345" >>$TF
14308         echo "12345" >>$DIR/$tfile
14309         cancel_lru_locks $OSC
14310         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14311 }
14312 run_test 150a "truncate/append tests"
14313
14314 test_150b() {
14315         check_set_fallocate_or_skip
14316
14317         touch $DIR/$tfile
14318         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14319         check_fallocate $DIR/$tfile || error "fallocate failed"
14320 }
14321 run_test 150b "Verify fallocate (prealloc) functionality"
14322
14323 test_150bb() {
14324         check_set_fallocate_or_skip
14325
14326         touch $DIR/$tfile
14327         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14328         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14329         > $DIR/$tfile
14330         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14331         # precomputed md5sum for 20MB of zeroes
14332         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14333         local sum=($(md5sum $DIR/$tfile))
14334
14335         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14336
14337         check_set_fallocate 1
14338
14339         > $DIR/$tfile
14340         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14341         sum=($(md5sum $DIR/$tfile))
14342
14343         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14344 }
14345 run_test 150bb "Verify fallocate modes both zero space"
14346
14347 test_150c() {
14348         check_set_fallocate_or_skip
14349         local striping="-c2"
14350
14351         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14352         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14353         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14354         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14355         local want=$((OSTCOUNT * 1048576))
14356
14357         # Must allocate all requested space, not more than 5% extra
14358         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14359                 error "bytes $bytes is not $want"
14360
14361         rm -f $DIR/$tfile
14362
14363         echo "verify fallocate on PFL file"
14364
14365         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14366
14367         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14368                 error "Create $DIR/$tfile failed"
14369         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14370                         error "fallocate failed"
14371         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14372         want=$((512 * 1048576))
14373
14374         # Must allocate all requested space, not more than 5% extra
14375         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14376                 error "bytes $bytes is not $want"
14377 }
14378 run_test 150c "Verify fallocate Size and Blocks"
14379
14380 test_150d() {
14381         check_set_fallocate_or_skip
14382         local striping="-c2"
14383
14384         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14385
14386         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14387         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14388                 error "setstripe failed"
14389         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14390         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14391         local want=$((OSTCOUNT * 1048576))
14392
14393         # Must allocate all requested space, not more than 5% extra
14394         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14395                 error "bytes $bytes is not $want"
14396 }
14397 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14398
14399 test_150e() {
14400         check_set_fallocate_or_skip
14401
14402         echo "df before:"
14403         $LFS df
14404         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14405         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14406                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14407
14408         # Find OST with Minimum Size
14409         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14410                        sort -un | head -1)
14411
14412         # Get 100MB per OST of the available space to reduce run time
14413         # else 60% of the available space if we are running SLOW tests
14414         if [ $SLOW == "no" ]; then
14415                 local space=$((1024 * 100 * OSTCOUNT))
14416         else
14417                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14418         fi
14419
14420         fallocate -l${space}k $DIR/$tfile ||
14421                 error "fallocate ${space}k $DIR/$tfile failed"
14422         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14423
14424         # get size immediately after fallocate. This should be correctly
14425         # updated
14426         local size=$(stat -c '%s' $DIR/$tfile)
14427         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14428
14429         # Sleep for a while for statfs to get updated. And not pull from cache.
14430         sleep 2
14431
14432         echo "df after fallocate:"
14433         $LFS df
14434
14435         (( size / 1024 == space )) || error "size $size != requested $space"
14436         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14437                 error "used $used < space $space"
14438
14439         rm $DIR/$tfile || error "rm failed"
14440         sync
14441         wait_delete_completed
14442
14443         echo "df after unlink:"
14444         $LFS df
14445 }
14446 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14447
14448 test_150f() {
14449         local size
14450         local blocks
14451         local want_size_before=20480 # in bytes
14452         local want_blocks_before=40 # 512 sized blocks
14453         local want_blocks_after=24  # 512 sized blocks
14454         local length=$(((want_blocks_before - want_blocks_after) * 512))
14455
14456         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14457                 skip "need at least 2.14.0 for fallocate punch"
14458
14459         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14460                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14461         fi
14462
14463         check_set_fallocate_or_skip
14464         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14465
14466         [[ "x$DOM" == "xyes" ]] &&
14467                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14468
14469         echo "Verify fallocate punch: Range within the file range"
14470         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14471                 error "dd failed for bs 4096 and count 5"
14472
14473         # Call fallocate with punch range which is within the file range
14474         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14475                 error "fallocate failed: offset 4096 and length $length"
14476         # client must see changes immediately after fallocate
14477         size=$(stat -c '%s' $DIR/$tfile)
14478         blocks=$(stat -c '%b' $DIR/$tfile)
14479
14480         # Verify punch worked.
14481         (( blocks == want_blocks_after )) ||
14482                 error "punch failed: blocks $blocks != $want_blocks_after"
14483
14484         (( size == want_size_before )) ||
14485                 error "punch failed: size $size != $want_size_before"
14486
14487         # Verify there is hole in file
14488         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14489         # precomputed md5sum
14490         local expect="4a9a834a2db02452929c0a348273b4aa"
14491
14492         cksum=($(md5sum $DIR/$tfile))
14493         [[ "${cksum[0]}" == "$expect" ]] ||
14494                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14495
14496         # Start second sub-case for fallocate punch.
14497         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14498         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14499                 error "dd failed for bs 4096 and count 5"
14500
14501         # Punch range less than block size will have no change in block count
14502         want_blocks_after=40  # 512 sized blocks
14503
14504         # Punch overlaps two blocks and less than blocksize
14505         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14506                 error "fallocate failed: offset 4000 length 3000"
14507         size=$(stat -c '%s' $DIR/$tfile)
14508         blocks=$(stat -c '%b' $DIR/$tfile)
14509
14510         # Verify punch worked.
14511         (( blocks == want_blocks_after )) ||
14512                 error "punch failed: blocks $blocks != $want_blocks_after"
14513
14514         (( size == want_size_before )) ||
14515                 error "punch failed: size $size != $want_size_before"
14516
14517         # Verify if range is really zero'ed out. We expect Zeros.
14518         # precomputed md5sum
14519         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14520         cksum=($(md5sum $DIR/$tfile))
14521         [[ "${cksum[0]}" == "$expect" ]] ||
14522                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14523 }
14524 run_test 150f "Verify fallocate punch functionality"
14525
14526 test_150g() {
14527         local space
14528         local size
14529         local blocks
14530         local blocks_after
14531         local size_after
14532         local BS=4096 # Block size in bytes
14533
14534         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14535                 skip "need at least 2.14.0 for fallocate punch"
14536
14537         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14538                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14539         fi
14540
14541         check_set_fallocate_or_skip
14542         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14543
14544         if [[ "x$DOM" == "xyes" ]]; then
14545                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14546                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14547         else
14548                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14549                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14550         fi
14551
14552         # Get 100MB per OST of the available space to reduce run time
14553         # else 60% of the available space if we are running SLOW tests
14554         if [ $SLOW == "no" ]; then
14555                 space=$((1024 * 100 * OSTCOUNT))
14556         else
14557                 # Find OST with Minimum Size
14558                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14559                         sort -un | head -1)
14560                 echo "min size OST: $space"
14561                 space=$(((space * 60)/100 * OSTCOUNT))
14562         fi
14563         # space in 1k units, round to 4k blocks
14564         local blkcount=$((space * 1024 / $BS))
14565
14566         echo "Verify fallocate punch: Very large Range"
14567         fallocate -l${space}k $DIR/$tfile ||
14568                 error "fallocate ${space}k $DIR/$tfile failed"
14569         # write 1M at the end, start and in the middle
14570         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14571                 error "dd failed: bs $BS count 256"
14572         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14573                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14574         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14575                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14576
14577         # Gather stats.
14578         size=$(stat -c '%s' $DIR/$tfile)
14579
14580         # gather punch length.
14581         local punch_size=$((size - (BS * 2)))
14582
14583         echo "punch_size = $punch_size"
14584         echo "size - punch_size: $((size - punch_size))"
14585         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14586
14587         # Call fallocate to punch all except 2 blocks. We leave the
14588         # first and the last block
14589         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14590         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14591                 error "fallocate failed: offset $BS length $punch_size"
14592
14593         size_after=$(stat -c '%s' $DIR/$tfile)
14594         blocks_after=$(stat -c '%b' $DIR/$tfile)
14595
14596         # Verify punch worked.
14597         # Size should be kept
14598         (( size == size_after )) ||
14599                 error "punch failed: size $size != $size_after"
14600
14601         # two 4k data blocks to remain plus possible 1 extra extent block
14602         (( blocks_after <= ((BS / 512) * 3) )) ||
14603                 error "too many blocks remains: $blocks_after"
14604
14605         # Verify that file has hole between the first and the last blocks
14606         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14607         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14608
14609         echo "Hole at [$hole_start, $hole_end)"
14610         (( hole_start == BS )) ||
14611                 error "no hole at offset $BS after punch"
14612
14613         (( hole_end == BS + punch_size )) ||
14614                 error "data at offset $hole_end < $((BS + punch_size))"
14615 }
14616 run_test 150g "Verify fallocate punch on large range"
14617
14618 #LU-2902 roc_hit was not able to read all values from lproc
14619 function roc_hit_init() {
14620         local list=$(comma_list $(osts_nodes))
14621         local dir=$DIR/$tdir-check
14622         local file=$dir/$tfile
14623         local BEFORE
14624         local AFTER
14625         local idx
14626
14627         test_mkdir $dir
14628         #use setstripe to do a write to every ost
14629         for i in $(seq 0 $((OSTCOUNT-1))); do
14630                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14631                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14632                 idx=$(printf %04x $i)
14633                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14634                         awk '$1 == "cache_access" {sum += $7}
14635                                 END { printf("%0.0f", sum) }')
14636
14637                 cancel_lru_locks osc
14638                 cat $file >/dev/null
14639
14640                 AFTER=$(get_osd_param $list *OST*$idx stats |
14641                         awk '$1 == "cache_access" {sum += $7}
14642                                 END { printf("%0.0f", sum) }')
14643
14644                 echo BEFORE:$BEFORE AFTER:$AFTER
14645                 if ! let "AFTER - BEFORE == 4"; then
14646                         rm -rf $dir
14647                         error "roc_hit is not safe to use"
14648                 fi
14649                 rm $file
14650         done
14651
14652         rm -rf $dir
14653 }
14654
14655 function roc_hit() {
14656         local list=$(comma_list $(osts_nodes))
14657         echo $(get_osd_param $list '' stats |
14658                 awk '$1 == "cache_hit" {sum += $7}
14659                         END { printf("%0.0f", sum) }')
14660 }
14661
14662 function set_cache() {
14663         local on=1
14664
14665         if [ "$2" == "off" ]; then
14666                 on=0;
14667         fi
14668         local list=$(comma_list $(osts_nodes))
14669         set_osd_param $list '' $1_cache_enable $on
14670
14671         cancel_lru_locks osc
14672 }
14673
14674 test_151() {
14675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14676         remote_ost_nodsh && skip "remote OST with nodsh"
14677
14678         local CPAGES=3
14679         local list=$(comma_list $(osts_nodes))
14680
14681         # check whether obdfilter is cache capable at all
14682         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14683                 skip "not cache-capable obdfilter"
14684         fi
14685
14686         # check cache is enabled on all obdfilters
14687         if get_osd_param $list '' read_cache_enable | grep 0; then
14688                 skip "oss cache is disabled"
14689         fi
14690
14691         set_osd_param $list '' writethrough_cache_enable 1
14692
14693         # check write cache is enabled on all obdfilters
14694         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14695                 skip "oss write cache is NOT enabled"
14696         fi
14697
14698         roc_hit_init
14699
14700         #define OBD_FAIL_OBD_NO_LRU  0x609
14701         do_nodes $list $LCTL set_param fail_loc=0x609
14702
14703         # pages should be in the case right after write
14704         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14705                 error "dd failed"
14706
14707         local BEFORE=$(roc_hit)
14708         cancel_lru_locks osc
14709         cat $DIR/$tfile >/dev/null
14710         local AFTER=$(roc_hit)
14711
14712         do_nodes $list $LCTL set_param fail_loc=0
14713
14714         if ! let "AFTER - BEFORE == CPAGES"; then
14715                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14716         fi
14717
14718         cancel_lru_locks osc
14719         # invalidates OST cache
14720         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14721         set_osd_param $list '' read_cache_enable 0
14722         cat $DIR/$tfile >/dev/null
14723
14724         # now data shouldn't be found in the cache
14725         BEFORE=$(roc_hit)
14726         cancel_lru_locks osc
14727         cat $DIR/$tfile >/dev/null
14728         AFTER=$(roc_hit)
14729         if let "AFTER - BEFORE != 0"; then
14730                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14731         fi
14732
14733         set_osd_param $list '' read_cache_enable 1
14734         rm -f $DIR/$tfile
14735 }
14736 run_test 151 "test cache on oss and controls ==============================="
14737
14738 test_152() {
14739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14740
14741         local TF="$TMP/$tfile"
14742
14743         # simulate ENOMEM during write
14744 #define OBD_FAIL_OST_NOMEM      0x226
14745         lctl set_param fail_loc=0x80000226
14746         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14747         cp $TF $DIR/$tfile
14748         sync || error "sync failed"
14749         lctl set_param fail_loc=0
14750
14751         # discard client's cache
14752         cancel_lru_locks osc
14753
14754         # simulate ENOMEM during read
14755         lctl set_param fail_loc=0x80000226
14756         cmp $TF $DIR/$tfile || error "cmp failed"
14757         lctl set_param fail_loc=0
14758
14759         rm -f $TF
14760 }
14761 run_test 152 "test read/write with enomem ============================"
14762
14763 test_153() {
14764         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14765 }
14766 run_test 153 "test if fdatasync does not crash ======================="
14767
14768 dot_lustre_fid_permission_check() {
14769         local fid=$1
14770         local ffid=$MOUNT/.lustre/fid/$fid
14771         local test_dir=$2
14772
14773         echo "stat fid $fid"
14774         stat $ffid > /dev/null || error "stat $ffid failed."
14775         echo "touch fid $fid"
14776         touch $ffid || error "touch $ffid failed."
14777         echo "write to fid $fid"
14778         cat /etc/hosts > $ffid || error "write $ffid failed."
14779         echo "read fid $fid"
14780         diff /etc/hosts $ffid || error "read $ffid failed."
14781         echo "append write to fid $fid"
14782         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14783         echo "rename fid $fid"
14784         mv $ffid $test_dir/$tfile.1 &&
14785                 error "rename $ffid to $tfile.1 should fail."
14786         touch $test_dir/$tfile.1
14787         mv $test_dir/$tfile.1 $ffid &&
14788                 error "rename $tfile.1 to $ffid should fail."
14789         rm -f $test_dir/$tfile.1
14790         echo "truncate fid $fid"
14791         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14792         echo "link fid $fid"
14793         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14794         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14795                 echo "setfacl fid $fid"
14796                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14797                 echo "getfacl fid $fid"
14798                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14799         fi
14800         echo "unlink fid $fid"
14801         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14802         echo "mknod fid $fid"
14803         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14804
14805         fid=[0xf00000400:0x1:0x0]
14806         ffid=$MOUNT/.lustre/fid/$fid
14807
14808         echo "stat non-exist fid $fid"
14809         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14810         echo "write to non-exist fid $fid"
14811         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14812         echo "link new fid $fid"
14813         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14814
14815         mkdir -p $test_dir/$tdir
14816         touch $test_dir/$tdir/$tfile
14817         fid=$($LFS path2fid $test_dir/$tdir)
14818         rc=$?
14819         [ $rc -ne 0 ] &&
14820                 error "error: could not get fid for $test_dir/$dir/$tfile."
14821
14822         ffid=$MOUNT/.lustre/fid/$fid
14823
14824         echo "ls $fid"
14825         ls $ffid > /dev/null || error "ls $ffid failed."
14826         echo "touch $fid/$tfile.1"
14827         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14828
14829         echo "touch $MOUNT/.lustre/fid/$tfile"
14830         touch $MOUNT/.lustre/fid/$tfile && \
14831                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14832
14833         echo "setxattr to $MOUNT/.lustre/fid"
14834         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14835
14836         echo "listxattr for $MOUNT/.lustre/fid"
14837         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14838
14839         echo "delxattr from $MOUNT/.lustre/fid"
14840         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14841
14842         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14843         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14844                 error "touch invalid fid should fail."
14845
14846         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14847         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14848                 error "touch non-normal fid should fail."
14849
14850         echo "rename $tdir to $MOUNT/.lustre/fid"
14851         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14852                 error "rename to $MOUNT/.lustre/fid should fail."
14853
14854         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14855         then            # LU-3547
14856                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14857                 local new_obf_mode=777
14858
14859                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14860                 chmod $new_obf_mode $DIR/.lustre/fid ||
14861                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14862
14863                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14864                 [ $obf_mode -eq $new_obf_mode ] ||
14865                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14866
14867                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14868                 chmod $old_obf_mode $DIR/.lustre/fid ||
14869                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14870         fi
14871
14872         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14873         fid=$($LFS path2fid $test_dir/$tfile-2)
14874
14875         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14876         then # LU-5424
14877                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14878                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14879                         error "create lov data thru .lustre failed"
14880         fi
14881         echo "cp /etc/passwd $test_dir/$tfile-2"
14882         cp /etc/passwd $test_dir/$tfile-2 ||
14883                 error "copy to $test_dir/$tfile-2 failed."
14884         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14885         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14886                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14887
14888         rm -rf $test_dir/tfile.lnk
14889         rm -rf $test_dir/$tfile-2
14890 }
14891
14892 test_154A() {
14893         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14894                 skip "Need MDS version at least 2.4.1"
14895
14896         local tf=$DIR/$tfile
14897         touch $tf
14898
14899         local fid=$($LFS path2fid $tf)
14900         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14901
14902         # check that we get the same pathname back
14903         local rootpath
14904         local found
14905         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14906                 echo "$rootpath $fid"
14907                 found=$($LFS fid2path $rootpath "$fid")
14908                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14909                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14910         done
14911
14912         # check wrong root path format
14913         rootpath=$MOUNT"_wrong"
14914         found=$($LFS fid2path $rootpath "$fid")
14915         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14916 }
14917 run_test 154A "lfs path2fid and fid2path basic checks"
14918
14919 test_154B() {
14920         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14921                 skip "Need MDS version at least 2.4.1"
14922
14923         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14924         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14925         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14926         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14927
14928         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14929         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14930
14931         # check that we get the same pathname
14932         echo "PFID: $PFID, name: $name"
14933         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14934         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14935         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14936                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14937
14938         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14939 }
14940 run_test 154B "verify the ll_decode_linkea tool"
14941
14942 test_154a() {
14943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14944         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14945         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14946                 skip "Need MDS version at least 2.2.51"
14947         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14948
14949         cp /etc/hosts $DIR/$tfile
14950
14951         fid=$($LFS path2fid $DIR/$tfile)
14952         rc=$?
14953         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14954
14955         dot_lustre_fid_permission_check "$fid" $DIR ||
14956                 error "dot lustre permission check $fid failed"
14957
14958         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14959
14960         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14961
14962         touch $MOUNT/.lustre/file &&
14963                 error "creation is not allowed under .lustre"
14964
14965         mkdir $MOUNT/.lustre/dir &&
14966                 error "mkdir is not allowed under .lustre"
14967
14968         rm -rf $DIR/$tfile
14969 }
14970 run_test 154a "Open-by-FID"
14971
14972 test_154b() {
14973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14974         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14976         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14977                 skip "Need MDS version at least 2.2.51"
14978
14979         local remote_dir=$DIR/$tdir/remote_dir
14980         local MDTIDX=1
14981         local rc=0
14982
14983         mkdir -p $DIR/$tdir
14984         $LFS mkdir -i $MDTIDX $remote_dir ||
14985                 error "create remote directory failed"
14986
14987         cp /etc/hosts $remote_dir/$tfile
14988
14989         fid=$($LFS path2fid $remote_dir/$tfile)
14990         rc=$?
14991         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14992
14993         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14994                 error "dot lustre permission check $fid failed"
14995         rm -rf $DIR/$tdir
14996 }
14997 run_test 154b "Open-by-FID for remote directory"
14998
14999 test_154c() {
15000         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15001                 skip "Need MDS version at least 2.4.1"
15002
15003         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15004         local FID1=$($LFS path2fid $DIR/$tfile.1)
15005         local FID2=$($LFS path2fid $DIR/$tfile.2)
15006         local FID3=$($LFS path2fid $DIR/$tfile.3)
15007
15008         local N=1
15009         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15010                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15011                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15012                 local want=FID$N
15013                 [ "$FID" = "${!want}" ] ||
15014                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15015                 N=$((N + 1))
15016         done
15017
15018         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15019         do
15020                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15021                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15022                 N=$((N + 1))
15023         done
15024 }
15025 run_test 154c "lfs path2fid and fid2path multiple arguments"
15026
15027 test_154d() {
15028         remote_mds_nodsh && skip "remote MDS with nodsh"
15029         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15030                 skip "Need MDS version at least 2.5.53"
15031
15032         if remote_mds; then
15033                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15034         else
15035                 nid="0@lo"
15036         fi
15037         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15038         local fd
15039         local cmd
15040
15041         rm -f $DIR/$tfile
15042         touch $DIR/$tfile
15043
15044         local fid=$($LFS path2fid $DIR/$tfile)
15045         # Open the file
15046         fd=$(free_fd)
15047         cmd="exec $fd<$DIR/$tfile"
15048         eval $cmd
15049         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15050         echo "$fid_list" | grep "$fid"
15051         rc=$?
15052
15053         cmd="exec $fd>/dev/null"
15054         eval $cmd
15055         if [ $rc -ne 0 ]; then
15056                 error "FID $fid not found in open files list $fid_list"
15057         fi
15058 }
15059 run_test 154d "Verify open file fid"
15060
15061 test_154e()
15062 {
15063         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15064                 skip "Need MDS version at least 2.6.50"
15065
15066         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15067                 error ".lustre returned by readdir"
15068         fi
15069 }
15070 run_test 154e ".lustre is not returned by readdir"
15071
15072 test_154f() {
15073         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15074
15075         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15076         mkdir_on_mdt0 $DIR/$tdir
15077         # test dirs inherit from its stripe
15078         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15079         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15080         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15081         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15082         touch $DIR/f
15083
15084         # get fid of parents
15085         local FID0=$($LFS path2fid $DIR/$tdir)
15086         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15087         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15088         local FID3=$($LFS path2fid $DIR)
15089
15090         # check that path2fid --parents returns expected <parent_fid>/name
15091         # 1) test for a directory (single parent)
15092         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15093         [ "$parent" == "$FID0/foo1" ] ||
15094                 error "expected parent: $FID0/foo1, got: $parent"
15095
15096         # 2) test for a file with nlink > 1 (multiple parents)
15097         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15098         echo "$parent" | grep -F "$FID1/$tfile" ||
15099                 error "$FID1/$tfile not returned in parent list"
15100         echo "$parent" | grep -F "$FID2/link" ||
15101                 error "$FID2/link not returned in parent list"
15102
15103         # 3) get parent by fid
15104         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15105         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15106         echo "$parent" | grep -F "$FID1/$tfile" ||
15107                 error "$FID1/$tfile not returned in parent list (by fid)"
15108         echo "$parent" | grep -F "$FID2/link" ||
15109                 error "$FID2/link not returned in parent list (by fid)"
15110
15111         # 4) test for entry in root directory
15112         parent=$($LFS path2fid --parents $DIR/f)
15113         echo "$parent" | grep -F "$FID3/f" ||
15114                 error "$FID3/f not returned in parent list"
15115
15116         # 5) test it on root directory
15117         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15118                 error "$MOUNT should not have parents"
15119
15120         # enable xattr caching and check that linkea is correctly updated
15121         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15122         save_lustre_params client "llite.*.xattr_cache" > $save
15123         lctl set_param llite.*.xattr_cache 1
15124
15125         # 6.1) linkea update on rename
15126         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15127
15128         # get parents by fid
15129         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15130         # foo1 should no longer be returned in parent list
15131         echo "$parent" | grep -F "$FID1" &&
15132                 error "$FID1 should no longer be in parent list"
15133         # the new path should appear
15134         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15135                 error "$FID2/$tfile.moved is not in parent list"
15136
15137         # 6.2) linkea update on unlink
15138         rm -f $DIR/$tdir/foo2/link
15139         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15140         # foo2/link should no longer be returned in parent list
15141         echo "$parent" | grep -F "$FID2/link" &&
15142                 error "$FID2/link should no longer be in parent list"
15143         true
15144
15145         rm -f $DIR/f
15146         restore_lustre_params < $save
15147         rm -f $save
15148 }
15149 run_test 154f "get parent fids by reading link ea"
15150
15151 test_154g()
15152 {
15153         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15154         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15155            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15156                 skip "Need MDS version at least 2.6.92"
15157
15158         mkdir_on_mdt0 $DIR/$tdir
15159         llapi_fid_test -d $DIR/$tdir
15160 }
15161 run_test 154g "various llapi FID tests"
15162
15163 test_155_small_load() {
15164     local temp=$TMP/$tfile
15165     local file=$DIR/$tfile
15166
15167     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15168         error "dd of=$temp bs=6096 count=1 failed"
15169     cp $temp $file
15170     cancel_lru_locks $OSC
15171     cmp $temp $file || error "$temp $file differ"
15172
15173     $TRUNCATE $temp 6000
15174     $TRUNCATE $file 6000
15175     cmp $temp $file || error "$temp $file differ (truncate1)"
15176
15177     echo "12345" >>$temp
15178     echo "12345" >>$file
15179     cmp $temp $file || error "$temp $file differ (append1)"
15180
15181     echo "12345" >>$temp
15182     echo "12345" >>$file
15183     cmp $temp $file || error "$temp $file differ (append2)"
15184
15185     rm -f $temp $file
15186     true
15187 }
15188
15189 test_155_big_load() {
15190         remote_ost_nodsh && skip "remote OST with nodsh"
15191
15192         local temp=$TMP/$tfile
15193         local file=$DIR/$tfile
15194
15195         free_min_max
15196         local cache_size=$(do_facet ost$((MAXI+1)) \
15197                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15198         local large_file_size=$((cache_size * 2))
15199
15200         echo "OSS cache size: $cache_size KB"
15201         echo "Large file size: $large_file_size KB"
15202
15203         [ $MAXV -le $large_file_size ] &&
15204                 skip_env "max available OST size needs > $large_file_size KB"
15205
15206         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15207
15208         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15209                 error "dd of=$temp bs=$large_file_size count=1k failed"
15210         cp $temp $file
15211         ls -lh $temp $file
15212         cancel_lru_locks osc
15213         cmp $temp $file || error "$temp $file differ"
15214
15215         rm -f $temp $file
15216         true
15217 }
15218
15219 save_writethrough() {
15220         local facets=$(get_facets OST)
15221
15222         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15223 }
15224
15225 test_155a() {
15226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15227
15228         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15229
15230         save_writethrough $p
15231
15232         set_cache read on
15233         set_cache writethrough on
15234         test_155_small_load
15235         restore_lustre_params < $p
15236         rm -f $p
15237 }
15238 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15239
15240 test_155b() {
15241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15242
15243         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15244
15245         save_writethrough $p
15246
15247         set_cache read on
15248         set_cache writethrough off
15249         test_155_small_load
15250         restore_lustre_params < $p
15251         rm -f $p
15252 }
15253 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15254
15255 test_155c() {
15256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15257
15258         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15259
15260         save_writethrough $p
15261
15262         set_cache read off
15263         set_cache writethrough on
15264         test_155_small_load
15265         restore_lustre_params < $p
15266         rm -f $p
15267 }
15268 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15269
15270 test_155d() {
15271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15272
15273         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15274
15275         save_writethrough $p
15276
15277         set_cache read off
15278         set_cache writethrough off
15279         test_155_small_load
15280         restore_lustre_params < $p
15281         rm -f $p
15282 }
15283 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15284
15285 test_155e() {
15286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15287
15288         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15289
15290         save_writethrough $p
15291
15292         set_cache read on
15293         set_cache writethrough on
15294         test_155_big_load
15295         restore_lustre_params < $p
15296         rm -f $p
15297 }
15298 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15299
15300 test_155f() {
15301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15302
15303         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15304
15305         save_writethrough $p
15306
15307         set_cache read on
15308         set_cache writethrough off
15309         test_155_big_load
15310         restore_lustre_params < $p
15311         rm -f $p
15312 }
15313 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15314
15315 test_155g() {
15316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15317
15318         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15319
15320         save_writethrough $p
15321
15322         set_cache read off
15323         set_cache writethrough on
15324         test_155_big_load
15325         restore_lustre_params < $p
15326         rm -f $p
15327 }
15328 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15329
15330 test_155h() {
15331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15332
15333         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15334
15335         save_writethrough $p
15336
15337         set_cache read off
15338         set_cache writethrough off
15339         test_155_big_load
15340         restore_lustre_params < $p
15341         rm -f $p
15342 }
15343 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15344
15345 test_156() {
15346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15347         remote_ost_nodsh && skip "remote OST with nodsh"
15348         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15349                 skip "stats not implemented on old servers"
15350         [ "$ost1_FSTYPE" = "zfs" ] &&
15351                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15352
15353         local CPAGES=3
15354         local BEFORE
15355         local AFTER
15356         local file="$DIR/$tfile"
15357         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15358
15359         save_writethrough $p
15360         roc_hit_init
15361
15362         log "Turn on read and write cache"
15363         set_cache read on
15364         set_cache writethrough on
15365
15366         log "Write data and read it back."
15367         log "Read should be satisfied from the cache."
15368         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15369         BEFORE=$(roc_hit)
15370         cancel_lru_locks osc
15371         cat $file >/dev/null
15372         AFTER=$(roc_hit)
15373         if ! let "AFTER - BEFORE == CPAGES"; then
15374                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15375         else
15376                 log "cache hits: before: $BEFORE, after: $AFTER"
15377         fi
15378
15379         log "Read again; it should be satisfied from the cache."
15380         BEFORE=$AFTER
15381         cancel_lru_locks osc
15382         cat $file >/dev/null
15383         AFTER=$(roc_hit)
15384         if ! let "AFTER - BEFORE == CPAGES"; then
15385                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15386         else
15387                 log "cache hits:: before: $BEFORE, after: $AFTER"
15388         fi
15389
15390         log "Turn off the read cache and turn on the write cache"
15391         set_cache read off
15392         set_cache writethrough on
15393
15394         log "Read again; it should be satisfied from the cache."
15395         BEFORE=$(roc_hit)
15396         cancel_lru_locks osc
15397         cat $file >/dev/null
15398         AFTER=$(roc_hit)
15399         if ! let "AFTER - BEFORE == CPAGES"; then
15400                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15401         else
15402                 log "cache hits:: before: $BEFORE, after: $AFTER"
15403         fi
15404
15405         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15406                 # > 2.12.56 uses pagecache if cached
15407                 log "Read again; it should not be satisfied from the cache."
15408                 BEFORE=$AFTER
15409                 cancel_lru_locks osc
15410                 cat $file >/dev/null
15411                 AFTER=$(roc_hit)
15412                 if ! let "AFTER - BEFORE == 0"; then
15413                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15414                 else
15415                         log "cache hits:: before: $BEFORE, after: $AFTER"
15416                 fi
15417         fi
15418
15419         log "Write data and read it back."
15420         log "Read should be satisfied from the cache."
15421         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15422         BEFORE=$(roc_hit)
15423         cancel_lru_locks osc
15424         cat $file >/dev/null
15425         AFTER=$(roc_hit)
15426         if ! let "AFTER - BEFORE == CPAGES"; then
15427                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15428         else
15429                 log "cache hits:: before: $BEFORE, after: $AFTER"
15430         fi
15431
15432         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15433                 # > 2.12.56 uses pagecache if cached
15434                 log "Read again; it should not be satisfied from the cache."
15435                 BEFORE=$AFTER
15436                 cancel_lru_locks osc
15437                 cat $file >/dev/null
15438                 AFTER=$(roc_hit)
15439                 if ! let "AFTER - BEFORE == 0"; then
15440                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15441                 else
15442                         log "cache hits:: before: $BEFORE, after: $AFTER"
15443                 fi
15444         fi
15445
15446         log "Turn off read and write cache"
15447         set_cache read off
15448         set_cache writethrough off
15449
15450         log "Write data and read it back"
15451         log "It should not be satisfied from the cache."
15452         rm -f $file
15453         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15454         cancel_lru_locks osc
15455         BEFORE=$(roc_hit)
15456         cat $file >/dev/null
15457         AFTER=$(roc_hit)
15458         if ! let "AFTER - BEFORE == 0"; then
15459                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15460         else
15461                 log "cache hits:: before: $BEFORE, after: $AFTER"
15462         fi
15463
15464         log "Turn on the read cache and turn off the write cache"
15465         set_cache read on
15466         set_cache writethrough off
15467
15468         log "Write data and read it back"
15469         log "It should not be satisfied from the cache."
15470         rm -f $file
15471         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15472         BEFORE=$(roc_hit)
15473         cancel_lru_locks osc
15474         cat $file >/dev/null
15475         AFTER=$(roc_hit)
15476         if ! let "AFTER - BEFORE == 0"; then
15477                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15478         else
15479                 log "cache hits:: before: $BEFORE, after: $AFTER"
15480         fi
15481
15482         log "Read again; it should be satisfied from the cache."
15483         BEFORE=$(roc_hit)
15484         cancel_lru_locks osc
15485         cat $file >/dev/null
15486         AFTER=$(roc_hit)
15487         if ! let "AFTER - BEFORE == CPAGES"; then
15488                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15489         else
15490                 log "cache hits:: before: $BEFORE, after: $AFTER"
15491         fi
15492
15493         restore_lustre_params < $p
15494         rm -f $p $file
15495 }
15496 run_test 156 "Verification of tunables"
15497
15498 test_160a() {
15499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15500         remote_mds_nodsh && skip "remote MDS with nodsh"
15501         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15502                 skip "Need MDS version at least 2.2.0"
15503
15504         changelog_register || error "changelog_register failed"
15505         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15506         changelog_users $SINGLEMDS | grep -q $cl_user ||
15507                 error "User $cl_user not found in changelog_users"
15508
15509         mkdir_on_mdt0 $DIR/$tdir
15510
15511         # change something
15512         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15513         changelog_clear 0 || error "changelog_clear failed"
15514         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15515         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15516         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15517         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15518         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15519         rm $DIR/$tdir/pics/desktop.jpg
15520
15521         echo "verifying changelog mask"
15522         changelog_chmask "-MKDIR"
15523         changelog_chmask "-CLOSE"
15524
15525         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15526         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15527
15528         changelog_chmask "+MKDIR"
15529         changelog_chmask "+CLOSE"
15530
15531         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15532         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15533
15534         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15535         CLOSES=$(changelog_dump | grep -c "CLOSE")
15536         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15537         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15538
15539         # verify contents
15540         echo "verifying target fid"
15541         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15542         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15543         [ "$fidc" == "$fidf" ] ||
15544                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15545         echo "verifying parent fid"
15546         # The FID returned from the Changelog may be the directory shard on
15547         # a different MDT, and not the FID returned by path2fid on the parent.
15548         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15549         # since this is what will matter when recreating this file in the tree.
15550         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15551         local pathp=$($LFS fid2path $MOUNT "$fidp")
15552         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15553                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15554
15555         echo "getting records for $cl_user"
15556         changelog_users $SINGLEMDS
15557         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15558         local nclr=3
15559         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15560                 error "changelog_clear failed"
15561         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15562         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15563         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15564                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15565
15566         local min0_rec=$(changelog_users $SINGLEMDS |
15567                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15568         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15569                           awk '{ print $1; exit; }')
15570
15571         changelog_dump | tail -n 5
15572         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15573         [ $first_rec == $((min0_rec + 1)) ] ||
15574                 error "first index should be $min0_rec + 1 not $first_rec"
15575
15576         # LU-3446 changelog index reset on MDT restart
15577         local cur_rec1=$(changelog_users $SINGLEMDS |
15578                          awk '/^current.index:/ { print $NF }')
15579         changelog_clear 0 ||
15580                 error "clear all changelog records for $cl_user failed"
15581         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15582         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15583                 error "Fail to start $SINGLEMDS"
15584         local cur_rec2=$(changelog_users $SINGLEMDS |
15585                          awk '/^current.index:/ { print $NF }')
15586         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15587         [ $cur_rec1 == $cur_rec2 ] ||
15588                 error "current index should be $cur_rec1 not $cur_rec2"
15589
15590         echo "verifying users from this test are deregistered"
15591         changelog_deregister || error "changelog_deregister failed"
15592         changelog_users $SINGLEMDS | grep -q $cl_user &&
15593                 error "User '$cl_user' still in changelog_users"
15594
15595         # lctl get_param -n mdd.*.changelog_users
15596         # current_index: 144
15597         # ID    index (idle seconds)
15598         # cl3   144   (2) mask=<list>
15599         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15600                 # this is the normal case where all users were deregistered
15601                 # make sure no new records are added when no users are present
15602                 local last_rec1=$(changelog_users $SINGLEMDS |
15603                                   awk '/^current.index:/ { print $NF }')
15604                 touch $DIR/$tdir/chloe
15605                 local last_rec2=$(changelog_users $SINGLEMDS |
15606                                   awk '/^current.index:/ { print $NF }')
15607                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15608                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15609         else
15610                 # any changelog users must be leftovers from a previous test
15611                 changelog_users $SINGLEMDS
15612                 echo "other changelog users; can't verify off"
15613         fi
15614 }
15615 run_test 160a "changelog sanity"
15616
15617 test_160b() { # LU-3587
15618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15619         remote_mds_nodsh && skip "remote MDS with nodsh"
15620         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15621                 skip "Need MDS version at least 2.2.0"
15622
15623         changelog_register || error "changelog_register failed"
15624         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15625         changelog_users $SINGLEMDS | grep -q $cl_user ||
15626                 error "User '$cl_user' not found in changelog_users"
15627
15628         local longname1=$(str_repeat a 255)
15629         local longname2=$(str_repeat b 255)
15630
15631         cd $DIR
15632         echo "creating very long named file"
15633         touch $longname1 || error "create of '$longname1' failed"
15634         echo "renaming very long named file"
15635         mv $longname1 $longname2
15636
15637         changelog_dump | grep RENME | tail -n 5
15638         rm -f $longname2
15639 }
15640 run_test 160b "Verify that very long rename doesn't crash in changelog"
15641
15642 test_160c() {
15643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15644         remote_mds_nodsh && skip "remote MDS with nodsh"
15645
15646         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15647                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15648                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15649                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15650
15651         local rc=0
15652
15653         # Registration step
15654         changelog_register || error "changelog_register failed"
15655
15656         rm -rf $DIR/$tdir
15657         mkdir -p $DIR/$tdir
15658         $MCREATE $DIR/$tdir/foo_160c
15659         changelog_chmask "-TRUNC"
15660         $TRUNCATE $DIR/$tdir/foo_160c 200
15661         changelog_chmask "+TRUNC"
15662         $TRUNCATE $DIR/$tdir/foo_160c 199
15663         changelog_dump | tail -n 5
15664         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15665         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15666 }
15667 run_test 160c "verify that changelog log catch the truncate event"
15668
15669 test_160d() {
15670         remote_mds_nodsh && skip "remote MDS with nodsh"
15671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15673         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15674                 skip "Need MDS version at least 2.7.60"
15675
15676         # Registration step
15677         changelog_register || error "changelog_register failed"
15678
15679         mkdir -p $DIR/$tdir/migrate_dir
15680         changelog_clear 0 || error "changelog_clear failed"
15681
15682         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15683         changelog_dump | tail -n 5
15684         local migrates=$(changelog_dump | grep -c "MIGRT")
15685         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15686 }
15687 run_test 160d "verify that changelog log catch the migrate event"
15688
15689 test_160e() {
15690         remote_mds_nodsh && skip "remote MDS with nodsh"
15691
15692         # Create a user
15693         changelog_register || error "changelog_register failed"
15694
15695         local MDT0=$(facet_svc $SINGLEMDS)
15696         local rc
15697
15698         # No user (expect fail)
15699         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15700         rc=$?
15701         if [ $rc -eq 0 ]; then
15702                 error "Should fail without user"
15703         elif [ $rc -ne 4 ]; then
15704                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15705         fi
15706
15707         # Delete a future user (expect fail)
15708         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15709         rc=$?
15710         if [ $rc -eq 0 ]; then
15711                 error "Deleted non-existant user cl77"
15712         elif [ $rc -ne 2 ]; then
15713                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15714         fi
15715
15716         # Clear to a bad index (1 billion should be safe)
15717         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15718         rc=$?
15719
15720         if [ $rc -eq 0 ]; then
15721                 error "Successfully cleared to invalid CL index"
15722         elif [ $rc -ne 22 ]; then
15723                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15724         fi
15725 }
15726 run_test 160e "changelog negative testing (should return errors)"
15727
15728 test_160f() {
15729         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15730         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15731                 skip "Need MDS version at least 2.10.56"
15732
15733         local mdts=$(comma_list $(mdts_nodes))
15734
15735         # Create a user
15736         changelog_register || error "first changelog_register failed"
15737         changelog_register || error "second changelog_register failed"
15738         local cl_users
15739         declare -A cl_user1
15740         declare -A cl_user2
15741         local user_rec1
15742         local user_rec2
15743         local i
15744
15745         # generate some changelog records to accumulate on each MDT
15746         # use all_char because created files should be evenly distributed
15747         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15748                 error "test_mkdir $tdir failed"
15749         log "$(date +%s): creating first files"
15750         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15751                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15752                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15753         done
15754
15755         # check changelogs have been generated
15756         local start=$SECONDS
15757         local idle_time=$((MDSCOUNT * 5 + 5))
15758         local nbcl=$(changelog_dump | wc -l)
15759         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15760
15761         for param in "changelog_max_idle_time=$idle_time" \
15762                      "changelog_gc=1" \
15763                      "changelog_min_gc_interval=2" \
15764                      "changelog_min_free_cat_entries=3"; do
15765                 local MDT0=$(facet_svc $SINGLEMDS)
15766                 local var="${param%=*}"
15767                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15768
15769                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15770                 do_nodes $mdts $LCTL set_param mdd.*.$param
15771         done
15772
15773         # force cl_user2 to be idle (1st part), but also cancel the
15774         # cl_user1 records so that it is not evicted later in the test.
15775         local sleep1=$((idle_time / 2))
15776         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15777         sleep $sleep1
15778
15779         # simulate changelog catalog almost full
15780         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15781         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15782
15783         for i in $(seq $MDSCOUNT); do
15784                 cl_users=(${CL_USERS[mds$i]})
15785                 cl_user1[mds$i]="${cl_users[0]}"
15786                 cl_user2[mds$i]="${cl_users[1]}"
15787
15788                 [ -n "${cl_user1[mds$i]}" ] ||
15789                         error "mds$i: no user registered"
15790                 [ -n "${cl_user2[mds$i]}" ] ||
15791                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15792
15793                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15794                 [ -n "$user_rec1" ] ||
15795                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15796                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15797                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15798                 [ -n "$user_rec2" ] ||
15799                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15800                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15801                      "$user_rec1 + 2 == $user_rec2"
15802                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15803                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15804                               "$user_rec1 + 2, but is $user_rec2"
15805                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15806                 [ -n "$user_rec2" ] ||
15807                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15808                 [ $user_rec1 == $user_rec2 ] ||
15809                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15810                               "$user_rec1, but is $user_rec2"
15811         done
15812
15813         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15814         local sleep2=$((idle_time - (SECONDS - start) + 1))
15815         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15816         sleep $sleep2
15817
15818         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15819         # cl_user1 should be OK because it recently processed records.
15820         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15821         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15822                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15823                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15824         done
15825
15826         # ensure gc thread is done
15827         for i in $(mdts_nodes); do
15828                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15829                         error "$i: GC-thread not done"
15830         done
15831
15832         local first_rec
15833         for (( i = 1; i <= MDSCOUNT; i++ )); do
15834                 # check cl_user1 still registered
15835                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15836                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15837                 # check cl_user2 unregistered
15838                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15839                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15840
15841                 # check changelogs are present and starting at $user_rec1 + 1
15842                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15843                 [ -n "$user_rec1" ] ||
15844                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15845                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15846                             awk '{ print $1; exit; }')
15847
15848                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15849                 [ $((user_rec1 + 1)) == $first_rec ] ||
15850                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15851         done
15852 }
15853 run_test 160f "changelog garbage collect (timestamped users)"
15854
15855 test_160g() {
15856         remote_mds_nodsh && skip "remote MDS with nodsh"
15857         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15858                 skip "Need MDS version at least 2.10.56"
15859
15860         local mdts=$(comma_list $(mdts_nodes))
15861
15862         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15863         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15864
15865         # Create a user
15866         changelog_register || error "first changelog_register failed"
15867         changelog_register || error "second changelog_register failed"
15868         local cl_users
15869         declare -A cl_user1
15870         declare -A cl_user2
15871         local user_rec1
15872         local user_rec2
15873         local i
15874
15875         # generate some changelog records to accumulate on each MDT
15876         # use all_char because created files should be evenly distributed
15877         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15878                 error "test_mkdir $tdir failed"
15879         for ((i = 0; i < MDSCOUNT; i++)); do
15880                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15881                         error "create $DIR/$tdir/d$i.1 failed"
15882         done
15883
15884         # check changelogs have been generated
15885         local nbcl=$(changelog_dump | wc -l)
15886         (( $nbcl > 0 )) || error "no changelogs found"
15887
15888         # reduce the max_idle_indexes value to make sure we exceed it
15889         for param in "changelog_max_idle_indexes=1" \
15890                      "changelog_gc=1" \
15891                      "changelog_min_gc_interval=2" \
15892                      "changelog_min_free_cat_entries=3"; do
15893                 local MDT0=$(facet_svc $SINGLEMDS)
15894                 local var="${param%=*}"
15895                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15896
15897                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15898                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15899                         error "unable to set mdd.*.$param"
15900         done
15901
15902         # simulate changelog catalog almost full
15903         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15904         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15905
15906         local start=$SECONDS
15907         for i in $(seq $MDSCOUNT); do
15908                 cl_users=(${CL_USERS[mds$i]})
15909                 cl_user1[mds$i]="${cl_users[0]}"
15910                 cl_user2[mds$i]="${cl_users[1]}"
15911
15912                 [ -n "${cl_user1[mds$i]}" ] ||
15913                         error "mds$i: no user registered"
15914                 [ -n "${cl_user2[mds$i]}" ] ||
15915                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15916
15917                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15918                 [ -n "$user_rec1" ] ||
15919                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15920                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15921                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15922                 [ -n "$user_rec2" ] ||
15923                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15924                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15925                      "$user_rec1 + 2 == $user_rec2"
15926                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15927                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15928                               "$user_rec1 + 2, but is $user_rec2"
15929                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15930                 [ -n "$user_rec2" ] ||
15931                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15932                 [ $user_rec1 == $user_rec2 ] ||
15933                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15934                               "$user_rec1, but is $user_rec2"
15935         done
15936
15937         # ensure we are past the previous changelog_min_gc_interval set above
15938         local sleep2=$((start + 2 - SECONDS))
15939         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15940
15941         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15942         # cl_user1 should be OK because it recently processed records.
15943         for ((i = 0; i < MDSCOUNT; i++)); do
15944                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15945                         error "create $DIR/$tdir/d$i.3 failed"
15946         done
15947
15948         # ensure gc thread is done
15949         for i in $(mdts_nodes); do
15950                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15951                         error "$i: GC-thread not done"
15952         done
15953
15954         local first_rec
15955         for (( i = 1; i <= MDSCOUNT; i++ )); do
15956                 # check cl_user1 still registered
15957                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15958                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15959                 # check cl_user2 unregistered
15960                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15961                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15962
15963                 # check changelogs are present and starting at $user_rec1 + 1
15964                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15965                 [ -n "$user_rec1" ] ||
15966                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15967                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15968                             awk '{ print $1; exit; }')
15969
15970                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15971                 [ $((user_rec1 + 1)) == $first_rec ] ||
15972                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15973         done
15974 }
15975 run_test 160g "changelog garbage collect (old users)"
15976
15977 test_160h() {
15978         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15979         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15980                 skip "Need MDS version at least 2.10.56"
15981
15982         local mdts=$(comma_list $(mdts_nodes))
15983
15984         # Create a user
15985         changelog_register || error "first changelog_register failed"
15986         changelog_register || error "second changelog_register failed"
15987         local cl_users
15988         declare -A cl_user1
15989         declare -A cl_user2
15990         local user_rec1
15991         local user_rec2
15992         local i
15993
15994         # generate some changelog records to accumulate on each MDT
15995         # use all_char because created files should be evenly distributed
15996         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15997                 error "test_mkdir $tdir failed"
15998         for ((i = 0; i < MDSCOUNT; i++)); do
15999                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16000                         error "create $DIR/$tdir/d$i.1 failed"
16001         done
16002
16003         # check changelogs have been generated
16004         local nbcl=$(changelog_dump | wc -l)
16005         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16006
16007         for param in "changelog_max_idle_time=10" \
16008                      "changelog_gc=1" \
16009                      "changelog_min_gc_interval=2"; do
16010                 local MDT0=$(facet_svc $SINGLEMDS)
16011                 local var="${param%=*}"
16012                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16013
16014                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16015                 do_nodes $mdts $LCTL set_param mdd.*.$param
16016         done
16017
16018         # force cl_user2 to be idle (1st part)
16019         sleep 9
16020
16021         for i in $(seq $MDSCOUNT); do
16022                 cl_users=(${CL_USERS[mds$i]})
16023                 cl_user1[mds$i]="${cl_users[0]}"
16024                 cl_user2[mds$i]="${cl_users[1]}"
16025
16026                 [ -n "${cl_user1[mds$i]}" ] ||
16027                         error "mds$i: no user registered"
16028                 [ -n "${cl_user2[mds$i]}" ] ||
16029                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16030
16031                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16032                 [ -n "$user_rec1" ] ||
16033                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16034                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16035                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16036                 [ -n "$user_rec2" ] ||
16037                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16038                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16039                      "$user_rec1 + 2 == $user_rec2"
16040                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16041                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16042                               "$user_rec1 + 2, but is $user_rec2"
16043                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16044                 [ -n "$user_rec2" ] ||
16045                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16046                 [ $user_rec1 == $user_rec2 ] ||
16047                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16048                               "$user_rec1, but is $user_rec2"
16049         done
16050
16051         # force cl_user2 to be idle (2nd part) and to reach
16052         # changelog_max_idle_time
16053         sleep 2
16054
16055         # force each GC-thread start and block then
16056         # one per MDT/MDD, set fail_val accordingly
16057         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16058         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16059
16060         # generate more changelogs to trigger fail_loc
16061         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16062                 error "create $DIR/$tdir/${tfile}bis failed"
16063
16064         # stop MDT to stop GC-thread, should be done in back-ground as it will
16065         # block waiting for the thread to be released and exit
16066         declare -A stop_pids
16067         for i in $(seq $MDSCOUNT); do
16068                 stop mds$i &
16069                 stop_pids[mds$i]=$!
16070         done
16071
16072         for i in $(mdts_nodes); do
16073                 local facet
16074                 local nb=0
16075                 local facets=$(facets_up_on_host $i)
16076
16077                 for facet in ${facets//,/ }; do
16078                         if [[ $facet == mds* ]]; then
16079                                 nb=$((nb + 1))
16080                         fi
16081                 done
16082                 # ensure each MDS's gc threads are still present and all in "R"
16083                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16084                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16085                         error "$i: expected $nb GC-thread"
16086                 wait_update $i \
16087                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16088                         "R" 20 ||
16089                         error "$i: GC-thread not found in R-state"
16090                 # check umounts of each MDT on MDS have reached kthread_stop()
16091                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16092                         error "$i: expected $nb umount"
16093                 wait_update $i \
16094                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16095                         error "$i: umount not found in D-state"
16096         done
16097
16098         # release all GC-threads
16099         do_nodes $mdts $LCTL set_param fail_loc=0
16100
16101         # wait for MDT stop to complete
16102         for i in $(seq $MDSCOUNT); do
16103                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16104         done
16105
16106         # XXX
16107         # may try to check if any orphan changelog records are present
16108         # via ldiskfs/zfs and llog_reader...
16109
16110         # re-start/mount MDTs
16111         for i in $(seq $MDSCOUNT); do
16112                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16113                         error "Fail to start mds$i"
16114         done
16115
16116         local first_rec
16117         for i in $(seq $MDSCOUNT); do
16118                 # check cl_user1 still registered
16119                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16120                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16121                 # check cl_user2 unregistered
16122                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16123                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16124
16125                 # check changelogs are present and starting at $user_rec1 + 1
16126                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16127                 [ -n "$user_rec1" ] ||
16128                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16129                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16130                             awk '{ print $1; exit; }')
16131
16132                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16133                 [ $((user_rec1 + 1)) == $first_rec ] ||
16134                         error "mds$i: first index should be $user_rec1 + 1, " \
16135                               "but is $first_rec"
16136         done
16137 }
16138 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16139               "during mount"
16140
16141 test_160i() {
16142
16143         local mdts=$(comma_list $(mdts_nodes))
16144
16145         changelog_register || error "first changelog_register failed"
16146
16147         # generate some changelog records to accumulate on each MDT
16148         # use all_char because created files should be evenly distributed
16149         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16150                 error "test_mkdir $tdir failed"
16151         for ((i = 0; i < MDSCOUNT; i++)); do
16152                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16153                         error "create $DIR/$tdir/d$i.1 failed"
16154         done
16155
16156         # check changelogs have been generated
16157         local nbcl=$(changelog_dump | wc -l)
16158         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16159
16160         # simulate race between register and unregister
16161         # XXX as fail_loc is set per-MDS, with DNE configs the race
16162         # simulation will only occur for one MDT per MDS and for the
16163         # others the normal race scenario will take place
16164         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16165         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16166         do_nodes $mdts $LCTL set_param fail_val=1
16167
16168         # unregister 1st user
16169         changelog_deregister &
16170         local pid1=$!
16171         # wait some time for deregister work to reach race rdv
16172         sleep 2
16173         # register 2nd user
16174         changelog_register || error "2nd user register failed"
16175
16176         wait $pid1 || error "1st user deregister failed"
16177
16178         local i
16179         local last_rec
16180         declare -A LAST_REC
16181         for i in $(seq $MDSCOUNT); do
16182                 if changelog_users mds$i | grep "^cl"; then
16183                         # make sure new records are added with one user present
16184                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16185                                           awk '/^current.index:/ { print $NF }')
16186                 else
16187                         error "mds$i has no user registered"
16188                 fi
16189         done
16190
16191         # generate more changelog records to accumulate on each MDT
16192         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16193                 error "create $DIR/$tdir/${tfile}bis failed"
16194
16195         for i in $(seq $MDSCOUNT); do
16196                 last_rec=$(changelog_users $SINGLEMDS |
16197                            awk '/^current.index:/ { print $NF }')
16198                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16199                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16200                         error "changelogs are off on mds$i"
16201         done
16202 }
16203 run_test 160i "changelog user register/unregister race"
16204
16205 test_160j() {
16206         remote_mds_nodsh && skip "remote MDS with nodsh"
16207         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16208                 skip "Need MDS version at least 2.12.56"
16209
16210         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16211         stack_trap "umount $MOUNT2" EXIT
16212
16213         changelog_register || error "first changelog_register failed"
16214         stack_trap "changelog_deregister" EXIT
16215
16216         # generate some changelog
16217         # use all_char because created files should be evenly distributed
16218         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16219                 error "mkdir $tdir failed"
16220         for ((i = 0; i < MDSCOUNT; i++)); do
16221                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16222                         error "create $DIR/$tdir/d$i.1 failed"
16223         done
16224
16225         # open the changelog device
16226         exec 3>/dev/changelog-$FSNAME-MDT0000
16227         stack_trap "exec 3>&-" EXIT
16228         exec 4</dev/changelog-$FSNAME-MDT0000
16229         stack_trap "exec 4<&-" EXIT
16230
16231         # umount the first lustre mount
16232         umount $MOUNT
16233         stack_trap "mount_client $MOUNT" EXIT
16234
16235         # read changelog, which may or may not fail, but should not crash
16236         cat <&4 >/dev/null
16237
16238         # clear changelog
16239         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16240         changelog_users $SINGLEMDS | grep -q $cl_user ||
16241                 error "User $cl_user not found in changelog_users"
16242
16243         printf 'clear:'$cl_user':0' >&3
16244 }
16245 run_test 160j "client can be umounted while its chanangelog is being used"
16246
16247 test_160k() {
16248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16249         remote_mds_nodsh && skip "remote MDS with nodsh"
16250
16251         mkdir -p $DIR/$tdir/1/1
16252
16253         changelog_register || error "changelog_register failed"
16254         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16255
16256         changelog_users $SINGLEMDS | grep -q $cl_user ||
16257                 error "User '$cl_user' not found in changelog_users"
16258 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16259         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16260         rmdir $DIR/$tdir/1/1 & sleep 1
16261         mkdir $DIR/$tdir/2
16262         touch $DIR/$tdir/2/2
16263         rm -rf $DIR/$tdir/2
16264
16265         wait
16266         sleep 4
16267
16268         changelog_dump | grep rmdir || error "rmdir not recorded"
16269 }
16270 run_test 160k "Verify that changelog records are not lost"
16271
16272 # Verifies that a file passed as a parameter has recently had an operation
16273 # performed on it that has generated an MTIME changelog which contains the
16274 # correct parent FID. As files might reside on a different MDT from the
16275 # parent directory in DNE configurations, the FIDs are translated to paths
16276 # before being compared, which should be identical
16277 compare_mtime_changelog() {
16278         local file="${1}"
16279         local mdtidx
16280         local mtime
16281         local cl_fid
16282         local pdir
16283         local dir
16284
16285         mdtidx=$($LFS getstripe --mdt-index $file)
16286         mdtidx=$(printf "%04x" $mdtidx)
16287
16288         # Obtain the parent FID from the MTIME changelog
16289         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16290         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16291
16292         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16293         [ -z "$cl_fid" ] && error "parent FID not present"
16294
16295         # Verify that the path for the parent FID is the same as the path for
16296         # the test directory
16297         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16298
16299         dir=$(dirname $1)
16300
16301         [[ "${pdir%/}" == "$dir" ]] ||
16302                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16303 }
16304
16305 test_160l() {
16306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16307
16308         remote_mds_nodsh && skip "remote MDS with nodsh"
16309         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16310                 skip "Need MDS version at least 2.13.55"
16311
16312         local cl_user
16313
16314         changelog_register || error "changelog_register failed"
16315         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16316
16317         changelog_users $SINGLEMDS | grep -q $cl_user ||
16318                 error "User '$cl_user' not found in changelog_users"
16319
16320         # Clear some types so that MTIME changelogs are generated
16321         changelog_chmask "-CREAT"
16322         changelog_chmask "-CLOSE"
16323
16324         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16325
16326         # Test CL_MTIME during setattr
16327         touch $DIR/$tdir/$tfile
16328         compare_mtime_changelog $DIR/$tdir/$tfile
16329
16330         # Test CL_MTIME during close
16331         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16332         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16333 }
16334 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16335
16336 test_160m() {
16337         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16338         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16339                 skip "Need MDS version at least 2.14.51"
16340         local cl_users
16341         local cl_user1
16342         local cl_user2
16343         local pid1
16344
16345         # Create a user
16346         changelog_register || error "first changelog_register failed"
16347         changelog_register || error "second changelog_register failed"
16348
16349         cl_users=(${CL_USERS[mds1]})
16350         cl_user1="${cl_users[0]}"
16351         cl_user2="${cl_users[1]}"
16352         # generate some changelog records to accumulate on MDT0
16353         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16354         createmany -m $DIR/$tdir/$tfile 50 ||
16355                 error "create $DIR/$tdir/$tfile failed"
16356         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16357         rm -f $DIR/$tdir
16358
16359         # check changelogs have been generated
16360         local nbcl=$(changelog_dump | wc -l)
16361         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16362
16363 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16364         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16365
16366         __changelog_clear mds1 $cl_user1 +10
16367         __changelog_clear mds1 $cl_user2 0 &
16368         pid1=$!
16369         sleep 2
16370         __changelog_clear mds1 $cl_user1 0 ||
16371                 error "fail to cancel record for $cl_user1"
16372         wait $pid1
16373         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16374 }
16375 run_test 160m "Changelog clear race"
16376
16377 test_160n() {
16378         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16379         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16380                 skip "Need MDS version at least 2.14.51"
16381         local cl_users
16382         local cl_user1
16383         local cl_user2
16384         local pid1
16385         local first_rec
16386         local last_rec=0
16387
16388         # Create a user
16389         changelog_register || error "first changelog_register failed"
16390
16391         cl_users=(${CL_USERS[mds1]})
16392         cl_user1="${cl_users[0]}"
16393
16394         # generate some changelog records to accumulate on MDT0
16395         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16396         first_rec=$(changelog_users $SINGLEMDS |
16397                         awk '/^current.index:/ { print $NF }')
16398         while (( last_rec < (( first_rec + 65000)) )); do
16399                 createmany -m $DIR/$tdir/$tfile 10000 ||
16400                         error "create $DIR/$tdir/$tfile failed"
16401
16402                 for i in $(seq 0 10000); do
16403                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16404                                 > /dev/null
16405                 done
16406
16407                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16408                         error "unlinkmany failed unlink"
16409                 last_rec=$(changelog_users $SINGLEMDS |
16410                         awk '/^current.index:/ { print $NF }')
16411                 echo last record $last_rec
16412                 (( last_rec == 0 )) && error "no changelog found"
16413         done
16414
16415 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16416         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16417
16418         __changelog_clear mds1 $cl_user1 0 &
16419         pid1=$!
16420         sleep 2
16421         __changelog_clear mds1 $cl_user1 0 ||
16422                 error "fail to cancel record for $cl_user1"
16423         wait $pid1
16424         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16425 }
16426 run_test 160n "Changelog destroy race"
16427
16428 test_160o() {
16429         local mdt="$(facet_svc $SINGLEMDS)"
16430
16431         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16432         remote_mds_nodsh && skip "remote MDS with nodsh"
16433         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16434                 skip "Need MDS version at least 2.14.52"
16435
16436         changelog_register --user test_160o -m unlnk+close+open ||
16437                 error "changelog_register failed"
16438
16439         do_facet $SINGLEMDS $LCTL --device $mdt \
16440                                 changelog_register -u "Tt3_-#" &&
16441                 error "bad symbols in name should fail"
16442
16443         do_facet $SINGLEMDS $LCTL --device $mdt \
16444                                 changelog_register -u test_160o &&
16445                 error "the same name registration should fail"
16446
16447         do_facet $SINGLEMDS $LCTL --device $mdt \
16448                         changelog_register -u test_160toolongname &&
16449                 error "too long name registration should fail"
16450
16451         changelog_chmask "MARK+HSM"
16452         lctl get_param mdd.*.changelog*mask
16453         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16454         changelog_users $SINGLEMDS | grep -q $cl_user ||
16455                 error "User $cl_user not found in changelog_users"
16456         #verify username
16457         echo $cl_user | grep -q test_160o ||
16458                 error "User $cl_user has no specific name 'test160o'"
16459
16460         # change something
16461         changelog_clear 0 || error "changelog_clear failed"
16462         # generate some changelog records to accumulate on MDT0
16463         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16464         touch $DIR/$tdir/$tfile                 # open 1
16465
16466         OPENS=$(changelog_dump | grep -c "OPEN")
16467         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16468
16469         # must be no MKDIR it wasn't set as user mask
16470         MKDIR=$(changelog_dump | grep -c "MKDIR")
16471         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16472
16473         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16474                                 mdd.$mdt.changelog_current_mask -n)
16475         # register maskless user
16476         changelog_register || error "changelog_register failed"
16477         # effective mask should be not changed because it is not minimal
16478         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16479                                 mdd.$mdt.changelog_current_mask -n)
16480         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16481         # set server mask to minimal value
16482         changelog_chmask "MARK"
16483         # check effective mask again, should be treated as DEFMASK now
16484         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16485                                 mdd.$mdt.changelog_current_mask -n)
16486         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16487
16488         do_facet $SINGLEMDS $LCTL --device $mdt \
16489                                 changelog_deregister -u test_160o ||
16490                 error "cannot deregister by name"
16491 }
16492 run_test 160o "changelog user name and mask"
16493
16494 test_160p() {
16495         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16496         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16497                 skip "Need MDS version at least 2.14.51"
16498         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16499         local cl_users
16500         local cl_user1
16501         local entry_count
16502
16503         # Create a user
16504         changelog_register || error "first changelog_register failed"
16505
16506         cl_users=(${CL_USERS[mds1]})
16507         cl_user1="${cl_users[0]}"
16508
16509         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16510         createmany -m $DIR/$tdir/$tfile 50 ||
16511                 error "create $DIR/$tdir/$tfile failed"
16512         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16513         rm -rf $DIR/$tdir
16514
16515         # check changelogs have been generated
16516         entry_count=$(changelog_dump | wc -l)
16517         ((entry_count != 0)) || error "no changelog entries found"
16518
16519         # remove changelog_users and check that orphan entries are removed
16520         stop mds1
16521         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16522         start mds1 || error "cannot start mdt"
16523         entry_count=$(changelog_dump | wc -l)
16524         ((entry_count == 0)) ||
16525                 error "found $entry_count changelog entries, expected none"
16526 }
16527 run_test 160p "Changelog orphan cleanup with no users"
16528
16529 test_160q() {
16530         local mdt="$(facet_svc $SINGLEMDS)"
16531         local clu
16532
16533         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16534         remote_mds_nodsh && skip "remote MDS with nodsh"
16535         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16536                 skip "Need MDS version at least 2.14.54"
16537
16538         # set server mask to minimal value like server init does
16539         changelog_chmask "MARK"
16540         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16541                 error "changelog_register failed"
16542         # check effective mask again, should be treated as DEFMASK now
16543         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16544                                 mdd.$mdt.changelog_current_mask -n)
16545         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16546                 error "changelog_deregister failed"
16547         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16548 }
16549 run_test 160q "changelog effective mask is DEFMASK if not set"
16550
16551 test_161a() {
16552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16553
16554         test_mkdir -c1 $DIR/$tdir
16555         cp /etc/hosts $DIR/$tdir/$tfile
16556         test_mkdir -c1 $DIR/$tdir/foo1
16557         test_mkdir -c1 $DIR/$tdir/foo2
16558         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16559         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16560         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16561         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16562         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16563         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16564                 $LFS fid2path $DIR $FID
16565                 error "bad link ea"
16566         fi
16567         # middle
16568         rm $DIR/$tdir/foo2/zachary
16569         # last
16570         rm $DIR/$tdir/foo2/thor
16571         # first
16572         rm $DIR/$tdir/$tfile
16573         # rename
16574         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16575         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16576                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16577         rm $DIR/$tdir/foo2/maggie
16578
16579         # overflow the EA
16580         local longname=$tfile.avg_len_is_thirty_two_
16581         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16582                 error_noexit 'failed to unlink many hardlinks'" EXIT
16583         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16584                 error "failed to hardlink many files"
16585         links=$($LFS fid2path $DIR $FID | wc -l)
16586         echo -n "${links}/1000 links in link EA"
16587         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16588 }
16589 run_test 161a "link ea sanity"
16590
16591 test_161b() {
16592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16593         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16594
16595         local MDTIDX=1
16596         local remote_dir=$DIR/$tdir/remote_dir
16597
16598         mkdir -p $DIR/$tdir
16599         $LFS mkdir -i $MDTIDX $remote_dir ||
16600                 error "create remote directory failed"
16601
16602         cp /etc/hosts $remote_dir/$tfile
16603         mkdir -p $remote_dir/foo1
16604         mkdir -p $remote_dir/foo2
16605         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16606         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16607         ln $remote_dir/$tfile $remote_dir/foo1/luna
16608         ln $remote_dir/$tfile $remote_dir/foo2/thor
16609
16610         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16611                      tr -d ']')
16612         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16613                 $LFS fid2path $DIR $FID
16614                 error "bad link ea"
16615         fi
16616         # middle
16617         rm $remote_dir/foo2/zachary
16618         # last
16619         rm $remote_dir/foo2/thor
16620         # first
16621         rm $remote_dir/$tfile
16622         # rename
16623         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16624         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16625         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16626                 $LFS fid2path $DIR $FID
16627                 error "bad link rename"
16628         fi
16629         rm $remote_dir/foo2/maggie
16630
16631         # overflow the EA
16632         local longname=filename_avg_len_is_thirty_two_
16633         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16634                 error "failed to hardlink many files"
16635         links=$($LFS fid2path $DIR $FID | wc -l)
16636         echo -n "${links}/1000 links in link EA"
16637         [[ ${links} -gt 60 ]] ||
16638                 error "expected at least 60 links in link EA"
16639         unlinkmany $remote_dir/foo2/$longname 1000 ||
16640         error "failed to unlink many hardlinks"
16641 }
16642 run_test 161b "link ea sanity under remote directory"
16643
16644 test_161c() {
16645         remote_mds_nodsh && skip "remote MDS with nodsh"
16646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16647         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16648                 skip "Need MDS version at least 2.1.5"
16649
16650         # define CLF_RENAME_LAST 0x0001
16651         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16652         changelog_register || error "changelog_register failed"
16653
16654         rm -rf $DIR/$tdir
16655         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16656         touch $DIR/$tdir/foo_161c
16657         touch $DIR/$tdir/bar_161c
16658         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16659         changelog_dump | grep RENME | tail -n 5
16660         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16661         changelog_clear 0 || error "changelog_clear failed"
16662         if [ x$flags != "x0x1" ]; then
16663                 error "flag $flags is not 0x1"
16664         fi
16665
16666         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16667         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16668         touch $DIR/$tdir/foo_161c
16669         touch $DIR/$tdir/bar_161c
16670         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16671         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16672         changelog_dump | grep RENME | tail -n 5
16673         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16674         changelog_clear 0 || error "changelog_clear failed"
16675         if [ x$flags != "x0x0" ]; then
16676                 error "flag $flags is not 0x0"
16677         fi
16678         echo "rename overwrite a target having nlink > 1," \
16679                 "changelog record has flags of $flags"
16680
16681         # rename doesn't overwrite a target (changelog flag 0x0)
16682         touch $DIR/$tdir/foo_161c
16683         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16684         changelog_dump | grep RENME | tail -n 5
16685         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16686         changelog_clear 0 || error "changelog_clear failed"
16687         if [ x$flags != "x0x0" ]; then
16688                 error "flag $flags is not 0x0"
16689         fi
16690         echo "rename doesn't overwrite a target," \
16691                 "changelog record has flags of $flags"
16692
16693         # define CLF_UNLINK_LAST 0x0001
16694         # unlink a file having nlink = 1 (changelog flag 0x1)
16695         rm -f $DIR/$tdir/foo2_161c
16696         changelog_dump | grep UNLNK | tail -n 5
16697         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16698         changelog_clear 0 || error "changelog_clear failed"
16699         if [ x$flags != "x0x1" ]; then
16700                 error "flag $flags is not 0x1"
16701         fi
16702         echo "unlink a file having nlink = 1," \
16703                 "changelog record has flags of $flags"
16704
16705         # unlink a file having nlink > 1 (changelog flag 0x0)
16706         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16707         rm -f $DIR/$tdir/foobar_161c
16708         changelog_dump | grep UNLNK | tail -n 5
16709         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16710         changelog_clear 0 || error "changelog_clear failed"
16711         if [ x$flags != "x0x0" ]; then
16712                 error "flag $flags is not 0x0"
16713         fi
16714         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16715 }
16716 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16717
16718 test_161d() {
16719         remote_mds_nodsh && skip "remote MDS with nodsh"
16720         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16721
16722         local pid
16723         local fid
16724
16725         changelog_register || error "changelog_register failed"
16726
16727         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16728         # interfer with $MOUNT/.lustre/fid/ access
16729         mkdir $DIR/$tdir
16730         [[ $? -eq 0 ]] || error "mkdir failed"
16731
16732         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16733         $LCTL set_param fail_loc=0x8000140c
16734         # 5s pause
16735         $LCTL set_param fail_val=5
16736
16737         # create file
16738         echo foofoo > $DIR/$tdir/$tfile &
16739         pid=$!
16740
16741         # wait for create to be delayed
16742         sleep 2
16743
16744         ps -p $pid
16745         [[ $? -eq 0 ]] || error "create should be blocked"
16746
16747         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16748         stack_trap "rm -f $tempfile"
16749         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16750         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16751         # some delay may occur during ChangeLog publishing and file read just
16752         # above, that could allow file write to happen finally
16753         [[ -s $tempfile ]] && echo "file should be empty"
16754
16755         $LCTL set_param fail_loc=0
16756
16757         wait $pid
16758         [[ $? -eq 0 ]] || error "create failed"
16759 }
16760 run_test 161d "create with concurrent .lustre/fid access"
16761
16762 check_path() {
16763         local expected="$1"
16764         shift
16765         local fid="$2"
16766
16767         local path
16768         path=$($LFS fid2path "$@")
16769         local rc=$?
16770
16771         if [ $rc -ne 0 ]; then
16772                 error "path looked up of '$expected' failed: rc=$rc"
16773         elif [ "$path" != "$expected" ]; then
16774                 error "path looked up '$path' instead of '$expected'"
16775         else
16776                 echo "FID '$fid' resolves to path '$path' as expected"
16777         fi
16778 }
16779
16780 test_162a() { # was test_162
16781         test_mkdir -p -c1 $DIR/$tdir/d2
16782         touch $DIR/$tdir/d2/$tfile
16783         touch $DIR/$tdir/d2/x1
16784         touch $DIR/$tdir/d2/x2
16785         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16786         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16787         # regular file
16788         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16789         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16790
16791         # softlink
16792         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16793         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16794         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16795
16796         # softlink to wrong file
16797         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16798         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16799         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16800
16801         # hardlink
16802         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16803         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16804         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16805         # fid2path dir/fsname should both work
16806         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16807         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16808
16809         # hardlink count: check that there are 2 links
16810         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16811         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16812
16813         # hardlink indexing: remove the first link
16814         rm $DIR/$tdir/d2/p/q/r/hlink
16815         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16816 }
16817 run_test 162a "path lookup sanity"
16818
16819 test_162b() {
16820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16822
16823         mkdir $DIR/$tdir
16824         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16825                                 error "create striped dir failed"
16826
16827         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16828                                         tail -n 1 | awk '{print $2}')
16829         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16830
16831         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16832         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16833
16834         # regular file
16835         for ((i=0;i<5;i++)); do
16836                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16837                         error "get fid for f$i failed"
16838                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16839
16840                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16841                         error "get fid for d$i failed"
16842                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16843         done
16844
16845         return 0
16846 }
16847 run_test 162b "striped directory path lookup sanity"
16848
16849 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16850 test_162c() {
16851         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16852                 skip "Need MDS version at least 2.7.51"
16853
16854         local lpath=$tdir.local
16855         local rpath=$tdir.remote
16856
16857         test_mkdir $DIR/$lpath
16858         test_mkdir $DIR/$rpath
16859
16860         for ((i = 0; i <= 101; i++)); do
16861                 lpath="$lpath/$i"
16862                 mkdir $DIR/$lpath
16863                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16864                         error "get fid for local directory $DIR/$lpath failed"
16865                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16866
16867                 rpath="$rpath/$i"
16868                 test_mkdir $DIR/$rpath
16869                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16870                         error "get fid for remote directory $DIR/$rpath failed"
16871                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16872         done
16873
16874         return 0
16875 }
16876 run_test 162c "fid2path works with paths 100 or more directories deep"
16877
16878 oalr_event_count() {
16879         local event="${1}"
16880         local trace="${2}"
16881
16882         awk -v name="${FSNAME}-OST0000" \
16883             -v event="${event}" \
16884             '$1 == "TRACE" && $2 == event && $3 == name' \
16885             "${trace}" |
16886         wc -l
16887 }
16888
16889 oalr_expect_event_count() {
16890         local event="${1}"
16891         local trace="${2}"
16892         local expect="${3}"
16893         local count
16894
16895         count=$(oalr_event_count "${event}" "${trace}")
16896         if ((count == expect)); then
16897                 return 0
16898         fi
16899
16900         error_noexit "${event} event count was '${count}', expected ${expect}"
16901         cat "${trace}" >&2
16902         exit 1
16903 }
16904
16905 cleanup_165() {
16906         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16907         stop ost1
16908         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16909 }
16910
16911 setup_165() {
16912         sync # Flush previous IOs so we can count log entries.
16913         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16914         stack_trap cleanup_165 EXIT
16915 }
16916
16917 test_165a() {
16918         local trace="/tmp/${tfile}.trace"
16919         local rc
16920         local count
16921
16922         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16923                 skip "OFD access log unsupported"
16924
16925         setup_165
16926         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16927         sleep 5
16928
16929         do_facet ost1 ofd_access_log_reader --list
16930         stop ost1
16931
16932         do_facet ost1 killall -TERM ofd_access_log_reader
16933         wait
16934         rc=$?
16935
16936         if ((rc != 0)); then
16937                 error "ofd_access_log_reader exited with rc = '${rc}'"
16938         fi
16939
16940         # Parse trace file for discovery events:
16941         oalr_expect_event_count alr_log_add "${trace}" 1
16942         oalr_expect_event_count alr_log_eof "${trace}" 1
16943         oalr_expect_event_count alr_log_free "${trace}" 1
16944 }
16945 run_test 165a "ofd access log discovery"
16946
16947 test_165b() {
16948         local trace="/tmp/${tfile}.trace"
16949         local file="${DIR}/${tfile}"
16950         local pfid1
16951         local pfid2
16952         local -a entry
16953         local rc
16954         local count
16955         local size
16956         local flags
16957
16958         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16959                 skip "OFD access log unsupported"
16960
16961         setup_165
16962         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16963         sleep 5
16964
16965         do_facet ost1 ofd_access_log_reader --list
16966
16967         lfs setstripe -c 1 -i 0 "${file}"
16968         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16969                 error "cannot create '${file}'"
16970
16971         sleep 5
16972         do_facet ost1 killall -TERM ofd_access_log_reader
16973         wait
16974         rc=$?
16975
16976         if ((rc != 0)); then
16977                 error "ofd_access_log_reader exited with rc = '${rc}'"
16978         fi
16979
16980         oalr_expect_event_count alr_log_entry "${trace}" 1
16981
16982         pfid1=$($LFS path2fid "${file}")
16983
16984         # 1     2             3   4    5     6   7    8    9     10
16985         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16986         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16987
16988         echo "entry = '${entry[*]}'" >&2
16989
16990         pfid2=${entry[4]}
16991         if [[ "${pfid1}" != "${pfid2}" ]]; then
16992                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16993         fi
16994
16995         size=${entry[8]}
16996         if ((size != 1048576)); then
16997                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16998         fi
16999
17000         flags=${entry[10]}
17001         if [[ "${flags}" != "w" ]]; then
17002                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17003         fi
17004
17005         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17006         sleep 5
17007
17008         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17009                 error "cannot read '${file}'"
17010         sleep 5
17011
17012         do_facet ost1 killall -TERM ofd_access_log_reader
17013         wait
17014         rc=$?
17015
17016         if ((rc != 0)); then
17017                 error "ofd_access_log_reader exited with rc = '${rc}'"
17018         fi
17019
17020         oalr_expect_event_count alr_log_entry "${trace}" 1
17021
17022         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17023         echo "entry = '${entry[*]}'" >&2
17024
17025         pfid2=${entry[4]}
17026         if [[ "${pfid1}" != "${pfid2}" ]]; then
17027                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17028         fi
17029
17030         size=${entry[8]}
17031         if ((size != 524288)); then
17032                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17033         fi
17034
17035         flags=${entry[10]}
17036         if [[ "${flags}" != "r" ]]; then
17037                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17038         fi
17039 }
17040 run_test 165b "ofd access log entries are produced and consumed"
17041
17042 test_165c() {
17043         local trace="/tmp/${tfile}.trace"
17044         local file="${DIR}/${tdir}/${tfile}"
17045
17046         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17047                 skip "OFD access log unsupported"
17048
17049         test_mkdir "${DIR}/${tdir}"
17050
17051         setup_165
17052         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17053         sleep 5
17054
17055         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17056
17057         # 4096 / 64 = 64. Create twice as many entries.
17058         for ((i = 0; i < 128; i++)); do
17059                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17060                         error "cannot create file"
17061         done
17062
17063         sync
17064
17065         do_facet ost1 killall -TERM ofd_access_log_reader
17066         wait
17067         rc=$?
17068         if ((rc != 0)); then
17069                 error "ofd_access_log_reader exited with rc = '${rc}'"
17070         fi
17071
17072         unlinkmany  "${file}-%d" 128
17073 }
17074 run_test 165c "full ofd access logs do not block IOs"
17075
17076 oal_get_read_count() {
17077         local stats="$1"
17078
17079         # STATS lustre-OST0001 alr_read_count 1
17080
17081         do_facet ost1 cat "${stats}" |
17082         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17083              END { print count; }'
17084 }
17085
17086 oal_expect_read_count() {
17087         local stats="$1"
17088         local count
17089         local expect="$2"
17090
17091         # Ask ofd_access_log_reader to write stats.
17092         do_facet ost1 killall -USR1 ofd_access_log_reader
17093
17094         # Allow some time for things to happen.
17095         sleep 1
17096
17097         count=$(oal_get_read_count "${stats}")
17098         if ((count == expect)); then
17099                 return 0
17100         fi
17101
17102         error_noexit "bad read count, got ${count}, expected ${expect}"
17103         do_facet ost1 cat "${stats}" >&2
17104         exit 1
17105 }
17106
17107 test_165d() {
17108         local stats="/tmp/${tfile}.stats"
17109         local file="${DIR}/${tdir}/${tfile}"
17110         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17111
17112         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17113                 skip "OFD access log unsupported"
17114
17115         test_mkdir "${DIR}/${tdir}"
17116
17117         setup_165
17118         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17119         sleep 5
17120
17121         lfs setstripe -c 1 -i 0 "${file}"
17122
17123         do_facet ost1 lctl set_param "${param}=rw"
17124         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17125                 error "cannot create '${file}'"
17126         oal_expect_read_count "${stats}" 1
17127
17128         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17129                 error "cannot read '${file}'"
17130         oal_expect_read_count "${stats}" 2
17131
17132         do_facet ost1 lctl set_param "${param}=r"
17133         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17134                 error "cannot create '${file}'"
17135         oal_expect_read_count "${stats}" 2
17136
17137         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17138                 error "cannot read '${file}'"
17139         oal_expect_read_count "${stats}" 3
17140
17141         do_facet ost1 lctl set_param "${param}=w"
17142         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17143                 error "cannot create '${file}'"
17144         oal_expect_read_count "${stats}" 4
17145
17146         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17147                 error "cannot read '${file}'"
17148         oal_expect_read_count "${stats}" 4
17149
17150         do_facet ost1 lctl set_param "${param}=0"
17151         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17152                 error "cannot create '${file}'"
17153         oal_expect_read_count "${stats}" 4
17154
17155         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17156                 error "cannot read '${file}'"
17157         oal_expect_read_count "${stats}" 4
17158
17159         do_facet ost1 killall -TERM ofd_access_log_reader
17160         wait
17161         rc=$?
17162         if ((rc != 0)); then
17163                 error "ofd_access_log_reader exited with rc = '${rc}'"
17164         fi
17165 }
17166 run_test 165d "ofd_access_log mask works"
17167
17168 test_165e() {
17169         local stats="/tmp/${tfile}.stats"
17170         local file0="${DIR}/${tdir}-0/${tfile}"
17171         local file1="${DIR}/${tdir}-1/${tfile}"
17172
17173         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17174                 skip "OFD access log unsupported"
17175
17176         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17177
17178         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17179         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17180
17181         lfs setstripe -c 1 -i 0 "${file0}"
17182         lfs setstripe -c 1 -i 0 "${file1}"
17183
17184         setup_165
17185         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17186         sleep 5
17187
17188         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17189                 error "cannot create '${file0}'"
17190         sync
17191         oal_expect_read_count "${stats}" 0
17192
17193         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17194                 error "cannot create '${file1}'"
17195         sync
17196         oal_expect_read_count "${stats}" 1
17197
17198         do_facet ost1 killall -TERM ofd_access_log_reader
17199         wait
17200         rc=$?
17201         if ((rc != 0)); then
17202                 error "ofd_access_log_reader exited with rc = '${rc}'"
17203         fi
17204 }
17205 run_test 165e "ofd_access_log MDT index filter works"
17206
17207 test_165f() {
17208         local trace="/tmp/${tfile}.trace"
17209         local rc
17210         local count
17211
17212         setup_165
17213         do_facet ost1 timeout 60 ofd_access_log_reader \
17214                 --exit-on-close --debug=- --trace=- > "${trace}" &
17215         sleep 5
17216         stop ost1
17217
17218         wait
17219         rc=$?
17220
17221         if ((rc != 0)); then
17222                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17223                 cat "${trace}"
17224                 exit 1
17225         fi
17226 }
17227 run_test 165f "ofd_access_log_reader --exit-on-close works"
17228
17229 test_169() {
17230         # do directio so as not to populate the page cache
17231         log "creating a 10 Mb file"
17232         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17233                 error "multiop failed while creating a file"
17234         log "starting reads"
17235         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17236         log "truncating the file"
17237         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17238                 error "multiop failed while truncating the file"
17239         log "killing dd"
17240         kill %+ || true # reads might have finished
17241         echo "wait until dd is finished"
17242         wait
17243         log "removing the temporary file"
17244         rm -rf $DIR/$tfile || error "tmp file removal failed"
17245 }
17246 run_test 169 "parallel read and truncate should not deadlock"
17247
17248 test_170() {
17249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17250
17251         $LCTL clear     # bug 18514
17252         $LCTL debug_daemon start $TMP/${tfile}_log_good
17253         touch $DIR/$tfile
17254         $LCTL debug_daemon stop
17255         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17256                 error "sed failed to read log_good"
17257
17258         $LCTL debug_daemon start $TMP/${tfile}_log_good
17259         rm -rf $DIR/$tfile
17260         $LCTL debug_daemon stop
17261
17262         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17263                error "lctl df log_bad failed"
17264
17265         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17266         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17267
17268         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17269         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17270
17271         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17272                 error "bad_line good_line1 good_line2 are empty"
17273
17274         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17275         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17276         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17277
17278         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17279         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17280         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17281
17282         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17283                 error "bad_line_new good_line_new are empty"
17284
17285         local expected_good=$((good_line1 + good_line2*2))
17286
17287         rm -f $TMP/${tfile}*
17288         # LU-231, short malformed line may not be counted into bad lines
17289         if [ $bad_line -ne $bad_line_new ] &&
17290                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17291                 error "expected $bad_line bad lines, but got $bad_line_new"
17292                 return 1
17293         fi
17294
17295         if [ $expected_good -ne $good_line_new ]; then
17296                 error "expected $expected_good good lines, but got $good_line_new"
17297                 return 2
17298         fi
17299         true
17300 }
17301 run_test 170 "test lctl df to handle corrupted log ====================="
17302
17303 test_171() { # bug20592
17304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17305
17306         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17307         $LCTL set_param fail_loc=0x50e
17308         $LCTL set_param fail_val=3000
17309         multiop_bg_pause $DIR/$tfile O_s || true
17310         local MULTIPID=$!
17311         kill -USR1 $MULTIPID
17312         # cause log dump
17313         sleep 3
17314         wait $MULTIPID
17315         if dmesg | grep "recursive fault"; then
17316                 error "caught a recursive fault"
17317         fi
17318         $LCTL set_param fail_loc=0
17319         true
17320 }
17321 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17322
17323 # it would be good to share it with obdfilter-survey/iokit-libecho code
17324 setup_obdecho_osc () {
17325         local rc=0
17326         local ost_nid=$1
17327         local obdfilter_name=$2
17328         echo "Creating new osc for $obdfilter_name on $ost_nid"
17329         # make sure we can find loopback nid
17330         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17331
17332         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17333                            ${obdfilter_name}_osc_UUID || rc=2; }
17334         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17335                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17336         return $rc
17337 }
17338
17339 cleanup_obdecho_osc () {
17340         local obdfilter_name=$1
17341         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17342         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17343         return 0
17344 }
17345
17346 obdecho_test() {
17347         local OBD=$1
17348         local node=$2
17349         local pages=${3:-64}
17350         local rc=0
17351         local id
17352
17353         local count=10
17354         local obd_size=$(get_obd_size $node $OBD)
17355         local page_size=$(get_page_size $node)
17356         if [[ -n "$obd_size" ]]; then
17357                 local new_count=$((obd_size / (pages * page_size / 1024)))
17358                 [[ $new_count -ge $count ]] || count=$new_count
17359         fi
17360
17361         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17362         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17363                            rc=2; }
17364         if [ $rc -eq 0 ]; then
17365             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17366             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17367         fi
17368         echo "New object id is $id"
17369         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17370                            rc=4; }
17371         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17372                            "test_brw $count w v $pages $id" || rc=4; }
17373         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17374                            rc=4; }
17375         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17376                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17377         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17378                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17379         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17380         return $rc
17381 }
17382
17383 test_180a() {
17384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17385
17386         if ! [ -d /sys/fs/lustre/echo_client ] &&
17387            ! module_loaded obdecho; then
17388                 load_module obdecho/obdecho &&
17389                         stack_trap "rmmod obdecho" EXIT ||
17390                         error "unable to load obdecho on client"
17391         fi
17392
17393         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17394         local host=$($LCTL get_param -n osc.$osc.import |
17395                      awk '/current_connection:/ { print $2 }' )
17396         local target=$($LCTL get_param -n osc.$osc.import |
17397                        awk '/target:/ { print $2 }' )
17398         target=${target%_UUID}
17399
17400         if [ -n "$target" ]; then
17401                 setup_obdecho_osc $host $target &&
17402                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17403                         { error "obdecho setup failed with $?"; return; }
17404
17405                 obdecho_test ${target}_osc client ||
17406                         error "obdecho_test failed on ${target}_osc"
17407         else
17408                 $LCTL get_param osc.$osc.import
17409                 error "there is no osc.$osc.import target"
17410         fi
17411 }
17412 run_test 180a "test obdecho on osc"
17413
17414 test_180b() {
17415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17416         remote_ost_nodsh && skip "remote OST with nodsh"
17417
17418         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17419                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17420                 error "failed to load module obdecho"
17421
17422         local target=$(do_facet ost1 $LCTL dl |
17423                        awk '/obdfilter/ { print $4; exit; }')
17424
17425         if [ -n "$target" ]; then
17426                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17427         else
17428                 do_facet ost1 $LCTL dl
17429                 error "there is no obdfilter target on ost1"
17430         fi
17431 }
17432 run_test 180b "test obdecho directly on obdfilter"
17433
17434 test_180c() { # LU-2598
17435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17436         remote_ost_nodsh && skip "remote OST with nodsh"
17437         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17438                 skip "Need MDS version at least 2.4.0"
17439
17440         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17441                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17442                 error "failed to load module obdecho"
17443
17444         local target=$(do_facet ost1 $LCTL dl |
17445                        awk '/obdfilter/ { print $4; exit; }')
17446
17447         if [ -n "$target" ]; then
17448                 local pages=16384 # 64MB bulk I/O RPC size
17449
17450                 obdecho_test "$target" ost1 "$pages" ||
17451                         error "obdecho_test with pages=$pages failed with $?"
17452         else
17453                 do_facet ost1 $LCTL dl
17454                 error "there is no obdfilter target on ost1"
17455         fi
17456 }
17457 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17458
17459 test_181() { # bug 22177
17460         test_mkdir $DIR/$tdir
17461         # create enough files to index the directory
17462         createmany -o $DIR/$tdir/foobar 4000
17463         # print attributes for debug purpose
17464         lsattr -d .
17465         # open dir
17466         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17467         MULTIPID=$!
17468         # remove the files & current working dir
17469         unlinkmany $DIR/$tdir/foobar 4000
17470         rmdir $DIR/$tdir
17471         kill -USR1 $MULTIPID
17472         wait $MULTIPID
17473         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17474         return 0
17475 }
17476 run_test 181 "Test open-unlinked dir ========================"
17477
17478 test_182() {
17479         local fcount=1000
17480         local tcount=10
17481
17482         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17483
17484         $LCTL set_param mdc.*.rpc_stats=clear
17485
17486         for (( i = 0; i < $tcount; i++ )) ; do
17487                 mkdir $DIR/$tdir/$i
17488         done
17489
17490         for (( i = 0; i < $tcount; i++ )) ; do
17491                 createmany -o $DIR/$tdir/$i/f- $fcount &
17492         done
17493         wait
17494
17495         for (( i = 0; i < $tcount; i++ )) ; do
17496                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17497         done
17498         wait
17499
17500         $LCTL get_param mdc.*.rpc_stats
17501
17502         rm -rf $DIR/$tdir
17503 }
17504 run_test 182 "Test parallel modify metadata operations ================"
17505
17506 test_183() { # LU-2275
17507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17508         remote_mds_nodsh && skip "remote MDS with nodsh"
17509         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17510                 skip "Need MDS version at least 2.3.56"
17511
17512         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17513         echo aaa > $DIR/$tdir/$tfile
17514
17515 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17516         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17517
17518         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17519         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17520
17521         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17522
17523         # Flush negative dentry cache
17524         touch $DIR/$tdir/$tfile
17525
17526         # We are not checking for any leaked references here, they'll
17527         # become evident next time we do cleanup with module unload.
17528         rm -rf $DIR/$tdir
17529 }
17530 run_test 183 "No crash or request leak in case of strange dispositions ========"
17531
17532 # test suite 184 is for LU-2016, LU-2017
17533 test_184a() {
17534         check_swap_layouts_support
17535
17536         dir0=$DIR/$tdir/$testnum
17537         test_mkdir -p -c1 $dir0
17538         ref1=/etc/passwd
17539         ref2=/etc/group
17540         file1=$dir0/f1
17541         file2=$dir0/f2
17542         $LFS setstripe -c1 $file1
17543         cp $ref1 $file1
17544         $LFS setstripe -c2 $file2
17545         cp $ref2 $file2
17546         gen1=$($LFS getstripe -g $file1)
17547         gen2=$($LFS getstripe -g $file2)
17548
17549         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17550         gen=$($LFS getstripe -g $file1)
17551         [[ $gen1 != $gen ]] ||
17552                 "Layout generation on $file1 does not change"
17553         gen=$($LFS getstripe -g $file2)
17554         [[ $gen2 != $gen ]] ||
17555                 "Layout generation on $file2 does not change"
17556
17557         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17558         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17559
17560         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17561 }
17562 run_test 184a "Basic layout swap"
17563
17564 test_184b() {
17565         check_swap_layouts_support
17566
17567         dir0=$DIR/$tdir/$testnum
17568         mkdir -p $dir0 || error "creating dir $dir0"
17569         file1=$dir0/f1
17570         file2=$dir0/f2
17571         file3=$dir0/f3
17572         dir1=$dir0/d1
17573         dir2=$dir0/d2
17574         mkdir $dir1 $dir2
17575         $LFS setstripe -c1 $file1
17576         $LFS setstripe -c2 $file2
17577         $LFS setstripe -c1 $file3
17578         chown $RUNAS_ID $file3
17579         gen1=$($LFS getstripe -g $file1)
17580         gen2=$($LFS getstripe -g $file2)
17581
17582         $LFS swap_layouts $dir1 $dir2 &&
17583                 error "swap of directories layouts should fail"
17584         $LFS swap_layouts $dir1 $file1 &&
17585                 error "swap of directory and file layouts should fail"
17586         $RUNAS $LFS swap_layouts $file1 $file2 &&
17587                 error "swap of file we cannot write should fail"
17588         $LFS swap_layouts $file1 $file3 &&
17589                 error "swap of file with different owner should fail"
17590         /bin/true # to clear error code
17591 }
17592 run_test 184b "Forbidden layout swap (will generate errors)"
17593
17594 test_184c() {
17595         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17596         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17597         check_swap_layouts_support
17598         check_swap_layout_no_dom $DIR
17599
17600         local dir0=$DIR/$tdir/$testnum
17601         mkdir -p $dir0 || error "creating dir $dir0"
17602
17603         local ref1=$dir0/ref1
17604         local ref2=$dir0/ref2
17605         local file1=$dir0/file1
17606         local file2=$dir0/file2
17607         # create a file large enough for the concurrent test
17608         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17609         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17610         echo "ref file size: ref1($(stat -c %s $ref1))," \
17611              "ref2($(stat -c %s $ref2))"
17612
17613         cp $ref2 $file2
17614         dd if=$ref1 of=$file1 bs=16k &
17615         local DD_PID=$!
17616
17617         # Make sure dd starts to copy file, but wait at most 5 seconds
17618         local loops=0
17619         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17620
17621         $LFS swap_layouts $file1 $file2
17622         local rc=$?
17623         wait $DD_PID
17624         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17625         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17626
17627         # how many bytes copied before swapping layout
17628         local copied=$(stat -c %s $file2)
17629         local remaining=$(stat -c %s $ref1)
17630         remaining=$((remaining - copied))
17631         echo "Copied $copied bytes before swapping layout..."
17632
17633         cmp -n $copied $file1 $ref2 | grep differ &&
17634                 error "Content mismatch [0, $copied) of ref2 and file1"
17635         cmp -n $copied $file2 $ref1 ||
17636                 error "Content mismatch [0, $copied) of ref1 and file2"
17637         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17638                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17639
17640         # clean up
17641         rm -f $ref1 $ref2 $file1 $file2
17642 }
17643 run_test 184c "Concurrent write and layout swap"
17644
17645 test_184d() {
17646         check_swap_layouts_support
17647         check_swap_layout_no_dom $DIR
17648         [ -z "$(which getfattr 2>/dev/null)" ] &&
17649                 skip_env "no getfattr command"
17650
17651         local file1=$DIR/$tdir/$tfile-1
17652         local file2=$DIR/$tdir/$tfile-2
17653         local file3=$DIR/$tdir/$tfile-3
17654         local lovea1
17655         local lovea2
17656
17657         mkdir -p $DIR/$tdir
17658         touch $file1 || error "create $file1 failed"
17659         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17660                 error "create $file2 failed"
17661         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17662                 error "create $file3 failed"
17663         lovea1=$(get_layout_param $file1)
17664
17665         $LFS swap_layouts $file2 $file3 ||
17666                 error "swap $file2 $file3 layouts failed"
17667         $LFS swap_layouts $file1 $file2 ||
17668                 error "swap $file1 $file2 layouts failed"
17669
17670         lovea2=$(get_layout_param $file2)
17671         echo "$lovea1"
17672         echo "$lovea2"
17673         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17674
17675         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17676         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17677 }
17678 run_test 184d "allow stripeless layouts swap"
17679
17680 test_184e() {
17681         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17682                 skip "Need MDS version at least 2.6.94"
17683         check_swap_layouts_support
17684         check_swap_layout_no_dom $DIR
17685         [ -z "$(which getfattr 2>/dev/null)" ] &&
17686                 skip_env "no getfattr command"
17687
17688         local file1=$DIR/$tdir/$tfile-1
17689         local file2=$DIR/$tdir/$tfile-2
17690         local file3=$DIR/$tdir/$tfile-3
17691         local lovea
17692
17693         mkdir -p $DIR/$tdir
17694         touch $file1 || error "create $file1 failed"
17695         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17696                 error "create $file2 failed"
17697         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17698                 error "create $file3 failed"
17699
17700         $LFS swap_layouts $file1 $file2 ||
17701                 error "swap $file1 $file2 layouts failed"
17702
17703         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17704         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17705
17706         echo 123 > $file1 || error "Should be able to write into $file1"
17707
17708         $LFS swap_layouts $file1 $file3 ||
17709                 error "swap $file1 $file3 layouts failed"
17710
17711         echo 123 > $file1 || error "Should be able to write into $file1"
17712
17713         rm -rf $file1 $file2 $file3
17714 }
17715 run_test 184e "Recreate layout after stripeless layout swaps"
17716
17717 test_184f() {
17718         # Create a file with name longer than sizeof(struct stat) ==
17719         # 144 to see if we can get chars from the file name to appear
17720         # in the returned striping. Note that 'f' == 0x66.
17721         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17722
17723         mkdir -p $DIR/$tdir
17724         mcreate $DIR/$tdir/$file
17725         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17726                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17727         fi
17728 }
17729 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17730
17731 test_185() { # LU-2441
17732         # LU-3553 - no volatile file support in old servers
17733         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17734                 skip "Need MDS version at least 2.3.60"
17735
17736         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17737         touch $DIR/$tdir/spoo
17738         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17739         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17740                 error "cannot create/write a volatile file"
17741         [ "$FILESET" == "" ] &&
17742         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17743                 error "FID is still valid after close"
17744
17745         multiop_bg_pause $DIR/$tdir vVw4096_c
17746         local multi_pid=$!
17747
17748         local OLD_IFS=$IFS
17749         IFS=":"
17750         local fidv=($fid)
17751         IFS=$OLD_IFS
17752         # assume that the next FID for this client is sequential, since stdout
17753         # is unfortunately eaten by multiop_bg_pause
17754         local n=$((${fidv[1]} + 1))
17755         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17756         if [ "$FILESET" == "" ]; then
17757                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17758                         error "FID is missing before close"
17759         fi
17760         kill -USR1 $multi_pid
17761         # 1 second delay, so if mtime change we will see it
17762         sleep 1
17763         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17764         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17765 }
17766 run_test 185 "Volatile file support"
17767
17768 function create_check_volatile() {
17769         local idx=$1
17770         local tgt
17771
17772         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17773         local PID=$!
17774         sleep 1
17775         local FID=$(cat /tmp/${tfile}.fid)
17776         [ "$FID" == "" ] && error "can't get FID for volatile"
17777         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17778         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17779         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17780         kill -USR1 $PID
17781         wait
17782         sleep 1
17783         cancel_lru_locks mdc # flush opencache
17784         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17785         return 0
17786 }
17787
17788 test_185a(){
17789         # LU-12516 - volatile creation via .lustre
17790         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17791                 skip "Need MDS version at least 2.3.55"
17792
17793         create_check_volatile 0
17794         [ $MDSCOUNT -lt 2 ] && return 0
17795
17796         # DNE case
17797         create_check_volatile 1
17798
17799         return 0
17800 }
17801 run_test 185a "Volatile file creation in .lustre/fid/"
17802
17803 test_187a() {
17804         remote_mds_nodsh && skip "remote MDS with nodsh"
17805         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17806                 skip "Need MDS version at least 2.3.0"
17807
17808         local dir0=$DIR/$tdir/$testnum
17809         mkdir -p $dir0 || error "creating dir $dir0"
17810
17811         local file=$dir0/file1
17812         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17813         local dv1=$($LFS data_version $file)
17814         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17815         local dv2=$($LFS data_version $file)
17816         [[ $dv1 != $dv2 ]] ||
17817                 error "data version did not change on write $dv1 == $dv2"
17818
17819         # clean up
17820         rm -f $file1
17821 }
17822 run_test 187a "Test data version change"
17823
17824 test_187b() {
17825         remote_mds_nodsh && skip "remote MDS with nodsh"
17826         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17827                 skip "Need MDS version at least 2.3.0"
17828
17829         local dir0=$DIR/$tdir/$testnum
17830         mkdir -p $dir0 || error "creating dir $dir0"
17831
17832         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17833         [[ ${DV[0]} != ${DV[1]} ]] ||
17834                 error "data version did not change on write"\
17835                       " ${DV[0]} == ${DV[1]}"
17836
17837         # clean up
17838         rm -f $file1
17839 }
17840 run_test 187b "Test data version change on volatile file"
17841
17842 test_200() {
17843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17844         remote_mgs_nodsh && skip "remote MGS with nodsh"
17845         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17846
17847         local POOL=${POOL:-cea1}
17848         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17849         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17850         # Pool OST targets
17851         local first_ost=0
17852         local last_ost=$(($OSTCOUNT - 1))
17853         local ost_step=2
17854         local ost_list=$(seq $first_ost $ost_step $last_ost)
17855         local ost_range="$first_ost $last_ost $ost_step"
17856         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17857         local file_dir=$POOL_ROOT/file_tst
17858         local subdir=$test_path/subdir
17859         local rc=0
17860
17861         while : ; do
17862                 # former test_200a test_200b
17863                 pool_add $POOL                          || { rc=$? ; break; }
17864                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17865                 # former test_200c test_200d
17866                 mkdir -p $test_path
17867                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17868                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17869                 mkdir -p $subdir
17870                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17871                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17872                                                         || { rc=$? ; break; }
17873                 # former test_200e test_200f
17874                 local files=$((OSTCOUNT*3))
17875                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17876                                                         || { rc=$? ; break; }
17877                 pool_create_files $POOL $file_dir $files "$ost_list" \
17878                                                         || { rc=$? ; break; }
17879                 # former test_200g test_200h
17880                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17881                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17882
17883                 # former test_201a test_201b test_201c
17884                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17885
17886                 local f=$test_path/$tfile
17887                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17888                 pool_remove $POOL $f                    || { rc=$? ; break; }
17889                 break
17890         done
17891
17892         destroy_test_pools
17893
17894         return $rc
17895 }
17896 run_test 200 "OST pools"
17897
17898 # usage: default_attr <count | size | offset>
17899 default_attr() {
17900         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17901 }
17902
17903 # usage: check_default_stripe_attr
17904 check_default_stripe_attr() {
17905         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17906         case $1 in
17907         --stripe-count|-c)
17908                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17909         --stripe-size|-S)
17910                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17911         --stripe-index|-i)
17912                 EXPECTED=-1;;
17913         *)
17914                 error "unknown getstripe attr '$1'"
17915         esac
17916
17917         [ $ACTUAL == $EXPECTED ] ||
17918                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17919 }
17920
17921 test_204a() {
17922         test_mkdir $DIR/$tdir
17923         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17924
17925         check_default_stripe_attr --stripe-count
17926         check_default_stripe_attr --stripe-size
17927         check_default_stripe_attr --stripe-index
17928 }
17929 run_test 204a "Print default stripe attributes"
17930
17931 test_204b() {
17932         test_mkdir $DIR/$tdir
17933         $LFS setstripe --stripe-count 1 $DIR/$tdir
17934
17935         check_default_stripe_attr --stripe-size
17936         check_default_stripe_attr --stripe-index
17937 }
17938 run_test 204b "Print default stripe size and offset"
17939
17940 test_204c() {
17941         test_mkdir $DIR/$tdir
17942         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17943
17944         check_default_stripe_attr --stripe-count
17945         check_default_stripe_attr --stripe-index
17946 }
17947 run_test 204c "Print default stripe count and offset"
17948
17949 test_204d() {
17950         test_mkdir $DIR/$tdir
17951         $LFS setstripe --stripe-index 0 $DIR/$tdir
17952
17953         check_default_stripe_attr --stripe-count
17954         check_default_stripe_attr --stripe-size
17955 }
17956 run_test 204d "Print default stripe count and size"
17957
17958 test_204e() {
17959         test_mkdir $DIR/$tdir
17960         $LFS setstripe -d $DIR/$tdir
17961
17962         check_default_stripe_attr --stripe-count --raw
17963         check_default_stripe_attr --stripe-size --raw
17964         check_default_stripe_attr --stripe-index --raw
17965 }
17966 run_test 204e "Print raw stripe attributes"
17967
17968 test_204f() {
17969         test_mkdir $DIR/$tdir
17970         $LFS setstripe --stripe-count 1 $DIR/$tdir
17971
17972         check_default_stripe_attr --stripe-size --raw
17973         check_default_stripe_attr --stripe-index --raw
17974 }
17975 run_test 204f "Print raw stripe size and offset"
17976
17977 test_204g() {
17978         test_mkdir $DIR/$tdir
17979         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17980
17981         check_default_stripe_attr --stripe-count --raw
17982         check_default_stripe_attr --stripe-index --raw
17983 }
17984 run_test 204g "Print raw stripe count and offset"
17985
17986 test_204h() {
17987         test_mkdir $DIR/$tdir
17988         $LFS setstripe --stripe-index 0 $DIR/$tdir
17989
17990         check_default_stripe_attr --stripe-count --raw
17991         check_default_stripe_attr --stripe-size --raw
17992 }
17993 run_test 204h "Print raw stripe count and size"
17994
17995 # Figure out which job scheduler is being used, if any,
17996 # or use a fake one
17997 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17998         JOBENV=SLURM_JOB_ID
17999 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18000         JOBENV=LSB_JOBID
18001 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18002         JOBENV=PBS_JOBID
18003 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18004         JOBENV=LOADL_STEP_ID
18005 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18006         JOBENV=JOB_ID
18007 else
18008         $LCTL list_param jobid_name > /dev/null 2>&1
18009         if [ $? -eq 0 ]; then
18010                 JOBENV=nodelocal
18011         else
18012                 JOBENV=FAKE_JOBID
18013         fi
18014 fi
18015 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18016
18017 verify_jobstats() {
18018         local cmd=($1)
18019         shift
18020         local facets="$@"
18021
18022 # we don't really need to clear the stats for this test to work, since each
18023 # command has a unique jobid, but it makes debugging easier if needed.
18024 #       for facet in $facets; do
18025 #               local dev=$(convert_facet2label $facet)
18026 #               # clear old jobstats
18027 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18028 #       done
18029
18030         # use a new JobID for each test, or we might see an old one
18031         [ "$JOBENV" = "FAKE_JOBID" ] &&
18032                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18033
18034         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18035
18036         [ "$JOBENV" = "nodelocal" ] && {
18037                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18038                 $LCTL set_param jobid_name=$FAKE_JOBID
18039                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18040         }
18041
18042         log "Test: ${cmd[*]}"
18043         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18044
18045         if [ $JOBENV = "FAKE_JOBID" ]; then
18046                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18047         else
18048                 ${cmd[*]}
18049         fi
18050
18051         # all files are created on OST0000
18052         for facet in $facets; do
18053                 local stats="*.$(convert_facet2label $facet).job_stats"
18054
18055                 # strip out libtool wrappers for in-tree executables
18056                 if [ $(do_facet $facet lctl get_param $stats |
18057                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18058                         do_facet $facet lctl get_param $stats
18059                         error "No jobstats for $JOBVAL found on $facet::$stats"
18060                 fi
18061         done
18062 }
18063
18064 jobstats_set() {
18065         local new_jobenv=$1
18066
18067         set_persistent_param_and_check client "jobid_var" \
18068                 "$FSNAME.sys.jobid_var" $new_jobenv
18069 }
18070
18071 test_205a() { # Job stats
18072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18073         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18074                 skip "Need MDS version with at least 2.7.1"
18075         remote_mgs_nodsh && skip "remote MGS with nodsh"
18076         remote_mds_nodsh && skip "remote MDS with nodsh"
18077         remote_ost_nodsh && skip "remote OST with nodsh"
18078         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18079                 skip "Server doesn't support jobstats"
18080         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18081
18082         local old_jobenv=$($LCTL get_param -n jobid_var)
18083         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18084
18085         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18086                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18087         else
18088                 stack_trap "do_facet mgs $PERM_CMD \
18089                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18090         fi
18091         changelog_register
18092
18093         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18094                                 mdt.*.job_cleanup_interval | head -n 1)
18095         local new_interval=5
18096         do_facet $SINGLEMDS \
18097                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18098         stack_trap "do_facet $SINGLEMDS \
18099                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18100         local start=$SECONDS
18101
18102         local cmd
18103         # mkdir
18104         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18105         verify_jobstats "$cmd" "$SINGLEMDS"
18106         # rmdir
18107         cmd="rmdir $DIR/$tdir"
18108         verify_jobstats "$cmd" "$SINGLEMDS"
18109         # mkdir on secondary MDT
18110         if [ $MDSCOUNT -gt 1 ]; then
18111                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18112                 verify_jobstats "$cmd" "mds2"
18113         fi
18114         # mknod
18115         cmd="mknod $DIR/$tfile c 1 3"
18116         verify_jobstats "$cmd" "$SINGLEMDS"
18117         # unlink
18118         cmd="rm -f $DIR/$tfile"
18119         verify_jobstats "$cmd" "$SINGLEMDS"
18120         # create all files on OST0000 so verify_jobstats can find OST stats
18121         # open & close
18122         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18123         verify_jobstats "$cmd" "$SINGLEMDS"
18124         # setattr
18125         cmd="touch $DIR/$tfile"
18126         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18127         # write
18128         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18129         verify_jobstats "$cmd" "ost1"
18130         # read
18131         cancel_lru_locks osc
18132         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18133         verify_jobstats "$cmd" "ost1"
18134         # truncate
18135         cmd="$TRUNCATE $DIR/$tfile 0"
18136         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18137         # rename
18138         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18139         verify_jobstats "$cmd" "$SINGLEMDS"
18140         # jobstats expiry - sleep until old stats should be expired
18141         local left=$((new_interval + 5 - (SECONDS - start)))
18142         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18143                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18144                         "0" $left
18145         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18146         verify_jobstats "$cmd" "$SINGLEMDS"
18147         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18148             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18149
18150         # Ensure that jobid are present in changelog (if supported by MDS)
18151         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18152                 changelog_dump | tail -10
18153                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18154                 [ $jobids -eq 9 ] ||
18155                         error "Wrong changelog jobid count $jobids != 9"
18156
18157                 # LU-5862
18158                 JOBENV="disable"
18159                 jobstats_set $JOBENV
18160                 touch $DIR/$tfile
18161                 changelog_dump | grep $tfile
18162                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18163                 [ $jobids -eq 0 ] ||
18164                         error "Unexpected jobids when jobid_var=$JOBENV"
18165         fi
18166
18167         # test '%j' access to environment variable - if supported
18168         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18169                 JOBENV="JOBCOMPLEX"
18170                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18171
18172                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18173         fi
18174
18175         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18176                 JOBENV="JOBCOMPLEX"
18177                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18178
18179                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18180         fi
18181
18182         # test '%j' access to per-session jobid - if supported
18183         if lctl list_param jobid_this_session > /dev/null 2>&1
18184         then
18185                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18186                 lctl set_param jobid_this_session=$USER
18187
18188                 JOBENV="JOBCOMPLEX"
18189                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18190
18191                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18192         fi
18193 }
18194 run_test 205a "Verify job stats"
18195
18196 # LU-13117, LU-13597
18197 test_205b() {
18198         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18199                 skip "Need MDS version at least 2.13.54.91"
18200
18201         job_stats="mdt.*.job_stats"
18202         $LCTL set_param $job_stats=clear
18203         # Setting jobid_var to USER might not be supported
18204         $LCTL set_param jobid_var=USER || true
18205         $LCTL set_param jobid_name="%e.%u"
18206         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18207         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18208                 grep "job_id:.*foolish" &&
18209                         error "Unexpected jobid found"
18210         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18211                 grep "open:.*min.*max.*sum" ||
18212                         error "wrong job_stats format found"
18213 }
18214 run_test 205b "Verify job stats jobid and output format"
18215
18216 # LU-13733
18217 test_205c() {
18218         $LCTL set_param llite.*.stats=0
18219         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18220         $LCTL get_param llite.*.stats
18221         $LCTL get_param llite.*.stats | grep \
18222                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18223                         error "wrong client stats format found"
18224 }
18225 run_test 205c "Verify client stats format"
18226
18227 # LU-1480, LU-1773 and LU-1657
18228 test_206() {
18229         mkdir -p $DIR/$tdir
18230         $LFS setstripe -c -1 $DIR/$tdir
18231 #define OBD_FAIL_LOV_INIT 0x1403
18232         $LCTL set_param fail_loc=0xa0001403
18233         $LCTL set_param fail_val=1
18234         touch $DIR/$tdir/$tfile || true
18235 }
18236 run_test 206 "fail lov_init_raid0() doesn't lbug"
18237
18238 test_207a() {
18239         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18240         local fsz=`stat -c %s $DIR/$tfile`
18241         cancel_lru_locks mdc
18242
18243         # do not return layout in getattr intent
18244 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18245         $LCTL set_param fail_loc=0x170
18246         local sz=`stat -c %s $DIR/$tfile`
18247
18248         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18249
18250         rm -rf $DIR/$tfile
18251 }
18252 run_test 207a "can refresh layout at glimpse"
18253
18254 test_207b() {
18255         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18256         local cksum=`md5sum $DIR/$tfile`
18257         local fsz=`stat -c %s $DIR/$tfile`
18258         cancel_lru_locks mdc
18259         cancel_lru_locks osc
18260
18261         # do not return layout in getattr intent
18262 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18263         $LCTL set_param fail_loc=0x171
18264
18265         # it will refresh layout after the file is opened but before read issues
18266         echo checksum is "$cksum"
18267         echo "$cksum" |md5sum -c --quiet || error "file differs"
18268
18269         rm -rf $DIR/$tfile
18270 }
18271 run_test 207b "can refresh layout at open"
18272
18273 test_208() {
18274         # FIXME: in this test suite, only RD lease is used. This is okay
18275         # for now as only exclusive open is supported. After generic lease
18276         # is done, this test suite should be revised. - Jinshan
18277
18278         remote_mds_nodsh && skip "remote MDS with nodsh"
18279         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18280                 skip "Need MDS version at least 2.4.52"
18281
18282         echo "==== test 1: verify get lease work"
18283         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18284
18285         echo "==== test 2: verify lease can be broken by upcoming open"
18286         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18287         local PID=$!
18288         sleep 1
18289
18290         $MULTIOP $DIR/$tfile oO_RDWR:c
18291         kill -USR1 $PID && wait $PID || error "break lease error"
18292
18293         echo "==== test 3: verify lease can't be granted if an open already exists"
18294         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18295         local PID=$!
18296         sleep 1
18297
18298         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18299         kill -USR1 $PID && wait $PID || error "open file error"
18300
18301         echo "==== test 4: lease can sustain over recovery"
18302         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18303         PID=$!
18304         sleep 1
18305
18306         fail mds1
18307
18308         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18309
18310         echo "==== test 5: lease broken can't be regained by replay"
18311         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18312         PID=$!
18313         sleep 1
18314
18315         # open file to break lease and then recovery
18316         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18317         fail mds1
18318
18319         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18320
18321         rm -f $DIR/$tfile
18322 }
18323 run_test 208 "Exclusive open"
18324
18325 test_209() {
18326         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18327                 skip_env "must have disp_stripe"
18328
18329         touch $DIR/$tfile
18330         sync; sleep 5; sync;
18331
18332         echo 3 > /proc/sys/vm/drop_caches
18333         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18334                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18335         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18336
18337         # open/close 500 times
18338         for i in $(seq 500); do
18339                 cat $DIR/$tfile
18340         done
18341
18342         echo 3 > /proc/sys/vm/drop_caches
18343         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18344                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18345         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18346
18347         echo "before: $req_before, after: $req_after"
18348         [ $((req_after - req_before)) -ge 300 ] &&
18349                 error "open/close requests are not freed"
18350         return 0
18351 }
18352 run_test 209 "read-only open/close requests should be freed promptly"
18353
18354 test_210() {
18355         local pid
18356
18357         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18358         pid=$!
18359         sleep 1
18360
18361         $LFS getstripe $DIR/$tfile
18362         kill -USR1 $pid
18363         wait $pid || error "multiop failed"
18364
18365         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18366         pid=$!
18367         sleep 1
18368
18369         $LFS getstripe $DIR/$tfile
18370         kill -USR1 $pid
18371         wait $pid || error "multiop failed"
18372 }
18373 run_test 210 "lfs getstripe does not break leases"
18374
18375 test_212() {
18376         size=`date +%s`
18377         size=$((size % 8192 + 1))
18378         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18379         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18380         rm -f $DIR/f212 $DIR/f212.xyz
18381 }
18382 run_test 212 "Sendfile test ============================================"
18383
18384 test_213() {
18385         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18386         cancel_lru_locks osc
18387         lctl set_param fail_loc=0x8000040f
18388         # generate a read lock
18389         cat $DIR/$tfile > /dev/null
18390         # write to the file, it will try to cancel the above read lock.
18391         cat /etc/hosts >> $DIR/$tfile
18392 }
18393 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18394
18395 test_214() { # for bug 20133
18396         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18397         for (( i=0; i < 340; i++ )) ; do
18398                 touch $DIR/$tdir/d214c/a$i
18399         done
18400
18401         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18402         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18403         ls $DIR/d214c || error "ls $DIR/d214c failed"
18404         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18405         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18406 }
18407 run_test 214 "hash-indexed directory test - bug 20133"
18408
18409 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18410 create_lnet_proc_files() {
18411         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18412 }
18413
18414 # counterpart of create_lnet_proc_files
18415 remove_lnet_proc_files() {
18416         rm -f $TMP/lnet_$1.sys
18417 }
18418
18419 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18420 # 3rd arg as regexp for body
18421 check_lnet_proc_stats() {
18422         local l=$(cat "$TMP/lnet_$1" |wc -l)
18423         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18424
18425         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18426 }
18427
18428 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18429 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18430 # optional and can be regexp for 2nd line (lnet.routes case)
18431 check_lnet_proc_entry() {
18432         local blp=2          # blp stands for 'position of 1st line of body'
18433         [ -z "$5" ] || blp=3 # lnet.routes case
18434
18435         local l=$(cat "$TMP/lnet_$1" |wc -l)
18436         # subtracting one from $blp because the body can be empty
18437         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18438
18439         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18440                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18441
18442         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18443                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18444
18445         # bail out if any unexpected line happened
18446         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18447         [ "$?" != 0 ] || error "$2 misformatted"
18448 }
18449
18450 test_215() { # for bugs 18102, 21079, 21517
18451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18452
18453         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18454         local P='[1-9][0-9]*'           # positive numeric
18455         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18456         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18457         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18458         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18459
18460         local L1 # regexp for 1st line
18461         local L2 # regexp for 2nd line (optional)
18462         local BR # regexp for the rest (body)
18463
18464         # lnet.stats should look as 11 space-separated non-negative numerics
18465         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18466         create_lnet_proc_files "stats"
18467         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18468         remove_lnet_proc_files "stats"
18469
18470         # lnet.routes should look like this:
18471         # Routing disabled/enabled
18472         # net hops priority state router
18473         # where net is a string like tcp0, hops > 0, priority >= 0,
18474         # state is up/down,
18475         # router is a string like 192.168.1.1@tcp2
18476         L1="^Routing (disabled|enabled)$"
18477         L2="^net +hops +priority +state +router$"
18478         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18479         create_lnet_proc_files "routes"
18480         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18481         remove_lnet_proc_files "routes"
18482
18483         # lnet.routers should look like this:
18484         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18485         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18486         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18487         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18488         L1="^ref +rtr_ref +alive +router$"
18489         BR="^$P +$P +(up|down) +$NID$"
18490         create_lnet_proc_files "routers"
18491         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18492         remove_lnet_proc_files "routers"
18493
18494         # lnet.peers should look like this:
18495         # nid refs state last max rtr min tx min queue
18496         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18497         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18498         # numeric (0 or >0 or <0), queue >= 0.
18499         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18500         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18501         create_lnet_proc_files "peers"
18502         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18503         remove_lnet_proc_files "peers"
18504
18505         # lnet.buffers  should look like this:
18506         # pages count credits min
18507         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18508         L1="^pages +count +credits +min$"
18509         BR="^ +$N +$N +$I +$I$"
18510         create_lnet_proc_files "buffers"
18511         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18512         remove_lnet_proc_files "buffers"
18513
18514         # lnet.nis should look like this:
18515         # nid status alive refs peer rtr max tx min
18516         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18517         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18518         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18519         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18520         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18521         create_lnet_proc_files "nis"
18522         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18523         remove_lnet_proc_files "nis"
18524
18525         # can we successfully write to lnet.stats?
18526         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18527 }
18528 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18529
18530 test_216() { # bug 20317
18531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18532         remote_ost_nodsh && skip "remote OST with nodsh"
18533
18534         local node
18535         local facets=$(get_facets OST)
18536         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18537
18538         save_lustre_params client "osc.*.contention_seconds" > $p
18539         save_lustre_params $facets \
18540                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18541         save_lustre_params $facets \
18542                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18543         save_lustre_params $facets \
18544                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18545         clear_stats osc.*.osc_stats
18546
18547         # agressive lockless i/o settings
18548         do_nodes $(comma_list $(osts_nodes)) \
18549                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18550                         ldlm.namespaces.filter-*.contended_locks=0 \
18551                         ldlm.namespaces.filter-*.contention_seconds=60"
18552         lctl set_param -n osc.*.contention_seconds=60
18553
18554         $DIRECTIO write $DIR/$tfile 0 10 4096
18555         $CHECKSTAT -s 40960 $DIR/$tfile
18556
18557         # disable lockless i/o
18558         do_nodes $(comma_list $(osts_nodes)) \
18559                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18560                         ldlm.namespaces.filter-*.contended_locks=32 \
18561                         ldlm.namespaces.filter-*.contention_seconds=0"
18562         lctl set_param -n osc.*.contention_seconds=0
18563         clear_stats osc.*.osc_stats
18564
18565         dd if=/dev/zero of=$DIR/$tfile count=0
18566         $CHECKSTAT -s 0 $DIR/$tfile
18567
18568         restore_lustre_params <$p
18569         rm -f $p
18570         rm $DIR/$tfile
18571 }
18572 run_test 216 "check lockless direct write updates file size and kms correctly"
18573
18574 test_217() { # bug 22430
18575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18576
18577         local node
18578         local nid
18579
18580         for node in $(nodes_list); do
18581                 nid=$(host_nids_address $node $NETTYPE)
18582                 if [[ $nid = *-* ]] ; then
18583                         echo "lctl ping $(h2nettype $nid)"
18584                         lctl ping $(h2nettype $nid)
18585                 else
18586                         echo "skipping $node (no hyphen detected)"
18587                 fi
18588         done
18589 }
18590 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18591
18592 test_218() {
18593        # do directio so as not to populate the page cache
18594        log "creating a 10 Mb file"
18595        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18596        log "starting reads"
18597        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18598        log "truncating the file"
18599        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18600        log "killing dd"
18601        kill %+ || true # reads might have finished
18602        echo "wait until dd is finished"
18603        wait
18604        log "removing the temporary file"
18605        rm -rf $DIR/$tfile || error "tmp file removal failed"
18606 }
18607 run_test 218 "parallel read and truncate should not deadlock"
18608
18609 test_219() {
18610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18611
18612         # write one partial page
18613         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18614         # set no grant so vvp_io_commit_write will do sync write
18615         $LCTL set_param fail_loc=0x411
18616         # write a full page at the end of file
18617         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18618
18619         $LCTL set_param fail_loc=0
18620         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18621         $LCTL set_param fail_loc=0x411
18622         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18623
18624         # LU-4201
18625         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18626         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18627 }
18628 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18629
18630 test_220() { #LU-325
18631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18632         remote_ost_nodsh && skip "remote OST with nodsh"
18633         remote_mds_nodsh && skip "remote MDS with nodsh"
18634         remote_mgs_nodsh && skip "remote MGS with nodsh"
18635
18636         local OSTIDX=0
18637
18638         # create on MDT0000 so the last_id and next_id are correct
18639         mkdir_on_mdt0 $DIR/$tdir
18640         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18641         OST=${OST%_UUID}
18642
18643         # on the mdt's osc
18644         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18645         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18646                         osp.$mdtosc_proc1.prealloc_last_id)
18647         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18648                         osp.$mdtosc_proc1.prealloc_next_id)
18649
18650         $LFS df -i
18651
18652         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18653         #define OBD_FAIL_OST_ENOINO              0x229
18654         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18655         create_pool $FSNAME.$TESTNAME || return 1
18656         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18657
18658         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18659
18660         MDSOBJS=$((last_id - next_id))
18661         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18662
18663         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18664         echo "OST still has $count kbytes free"
18665
18666         echo "create $MDSOBJS files @next_id..."
18667         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18668
18669         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18670                         osp.$mdtosc_proc1.prealloc_last_id)
18671         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18672                         osp.$mdtosc_proc1.prealloc_next_id)
18673
18674         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18675         $LFS df -i
18676
18677         echo "cleanup..."
18678
18679         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18680         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18681
18682         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18683                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18684         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18685                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18686         echo "unlink $MDSOBJS files @$next_id..."
18687         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18688 }
18689 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18690
18691 test_221() {
18692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18693
18694         dd if=`which date` of=$MOUNT/date oflag=sync
18695         chmod +x $MOUNT/date
18696
18697         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18698         $LCTL set_param fail_loc=0x80001401
18699
18700         $MOUNT/date > /dev/null
18701         rm -f $MOUNT/date
18702 }
18703 run_test 221 "make sure fault and truncate race to not cause OOM"
18704
18705 test_222a () {
18706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18707
18708         rm -rf $DIR/$tdir
18709         test_mkdir $DIR/$tdir
18710         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18711         createmany -o $DIR/$tdir/$tfile 10
18712         cancel_lru_locks mdc
18713         cancel_lru_locks osc
18714         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18715         $LCTL set_param fail_loc=0x31a
18716         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18717         $LCTL set_param fail_loc=0
18718         rm -r $DIR/$tdir
18719 }
18720 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18721
18722 test_222b () {
18723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18724
18725         rm -rf $DIR/$tdir
18726         test_mkdir $DIR/$tdir
18727         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18728         createmany -o $DIR/$tdir/$tfile 10
18729         cancel_lru_locks mdc
18730         cancel_lru_locks osc
18731         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18732         $LCTL set_param fail_loc=0x31a
18733         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18734         $LCTL set_param fail_loc=0
18735 }
18736 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18737
18738 test_223 () {
18739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18740
18741         rm -rf $DIR/$tdir
18742         test_mkdir $DIR/$tdir
18743         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18744         createmany -o $DIR/$tdir/$tfile 10
18745         cancel_lru_locks mdc
18746         cancel_lru_locks osc
18747         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18748         $LCTL set_param fail_loc=0x31b
18749         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18750         $LCTL set_param fail_loc=0
18751         rm -r $DIR/$tdir
18752 }
18753 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18754
18755 test_224a() { # LU-1039, MRP-303
18756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18757
18758         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18759         $LCTL set_param fail_loc=0x508
18760         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18761         $LCTL set_param fail_loc=0
18762         df $DIR
18763 }
18764 run_test 224a "Don't panic on bulk IO failure"
18765
18766 test_224b() { # LU-1039, MRP-303
18767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18768
18769         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18770         cancel_lru_locks osc
18771         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18772         $LCTL set_param fail_loc=0x515
18773         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18774         $LCTL set_param fail_loc=0
18775         df $DIR
18776 }
18777 run_test 224b "Don't panic on bulk IO failure"
18778
18779 test_224c() { # LU-6441
18780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18781         remote_mds_nodsh && skip "remote MDS with nodsh"
18782
18783         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18784         save_writethrough $p
18785         set_cache writethrough on
18786
18787         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18788         local at_max=$($LCTL get_param -n at_max)
18789         local timeout=$($LCTL get_param -n timeout)
18790         local test_at="at_max"
18791         local param_at="$FSNAME.sys.at_max"
18792         local test_timeout="timeout"
18793         local param_timeout="$FSNAME.sys.timeout"
18794
18795         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18796
18797         set_persistent_param_and_check client "$test_at" "$param_at" 0
18798         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18799
18800         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18801         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18802         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18803         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18804         sync
18805         do_facet ost1 "$LCTL set_param fail_loc=0"
18806
18807         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18808         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18809                 $timeout
18810
18811         $LCTL set_param -n $pages_per_rpc
18812         restore_lustre_params < $p
18813         rm -f $p
18814 }
18815 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18816
18817 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18818 test_225a () {
18819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18820         if [ -z ${MDSSURVEY} ]; then
18821                 skip_env "mds-survey not found"
18822         fi
18823         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18824                 skip "Need MDS version at least 2.2.51"
18825
18826         local mds=$(facet_host $SINGLEMDS)
18827         local target=$(do_nodes $mds 'lctl dl' |
18828                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18829
18830         local cmd1="file_count=1000 thrhi=4"
18831         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18832         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18833         local cmd="$cmd1 $cmd2 $cmd3"
18834
18835         rm -f ${TMP}/mds_survey*
18836         echo + $cmd
18837         eval $cmd || error "mds-survey with zero-stripe failed"
18838         cat ${TMP}/mds_survey*
18839         rm -f ${TMP}/mds_survey*
18840 }
18841 run_test 225a "Metadata survey sanity with zero-stripe"
18842
18843 test_225b () {
18844         if [ -z ${MDSSURVEY} ]; then
18845                 skip_env "mds-survey not found"
18846         fi
18847         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18848                 skip "Need MDS version at least 2.2.51"
18849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18850         remote_mds_nodsh && skip "remote MDS with nodsh"
18851         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18852                 skip_env "Need to mount OST to test"
18853         fi
18854
18855         local mds=$(facet_host $SINGLEMDS)
18856         local target=$(do_nodes $mds 'lctl dl' |
18857                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18858
18859         local cmd1="file_count=1000 thrhi=4"
18860         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18861         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18862         local cmd="$cmd1 $cmd2 $cmd3"
18863
18864         rm -f ${TMP}/mds_survey*
18865         echo + $cmd
18866         eval $cmd || error "mds-survey with stripe_count failed"
18867         cat ${TMP}/mds_survey*
18868         rm -f ${TMP}/mds_survey*
18869 }
18870 run_test 225b "Metadata survey sanity with stripe_count = 1"
18871
18872 mcreate_path2fid () {
18873         local mode=$1
18874         local major=$2
18875         local minor=$3
18876         local name=$4
18877         local desc=$5
18878         local path=$DIR/$tdir/$name
18879         local fid
18880         local rc
18881         local fid_path
18882
18883         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18884                 error "cannot create $desc"
18885
18886         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18887         rc=$?
18888         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18889
18890         fid_path=$($LFS fid2path $MOUNT $fid)
18891         rc=$?
18892         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18893
18894         [ "$path" == "$fid_path" ] ||
18895                 error "fid2path returned $fid_path, expected $path"
18896
18897         echo "pass with $path and $fid"
18898 }
18899
18900 test_226a () {
18901         rm -rf $DIR/$tdir
18902         mkdir -p $DIR/$tdir
18903
18904         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18905         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18906         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18907         mcreate_path2fid 0040666 0 0 dir "directory"
18908         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18909         mcreate_path2fid 0100666 0 0 file "regular file"
18910         mcreate_path2fid 0120666 0 0 link "symbolic link"
18911         mcreate_path2fid 0140666 0 0 sock "socket"
18912 }
18913 run_test 226a "call path2fid and fid2path on files of all type"
18914
18915 test_226b () {
18916         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18917
18918         local MDTIDX=1
18919
18920         rm -rf $DIR/$tdir
18921         mkdir -p $DIR/$tdir
18922         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18923                 error "create remote directory failed"
18924         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18925         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18926                                 "character special file (null)"
18927         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18928                                 "character special file (no device)"
18929         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18930         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18931                                 "block special file (loop)"
18932         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18933         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18934         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18935 }
18936 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18937
18938 test_226c () {
18939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18940         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18941                 skip "Need MDS version at least 2.13.55"
18942
18943         local submnt=/mnt/submnt
18944         local srcfile=/etc/passwd
18945         local dstfile=$submnt/passwd
18946         local path
18947         local fid
18948
18949         rm -rf $DIR/$tdir
18950         rm -rf $submnt
18951         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18952                 error "create remote directory failed"
18953         mkdir -p $submnt || error "create $submnt failed"
18954         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18955                 error "mount $submnt failed"
18956         stack_trap "umount $submnt" EXIT
18957
18958         cp $srcfile $dstfile
18959         fid=$($LFS path2fid $dstfile)
18960         path=$($LFS fid2path $submnt "$fid")
18961         [ "$path" = "$dstfile" ] ||
18962                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18963 }
18964 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18965
18966 # LU-1299 Executing or running ldd on a truncated executable does not
18967 # cause an out-of-memory condition.
18968 test_227() {
18969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18970         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18971
18972         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18973         chmod +x $MOUNT/date
18974
18975         $MOUNT/date > /dev/null
18976         ldd $MOUNT/date > /dev/null
18977         rm -f $MOUNT/date
18978 }
18979 run_test 227 "running truncated executable does not cause OOM"
18980
18981 # LU-1512 try to reuse idle OI blocks
18982 test_228a() {
18983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18984         remote_mds_nodsh && skip "remote MDS with nodsh"
18985         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18986
18987         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18988         local myDIR=$DIR/$tdir
18989
18990         mkdir -p $myDIR
18991         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18992         $LCTL set_param fail_loc=0x80001002
18993         createmany -o $myDIR/t- 10000
18994         $LCTL set_param fail_loc=0
18995         # The guard is current the largest FID holder
18996         touch $myDIR/guard
18997         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18998                     tr -d '[')
18999         local IDX=$(($SEQ % 64))
19000
19001         do_facet $SINGLEMDS sync
19002         # Make sure journal flushed.
19003         sleep 6
19004         local blk1=$(do_facet $SINGLEMDS \
19005                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19006                      grep Blockcount | awk '{print $4}')
19007
19008         # Remove old files, some OI blocks will become idle.
19009         unlinkmany $myDIR/t- 10000
19010         # Create new files, idle OI blocks should be reused.
19011         createmany -o $myDIR/t- 2000
19012         do_facet $SINGLEMDS sync
19013         # Make sure journal flushed.
19014         sleep 6
19015         local blk2=$(do_facet $SINGLEMDS \
19016                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19017                      grep Blockcount | awk '{print $4}')
19018
19019         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19020 }
19021 run_test 228a "try to reuse idle OI blocks"
19022
19023 test_228b() {
19024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19025         remote_mds_nodsh && skip "remote MDS with nodsh"
19026         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19027
19028         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19029         local myDIR=$DIR/$tdir
19030
19031         mkdir -p $myDIR
19032         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19033         $LCTL set_param fail_loc=0x80001002
19034         createmany -o $myDIR/t- 10000
19035         $LCTL set_param fail_loc=0
19036         # The guard is current the largest FID holder
19037         touch $myDIR/guard
19038         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19039                     tr -d '[')
19040         local IDX=$(($SEQ % 64))
19041
19042         do_facet $SINGLEMDS sync
19043         # Make sure journal flushed.
19044         sleep 6
19045         local blk1=$(do_facet $SINGLEMDS \
19046                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19047                      grep Blockcount | awk '{print $4}')
19048
19049         # Remove old files, some OI blocks will become idle.
19050         unlinkmany $myDIR/t- 10000
19051
19052         # stop the MDT
19053         stop $SINGLEMDS || error "Fail to stop MDT."
19054         # remount the MDT
19055         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19056
19057         df $MOUNT || error "Fail to df."
19058         # Create new files, idle OI blocks should be reused.
19059         createmany -o $myDIR/t- 2000
19060         do_facet $SINGLEMDS sync
19061         # Make sure journal flushed.
19062         sleep 6
19063         local blk2=$(do_facet $SINGLEMDS \
19064                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19065                      grep Blockcount | awk '{print $4}')
19066
19067         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19068 }
19069 run_test 228b "idle OI blocks can be reused after MDT restart"
19070
19071 #LU-1881
19072 test_228c() {
19073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19074         remote_mds_nodsh && skip "remote MDS with nodsh"
19075         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19076
19077         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19078         local myDIR=$DIR/$tdir
19079
19080         mkdir -p $myDIR
19081         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19082         $LCTL set_param fail_loc=0x80001002
19083         # 20000 files can guarantee there are index nodes in the OI file
19084         createmany -o $myDIR/t- 20000
19085         $LCTL set_param fail_loc=0
19086         # The guard is current the largest FID holder
19087         touch $myDIR/guard
19088         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19089                     tr -d '[')
19090         local IDX=$(($SEQ % 64))
19091
19092         do_facet $SINGLEMDS sync
19093         # Make sure journal flushed.
19094         sleep 6
19095         local blk1=$(do_facet $SINGLEMDS \
19096                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19097                      grep Blockcount | awk '{print $4}')
19098
19099         # Remove old files, some OI blocks will become idle.
19100         unlinkmany $myDIR/t- 20000
19101         rm -f $myDIR/guard
19102         # The OI file should become empty now
19103
19104         # Create new files, idle OI blocks should be reused.
19105         createmany -o $myDIR/t- 2000
19106         do_facet $SINGLEMDS sync
19107         # Make sure journal flushed.
19108         sleep 6
19109         local blk2=$(do_facet $SINGLEMDS \
19110                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19111                      grep Blockcount | awk '{print $4}')
19112
19113         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19114 }
19115 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19116
19117 test_229() { # LU-2482, LU-3448
19118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19119         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19120         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19121                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19122
19123         rm -f $DIR/$tfile
19124
19125         # Create a file with a released layout and stripe count 2.
19126         $MULTIOP $DIR/$tfile H2c ||
19127                 error "failed to create file with released layout"
19128
19129         $LFS getstripe -v $DIR/$tfile
19130
19131         local pattern=$($LFS getstripe -L $DIR/$tfile)
19132         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19133
19134         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19135                 error "getstripe"
19136         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19137         stat $DIR/$tfile || error "failed to stat released file"
19138
19139         chown $RUNAS_ID $DIR/$tfile ||
19140                 error "chown $RUNAS_ID $DIR/$tfile failed"
19141
19142         chgrp $RUNAS_ID $DIR/$tfile ||
19143                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19144
19145         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19146         rm $DIR/$tfile || error "failed to remove released file"
19147 }
19148 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19149
19150 test_230a() {
19151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19153         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19154                 skip "Need MDS version at least 2.11.52"
19155
19156         local MDTIDX=1
19157
19158         test_mkdir $DIR/$tdir
19159         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19160         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19161         [ $mdt_idx -ne 0 ] &&
19162                 error "create local directory on wrong MDT $mdt_idx"
19163
19164         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19165                         error "create remote directory failed"
19166         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19167         [ $mdt_idx -ne $MDTIDX ] &&
19168                 error "create remote directory on wrong MDT $mdt_idx"
19169
19170         createmany -o $DIR/$tdir/test_230/t- 10 ||
19171                 error "create files on remote directory failed"
19172         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19173         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19174         rm -r $DIR/$tdir || error "unlink remote directory failed"
19175 }
19176 run_test 230a "Create remote directory and files under the remote directory"
19177
19178 test_230b() {
19179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19180         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19181         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19182                 skip "Need MDS version at least 2.11.52"
19183
19184         local MDTIDX=1
19185         local mdt_index
19186         local i
19187         local file
19188         local pid
19189         local stripe_count
19190         local migrate_dir=$DIR/$tdir/migrate_dir
19191         local other_dir=$DIR/$tdir/other_dir
19192
19193         test_mkdir $DIR/$tdir
19194         test_mkdir -i0 -c1 $migrate_dir
19195         test_mkdir -i0 -c1 $other_dir
19196         for ((i=0; i<10; i++)); do
19197                 mkdir -p $migrate_dir/dir_${i}
19198                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19199                         error "create files under remote dir failed $i"
19200         done
19201
19202         cp /etc/passwd $migrate_dir/$tfile
19203         cp /etc/passwd $other_dir/$tfile
19204         chattr +SAD $migrate_dir
19205         chattr +SAD $migrate_dir/$tfile
19206
19207         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19208         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19209         local old_dir_mode=$(stat -c%f $migrate_dir)
19210         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19211
19212         mkdir -p $migrate_dir/dir_default_stripe2
19213         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19214         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19215
19216         mkdir -p $other_dir
19217         ln $migrate_dir/$tfile $other_dir/luna
19218         ln $migrate_dir/$tfile $migrate_dir/sofia
19219         ln $other_dir/$tfile $migrate_dir/david
19220         ln -s $migrate_dir/$tfile $other_dir/zachary
19221         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19222         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19223
19224         local len
19225         local lnktgt
19226
19227         # inline symlink
19228         for len in 58 59 60; do
19229                 lnktgt=$(str_repeat 'l' $len)
19230                 touch $migrate_dir/$lnktgt
19231                 ln -s $lnktgt $migrate_dir/${len}char_ln
19232         done
19233
19234         # PATH_MAX
19235         for len in 4094 4095; do
19236                 lnktgt=$(str_repeat 'l' $len)
19237                 ln -s $lnktgt $migrate_dir/${len}char_ln
19238         done
19239
19240         # NAME_MAX
19241         for len in 254 255; do
19242                 touch $migrate_dir/$(str_repeat 'l' $len)
19243         done
19244
19245         $LFS migrate -m $MDTIDX $migrate_dir ||
19246                 error "fails on migrating remote dir to MDT1"
19247
19248         echo "migratate to MDT1, then checking.."
19249         for ((i = 0; i < 10; i++)); do
19250                 for file in $(find $migrate_dir/dir_${i}); do
19251                         mdt_index=$($LFS getstripe -m $file)
19252                         # broken symlink getstripe will fail
19253                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19254                                 error "$file is not on MDT${MDTIDX}"
19255                 done
19256         done
19257
19258         # the multiple link file should still in MDT0
19259         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19260         [ $mdt_index == 0 ] ||
19261                 error "$file is not on MDT${MDTIDX}"
19262
19263         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19264         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19265                 error " expect $old_dir_flag get $new_dir_flag"
19266
19267         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19268         [ "$old_file_flag" = "$new_file_flag" ] ||
19269                 error " expect $old_file_flag get $new_file_flag"
19270
19271         local new_dir_mode=$(stat -c%f $migrate_dir)
19272         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19273                 error "expect mode $old_dir_mode get $new_dir_mode"
19274
19275         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19276         [ "$old_file_mode" = "$new_file_mode" ] ||
19277                 error "expect mode $old_file_mode get $new_file_mode"
19278
19279         diff /etc/passwd $migrate_dir/$tfile ||
19280                 error "$tfile different after migration"
19281
19282         diff /etc/passwd $other_dir/luna ||
19283                 error "luna different after migration"
19284
19285         diff /etc/passwd $migrate_dir/sofia ||
19286                 error "sofia different after migration"
19287
19288         diff /etc/passwd $migrate_dir/david ||
19289                 error "david different after migration"
19290
19291         diff /etc/passwd $other_dir/zachary ||
19292                 error "zachary different after migration"
19293
19294         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19295                 error "${tfile}_ln different after migration"
19296
19297         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19298                 error "${tfile}_ln_other different after migration"
19299
19300         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19301         [ $stripe_count = 2 ] ||
19302                 error "dir strpe_count $d != 2 after migration."
19303
19304         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19305         [ $stripe_count = 2 ] ||
19306                 error "file strpe_count $d != 2 after migration."
19307
19308         #migrate back to MDT0
19309         MDTIDX=0
19310
19311         $LFS migrate -m $MDTIDX $migrate_dir ||
19312                 error "fails on migrating remote dir to MDT0"
19313
19314         echo "migrate back to MDT0, checking.."
19315         for file in $(find $migrate_dir); do
19316                 mdt_index=$($LFS getstripe -m $file)
19317                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19318                         error "$file is not on MDT${MDTIDX}"
19319         done
19320
19321         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19322         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19323                 error " expect $old_dir_flag get $new_dir_flag"
19324
19325         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19326         [ "$old_file_flag" = "$new_file_flag" ] ||
19327                 error " expect $old_file_flag get $new_file_flag"
19328
19329         local new_dir_mode=$(stat -c%f $migrate_dir)
19330         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19331                 error "expect mode $old_dir_mode get $new_dir_mode"
19332
19333         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19334         [ "$old_file_mode" = "$new_file_mode" ] ||
19335                 error "expect mode $old_file_mode get $new_file_mode"
19336
19337         diff /etc/passwd ${migrate_dir}/$tfile ||
19338                 error "$tfile different after migration"
19339
19340         diff /etc/passwd ${other_dir}/luna ||
19341                 error "luna different after migration"
19342
19343         diff /etc/passwd ${migrate_dir}/sofia ||
19344                 error "sofia different after migration"
19345
19346         diff /etc/passwd ${other_dir}/zachary ||
19347                 error "zachary different after migration"
19348
19349         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19350                 error "${tfile}_ln different after migration"
19351
19352         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19353                 error "${tfile}_ln_other different after migration"
19354
19355         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19356         [ $stripe_count = 2 ] ||
19357                 error "dir strpe_count $d != 2 after migration."
19358
19359         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19360         [ $stripe_count = 2 ] ||
19361                 error "file strpe_count $d != 2 after migration."
19362
19363         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19364 }
19365 run_test 230b "migrate directory"
19366
19367 test_230c() {
19368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19369         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19370         remote_mds_nodsh && skip "remote MDS with nodsh"
19371         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19372                 skip "Need MDS version at least 2.11.52"
19373
19374         local MDTIDX=1
19375         local total=3
19376         local mdt_index
19377         local file
19378         local migrate_dir=$DIR/$tdir/migrate_dir
19379
19380         #If migrating directory fails in the middle, all entries of
19381         #the directory is still accessiable.
19382         test_mkdir $DIR/$tdir
19383         test_mkdir -i0 -c1 $migrate_dir
19384         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19385         stat $migrate_dir
19386         createmany -o $migrate_dir/f $total ||
19387                 error "create files under ${migrate_dir} failed"
19388
19389         # fail after migrating top dir, and this will fail only once, so the
19390         # first sub file migration will fail (currently f3), others succeed.
19391         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19392         do_facet mds1 lctl set_param fail_loc=0x1801
19393         local t=$(ls $migrate_dir | wc -l)
19394         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19395                 error "migrate should fail"
19396         local u=$(ls $migrate_dir | wc -l)
19397         [ "$u" == "$t" ] || error "$u != $t during migration"
19398
19399         # add new dir/file should succeed
19400         mkdir $migrate_dir/dir ||
19401                 error "mkdir failed under migrating directory"
19402         touch $migrate_dir/file ||
19403                 error "create file failed under migrating directory"
19404
19405         # add file with existing name should fail
19406         for file in $migrate_dir/f*; do
19407                 stat $file > /dev/null || error "stat $file failed"
19408                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19409                         error "open(O_CREAT|O_EXCL) $file should fail"
19410                 $MULTIOP $file m && error "create $file should fail"
19411                 touch $DIR/$tdir/remote_dir/$tfile ||
19412                         error "touch $tfile failed"
19413                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19414                         error "link $file should fail"
19415                 mdt_index=$($LFS getstripe -m $file)
19416                 if [ $mdt_index == 0 ]; then
19417                         # file failed to migrate is not allowed to rename to
19418                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19419                                 error "rename to $file should fail"
19420                 else
19421                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19422                                 error "rename to $file failed"
19423                 fi
19424                 echo hello >> $file || error "write $file failed"
19425         done
19426
19427         # resume migration with different options should fail
19428         $LFS migrate -m 0 $migrate_dir &&
19429                 error "migrate -m 0 $migrate_dir should fail"
19430
19431         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19432                 error "migrate -c 2 $migrate_dir should fail"
19433
19434         # resume migration should succeed
19435         $LFS migrate -m $MDTIDX $migrate_dir ||
19436                 error "migrate $migrate_dir failed"
19437
19438         echo "Finish migration, then checking.."
19439         for file in $(find $migrate_dir); do
19440                 mdt_index=$($LFS getstripe -m $file)
19441                 [ $mdt_index == $MDTIDX ] ||
19442                         error "$file is not on MDT${MDTIDX}"
19443         done
19444
19445         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19446 }
19447 run_test 230c "check directory accessiblity if migration failed"
19448
19449 test_230d() {
19450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19452         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19453                 skip "Need MDS version at least 2.11.52"
19454         # LU-11235
19455         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19456
19457         local migrate_dir=$DIR/$tdir/migrate_dir
19458         local old_index
19459         local new_index
19460         local old_count
19461         local new_count
19462         local new_hash
19463         local mdt_index
19464         local i
19465         local j
19466
19467         old_index=$((RANDOM % MDSCOUNT))
19468         old_count=$((MDSCOUNT - old_index))
19469         new_index=$((RANDOM % MDSCOUNT))
19470         new_count=$((MDSCOUNT - new_index))
19471         new_hash=1 # for all_char
19472
19473         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19474         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19475
19476         test_mkdir $DIR/$tdir
19477         test_mkdir -i $old_index -c $old_count $migrate_dir
19478
19479         for ((i=0; i<100; i++)); do
19480                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19481                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19482                         error "create files under remote dir failed $i"
19483         done
19484
19485         echo -n "Migrate from MDT$old_index "
19486         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19487         echo -n "to MDT$new_index"
19488         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19489         echo
19490
19491         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19492         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19493                 error "migrate remote dir error"
19494
19495         echo "Finish migration, then checking.."
19496         for file in $(find $migrate_dir); do
19497                 mdt_index=$($LFS getstripe -m $file)
19498                 if [ $mdt_index -lt $new_index ] ||
19499                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19500                         error "$file is on MDT$mdt_index"
19501                 fi
19502         done
19503
19504         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19505 }
19506 run_test 230d "check migrate big directory"
19507
19508 test_230e() {
19509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19511         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19512                 skip "Need MDS version at least 2.11.52"
19513
19514         local i
19515         local j
19516         local a_fid
19517         local b_fid
19518
19519         mkdir_on_mdt0 $DIR/$tdir
19520         mkdir $DIR/$tdir/migrate_dir
19521         mkdir $DIR/$tdir/other_dir
19522         touch $DIR/$tdir/migrate_dir/a
19523         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19524         ls $DIR/$tdir/other_dir
19525
19526         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19527                 error "migrate dir fails"
19528
19529         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19530         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19531
19532         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19533         [ $mdt_index == 0 ] || error "a is not on MDT0"
19534
19535         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19536                 error "migrate dir fails"
19537
19538         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19539         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19540
19541         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19542         [ $mdt_index == 1 ] || error "a is not on MDT1"
19543
19544         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19545         [ $mdt_index == 1 ] || error "b is not on MDT1"
19546
19547         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19548         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19549
19550         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19551
19552         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19553 }
19554 run_test 230e "migrate mulitple local link files"
19555
19556 test_230f() {
19557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19559         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19560                 skip "Need MDS version at least 2.11.52"
19561
19562         local a_fid
19563         local ln_fid
19564
19565         mkdir -p $DIR/$tdir
19566         mkdir $DIR/$tdir/migrate_dir
19567         $LFS mkdir -i1 $DIR/$tdir/other_dir
19568         touch $DIR/$tdir/migrate_dir/a
19569         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19570         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19571         ls $DIR/$tdir/other_dir
19572
19573         # a should be migrated to MDT1, since no other links on MDT0
19574         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19575                 error "#1 migrate dir fails"
19576         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19577         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19578         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19579         [ $mdt_index == 1 ] || error "a is not on MDT1"
19580
19581         # a should stay on MDT1, because it is a mulitple link file
19582         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19583                 error "#2 migrate dir fails"
19584         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19585         [ $mdt_index == 1 ] || error "a is not on MDT1"
19586
19587         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19588                 error "#3 migrate dir fails"
19589
19590         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19591         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19592         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19593
19594         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19595         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19596
19597         # a should be migrated to MDT0, since no other links on MDT1
19598         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19599                 error "#4 migrate dir fails"
19600         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19601         [ $mdt_index == 0 ] || error "a is not on MDT0"
19602
19603         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19604 }
19605 run_test 230f "migrate mulitple remote link files"
19606
19607 test_230g() {
19608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19610         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19611                 skip "Need MDS version at least 2.11.52"
19612
19613         mkdir -p $DIR/$tdir/migrate_dir
19614
19615         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19616                 error "migrating dir to non-exist MDT succeeds"
19617         true
19618 }
19619 run_test 230g "migrate dir to non-exist MDT"
19620
19621 test_230h() {
19622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19623         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19624         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19625                 skip "Need MDS version at least 2.11.52"
19626
19627         local mdt_index
19628
19629         mkdir -p $DIR/$tdir/migrate_dir
19630
19631         $LFS migrate -m1 $DIR &&
19632                 error "migrating mountpoint1 should fail"
19633
19634         $LFS migrate -m1 $DIR/$tdir/.. &&
19635                 error "migrating mountpoint2 should fail"
19636
19637         # same as mv
19638         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19639                 error "migrating $tdir/migrate_dir/.. should fail"
19640
19641         true
19642 }
19643 run_test 230h "migrate .. and root"
19644
19645 test_230i() {
19646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19647         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19648         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19649                 skip "Need MDS version at least 2.11.52"
19650
19651         mkdir -p $DIR/$tdir/migrate_dir
19652
19653         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19654                 error "migration fails with a tailing slash"
19655
19656         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19657                 error "migration fails with two tailing slashes"
19658 }
19659 run_test 230i "lfs migrate -m tolerates trailing slashes"
19660
19661 test_230j() {
19662         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19663         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19664                 skip "Need MDS version at least 2.11.52"
19665
19666         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19667         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19668                 error "create $tfile failed"
19669         cat /etc/passwd > $DIR/$tdir/$tfile
19670
19671         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19672
19673         cmp /etc/passwd $DIR/$tdir/$tfile ||
19674                 error "DoM file mismatch after migration"
19675 }
19676 run_test 230j "DoM file data not changed after dir migration"
19677
19678 test_230k() {
19679         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19680         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19681                 skip "Need MDS version at least 2.11.56"
19682
19683         local total=20
19684         local files_on_starting_mdt=0
19685
19686         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19687         $LFS getdirstripe $DIR/$tdir
19688         for i in $(seq $total); do
19689                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19690                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19691                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19692         done
19693
19694         echo "$files_on_starting_mdt files on MDT0"
19695
19696         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19697         $LFS getdirstripe $DIR/$tdir
19698
19699         files_on_starting_mdt=0
19700         for i in $(seq $total); do
19701                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19702                         error "file $tfile.$i mismatch after migration"
19703                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19704                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19705         done
19706
19707         echo "$files_on_starting_mdt files on MDT1 after migration"
19708         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19709
19710         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19711         $LFS getdirstripe $DIR/$tdir
19712
19713         files_on_starting_mdt=0
19714         for i in $(seq $total); do
19715                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19716                         error "file $tfile.$i mismatch after 2nd migration"
19717                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19718                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19719         done
19720
19721         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19722         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19723
19724         true
19725 }
19726 run_test 230k "file data not changed after dir migration"
19727
19728 test_230l() {
19729         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19730         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19731                 skip "Need MDS version at least 2.11.56"
19732
19733         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19734         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19735                 error "create files under remote dir failed $i"
19736         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19737 }
19738 run_test 230l "readdir between MDTs won't crash"
19739
19740 test_230m() {
19741         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19742         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19743                 skip "Need MDS version at least 2.11.56"
19744
19745         local MDTIDX=1
19746         local mig_dir=$DIR/$tdir/migrate_dir
19747         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19748         local shortstr="b"
19749         local val
19750
19751         echo "Creating files and dirs with xattrs"
19752         test_mkdir $DIR/$tdir
19753         test_mkdir -i0 -c1 $mig_dir
19754         mkdir $mig_dir/dir
19755         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19756                 error "cannot set xattr attr1 on dir"
19757         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19758                 error "cannot set xattr attr2 on dir"
19759         touch $mig_dir/dir/f0
19760         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19761                 error "cannot set xattr attr1 on file"
19762         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19763                 error "cannot set xattr attr2 on file"
19764         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19765         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19766         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19767         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19768         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19769         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19770         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19771         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19772         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19773
19774         echo "Migrating to MDT1"
19775         $LFS migrate -m $MDTIDX $mig_dir ||
19776                 error "fails on migrating dir to MDT1"
19777
19778         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19779         echo "Checking xattrs"
19780         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19781         [ "$val" = $longstr ] ||
19782                 error "expecting xattr1 $longstr on dir, found $val"
19783         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19784         [ "$val" = $shortstr ] ||
19785                 error "expecting xattr2 $shortstr on dir, found $val"
19786         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19787         [ "$val" = $longstr ] ||
19788                 error "expecting xattr1 $longstr on file, found $val"
19789         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19790         [ "$val" = $shortstr ] ||
19791                 error "expecting xattr2 $shortstr on file, found $val"
19792 }
19793 run_test 230m "xattrs not changed after dir migration"
19794
19795 test_230n() {
19796         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19797         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19798                 skip "Need MDS version at least 2.13.53"
19799
19800         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19801         cat /etc/hosts > $DIR/$tdir/$tfile
19802         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19803         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19804
19805         cmp /etc/hosts $DIR/$tdir/$tfile ||
19806                 error "File data mismatch after migration"
19807 }
19808 run_test 230n "Dir migration with mirrored file"
19809
19810 test_230o() {
19811         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19812         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19813                 skip "Need MDS version at least 2.13.52"
19814
19815         local mdts=$(comma_list $(mdts_nodes))
19816         local timeout=100
19817         local restripe_status
19818         local delta
19819         local i
19820
19821         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19822
19823         # in case "crush" hash type is not set
19824         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19825
19826         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19827                            mdt.*MDT0000.enable_dir_restripe)
19828         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19829         stack_trap "do_nodes $mdts $LCTL set_param \
19830                     mdt.*.enable_dir_restripe=$restripe_status"
19831
19832         mkdir $DIR/$tdir
19833         createmany -m $DIR/$tdir/f 100 ||
19834                 error "create files under remote dir failed $i"
19835         createmany -d $DIR/$tdir/d 100 ||
19836                 error "create dirs under remote dir failed $i"
19837
19838         for i in $(seq 2 $MDSCOUNT); do
19839                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19840                 $LFS setdirstripe -c $i $DIR/$tdir ||
19841                         error "split -c $i $tdir failed"
19842                 wait_update $HOSTNAME \
19843                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19844                         error "dir split not finished"
19845                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19846                         awk '/migrate/ {sum += $2} END { print sum }')
19847                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19848                 # delta is around total_files/stripe_count
19849                 (( $delta < 200 / (i - 1) + 4 )) ||
19850                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19851         done
19852 }
19853 run_test 230o "dir split"
19854
19855 test_230p() {
19856         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19857         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19858                 skip "Need MDS version at least 2.13.52"
19859
19860         local mdts=$(comma_list $(mdts_nodes))
19861         local timeout=100
19862         local restripe_status
19863         local delta
19864         local c
19865
19866         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19867
19868         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19869
19870         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19871                            mdt.*MDT0000.enable_dir_restripe)
19872         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19873         stack_trap "do_nodes $mdts $LCTL set_param \
19874                     mdt.*.enable_dir_restripe=$restripe_status"
19875
19876         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19877         createmany -m $DIR/$tdir/f 100 ||
19878                 error "create files under remote dir failed"
19879         createmany -d $DIR/$tdir/d 100 ||
19880                 error "create dirs under remote dir failed"
19881
19882         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19883                 local mdt_hash="crush"
19884
19885                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19886                 $LFS setdirstripe -c $c $DIR/$tdir ||
19887                         error "split -c $c $tdir failed"
19888                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19889                         mdt_hash="$mdt_hash,fixed"
19890                 elif [ $c -eq 1 ]; then
19891                         mdt_hash="none"
19892                 fi
19893                 wait_update $HOSTNAME \
19894                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19895                         error "dir merge not finished"
19896                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19897                         awk '/migrate/ {sum += $2} END { print sum }')
19898                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19899                 # delta is around total_files/stripe_count
19900                 (( delta < 200 / c + 4 )) ||
19901                         error "$delta files migrated >= $((200 / c + 4))"
19902         done
19903 }
19904 run_test 230p "dir merge"
19905
19906 test_230q() {
19907         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19908         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19909                 skip "Need MDS version at least 2.13.52"
19910
19911         local mdts=$(comma_list $(mdts_nodes))
19912         local saved_threshold=$(do_facet mds1 \
19913                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19914         local saved_delta=$(do_facet mds1 \
19915                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19916         local threshold=100
19917         local delta=2
19918         local total=0
19919         local stripe_count=0
19920         local stripe_index
19921         local nr_files
19922         local create
19923
19924         # test with fewer files on ZFS
19925         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19926
19927         stack_trap "do_nodes $mdts $LCTL set_param \
19928                     mdt.*.dir_split_count=$saved_threshold"
19929         stack_trap "do_nodes $mdts $LCTL set_param \
19930                     mdt.*.dir_split_delta=$saved_delta"
19931         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19932         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19933         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19934         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19935         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19936         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19937
19938         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19939         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19940
19941         create=$((threshold * 3 / 2))
19942         while [ $stripe_count -lt $MDSCOUNT ]; do
19943                 createmany -m $DIR/$tdir/f $total $create ||
19944                         error "create sub files failed"
19945                 stat $DIR/$tdir > /dev/null
19946                 total=$((total + create))
19947                 stripe_count=$((stripe_count + delta))
19948                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19949
19950                 wait_update $HOSTNAME \
19951                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19952                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19953
19954                 wait_update $HOSTNAME \
19955                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19956                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19957
19958                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19959                 echo "$nr_files/$total files on MDT$stripe_index after split"
19960                 # allow 10% margin of imbalance with crush hash
19961                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19962                         error "$nr_files files on MDT$stripe_index after split"
19963
19964                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19965                 [ $nr_files -eq $total ] ||
19966                         error "total sub files $nr_files != $total"
19967         done
19968
19969         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19970
19971         echo "fixed layout directory won't auto split"
19972         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19973         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19974                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19975         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19976                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19977 }
19978 run_test 230q "dir auto split"
19979
19980 test_230r() {
19981         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19982         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19983         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19984                 skip "Need MDS version at least 2.13.54"
19985
19986         # maximum amount of local locks:
19987         # parent striped dir - 2 locks
19988         # new stripe in parent to migrate to - 1 lock
19989         # source and target - 2 locks
19990         # Total 5 locks for regular file
19991         mkdir -p $DIR/$tdir
19992         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19993         touch $DIR/$tdir/dir1/eee
19994
19995         # create 4 hardlink for 4 more locks
19996         # Total: 9 locks > RS_MAX_LOCKS (8)
19997         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19998         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19999         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20000         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20001         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20002         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20003         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20004         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20005
20006         cancel_lru_locks mdc
20007
20008         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20009                 error "migrate dir fails"
20010
20011         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20012 }
20013 run_test 230r "migrate with too many local locks"
20014
20015 test_230s() {
20016         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20017                 skip "Need MDS version at least 2.13.57"
20018
20019         local mdts=$(comma_list $(mdts_nodes))
20020         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20021                                 mdt.*MDT0000.enable_dir_restripe)
20022
20023         stack_trap "do_nodes $mdts $LCTL set_param \
20024                     mdt.*.enable_dir_restripe=$restripe_status"
20025
20026         local st
20027         for st in 0 1; do
20028                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20029                 test_mkdir $DIR/$tdir
20030                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20031                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20032                 rmdir $DIR/$tdir
20033         done
20034 }
20035 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20036
20037 test_230t()
20038 {
20039         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20040         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20041                 skip "Need MDS version at least 2.14.50"
20042
20043         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20044         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20045         $LFS project -p 1 -s $DIR/$tdir ||
20046                 error "set $tdir project id failed"
20047         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20048                 error "set subdir project id failed"
20049         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20050 }
20051 run_test 230t "migrate directory with project ID set"
20052
20053 test_231a()
20054 {
20055         # For simplicity this test assumes that max_pages_per_rpc
20056         # is the same across all OSCs
20057         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20058         local bulk_size=$((max_pages * PAGE_SIZE))
20059         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20060                                        head -n 1)
20061
20062         mkdir -p $DIR/$tdir
20063         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20064                 error "failed to set stripe with -S ${brw_size}M option"
20065
20066         # clear the OSC stats
20067         $LCTL set_param osc.*.stats=0 &>/dev/null
20068         stop_writeback
20069
20070         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20071         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20072                 oflag=direct &>/dev/null || error "dd failed"
20073
20074         sync; sleep 1; sync # just to be safe
20075         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20076         if [ x$nrpcs != "x1" ]; then
20077                 $LCTL get_param osc.*.stats
20078                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20079         fi
20080
20081         start_writeback
20082         # Drop the OSC cache, otherwise we will read from it
20083         cancel_lru_locks osc
20084
20085         # clear the OSC stats
20086         $LCTL set_param osc.*.stats=0 &>/dev/null
20087
20088         # Client reads $bulk_size.
20089         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20090                 iflag=direct &>/dev/null || error "dd failed"
20091
20092         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20093         if [ x$nrpcs != "x1" ]; then
20094                 $LCTL get_param osc.*.stats
20095                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20096         fi
20097 }
20098 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20099
20100 test_231b() {
20101         mkdir -p $DIR/$tdir
20102         local i
20103         for i in {0..1023}; do
20104                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20105                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20106                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20107         done
20108         sync
20109 }
20110 run_test 231b "must not assert on fully utilized OST request buffer"
20111
20112 test_232a() {
20113         mkdir -p $DIR/$tdir
20114         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20115
20116         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20117         do_facet ost1 $LCTL set_param fail_loc=0x31c
20118
20119         # ignore dd failure
20120         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20121
20122         do_facet ost1 $LCTL set_param fail_loc=0
20123         umount_client $MOUNT || error "umount failed"
20124         mount_client $MOUNT || error "mount failed"
20125         stop ost1 || error "cannot stop ost1"
20126         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20127 }
20128 run_test 232a "failed lock should not block umount"
20129
20130 test_232b() {
20131         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20132                 skip "Need MDS version at least 2.10.58"
20133
20134         mkdir -p $DIR/$tdir
20135         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20136         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20137         sync
20138         cancel_lru_locks osc
20139
20140         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20141         do_facet ost1 $LCTL set_param fail_loc=0x31c
20142
20143         # ignore failure
20144         $LFS data_version $DIR/$tdir/$tfile || true
20145
20146         do_facet ost1 $LCTL set_param fail_loc=0
20147         umount_client $MOUNT || error "umount failed"
20148         mount_client $MOUNT || error "mount failed"
20149         stop ost1 || error "cannot stop ost1"
20150         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20151 }
20152 run_test 232b "failed data version lock should not block umount"
20153
20154 test_233a() {
20155         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20156                 skip "Need MDS version at least 2.3.64"
20157         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20158
20159         local fid=$($LFS path2fid $MOUNT)
20160
20161         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20162                 error "cannot access $MOUNT using its FID '$fid'"
20163 }
20164 run_test 233a "checking that OBF of the FS root succeeds"
20165
20166 test_233b() {
20167         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20168                 skip "Need MDS version at least 2.5.90"
20169         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20170
20171         local fid=$($LFS path2fid $MOUNT/.lustre)
20172
20173         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20174                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20175
20176         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20177         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20178                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20179 }
20180 run_test 233b "checking that OBF of the FS .lustre succeeds"
20181
20182 test_234() {
20183         local p="$TMP/sanityN-$TESTNAME.parameters"
20184         save_lustre_params client "llite.*.xattr_cache" > $p
20185         lctl set_param llite.*.xattr_cache 1 ||
20186                 skip_env "xattr cache is not supported"
20187
20188         mkdir -p $DIR/$tdir || error "mkdir failed"
20189         touch $DIR/$tdir/$tfile || error "touch failed"
20190         # OBD_FAIL_LLITE_XATTR_ENOMEM
20191         $LCTL set_param fail_loc=0x1405
20192         getfattr -n user.attr $DIR/$tdir/$tfile &&
20193                 error "getfattr should have failed with ENOMEM"
20194         $LCTL set_param fail_loc=0x0
20195         rm -rf $DIR/$tdir
20196
20197         restore_lustre_params < $p
20198         rm -f $p
20199 }
20200 run_test 234 "xattr cache should not crash on ENOMEM"
20201
20202 test_235() {
20203         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20204                 skip "Need MDS version at least 2.4.52"
20205
20206         flock_deadlock $DIR/$tfile
20207         local RC=$?
20208         case $RC in
20209                 0)
20210                 ;;
20211                 124) error "process hangs on a deadlock"
20212                 ;;
20213                 *) error "error executing flock_deadlock $DIR/$tfile"
20214                 ;;
20215         esac
20216 }
20217 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20218
20219 #LU-2935
20220 test_236() {
20221         check_swap_layouts_support
20222
20223         local ref1=/etc/passwd
20224         local ref2=/etc/group
20225         local file1=$DIR/$tdir/f1
20226         local file2=$DIR/$tdir/f2
20227
20228         test_mkdir -c1 $DIR/$tdir
20229         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20230         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20231         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20232         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20233         local fd=$(free_fd)
20234         local cmd="exec $fd<>$file2"
20235         eval $cmd
20236         rm $file2
20237         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20238                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20239         cmd="exec $fd>&-"
20240         eval $cmd
20241         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20242
20243         #cleanup
20244         rm -rf $DIR/$tdir
20245 }
20246 run_test 236 "Layout swap on open unlinked file"
20247
20248 # LU-4659 linkea consistency
20249 test_238() {
20250         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20251                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20252                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20253                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20254
20255         touch $DIR/$tfile
20256         ln $DIR/$tfile $DIR/$tfile.lnk
20257         touch $DIR/$tfile.new
20258         mv $DIR/$tfile.new $DIR/$tfile
20259         local fid1=$($LFS path2fid $DIR/$tfile)
20260         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20261         local path1=$($LFS fid2path $FSNAME "$fid1")
20262         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20263         local path2=$($LFS fid2path $FSNAME "$fid2")
20264         [ $tfile.lnk == $path2 ] ||
20265                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20266         rm -f $DIR/$tfile*
20267 }
20268 run_test 238 "Verify linkea consistency"
20269
20270 test_239A() { # was test_239
20271         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20272                 skip "Need MDS version at least 2.5.60"
20273
20274         local list=$(comma_list $(mdts_nodes))
20275
20276         mkdir -p $DIR/$tdir
20277         createmany -o $DIR/$tdir/f- 5000
20278         unlinkmany $DIR/$tdir/f- 5000
20279         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20280                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20281         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20282                         osp.*MDT*.sync_in_flight" | calc_sum)
20283         [ "$changes" -eq 0 ] || error "$changes not synced"
20284 }
20285 run_test 239A "osp_sync test"
20286
20287 test_239a() { #LU-5297
20288         remote_mds_nodsh && skip "remote MDS with nodsh"
20289
20290         touch $DIR/$tfile
20291         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20292         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20293         chgrp $RUNAS_GID $DIR/$tfile
20294         wait_delete_completed
20295 }
20296 run_test 239a "process invalid osp sync record correctly"
20297
20298 test_239b() { #LU-5297
20299         remote_mds_nodsh && skip "remote MDS with nodsh"
20300
20301         touch $DIR/$tfile1
20302         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20303         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20304         chgrp $RUNAS_GID $DIR/$tfile1
20305         wait_delete_completed
20306         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20307         touch $DIR/$tfile2
20308         chgrp $RUNAS_GID $DIR/$tfile2
20309         wait_delete_completed
20310 }
20311 run_test 239b "process osp sync record with ENOMEM error correctly"
20312
20313 test_240() {
20314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20315         remote_mds_nodsh && skip "remote MDS with nodsh"
20316
20317         mkdir -p $DIR/$tdir
20318
20319         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20320                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20321         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20322                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20323
20324         umount_client $MOUNT || error "umount failed"
20325         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20326         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20327         mount_client $MOUNT || error "failed to mount client"
20328
20329         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20330         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20331 }
20332 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20333
20334 test_241_bio() {
20335         local count=$1
20336         local bsize=$2
20337
20338         for LOOP in $(seq $count); do
20339                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20340                 cancel_lru_locks $OSC || true
20341         done
20342 }
20343
20344 test_241_dio() {
20345         local count=$1
20346         local bsize=$2
20347
20348         for LOOP in $(seq $1); do
20349                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20350                         2>/dev/null
20351         done
20352 }
20353
20354 test_241a() { # was test_241
20355         local bsize=$PAGE_SIZE
20356
20357         (( bsize < 40960 )) && bsize=40960
20358         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20359         ls -la $DIR/$tfile
20360         cancel_lru_locks $OSC
20361         test_241_bio 1000 $bsize &
20362         PID=$!
20363         test_241_dio 1000 $bsize
20364         wait $PID
20365 }
20366 run_test 241a "bio vs dio"
20367
20368 test_241b() {
20369         local bsize=$PAGE_SIZE
20370
20371         (( bsize < 40960 )) && bsize=40960
20372         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20373         ls -la $DIR/$tfile
20374         test_241_dio 1000 $bsize &
20375         PID=$!
20376         test_241_dio 1000 $bsize
20377         wait $PID
20378 }
20379 run_test 241b "dio vs dio"
20380
20381 test_242() {
20382         remote_mds_nodsh && skip "remote MDS with nodsh"
20383
20384         mkdir_on_mdt0 $DIR/$tdir
20385         touch $DIR/$tdir/$tfile
20386
20387         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20388         do_facet mds1 lctl set_param fail_loc=0x105
20389         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20390
20391         do_facet mds1 lctl set_param fail_loc=0
20392         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20393 }
20394 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20395
20396 test_243()
20397 {
20398         test_mkdir $DIR/$tdir
20399         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20400 }
20401 run_test 243 "various group lock tests"
20402
20403 test_244a()
20404 {
20405         test_mkdir $DIR/$tdir
20406         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20407         sendfile_grouplock $DIR/$tdir/$tfile || \
20408                 error "sendfile+grouplock failed"
20409         rm -rf $DIR/$tdir
20410 }
20411 run_test 244a "sendfile with group lock tests"
20412
20413 test_244b()
20414 {
20415         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20416
20417         local threads=50
20418         local size=$((1024*1024))
20419
20420         test_mkdir $DIR/$tdir
20421         for i in $(seq 1 $threads); do
20422                 local file=$DIR/$tdir/file_$((i / 10))
20423                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20424                 local pids[$i]=$!
20425         done
20426         for i in $(seq 1 $threads); do
20427                 wait ${pids[$i]}
20428         done
20429 }
20430 run_test 244b "multi-threaded write with group lock"
20431
20432 test_245() {
20433         local flagname="multi_mod_rpcs"
20434         local connect_data_name="max_mod_rpcs"
20435         local out
20436
20437         # check if multiple modify RPCs flag is set
20438         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20439                 grep "connect_flags:")
20440         echo "$out"
20441
20442         echo "$out" | grep -qw $flagname
20443         if [ $? -ne 0 ]; then
20444                 echo "connect flag $flagname is not set"
20445                 return
20446         fi
20447
20448         # check if multiple modify RPCs data is set
20449         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20450         echo "$out"
20451
20452         echo "$out" | grep -qw $connect_data_name ||
20453                 error "import should have connect data $connect_data_name"
20454 }
20455 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20456
20457 cleanup_247() {
20458         local submount=$1
20459
20460         trap 0
20461         umount_client $submount
20462         rmdir $submount
20463 }
20464
20465 test_247a() {
20466         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20467                 grep -q subtree ||
20468                 skip_env "Fileset feature is not supported"
20469
20470         local submount=${MOUNT}_$tdir
20471
20472         mkdir $MOUNT/$tdir
20473         mkdir -p $submount || error "mkdir $submount failed"
20474         FILESET="$FILESET/$tdir" mount_client $submount ||
20475                 error "mount $submount failed"
20476         trap "cleanup_247 $submount" EXIT
20477         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20478         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20479                 error "read $MOUNT/$tdir/$tfile failed"
20480         cleanup_247 $submount
20481 }
20482 run_test 247a "mount subdir as fileset"
20483
20484 test_247b() {
20485         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20486                 skip_env "Fileset feature is not supported"
20487
20488         local submount=${MOUNT}_$tdir
20489
20490         rm -rf $MOUNT/$tdir
20491         mkdir -p $submount || error "mkdir $submount failed"
20492         SKIP_FILESET=1
20493         FILESET="$FILESET/$tdir" mount_client $submount &&
20494                 error "mount $submount should fail"
20495         rmdir $submount
20496 }
20497 run_test 247b "mount subdir that dose not exist"
20498
20499 test_247c() {
20500         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20501                 skip_env "Fileset feature is not supported"
20502
20503         local submount=${MOUNT}_$tdir
20504
20505         mkdir -p $MOUNT/$tdir/dir1
20506         mkdir -p $submount || error "mkdir $submount failed"
20507         trap "cleanup_247 $submount" EXIT
20508         FILESET="$FILESET/$tdir" mount_client $submount ||
20509                 error "mount $submount failed"
20510         local fid=$($LFS path2fid $MOUNT/)
20511         $LFS fid2path $submount $fid && error "fid2path should fail"
20512         cleanup_247 $submount
20513 }
20514 run_test 247c "running fid2path outside subdirectory root"
20515
20516 test_247d() {
20517         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20518                 skip "Fileset feature is not supported"
20519
20520         local submount=${MOUNT}_$tdir
20521
20522         mkdir -p $MOUNT/$tdir/dir1
20523         mkdir -p $submount || error "mkdir $submount failed"
20524         FILESET="$FILESET/$tdir" mount_client $submount ||
20525                 error "mount $submount failed"
20526         trap "cleanup_247 $submount" EXIT
20527
20528         local td=$submount/dir1
20529         local fid=$($LFS path2fid $td)
20530         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20531
20532         # check that we get the same pathname back
20533         local rootpath
20534         local found
20535         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20536                 echo "$rootpath $fid"
20537                 found=$($LFS fid2path $rootpath "$fid")
20538                 [ -n "found" ] || error "fid2path should succeed"
20539                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20540         done
20541         # check wrong root path format
20542         rootpath=$submount"_wrong"
20543         found=$($LFS fid2path $rootpath "$fid")
20544         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20545
20546         cleanup_247 $submount
20547 }
20548 run_test 247d "running fid2path inside subdirectory root"
20549
20550 # LU-8037
20551 test_247e() {
20552         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20553                 grep -q subtree ||
20554                 skip "Fileset feature is not supported"
20555
20556         local submount=${MOUNT}_$tdir
20557
20558         mkdir $MOUNT/$tdir
20559         mkdir -p $submount || error "mkdir $submount failed"
20560         FILESET="$FILESET/.." mount_client $submount &&
20561                 error "mount $submount should fail"
20562         rmdir $submount
20563 }
20564 run_test 247e "mount .. as fileset"
20565
20566 test_247f() {
20567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20568         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20569                 skip "Need at least version 2.13.52"
20570         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20571                 skip "Need at least version 2.14.50"
20572         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20573                 grep -q subtree ||
20574                 skip "Fileset feature is not supported"
20575
20576         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20577         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20578                 error "mkdir remote failed"
20579         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20580                 error "mkdir remote/subdir failed"
20581         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20582                 error "mkdir striped failed"
20583         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20584
20585         local submount=${MOUNT}_$tdir
20586
20587         mkdir -p $submount || error "mkdir $submount failed"
20588         stack_trap "rmdir $submount"
20589
20590         local dir
20591         local stat
20592         local fileset=$FILESET
20593         local mdts=$(comma_list $(mdts_nodes))
20594
20595         stat=$(do_facet mds1 $LCTL get_param -n \
20596                 mdt.*MDT0000.enable_remote_subdir_mount)
20597         stack_trap "do_nodes $mdts $LCTL set_param \
20598                 mdt.*.enable_remote_subdir_mount=$stat"
20599
20600         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20601         stack_trap "umount_client $submount"
20602         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20603                 error "mount remote dir $dir should fail"
20604
20605         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20606                 $tdir/striped/. ; do
20607                 FILESET="$fileset/$dir" mount_client $submount ||
20608                         error "mount $dir failed"
20609                 umount_client $submount
20610         done
20611
20612         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20613         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20614                 error "mount $tdir/remote failed"
20615 }
20616 run_test 247f "mount striped or remote directory as fileset"
20617
20618 test_247g() {
20619         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20620         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20621                 skip "Need at least version 2.14.50"
20622
20623         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20624                 error "mkdir $tdir failed"
20625         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20626
20627         local submount=${MOUNT}_$tdir
20628
20629         mkdir -p $submount || error "mkdir $submount failed"
20630         stack_trap "rmdir $submount"
20631
20632         FILESET="$fileset/$tdir" mount_client $submount ||
20633                 error "mount $dir failed"
20634         stack_trap "umount $submount"
20635
20636         local mdts=$(comma_list $(mdts_nodes))
20637
20638         local nrpcs
20639
20640         stat $submount > /dev/null
20641         cancel_lru_locks $MDC
20642         stat $submount > /dev/null
20643         stat $submount/$tfile > /dev/null
20644         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20645         stat $submount/$tfile > /dev/null
20646         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20647                 awk '/getattr/ {sum += $2} END {print sum}')
20648
20649         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20650 }
20651 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20652
20653 test_248a() {
20654         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20655         [ -z "$fast_read_sav" ] && skip "no fast read support"
20656
20657         # create a large file for fast read verification
20658         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20659
20660         # make sure the file is created correctly
20661         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20662                 { rm -f $DIR/$tfile; skip "file creation error"; }
20663
20664         echo "Test 1: verify that fast read is 4 times faster on cache read"
20665
20666         # small read with fast read enabled
20667         $LCTL set_param -n llite.*.fast_read=1
20668         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20669                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20670                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20671         # small read with fast read disabled
20672         $LCTL set_param -n llite.*.fast_read=0
20673         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20674                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20675                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20676
20677         # verify that fast read is 4 times faster for cache read
20678         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20679                 error_not_in_vm "fast read was not 4 times faster: " \
20680                            "$t_fast vs $t_slow"
20681
20682         echo "Test 2: verify the performance between big and small read"
20683         $LCTL set_param -n llite.*.fast_read=1
20684
20685         # 1k non-cache read
20686         cancel_lru_locks osc
20687         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20688                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20689                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20690
20691         # 1M non-cache read
20692         cancel_lru_locks osc
20693         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20694                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20695                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20696
20697         # verify that big IO is not 4 times faster than small IO
20698         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20699                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20700
20701         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20702         rm -f $DIR/$tfile
20703 }
20704 run_test 248a "fast read verification"
20705
20706 test_248b() {
20707         # Default short_io_bytes=16384, try both smaller and larger sizes.
20708         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20709         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20710         echo "bs=53248 count=113 normal buffered write"
20711         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20712                 error "dd of initial data file failed"
20713         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20714
20715         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20716         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20717                 error "dd with sync normal writes failed"
20718         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20719
20720         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20721         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20722                 error "dd with sync small writes failed"
20723         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20724
20725         cancel_lru_locks osc
20726
20727         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20728         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20729         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20730         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20731                 iflag=direct || error "dd with O_DIRECT small read failed"
20732         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20733         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20734                 error "compare $TMP/$tfile.1 failed"
20735
20736         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20737         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20738
20739         # just to see what the maximum tunable value is, and test parsing
20740         echo "test invalid parameter 2MB"
20741         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20742                 error "too-large short_io_bytes allowed"
20743         echo "test maximum parameter 512KB"
20744         # if we can set a larger short_io_bytes, run test regardless of version
20745         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20746                 # older clients may not allow setting it this large, that's OK
20747                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20748                         skip "Need at least client version 2.13.50"
20749                 error "medium short_io_bytes failed"
20750         fi
20751         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20752         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20753
20754         echo "test large parameter 64KB"
20755         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20756         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20757
20758         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20759         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20760                 error "dd with sync large writes failed"
20761         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20762
20763         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20764         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20765         num=$((113 * 4096 / PAGE_SIZE))
20766         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20767         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20768                 error "dd with O_DIRECT large writes failed"
20769         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20770                 error "compare $DIR/$tfile.3 failed"
20771
20772         cancel_lru_locks osc
20773
20774         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20775         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20776                 error "dd with O_DIRECT large read failed"
20777         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20778                 error "compare $TMP/$tfile.2 failed"
20779
20780         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20781         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20782                 error "dd with O_DIRECT large read failed"
20783         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20784                 error "compare $TMP/$tfile.3 failed"
20785 }
20786 run_test 248b "test short_io read and write for both small and large sizes"
20787
20788 test_249() { # LU-7890
20789         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20790                 skip "Need at least version 2.8.54"
20791
20792         rm -f $DIR/$tfile
20793         $LFS setstripe -c 1 $DIR/$tfile
20794         # Offset 2T == 4k * 512M
20795         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20796                 error "dd to 2T offset failed"
20797 }
20798 run_test 249 "Write above 2T file size"
20799
20800 test_250() {
20801         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20802          && skip "no 16TB file size limit on ZFS"
20803
20804         $LFS setstripe -c 1 $DIR/$tfile
20805         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20806         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20807         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20808         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20809                 conv=notrunc,fsync && error "append succeeded"
20810         return 0
20811 }
20812 run_test 250 "Write above 16T limit"
20813
20814 test_251() {
20815         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20816
20817         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20818         #Skip once - writing the first stripe will succeed
20819         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20820         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20821                 error "short write happened"
20822
20823         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20824         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20825                 error "short read happened"
20826
20827         rm -f $DIR/$tfile
20828 }
20829 run_test 251 "Handling short read and write correctly"
20830
20831 test_252() {
20832         remote_mds_nodsh && skip "remote MDS with nodsh"
20833         remote_ost_nodsh && skip "remote OST with nodsh"
20834         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20835                 skip_env "ldiskfs only test"
20836         fi
20837
20838         local tgt
20839         local dev
20840         local out
20841         local uuid
20842         local num
20843         local gen
20844
20845         # check lr_reader on OST0000
20846         tgt=ost1
20847         dev=$(facet_device $tgt)
20848         out=$(do_facet $tgt $LR_READER $dev)
20849         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20850         echo "$out"
20851         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20852         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20853                 error "Invalid uuid returned by $LR_READER on target $tgt"
20854         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20855
20856         # check lr_reader -c on MDT0000
20857         tgt=mds1
20858         dev=$(facet_device $tgt)
20859         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20860                 skip "$LR_READER does not support additional options"
20861         fi
20862         out=$(do_facet $tgt $LR_READER -c $dev)
20863         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20864         echo "$out"
20865         num=$(echo "$out" | grep -c "mdtlov")
20866         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20867                 error "Invalid number of mdtlov clients returned by $LR_READER"
20868         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20869
20870         # check lr_reader -cr on MDT0000
20871         out=$(do_facet $tgt $LR_READER -cr $dev)
20872         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20873         echo "$out"
20874         echo "$out" | grep -q "^reply_data:$" ||
20875                 error "$LR_READER should have returned 'reply_data' section"
20876         num=$(echo "$out" | grep -c "client_generation")
20877         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20878 }
20879 run_test 252 "check lr_reader tool"
20880
20881 test_253() {
20882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20883         remote_mds_nodsh && skip "remote MDS with nodsh"
20884         remote_mgs_nodsh && skip "remote MGS with nodsh"
20885
20886         local ostidx=0
20887         local rc=0
20888         local ost_name=$(ostname_from_index $ostidx)
20889
20890         # on the mdt's osc
20891         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20892         do_facet $SINGLEMDS $LCTL get_param -n \
20893                 osp.$mdtosc_proc1.reserved_mb_high ||
20894                 skip  "remote MDS does not support reserved_mb_high"
20895
20896         rm -rf $DIR/$tdir
20897         wait_mds_ost_sync
20898         wait_delete_completed
20899         mkdir $DIR/$tdir
20900
20901         pool_add $TESTNAME || error "Pool creation failed"
20902         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20903
20904         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20905                 error "Setstripe failed"
20906
20907         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20908
20909         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20910                     grep "watermarks")
20911         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20912
20913         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20914                         osp.$mdtosc_proc1.prealloc_status)
20915         echo "prealloc_status $oa_status"
20916
20917         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20918                 error "File creation should fail"
20919
20920         #object allocation was stopped, but we still able to append files
20921         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20922                 oflag=append || error "Append failed"
20923
20924         rm -f $DIR/$tdir/$tfile.0
20925
20926         # For this test, we want to delete the files we created to go out of
20927         # space but leave the watermark, so we remain nearly out of space
20928         ost_watermarks_enospc_delete_files $tfile $ostidx
20929
20930         wait_delete_completed
20931
20932         sleep_maxage
20933
20934         for i in $(seq 10 12); do
20935                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20936                         2>/dev/null || error "File creation failed after rm"
20937         done
20938
20939         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20940                         osp.$mdtosc_proc1.prealloc_status)
20941         echo "prealloc_status $oa_status"
20942
20943         if (( oa_status != 0 )); then
20944                 error "Object allocation still disable after rm"
20945         fi
20946 }
20947 run_test 253 "Check object allocation limit"
20948
20949 test_254() {
20950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20951         remote_mds_nodsh && skip "remote MDS with nodsh"
20952         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20953                 skip "MDS does not support changelog_size"
20954
20955         local cl_user
20956         local MDT0=$(facet_svc $SINGLEMDS)
20957
20958         changelog_register || error "changelog_register failed"
20959
20960         changelog_clear 0 || error "changelog_clear failed"
20961
20962         local size1=$(do_facet $SINGLEMDS \
20963                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20964         echo "Changelog size $size1"
20965
20966         rm -rf $DIR/$tdir
20967         $LFS mkdir -i 0 $DIR/$tdir
20968         # change something
20969         mkdir -p $DIR/$tdir/pics/2008/zachy
20970         touch $DIR/$tdir/pics/2008/zachy/timestamp
20971         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20972         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20973         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20974         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20975         rm $DIR/$tdir/pics/desktop.jpg
20976
20977         local size2=$(do_facet $SINGLEMDS \
20978                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20979         echo "Changelog size after work $size2"
20980
20981         (( $size2 > $size1 )) ||
20982                 error "new Changelog size=$size2 less than old size=$size1"
20983 }
20984 run_test 254 "Check changelog size"
20985
20986 ladvise_no_type()
20987 {
20988         local type=$1
20989         local file=$2
20990
20991         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20992                 awk -F: '{print $2}' | grep $type > /dev/null
20993         if [ $? -ne 0 ]; then
20994                 return 0
20995         fi
20996         return 1
20997 }
20998
20999 ladvise_no_ioctl()
21000 {
21001         local file=$1
21002
21003         lfs ladvise -a willread $file > /dev/null 2>&1
21004         if [ $? -eq 0 ]; then
21005                 return 1
21006         fi
21007
21008         lfs ladvise -a willread $file 2>&1 |
21009                 grep "Inappropriate ioctl for device" > /dev/null
21010         if [ $? -eq 0 ]; then
21011                 return 0
21012         fi
21013         return 1
21014 }
21015
21016 percent() {
21017         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21018 }
21019
21020 # run a random read IO workload
21021 # usage: random_read_iops <filename> <filesize> <iosize>
21022 random_read_iops() {
21023         local file=$1
21024         local fsize=$2
21025         local iosize=${3:-4096}
21026
21027         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21028                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21029 }
21030
21031 drop_file_oss_cache() {
21032         local file="$1"
21033         local nodes="$2"
21034
21035         $LFS ladvise -a dontneed $file 2>/dev/null ||
21036                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21037 }
21038
21039 ladvise_willread_performance()
21040 {
21041         local repeat=10
21042         local average_origin=0
21043         local average_cache=0
21044         local average_ladvise=0
21045
21046         for ((i = 1; i <= $repeat; i++)); do
21047                 echo "Iter $i/$repeat: reading without willread hint"
21048                 cancel_lru_locks osc
21049                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21050                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21051                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21052                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21053
21054                 cancel_lru_locks osc
21055                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21056                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21057                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21058
21059                 cancel_lru_locks osc
21060                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21061                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21062                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21063                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21064                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21065         done
21066         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21067         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21068         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21069
21070         speedup_cache=$(percent $average_cache $average_origin)
21071         speedup_ladvise=$(percent $average_ladvise $average_origin)
21072
21073         echo "Average uncached read: $average_origin"
21074         echo "Average speedup with OSS cached read: " \
21075                 "$average_cache = +$speedup_cache%"
21076         echo "Average speedup with ladvise willread: " \
21077                 "$average_ladvise = +$speedup_ladvise%"
21078
21079         local lowest_speedup=20
21080         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21081                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21082                         "got $average_cache%. Skipping ladvise willread check."
21083                 return 0
21084         fi
21085
21086         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21087         # it is still good to run until then to exercise 'ladvise willread'
21088         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21089                 [ "$ost1_FSTYPE" = "zfs" ] &&
21090                 echo "osd-zfs does not support dontneed or drop_caches" &&
21091                 return 0
21092
21093         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21094         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21095                 error_not_in_vm "Speedup with willread is less than " \
21096                         "$lowest_speedup%, got $average_ladvise%"
21097 }
21098
21099 test_255a() {
21100         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21101                 skip "lustre < 2.8.54 does not support ladvise "
21102         remote_ost_nodsh && skip "remote OST with nodsh"
21103
21104         stack_trap "rm -f $DIR/$tfile"
21105         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21106
21107         ladvise_no_type willread $DIR/$tfile &&
21108                 skip "willread ladvise is not supported"
21109
21110         ladvise_no_ioctl $DIR/$tfile &&
21111                 skip "ladvise ioctl is not supported"
21112
21113         local size_mb=100
21114         local size=$((size_mb * 1048576))
21115         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21116                 error "dd to $DIR/$tfile failed"
21117
21118         lfs ladvise -a willread $DIR/$tfile ||
21119                 error "Ladvise failed with no range argument"
21120
21121         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21122                 error "Ladvise failed with no -l or -e argument"
21123
21124         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21125                 error "Ladvise failed with only -e argument"
21126
21127         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21128                 error "Ladvise failed with only -l argument"
21129
21130         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21131                 error "End offset should not be smaller than start offset"
21132
21133         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21134                 error "End offset should not be equal to start offset"
21135
21136         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21137                 error "Ladvise failed with overflowing -s argument"
21138
21139         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21140                 error "Ladvise failed with overflowing -e argument"
21141
21142         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21143                 error "Ladvise failed with overflowing -l argument"
21144
21145         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21146                 error "Ladvise succeeded with conflicting -l and -e arguments"
21147
21148         echo "Synchronous ladvise should wait"
21149         local delay=4
21150 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21151         do_nodes $(comma_list $(osts_nodes)) \
21152                 $LCTL set_param fail_val=$delay fail_loc=0x237
21153
21154         local start_ts=$SECONDS
21155         lfs ladvise -a willread $DIR/$tfile ||
21156                 error "Ladvise failed with no range argument"
21157         local end_ts=$SECONDS
21158         local inteval_ts=$((end_ts - start_ts))
21159
21160         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21161                 error "Synchronous advice didn't wait reply"
21162         fi
21163
21164         echo "Asynchronous ladvise shouldn't wait"
21165         local start_ts=$SECONDS
21166         lfs ladvise -a willread -b $DIR/$tfile ||
21167                 error "Ladvise failed with no range argument"
21168         local end_ts=$SECONDS
21169         local inteval_ts=$((end_ts - start_ts))
21170
21171         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21172                 error "Asynchronous advice blocked"
21173         fi
21174
21175         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21176         ladvise_willread_performance
21177 }
21178 run_test 255a "check 'lfs ladvise -a willread'"
21179
21180 facet_meminfo() {
21181         local facet=$1
21182         local info=$2
21183
21184         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21185 }
21186
21187 test_255b() {
21188         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21189                 skip "lustre < 2.8.54 does not support ladvise "
21190         remote_ost_nodsh && skip "remote OST with nodsh"
21191
21192         stack_trap "rm -f $DIR/$tfile"
21193         lfs setstripe -c 1 -i 0 $DIR/$tfile
21194
21195         ladvise_no_type dontneed $DIR/$tfile &&
21196                 skip "dontneed ladvise is not supported"
21197
21198         ladvise_no_ioctl $DIR/$tfile &&
21199                 skip "ladvise ioctl is not supported"
21200
21201         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21202                 [ "$ost1_FSTYPE" = "zfs" ] &&
21203                 skip "zfs-osd does not support 'ladvise dontneed'"
21204
21205         local size_mb=100
21206         local size=$((size_mb * 1048576))
21207         # In order to prevent disturbance of other processes, only check 3/4
21208         # of the memory usage
21209         local kibibytes=$((size_mb * 1024 * 3 / 4))
21210
21211         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21212                 error "dd to $DIR/$tfile failed"
21213
21214         #force write to complete before dropping OST cache & checking memory
21215         sync
21216
21217         local total=$(facet_meminfo ost1 MemTotal)
21218         echo "Total memory: $total KiB"
21219
21220         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21221         local before_read=$(facet_meminfo ost1 Cached)
21222         echo "Cache used before read: $before_read KiB"
21223
21224         lfs ladvise -a willread $DIR/$tfile ||
21225                 error "Ladvise willread failed"
21226         local after_read=$(facet_meminfo ost1 Cached)
21227         echo "Cache used after read: $after_read KiB"
21228
21229         lfs ladvise -a dontneed $DIR/$tfile ||
21230                 error "Ladvise dontneed again failed"
21231         local no_read=$(facet_meminfo ost1 Cached)
21232         echo "Cache used after dontneed ladvise: $no_read KiB"
21233
21234         if [ $total -lt $((before_read + kibibytes)) ]; then
21235                 echo "Memory is too small, abort checking"
21236                 return 0
21237         fi
21238
21239         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21240                 error "Ladvise willread should use more memory" \
21241                         "than $kibibytes KiB"
21242         fi
21243
21244         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21245                 error "Ladvise dontneed should release more memory" \
21246                         "than $kibibytes KiB"
21247         fi
21248 }
21249 run_test 255b "check 'lfs ladvise -a dontneed'"
21250
21251 test_255c() {
21252         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21253                 skip "lustre < 2.10.50 does not support lockahead"
21254
21255         local ost1_imp=$(get_osc_import_name client ost1)
21256         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21257                          cut -d'.' -f2)
21258         local count
21259         local new_count
21260         local difference
21261         local i
21262         local rc
21263
21264         test_mkdir -p $DIR/$tdir
21265         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21266
21267         #test 10 returns only success/failure
21268         i=10
21269         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21270         rc=$?
21271         if [ $rc -eq 255 ]; then
21272                 error "Ladvise test${i} failed, ${rc}"
21273         fi
21274
21275         #test 11 counts lock enqueue requests, all others count new locks
21276         i=11
21277         count=$(do_facet ost1 \
21278                 $LCTL get_param -n ost.OSS.ost.stats)
21279         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21280
21281         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21282         rc=$?
21283         if [ $rc -eq 255 ]; then
21284                 error "Ladvise test${i} failed, ${rc}"
21285         fi
21286
21287         new_count=$(do_facet ost1 \
21288                 $LCTL get_param -n ost.OSS.ost.stats)
21289         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21290                    awk '{ print $2 }')
21291
21292         difference="$((new_count - count))"
21293         if [ $difference -ne $rc ]; then
21294                 error "Ladvise test${i}, bad enqueue count, returned " \
21295                       "${rc}, actual ${difference}"
21296         fi
21297
21298         for i in $(seq 12 21); do
21299                 # If we do not do this, we run the risk of having too many
21300                 # locks and starting lock cancellation while we are checking
21301                 # lock counts.
21302                 cancel_lru_locks osc
21303
21304                 count=$($LCTL get_param -n \
21305                        ldlm.namespaces.$imp_name.lock_unused_count)
21306
21307                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21308                 rc=$?
21309                 if [ $rc -eq 255 ]; then
21310                         error "Ladvise test ${i} failed, ${rc}"
21311                 fi
21312
21313                 new_count=$($LCTL get_param -n \
21314                        ldlm.namespaces.$imp_name.lock_unused_count)
21315                 difference="$((new_count - count))"
21316
21317                 # Test 15 output is divided by 100 to map down to valid return
21318                 if [ $i -eq 15 ]; then
21319                         rc="$((rc * 100))"
21320                 fi
21321
21322                 if [ $difference -ne $rc ]; then
21323                         error "Ladvise test ${i}, bad lock count, returned " \
21324                               "${rc}, actual ${difference}"
21325                 fi
21326         done
21327
21328         #test 22 returns only success/failure
21329         i=22
21330         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21331         rc=$?
21332         if [ $rc -eq 255 ]; then
21333                 error "Ladvise test${i} failed, ${rc}"
21334         fi
21335 }
21336 run_test 255c "suite of ladvise lockahead tests"
21337
21338 test_256() {
21339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21340         remote_mds_nodsh && skip "remote MDS with nodsh"
21341         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21342         changelog_users $SINGLEMDS | grep "^cl" &&
21343                 skip "active changelog user"
21344
21345         local cl_user
21346         local cat_sl
21347         local mdt_dev
21348
21349         mdt_dev=$(mdsdevname 1)
21350         echo $mdt_dev
21351
21352         changelog_register || error "changelog_register failed"
21353
21354         rm -rf $DIR/$tdir
21355         mkdir_on_mdt0 $DIR/$tdir
21356
21357         changelog_clear 0 || error "changelog_clear failed"
21358
21359         # change something
21360         touch $DIR/$tdir/{1..10}
21361
21362         # stop the MDT
21363         stop $SINGLEMDS || error "Fail to stop MDT"
21364
21365         # remount the MDT
21366
21367         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21368
21369         #after mount new plainllog is used
21370         touch $DIR/$tdir/{11..19}
21371         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21372         stack_trap "rm -f $tmpfile"
21373         cat_sl=$(do_facet $SINGLEMDS "sync; \
21374                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21375                  llog_reader $tmpfile | grep -c type=1064553b")
21376         do_facet $SINGLEMDS llog_reader $tmpfile
21377
21378         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21379
21380         changelog_clear 0 || error "changelog_clear failed"
21381
21382         cat_sl=$(do_facet $SINGLEMDS "sync; \
21383                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21384                  llog_reader $tmpfile | grep -c type=1064553b")
21385
21386         if (( cat_sl == 2 )); then
21387                 error "Empty plain llog was not deleted from changelog catalog"
21388         elif (( cat_sl != 1 )); then
21389                 error "Active plain llog shouldn't be deleted from catalog"
21390         fi
21391 }
21392 run_test 256 "Check llog delete for empty and not full state"
21393
21394 test_257() {
21395         remote_mds_nodsh && skip "remote MDS with nodsh"
21396         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21397                 skip "Need MDS version at least 2.8.55"
21398
21399         test_mkdir $DIR/$tdir
21400
21401         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21402                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21403         stat $DIR/$tdir
21404
21405 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21406         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21407         local facet=mds$((mdtidx + 1))
21408         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21409         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21410
21411         stop $facet || error "stop MDS failed"
21412         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21413                 error "start MDS fail"
21414         wait_recovery_complete $facet
21415 }
21416 run_test 257 "xattr locks are not lost"
21417
21418 # Verify we take the i_mutex when security requires it
21419 test_258a() {
21420 #define OBD_FAIL_IMUTEX_SEC 0x141c
21421         $LCTL set_param fail_loc=0x141c
21422         touch $DIR/$tfile
21423         chmod u+s $DIR/$tfile
21424         chmod a+rwx $DIR/$tfile
21425         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21426         RC=$?
21427         if [ $RC -ne 0 ]; then
21428                 error "error, failed to take i_mutex, rc=$?"
21429         fi
21430         rm -f $DIR/$tfile
21431 }
21432 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21433
21434 # Verify we do NOT take the i_mutex in the normal case
21435 test_258b() {
21436 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21437         $LCTL set_param fail_loc=0x141d
21438         touch $DIR/$tfile
21439         chmod a+rwx $DIR
21440         chmod a+rw $DIR/$tfile
21441         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21442         RC=$?
21443         if [ $RC -ne 0 ]; then
21444                 error "error, took i_mutex unnecessarily, rc=$?"
21445         fi
21446         rm -f $DIR/$tfile
21447
21448 }
21449 run_test 258b "verify i_mutex security behavior"
21450
21451 test_259() {
21452         local file=$DIR/$tfile
21453         local before
21454         local after
21455
21456         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21457
21458         stack_trap "rm -f $file" EXIT
21459
21460         wait_delete_completed
21461         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21462         echo "before: $before"
21463
21464         $LFS setstripe -i 0 -c 1 $file
21465         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21466         sync_all_data
21467         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21468         echo "after write: $after"
21469
21470 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21471         do_facet ost1 $LCTL set_param fail_loc=0x2301
21472         $TRUNCATE $file 0
21473         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21474         echo "after truncate: $after"
21475
21476         stop ost1
21477         do_facet ost1 $LCTL set_param fail_loc=0
21478         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21479         sleep 2
21480         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21481         echo "after restart: $after"
21482         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21483                 error "missing truncate?"
21484
21485         return 0
21486 }
21487 run_test 259 "crash at delayed truncate"
21488
21489 test_260() {
21490 #define OBD_FAIL_MDC_CLOSE               0x806
21491         $LCTL set_param fail_loc=0x80000806
21492         touch $DIR/$tfile
21493
21494 }
21495 run_test 260 "Check mdc_close fail"
21496
21497 ### Data-on-MDT sanity tests ###
21498 test_270a() {
21499         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21500                 skip "Need MDS version at least 2.10.55 for DoM"
21501
21502         # create DoM file
21503         local dom=$DIR/$tdir/dom_file
21504         local tmp=$DIR/$tdir/tmp_file
21505
21506         mkdir_on_mdt0 $DIR/$tdir
21507
21508         # basic checks for DoM component creation
21509         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21510                 error "Can set MDT layout to non-first entry"
21511
21512         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21513                 error "Can define multiple entries as MDT layout"
21514
21515         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21516
21517         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21518         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21519         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21520
21521         local mdtidx=$($LFS getstripe -m $dom)
21522         local mdtname=MDT$(printf %04x $mdtidx)
21523         local facet=mds$((mdtidx + 1))
21524         local space_check=1
21525
21526         # Skip free space checks with ZFS
21527         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21528
21529         # write
21530         sync
21531         local size_tmp=$((65536 * 3))
21532         local mdtfree1=$(do_facet $facet \
21533                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21534
21535         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21536         # check also direct IO along write
21537         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21538         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21539         sync
21540         cmp $tmp $dom || error "file data is different"
21541         [ $(stat -c%s $dom) == $size_tmp ] ||
21542                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21543         if [ $space_check == 1 ]; then
21544                 local mdtfree2=$(do_facet $facet \
21545                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21546
21547                 # increase in usage from by $size_tmp
21548                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21549                         error "MDT free space wrong after write: " \
21550                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21551         fi
21552
21553         # truncate
21554         local size_dom=10000
21555
21556         $TRUNCATE $dom $size_dom
21557         [ $(stat -c%s $dom) == $size_dom ] ||
21558                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21559         if [ $space_check == 1 ]; then
21560                 mdtfree1=$(do_facet $facet \
21561                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21562                 # decrease in usage from $size_tmp to new $size_dom
21563                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21564                   $(((size_tmp - size_dom) / 1024)) ] ||
21565                         error "MDT free space is wrong after truncate: " \
21566                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21567         fi
21568
21569         # append
21570         cat $tmp >> $dom
21571         sync
21572         size_dom=$((size_dom + size_tmp))
21573         [ $(stat -c%s $dom) == $size_dom ] ||
21574                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21575         if [ $space_check == 1 ]; then
21576                 mdtfree2=$(do_facet $facet \
21577                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21578                 # increase in usage by $size_tmp from previous
21579                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21580                         error "MDT free space is wrong after append: " \
21581                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21582         fi
21583
21584         # delete
21585         rm $dom
21586         if [ $space_check == 1 ]; then
21587                 mdtfree1=$(do_facet $facet \
21588                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21589                 # decrease in usage by $size_dom from previous
21590                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21591                         error "MDT free space is wrong after removal: " \
21592                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21593         fi
21594
21595         # combined striping
21596         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21597                 error "Can't create DoM + OST striping"
21598
21599         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21600         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21601         # check also direct IO along write
21602         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21603         sync
21604         cmp $tmp $dom || error "file data is different"
21605         [ $(stat -c%s $dom) == $size_tmp ] ||
21606                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21607         rm $dom $tmp
21608
21609         return 0
21610 }
21611 run_test 270a "DoM: basic functionality tests"
21612
21613 test_270b() {
21614         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21615                 skip "Need MDS version at least 2.10.55"
21616
21617         local dom=$DIR/$tdir/dom_file
21618         local max_size=1048576
21619
21620         mkdir -p $DIR/$tdir
21621         $LFS setstripe -E $max_size -L mdt $dom
21622
21623         # truncate over the limit
21624         $TRUNCATE $dom $(($max_size + 1)) &&
21625                 error "successful truncate over the maximum size"
21626         # write over the limit
21627         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21628                 error "successful write over the maximum size"
21629         # append over the limit
21630         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21631         echo "12345" >> $dom && error "successful append over the maximum size"
21632         rm $dom
21633
21634         return 0
21635 }
21636 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21637
21638 test_270c() {
21639         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21640                 skip "Need MDS version at least 2.10.55"
21641
21642         mkdir -p $DIR/$tdir
21643         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21644
21645         # check files inherit DoM EA
21646         touch $DIR/$tdir/first
21647         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21648                 error "bad pattern"
21649         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21650                 error "bad stripe count"
21651         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21652                 error "bad stripe size"
21653
21654         # check directory inherits DoM EA and uses it as default
21655         mkdir $DIR/$tdir/subdir
21656         touch $DIR/$tdir/subdir/second
21657         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21658                 error "bad pattern in sub-directory"
21659         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21660                 error "bad stripe count in sub-directory"
21661         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21662                 error "bad stripe size in sub-directory"
21663         return 0
21664 }
21665 run_test 270c "DoM: DoM EA inheritance tests"
21666
21667 test_270d() {
21668         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21669                 skip "Need MDS version at least 2.10.55"
21670
21671         mkdir -p $DIR/$tdir
21672         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21673
21674         # inherit default DoM striping
21675         mkdir $DIR/$tdir/subdir
21676         touch $DIR/$tdir/subdir/f1
21677
21678         # change default directory striping
21679         $LFS setstripe -c 1 $DIR/$tdir/subdir
21680         touch $DIR/$tdir/subdir/f2
21681         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21682                 error "wrong default striping in file 2"
21683         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21684                 error "bad pattern in file 2"
21685         return 0
21686 }
21687 run_test 270d "DoM: change striping from DoM to RAID0"
21688
21689 test_270e() {
21690         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21691                 skip "Need MDS version at least 2.10.55"
21692
21693         mkdir -p $DIR/$tdir/dom
21694         mkdir -p $DIR/$tdir/norm
21695         DOMFILES=20
21696         NORMFILES=10
21697         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21698         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21699
21700         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21701         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21702
21703         # find DoM files by layout
21704         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21705         [ $NUM -eq  $DOMFILES ] ||
21706                 error "lfs find -L: found $NUM, expected $DOMFILES"
21707         echo "Test 1: lfs find 20 DOM files by layout: OK"
21708
21709         # there should be 1 dir with default DOM striping
21710         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21711         [ $NUM -eq  1 ] ||
21712                 error "lfs find -L: found $NUM, expected 1 dir"
21713         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21714
21715         # find DoM files by stripe size
21716         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21717         [ $NUM -eq  $DOMFILES ] ||
21718                 error "lfs find -S: found $NUM, expected $DOMFILES"
21719         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21720
21721         # find files by stripe offset except DoM files
21722         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21723         [ $NUM -eq  $NORMFILES ] ||
21724                 error "lfs find -i: found $NUM, expected $NORMFILES"
21725         echo "Test 5: lfs find no DOM files by stripe index: OK"
21726         return 0
21727 }
21728 run_test 270e "DoM: lfs find with DoM files test"
21729
21730 test_270f() {
21731         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21732                 skip "Need MDS version at least 2.10.55"
21733
21734         local mdtname=${FSNAME}-MDT0000-mdtlov
21735         local dom=$DIR/$tdir/dom_file
21736         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21737                                                 lod.$mdtname.dom_stripesize)
21738         local dom_limit=131072
21739
21740         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21741         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21742                                                 lod.$mdtname.dom_stripesize)
21743         [ ${dom_limit} -eq ${dom_current} ] ||
21744                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21745
21746         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21747         $LFS setstripe -d $DIR/$tdir
21748         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21749                 error "Can't set directory default striping"
21750
21751         # exceed maximum stripe size
21752         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21753                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21754         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21755                 error "Able to create DoM component size more than LOD limit"
21756
21757         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21758         dom_current=$(do_facet mds1 $LCTL get_param -n \
21759                                                 lod.$mdtname.dom_stripesize)
21760         [ 0 -eq ${dom_current} ] ||
21761                 error "Can't set zero DoM stripe limit"
21762         rm $dom
21763
21764         # attempt to create DoM file on server with disabled DoM should
21765         # remove DoM entry from layout and be succeed
21766         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21767                 error "Can't create DoM file (DoM is disabled)"
21768         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21769                 error "File has DoM component while DoM is disabled"
21770         rm $dom
21771
21772         # attempt to create DoM file with only DoM stripe should return error
21773         $LFS setstripe -E $dom_limit -L mdt $dom &&
21774                 error "Able to create DoM-only file while DoM is disabled"
21775
21776         # too low values to be aligned with smallest stripe size 64K
21777         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21778         dom_current=$(do_facet mds1 $LCTL get_param -n \
21779                                                 lod.$mdtname.dom_stripesize)
21780         [ 30000 -eq ${dom_current} ] &&
21781                 error "Can set too small DoM stripe limit"
21782
21783         # 64K is a minimal stripe size in Lustre, expect limit of that size
21784         [ 65536 -eq ${dom_current} ] ||
21785                 error "Limit is not set to 64K but ${dom_current}"
21786
21787         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21788         dom_current=$(do_facet mds1 $LCTL get_param -n \
21789                                                 lod.$mdtname.dom_stripesize)
21790         echo $dom_current
21791         [ 2147483648 -eq ${dom_current} ] &&
21792                 error "Can set too large DoM stripe limit"
21793
21794         do_facet mds1 $LCTL set_param -n \
21795                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21796         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21797                 error "Can't create DoM component size after limit change"
21798         do_facet mds1 $LCTL set_param -n \
21799                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21800         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21801                 error "Can't create DoM file after limit decrease"
21802         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21803                 error "Can create big DoM component after limit decrease"
21804         touch ${dom}_def ||
21805                 error "Can't create file with old default layout"
21806
21807         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21808         return 0
21809 }
21810 run_test 270f "DoM: maximum DoM stripe size checks"
21811
21812 test_270g() {
21813         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21814                 skip "Need MDS version at least 2.13.52"
21815         local dom=$DIR/$tdir/$tfile
21816
21817         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21818         local lodname=${FSNAME}-MDT0000-mdtlov
21819
21820         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21821         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21822         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21823         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21824
21825         local dom_limit=1024
21826         local dom_threshold="50%"
21827
21828         $LFS setstripe -d $DIR/$tdir
21829         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21830                 error "Can't set directory default striping"
21831
21832         do_facet mds1 $LCTL set_param -n \
21833                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21834         # set 0 threshold and create DOM file to change tunable stripesize
21835         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21836         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21837                 error "Failed to create $dom file"
21838         # now tunable dom_cur_stripesize should reach maximum
21839         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21840                                         lod.${lodname}.dom_stripesize_cur_kb)
21841         [[ $dom_current == $dom_limit ]] ||
21842                 error "Current DOM stripesize is not maximum"
21843         rm $dom
21844
21845         # set threshold for further tests
21846         do_facet mds1 $LCTL set_param -n \
21847                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21848         echo "DOM threshold is $dom_threshold free space"
21849         local dom_def
21850         local dom_set
21851         # Spoof bfree to exceed threshold
21852         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21853         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21854         for spfree in 40 20 0 15 30 55; do
21855                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21856                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21857                         error "Failed to create $dom file"
21858                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21859                                         lod.${lodname}.dom_stripesize_cur_kb)
21860                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21861                 [[ $dom_def != $dom_current ]] ||
21862                         error "Default stripe size was not changed"
21863                 if [[ $spfree > 0 ]] ; then
21864                         dom_set=$($LFS getstripe -S $dom)
21865                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21866                                 error "DOM component size is still old"
21867                 else
21868                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21869                                 error "DoM component is set with no free space"
21870                 fi
21871                 rm $dom
21872                 dom_current=$dom_def
21873         done
21874 }
21875 run_test 270g "DoM: default DoM stripe size depends on free space"
21876
21877 test_270h() {
21878         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21879                 skip "Need MDS version at least 2.13.53"
21880
21881         local mdtname=${FSNAME}-MDT0000-mdtlov
21882         local dom=$DIR/$tdir/$tfile
21883         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21884
21885         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21886         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21887
21888         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21889         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21890                 error "can't create OST file"
21891         # mirrored file with DOM entry in the second mirror
21892         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21893                 error "can't create mirror with DoM component"
21894
21895         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21896
21897         # DOM component in the middle and has other enries in the same mirror,
21898         # should succeed but lost DoM component
21899         $LFS setstripe --copy=${dom}_1 $dom ||
21900                 error "Can't create file from OST|DOM mirror layout"
21901         # check new file has no DoM layout after all
21902         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21903                 error "File has DoM component while DoM is disabled"
21904 }
21905 run_test 270h "DoM: DoM stripe removal when disabled on server"
21906
21907 test_271a() {
21908         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21909                 skip "Need MDS version at least 2.10.55"
21910
21911         local dom=$DIR/$tdir/dom
21912
21913         mkdir -p $DIR/$tdir
21914
21915         $LFS setstripe -E 1024K -L mdt $dom
21916
21917         lctl set_param -n mdc.*.stats=clear
21918         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21919         cat $dom > /dev/null
21920         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21921         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21922         ls $dom
21923         rm -f $dom
21924 }
21925 run_test 271a "DoM: data is cached for read after write"
21926
21927 test_271b() {
21928         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21929                 skip "Need MDS version at least 2.10.55"
21930
21931         local dom=$DIR/$tdir/dom
21932
21933         mkdir -p $DIR/$tdir
21934
21935         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21936
21937         lctl set_param -n mdc.*.stats=clear
21938         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21939         cancel_lru_locks mdc
21940         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21941         # second stat to check size is cached on client
21942         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21943         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21944         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21945         rm -f $dom
21946 }
21947 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21948
21949 test_271ba() {
21950         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21951                 skip "Need MDS version at least 2.10.55"
21952
21953         local dom=$DIR/$tdir/dom
21954
21955         mkdir -p $DIR/$tdir
21956
21957         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21958
21959         lctl set_param -n mdc.*.stats=clear
21960         lctl set_param -n osc.*.stats=clear
21961         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21962         cancel_lru_locks mdc
21963         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21964         # second stat to check size is cached on client
21965         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21966         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21967         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21968         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21969         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21970         rm -f $dom
21971 }
21972 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21973
21974
21975 get_mdc_stats() {
21976         local mdtidx=$1
21977         local param=$2
21978         local mdt=MDT$(printf %04x $mdtidx)
21979
21980         if [ -z $param ]; then
21981                 lctl get_param -n mdc.*$mdt*.stats
21982         else
21983                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21984         fi
21985 }
21986
21987 test_271c() {
21988         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21989                 skip "Need MDS version at least 2.10.55"
21990
21991         local dom=$DIR/$tdir/dom
21992
21993         mkdir -p $DIR/$tdir
21994
21995         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21996
21997         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21998         local facet=mds$((mdtidx + 1))
21999
22000         cancel_lru_locks mdc
22001         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22002         createmany -o $dom 1000
22003         lctl set_param -n mdc.*.stats=clear
22004         smalliomany -w $dom 1000 200
22005         get_mdc_stats $mdtidx
22006         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22007         # Each file has 1 open, 1 IO enqueues, total 2000
22008         # but now we have also +1 getxattr for security.capability, total 3000
22009         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22010         unlinkmany $dom 1000
22011
22012         cancel_lru_locks mdc
22013         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22014         createmany -o $dom 1000
22015         lctl set_param -n mdc.*.stats=clear
22016         smalliomany -w $dom 1000 200
22017         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22018         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22019         # for OPEN and IO lock.
22020         [ $((enq - enq_2)) -ge 1000 ] ||
22021                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22022         unlinkmany $dom 1000
22023         return 0
22024 }
22025 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22026
22027 cleanup_271def_tests() {
22028         trap 0
22029         rm -f $1
22030 }
22031
22032 test_271d() {
22033         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22034                 skip "Need MDS version at least 2.10.57"
22035
22036         local dom=$DIR/$tdir/dom
22037         local tmp=$TMP/$tfile
22038         trap "cleanup_271def_tests $tmp" EXIT
22039
22040         mkdir -p $DIR/$tdir
22041
22042         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22043
22044         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22045
22046         cancel_lru_locks mdc
22047         dd if=/dev/urandom of=$tmp bs=1000 count=1
22048         dd if=$tmp of=$dom bs=1000 count=1
22049         cancel_lru_locks mdc
22050
22051         cat /etc/hosts >> $tmp
22052         lctl set_param -n mdc.*.stats=clear
22053
22054         # append data to the same file it should update local page
22055         echo "Append to the same page"
22056         cat /etc/hosts >> $dom
22057         local num=$(get_mdc_stats $mdtidx ost_read)
22058         local ra=$(get_mdc_stats $mdtidx req_active)
22059         local rw=$(get_mdc_stats $mdtidx req_waittime)
22060
22061         [ -z $num ] || error "$num READ RPC occured"
22062         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22063         echo "... DONE"
22064
22065         # compare content
22066         cmp $tmp $dom || error "file miscompare"
22067
22068         cancel_lru_locks mdc
22069         lctl set_param -n mdc.*.stats=clear
22070
22071         echo "Open and read file"
22072         cat $dom > /dev/null
22073         local num=$(get_mdc_stats $mdtidx ost_read)
22074         local ra=$(get_mdc_stats $mdtidx req_active)
22075         local rw=$(get_mdc_stats $mdtidx req_waittime)
22076
22077         [ -z $num ] || error "$num READ RPC occured"
22078         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22079         echo "... DONE"
22080
22081         # compare content
22082         cmp $tmp $dom || error "file miscompare"
22083
22084         return 0
22085 }
22086 run_test 271d "DoM: read on open (1K file in reply buffer)"
22087
22088 test_271f() {
22089         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22090                 skip "Need MDS version at least 2.10.57"
22091
22092         local dom=$DIR/$tdir/dom
22093         local tmp=$TMP/$tfile
22094         trap "cleanup_271def_tests $tmp" EXIT
22095
22096         mkdir -p $DIR/$tdir
22097
22098         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22099
22100         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22101
22102         cancel_lru_locks mdc
22103         dd if=/dev/urandom of=$tmp bs=265000 count=1
22104         dd if=$tmp of=$dom bs=265000 count=1
22105         cancel_lru_locks mdc
22106         cat /etc/hosts >> $tmp
22107         lctl set_param -n mdc.*.stats=clear
22108
22109         echo "Append to the same page"
22110         cat /etc/hosts >> $dom
22111         local num=$(get_mdc_stats $mdtidx ost_read)
22112         local ra=$(get_mdc_stats $mdtidx req_active)
22113         local rw=$(get_mdc_stats $mdtidx req_waittime)
22114
22115         [ -z $num ] || error "$num READ RPC occured"
22116         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22117         echo "... DONE"
22118
22119         # compare content
22120         cmp $tmp $dom || error "file miscompare"
22121
22122         cancel_lru_locks mdc
22123         lctl set_param -n mdc.*.stats=clear
22124
22125         echo "Open and read file"
22126         cat $dom > /dev/null
22127         local num=$(get_mdc_stats $mdtidx ost_read)
22128         local ra=$(get_mdc_stats $mdtidx req_active)
22129         local rw=$(get_mdc_stats $mdtidx req_waittime)
22130
22131         [ -z $num ] && num=0
22132         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22133         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22134         echo "... DONE"
22135
22136         # compare content
22137         cmp $tmp $dom || error "file miscompare"
22138
22139         return 0
22140 }
22141 run_test 271f "DoM: read on open (200K file and read tail)"
22142
22143 test_271g() {
22144         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22145                 skip "Skipping due to old client or server version"
22146
22147         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22148         # to get layout
22149         $CHECKSTAT -t file $DIR1/$tfile
22150
22151         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22152         MULTIOP_PID=$!
22153         sleep 1
22154         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22155         $LCTL set_param fail_loc=0x80000314
22156         rm $DIR1/$tfile || error "Unlink fails"
22157         RC=$?
22158         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22159         [ $RC -eq 0 ] || error "Failed write to stale object"
22160 }
22161 run_test 271g "Discard DoM data vs client flush race"
22162
22163 test_272a() {
22164         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22165                 skip "Need MDS version at least 2.11.50"
22166
22167         local dom=$DIR/$tdir/dom
22168         mkdir -p $DIR/$tdir
22169
22170         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22171         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22172                 error "failed to write data into $dom"
22173         local old_md5=$(md5sum $dom)
22174
22175         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22176                 error "failed to migrate to the same DoM component"
22177
22178         local new_md5=$(md5sum $dom)
22179
22180         [ "$old_md5" == "$new_md5" ] ||
22181                 error "md5sum differ: $old_md5, $new_md5"
22182
22183         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22184                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22185 }
22186 run_test 272a "DoM migration: new layout with the same DOM component"
22187
22188 test_272b() {
22189         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22190                 skip "Need MDS version at least 2.11.50"
22191
22192         local dom=$DIR/$tdir/dom
22193         mkdir -p $DIR/$tdir
22194         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22195
22196         local mdtidx=$($LFS getstripe -m $dom)
22197         local mdtname=MDT$(printf %04x $mdtidx)
22198         local facet=mds$((mdtidx + 1))
22199
22200         local mdtfree1=$(do_facet $facet \
22201                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22202         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22203                 error "failed to write data into $dom"
22204         local old_md5=$(md5sum $dom)
22205         cancel_lru_locks mdc
22206         local mdtfree1=$(do_facet $facet \
22207                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22208
22209         $LFS migrate -c2 $dom ||
22210                 error "failed to migrate to the new composite layout"
22211         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22212                 error "MDT stripe was not removed"
22213
22214         cancel_lru_locks mdc
22215         local new_md5=$(md5sum $dom)
22216         [ "$old_md5" == "$new_md5" ] ||
22217                 error "$old_md5 != $new_md5"
22218
22219         # Skip free space checks with ZFS
22220         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22221                 local mdtfree2=$(do_facet $facet \
22222                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22223                 [ $mdtfree2 -gt $mdtfree1 ] ||
22224                         error "MDT space is not freed after migration"
22225         fi
22226         return 0
22227 }
22228 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22229
22230 test_272c() {
22231         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22232                 skip "Need MDS version at least 2.11.50"
22233
22234         local dom=$DIR/$tdir/$tfile
22235         mkdir -p $DIR/$tdir
22236         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22237
22238         local mdtidx=$($LFS getstripe -m $dom)
22239         local mdtname=MDT$(printf %04x $mdtidx)
22240         local facet=mds$((mdtidx + 1))
22241
22242         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22243                 error "failed to write data into $dom"
22244         local old_md5=$(md5sum $dom)
22245         cancel_lru_locks mdc
22246         local mdtfree1=$(do_facet $facet \
22247                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22248
22249         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22250                 error "failed to migrate to the new composite layout"
22251         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22252                 error "MDT stripe was not removed"
22253
22254         cancel_lru_locks mdc
22255         local new_md5=$(md5sum $dom)
22256         [ "$old_md5" == "$new_md5" ] ||
22257                 error "$old_md5 != $new_md5"
22258
22259         # Skip free space checks with ZFS
22260         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22261                 local mdtfree2=$(do_facet $facet \
22262                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22263                 [ $mdtfree2 -gt $mdtfree1 ] ||
22264                         error "MDS space is not freed after migration"
22265         fi
22266         return 0
22267 }
22268 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22269
22270 test_272d() {
22271         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22272                 skip "Need MDS version at least 2.12.55"
22273
22274         local dom=$DIR/$tdir/$tfile
22275         mkdir -p $DIR/$tdir
22276         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22277
22278         local mdtidx=$($LFS getstripe -m $dom)
22279         local mdtname=MDT$(printf %04x $mdtidx)
22280         local facet=mds$((mdtidx + 1))
22281
22282         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22283                 error "failed to write data into $dom"
22284         local old_md5=$(md5sum $dom)
22285         cancel_lru_locks mdc
22286         local mdtfree1=$(do_facet $facet \
22287                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22288
22289         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22290                 error "failed mirroring to the new composite layout"
22291         $LFS mirror resync $dom ||
22292                 error "failed mirror resync"
22293         $LFS mirror split --mirror-id 1 -d $dom ||
22294                 error "failed mirror split"
22295
22296         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22297                 error "MDT stripe was not removed"
22298
22299         cancel_lru_locks mdc
22300         local new_md5=$(md5sum $dom)
22301         [ "$old_md5" == "$new_md5" ] ||
22302                 error "$old_md5 != $new_md5"
22303
22304         # Skip free space checks with ZFS
22305         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22306                 local mdtfree2=$(do_facet $facet \
22307                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22308                 [ $mdtfree2 -gt $mdtfree1 ] ||
22309                         error "MDS space is not freed after DOM mirror deletion"
22310         fi
22311         return 0
22312 }
22313 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22314
22315 test_272e() {
22316         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22317                 skip "Need MDS version at least 2.12.55"
22318
22319         local dom=$DIR/$tdir/$tfile
22320         mkdir -p $DIR/$tdir
22321         $LFS setstripe -c 2 $dom
22322
22323         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22324                 error "failed to write data into $dom"
22325         local old_md5=$(md5sum $dom)
22326         cancel_lru_locks mdc
22327
22328         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22329                 error "failed mirroring to the DOM layout"
22330         $LFS mirror resync $dom ||
22331                 error "failed mirror resync"
22332         $LFS mirror split --mirror-id 1 -d $dom ||
22333                 error "failed mirror split"
22334
22335         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22336                 error "MDT stripe was not removed"
22337
22338         cancel_lru_locks mdc
22339         local new_md5=$(md5sum $dom)
22340         [ "$old_md5" == "$new_md5" ] ||
22341                 error "$old_md5 != $new_md5"
22342
22343         return 0
22344 }
22345 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22346
22347 test_272f() {
22348         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22349                 skip "Need MDS version at least 2.12.55"
22350
22351         local dom=$DIR/$tdir/$tfile
22352         mkdir -p $DIR/$tdir
22353         $LFS setstripe -c 2 $dom
22354
22355         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22356                 error "failed to write data into $dom"
22357         local old_md5=$(md5sum $dom)
22358         cancel_lru_locks mdc
22359
22360         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22361                 error "failed migrating to the DOM file"
22362
22363         cancel_lru_locks mdc
22364         local new_md5=$(md5sum $dom)
22365         [ "$old_md5" != "$new_md5" ] &&
22366                 error "$old_md5 != $new_md5"
22367
22368         return 0
22369 }
22370 run_test 272f "DoM migration: OST-striped file to DOM file"
22371
22372 test_273a() {
22373         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22374                 skip "Need MDS version at least 2.11.50"
22375
22376         # Layout swap cannot be done if either file has DOM component,
22377         # this will never be supported, migration should be used instead
22378
22379         local dom=$DIR/$tdir/$tfile
22380         mkdir -p $DIR/$tdir
22381
22382         $LFS setstripe -c2 ${dom}_plain
22383         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22384         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22385                 error "can swap layout with DoM component"
22386         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22387                 error "can swap layout with DoM component"
22388
22389         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22390         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22391                 error "can swap layout with DoM component"
22392         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22393                 error "can swap layout with DoM component"
22394         return 0
22395 }
22396 run_test 273a "DoM: layout swapping should fail with DOM"
22397
22398 test_273b() {
22399         mkdir -p $DIR/$tdir
22400         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22401
22402 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22403         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22404
22405         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22406 }
22407 run_test 273b "DoM: race writeback and object destroy"
22408
22409 test_275() {
22410         remote_ost_nodsh && skip "remote OST with nodsh"
22411         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22412                 skip "Need OST version >= 2.10.57"
22413
22414         local file=$DIR/$tfile
22415         local oss
22416
22417         oss=$(comma_list $(osts_nodes))
22418
22419         dd if=/dev/urandom of=$file bs=1M count=2 ||
22420                 error "failed to create a file"
22421         cancel_lru_locks osc
22422
22423         #lock 1
22424         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22425                 error "failed to read a file"
22426
22427 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22428         $LCTL set_param fail_loc=0x8000031f
22429
22430         cancel_lru_locks osc &
22431         sleep 1
22432
22433 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22434         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22435         #IO takes another lock, but matches the PENDING one
22436         #and places it to the IO RPC
22437         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22438                 error "failed to read a file with PENDING lock"
22439 }
22440 run_test 275 "Read on a canceled duplicate lock"
22441
22442 test_276() {
22443         remote_ost_nodsh && skip "remote OST with nodsh"
22444         local pid
22445
22446         do_facet ost1 "(while true; do \
22447                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22448                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22449         pid=$!
22450
22451         for LOOP in $(seq 20); do
22452                 stop ost1
22453                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22454         done
22455         kill -9 $pid
22456         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22457                 rm $TMP/sanity_276_pid"
22458 }
22459 run_test 276 "Race between mount and obd_statfs"
22460
22461 test_277() {
22462         $LCTL set_param ldlm.namespaces.*.lru_size=0
22463         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22464         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22465                         grep ^used_mb | awk '{print $2}')
22466         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22467         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22468                 oflag=direct conv=notrunc
22469         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22470                         grep ^used_mb | awk '{print $2}')
22471         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22472 }
22473 run_test 277 "Direct IO shall drop page cache"
22474
22475 test_278() {
22476         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22477         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22478         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22479                 skip "needs the same host for mdt1 mdt2" && return
22480
22481         local pid1
22482         local pid2
22483
22484 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22485         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22486         stop mds2 &
22487         pid2=$!
22488
22489         stop mds1
22490
22491         echo "Starting MDTs"
22492         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22493         wait $pid2
22494 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22495 #will return NULL
22496         do_facet mds2 $LCTL set_param fail_loc=0
22497
22498         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22499         wait_recovery_complete mds2
22500 }
22501 run_test 278 "Race starting MDS between MDTs stop/start"
22502
22503 test_280() {
22504         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22505                 skip "Need MGS version at least 2.13.52"
22506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22507         combined_mgs_mds || skip "needs combined MGS/MDT"
22508
22509         umount_client $MOUNT
22510 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22511         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22512
22513         mount_client $MOUNT &
22514         sleep 1
22515         stop mgs || error "stop mgs failed"
22516         #for a race mgs would crash
22517         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22518         # make sure we unmount client before remounting
22519         wait
22520         umount_client $MOUNT
22521         mount_client $MOUNT || error "mount client failed"
22522 }
22523 run_test 280 "Race between MGS umount and client llog processing"
22524
22525 cleanup_test_300() {
22526         trap 0
22527         umask $SAVE_UMASK
22528 }
22529 test_striped_dir() {
22530         local mdt_index=$1
22531         local stripe_count
22532         local stripe_index
22533
22534         mkdir -p $DIR/$tdir
22535
22536         SAVE_UMASK=$(umask)
22537         trap cleanup_test_300 RETURN EXIT
22538
22539         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22540                                                 $DIR/$tdir/striped_dir ||
22541                 error "set striped dir error"
22542
22543         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22544         [ "$mode" = "755" ] || error "expect 755 got $mode"
22545
22546         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22547                 error "getdirstripe failed"
22548         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22549         if [ "$stripe_count" != "2" ]; then
22550                 error "1:stripe_count is $stripe_count, expect 2"
22551         fi
22552         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22553         if [ "$stripe_count" != "2" ]; then
22554                 error "2:stripe_count is $stripe_count, expect 2"
22555         fi
22556
22557         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22558         if [ "$stripe_index" != "$mdt_index" ]; then
22559                 error "stripe_index is $stripe_index, expect $mdt_index"
22560         fi
22561
22562         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22563                 error "nlink error after create striped dir"
22564
22565         mkdir $DIR/$tdir/striped_dir/a
22566         mkdir $DIR/$tdir/striped_dir/b
22567
22568         stat $DIR/$tdir/striped_dir/a ||
22569                 error "create dir under striped dir failed"
22570         stat $DIR/$tdir/striped_dir/b ||
22571                 error "create dir under striped dir failed"
22572
22573         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22574                 error "nlink error after mkdir"
22575
22576         rmdir $DIR/$tdir/striped_dir/a
22577         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22578                 error "nlink error after rmdir"
22579
22580         rmdir $DIR/$tdir/striped_dir/b
22581         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22582                 error "nlink error after rmdir"
22583
22584         chattr +i $DIR/$tdir/striped_dir
22585         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22586                 error "immutable flags not working under striped dir!"
22587         chattr -i $DIR/$tdir/striped_dir
22588
22589         rmdir $DIR/$tdir/striped_dir ||
22590                 error "rmdir striped dir error"
22591
22592         cleanup_test_300
22593
22594         true
22595 }
22596
22597 test_300a() {
22598         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22599                 skip "skipped for lustre < 2.7.0"
22600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22602
22603         test_striped_dir 0 || error "failed on striped dir on MDT0"
22604         test_striped_dir 1 || error "failed on striped dir on MDT0"
22605 }
22606 run_test 300a "basic striped dir sanity test"
22607
22608 test_300b() {
22609         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22610                 skip "skipped for lustre < 2.7.0"
22611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22613
22614         local i
22615         local mtime1
22616         local mtime2
22617         local mtime3
22618
22619         test_mkdir $DIR/$tdir || error "mkdir fail"
22620         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22621                 error "set striped dir error"
22622         for i in {0..9}; do
22623                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22624                 sleep 1
22625                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22626                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22627                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22628                 sleep 1
22629                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22630                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22631                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22632         done
22633         true
22634 }
22635 run_test 300b "check ctime/mtime for striped dir"
22636
22637 test_300c() {
22638         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22639                 skip "skipped for lustre < 2.7.0"
22640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22641         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22642
22643         local file_count
22644
22645         mkdir_on_mdt0 $DIR/$tdir
22646         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22647                 error "set striped dir error"
22648
22649         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22650                 error "chown striped dir failed"
22651
22652         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22653                 error "create 5k files failed"
22654
22655         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22656
22657         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22658
22659         rm -rf $DIR/$tdir
22660 }
22661 run_test 300c "chown && check ls under striped directory"
22662
22663 test_300d() {
22664         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22665                 skip "skipped for lustre < 2.7.0"
22666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22668
22669         local stripe_count
22670         local file
22671
22672         mkdir -p $DIR/$tdir
22673         $LFS setstripe -c 2 $DIR/$tdir
22674
22675         #local striped directory
22676         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22677                 error "set striped dir error"
22678         #look at the directories for debug purposes
22679         ls -l $DIR/$tdir
22680         $LFS getdirstripe $DIR/$tdir
22681         ls -l $DIR/$tdir/striped_dir
22682         $LFS getdirstripe $DIR/$tdir/striped_dir
22683         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22684                 error "create 10 files failed"
22685
22686         #remote striped directory
22687         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22688                 error "set striped dir error"
22689         #look at the directories for debug purposes
22690         ls -l $DIR/$tdir
22691         $LFS getdirstripe $DIR/$tdir
22692         ls -l $DIR/$tdir/remote_striped_dir
22693         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22694         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22695                 error "create 10 files failed"
22696
22697         for file in $(find $DIR/$tdir); do
22698                 stripe_count=$($LFS getstripe -c $file)
22699                 [ $stripe_count -eq 2 ] ||
22700                         error "wrong stripe $stripe_count for $file"
22701         done
22702
22703         rm -rf $DIR/$tdir
22704 }
22705 run_test 300d "check default stripe under striped directory"
22706
22707 test_300e() {
22708         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22709                 skip "Need MDS version at least 2.7.55"
22710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22711         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22712
22713         local stripe_count
22714         local file
22715
22716         mkdir -p $DIR/$tdir
22717
22718         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22719                 error "set striped dir error"
22720
22721         touch $DIR/$tdir/striped_dir/a
22722         touch $DIR/$tdir/striped_dir/b
22723         touch $DIR/$tdir/striped_dir/c
22724
22725         mkdir $DIR/$tdir/striped_dir/dir_a
22726         mkdir $DIR/$tdir/striped_dir/dir_b
22727         mkdir $DIR/$tdir/striped_dir/dir_c
22728
22729         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22730                 error "set striped adir under striped dir error"
22731
22732         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22733                 error "set striped bdir under striped dir error"
22734
22735         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22736                 error "set striped cdir under striped dir error"
22737
22738         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22739                 error "rename dir under striped dir fails"
22740
22741         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22742                 error "rename dir under different stripes fails"
22743
22744         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22745                 error "rename file under striped dir should succeed"
22746
22747         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22748                 error "rename dir under striped dir should succeed"
22749
22750         rm -rf $DIR/$tdir
22751 }
22752 run_test 300e "check rename under striped directory"
22753
22754 test_300f() {
22755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22756         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22757         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22758                 skip "Need MDS version at least 2.7.55"
22759
22760         local stripe_count
22761         local file
22762
22763         rm -rf $DIR/$tdir
22764         mkdir -p $DIR/$tdir
22765
22766         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22767                 error "set striped dir error"
22768
22769         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22770                 error "set striped dir error"
22771
22772         touch $DIR/$tdir/striped_dir/a
22773         mkdir $DIR/$tdir/striped_dir/dir_a
22774         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22775                 error "create striped dir under striped dir fails"
22776
22777         touch $DIR/$tdir/striped_dir1/b
22778         mkdir $DIR/$tdir/striped_dir1/dir_b
22779         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22780                 error "create striped dir under striped dir fails"
22781
22782         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22783                 error "rename dir under different striped dir should fail"
22784
22785         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22786                 error "rename striped dir under diff striped dir should fail"
22787
22788         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22789                 error "rename file under diff striped dirs fails"
22790
22791         rm -rf $DIR/$tdir
22792 }
22793 run_test 300f "check rename cross striped directory"
22794
22795 test_300_check_default_striped_dir()
22796 {
22797         local dirname=$1
22798         local default_count=$2
22799         local default_index=$3
22800         local stripe_count
22801         local stripe_index
22802         local dir_stripe_index
22803         local dir
22804
22805         echo "checking $dirname $default_count $default_index"
22806         $LFS setdirstripe -D -c $default_count -i $default_index \
22807                                 -H all_char $DIR/$tdir/$dirname ||
22808                 error "set default stripe on striped dir error"
22809         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22810         [ $stripe_count -eq $default_count ] ||
22811                 error "expect $default_count get $stripe_count for $dirname"
22812
22813         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22814         [ $stripe_index -eq $default_index ] ||
22815                 error "expect $default_index get $stripe_index for $dirname"
22816
22817         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22818                                                 error "create dirs failed"
22819
22820         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22821         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22822         for dir in $(find $DIR/$tdir/$dirname/*); do
22823                 stripe_count=$($LFS getdirstripe -c $dir)
22824                 (( $stripe_count == $default_count )) ||
22825                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22826                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22827                 error "stripe count $default_count != $stripe_count for $dir"
22828
22829                 stripe_index=$($LFS getdirstripe -i $dir)
22830                 [ $default_index -eq -1 ] ||
22831                         [ $stripe_index -eq $default_index ] ||
22832                         error "$stripe_index != $default_index for $dir"
22833
22834                 #check default stripe
22835                 stripe_count=$($LFS getdirstripe -D -c $dir)
22836                 [ $stripe_count -eq $default_count ] ||
22837                 error "default count $default_count != $stripe_count for $dir"
22838
22839                 stripe_index=$($LFS getdirstripe -D -i $dir)
22840                 [ $stripe_index -eq $default_index ] ||
22841                 error "default index $default_index != $stripe_index for $dir"
22842         done
22843         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22844 }
22845
22846 test_300g() {
22847         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22848         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22849                 skip "Need MDS version at least 2.7.55"
22850
22851         local dir
22852         local stripe_count
22853         local stripe_index
22854
22855         mkdir_on_mdt0 $DIR/$tdir
22856         mkdir $DIR/$tdir/normal_dir
22857
22858         #Checking when client cache stripe index
22859         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22860         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22861                 error "create striped_dir failed"
22862
22863         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22864                 error "create dir0 fails"
22865         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22866         [ $stripe_index -eq 0 ] ||
22867                 error "dir0 expect index 0 got $stripe_index"
22868
22869         mkdir $DIR/$tdir/striped_dir/dir1 ||
22870                 error "create dir1 fails"
22871         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22872         [ $stripe_index -eq 1 ] ||
22873                 error "dir1 expect index 1 got $stripe_index"
22874
22875         #check default stripe count/stripe index
22876         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22877         test_300_check_default_striped_dir normal_dir 1 0
22878         test_300_check_default_striped_dir normal_dir -1 1
22879         test_300_check_default_striped_dir normal_dir 2 -1
22880
22881         #delete default stripe information
22882         echo "delete default stripeEA"
22883         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22884                 error "set default stripe on striped dir error"
22885
22886         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22887         for dir in $(find $DIR/$tdir/normal_dir/*); do
22888                 stripe_count=$($LFS getdirstripe -c $dir)
22889                 [ $stripe_count -eq 0 ] ||
22890                         error "expect 1 get $stripe_count for $dir"
22891         done
22892 }
22893 run_test 300g "check default striped directory for normal directory"
22894
22895 test_300h() {
22896         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22897         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22898                 skip "Need MDS version at least 2.7.55"
22899
22900         local dir
22901         local stripe_count
22902
22903         mkdir $DIR/$tdir
22904         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22905                 error "set striped dir error"
22906
22907         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22908         test_300_check_default_striped_dir striped_dir 1 0
22909         test_300_check_default_striped_dir striped_dir -1 1
22910         test_300_check_default_striped_dir striped_dir 2 -1
22911
22912         #delete default stripe information
22913         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22914                 error "set default stripe on striped dir error"
22915
22916         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22917         for dir in $(find $DIR/$tdir/striped_dir/*); do
22918                 stripe_count=$($LFS getdirstripe -c $dir)
22919                 [ $stripe_count -eq 0 ] ||
22920                         error "expect 1 get $stripe_count for $dir"
22921         done
22922 }
22923 run_test 300h "check default striped directory for striped directory"
22924
22925 test_300i() {
22926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22928         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22929                 skip "Need MDS version at least 2.7.55"
22930
22931         local stripe_count
22932         local file
22933
22934         mkdir $DIR/$tdir
22935
22936         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22937                 error "set striped dir error"
22938
22939         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22940                 error "create files under striped dir failed"
22941
22942         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22943                 error "set striped hashdir error"
22944
22945         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22946                 error "create dir0 under hash dir failed"
22947         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22948                 error "create dir1 under hash dir failed"
22949         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22950                 error "create dir2 under hash dir failed"
22951
22952         # unfortunately, we need to umount to clear dir layout cache for now
22953         # once we fully implement dir layout, we can drop this
22954         umount_client $MOUNT || error "umount failed"
22955         mount_client $MOUNT || error "mount failed"
22956
22957         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22958         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22959         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22960
22961         #set the stripe to be unknown hash type
22962         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22963         $LCTL set_param fail_loc=0x1901
22964         for ((i = 0; i < 10; i++)); do
22965                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22966                         error "stat f-$i failed"
22967                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22968         done
22969
22970         touch $DIR/$tdir/striped_dir/f0 &&
22971                 error "create under striped dir with unknown hash should fail"
22972
22973         $LCTL set_param fail_loc=0
22974
22975         umount_client $MOUNT || error "umount failed"
22976         mount_client $MOUNT || error "mount failed"
22977
22978         return 0
22979 }
22980 run_test 300i "client handle unknown hash type striped directory"
22981
22982 test_300j() {
22983         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22985         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22986                 skip "Need MDS version at least 2.7.55"
22987
22988         local stripe_count
22989         local file
22990
22991         mkdir $DIR/$tdir
22992
22993         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22994         $LCTL set_param fail_loc=0x1702
22995         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22996                 error "set striped dir error"
22997
22998         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22999                 error "create files under striped dir failed"
23000
23001         $LCTL set_param fail_loc=0
23002
23003         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23004
23005         return 0
23006 }
23007 run_test 300j "test large update record"
23008
23009 test_300k() {
23010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23011         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23012         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23013                 skip "Need MDS version at least 2.7.55"
23014
23015         # this test needs a huge transaction
23016         local kb
23017         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23018              osd*.$FSNAME-MDT0000.kbytestotal")
23019         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23020
23021         local stripe_count
23022         local file
23023
23024         mkdir $DIR/$tdir
23025
23026         #define OBD_FAIL_LARGE_STRIPE   0x1703
23027         $LCTL set_param fail_loc=0x1703
23028         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23029                 error "set striped dir error"
23030         $LCTL set_param fail_loc=0
23031
23032         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23033                 error "getstripeddir fails"
23034         rm -rf $DIR/$tdir/striped_dir ||
23035                 error "unlink striped dir fails"
23036
23037         return 0
23038 }
23039 run_test 300k "test large striped directory"
23040
23041 test_300l() {
23042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23043         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23044         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23045                 skip "Need MDS version at least 2.7.55"
23046
23047         local stripe_index
23048
23049         test_mkdir -p $DIR/$tdir/striped_dir
23050         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23051                         error "chown $RUNAS_ID failed"
23052         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23053                 error "set default striped dir failed"
23054
23055         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23056         $LCTL set_param fail_loc=0x80000158
23057         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23058
23059         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23060         [ $stripe_index -eq 1 ] ||
23061                 error "expect 1 get $stripe_index for $dir"
23062 }
23063 run_test 300l "non-root user to create dir under striped dir with stale layout"
23064
23065 test_300m() {
23066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23067         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23068         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23069                 skip "Need MDS version at least 2.7.55"
23070
23071         mkdir -p $DIR/$tdir/striped_dir
23072         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23073                 error "set default stripes dir error"
23074
23075         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23076
23077         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23078         [ $stripe_count -eq 0 ] ||
23079                         error "expect 0 get $stripe_count for a"
23080
23081         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23082                 error "set default stripes dir error"
23083
23084         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23085
23086         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23087         [ $stripe_count -eq 0 ] ||
23088                         error "expect 0 get $stripe_count for b"
23089
23090         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23091                 error "set default stripes dir error"
23092
23093         mkdir $DIR/$tdir/striped_dir/c &&
23094                 error "default stripe_index is invalid, mkdir c should fails"
23095
23096         rm -rf $DIR/$tdir || error "rmdir fails"
23097 }
23098 run_test 300m "setstriped directory on single MDT FS"
23099
23100 cleanup_300n() {
23101         local list=$(comma_list $(mdts_nodes))
23102
23103         trap 0
23104         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23105 }
23106
23107 test_300n() {
23108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23110         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23111                 skip "Need MDS version at least 2.7.55"
23112         remote_mds_nodsh && skip "remote MDS with nodsh"
23113
23114         local stripe_index
23115         local list=$(comma_list $(mdts_nodes))
23116
23117         trap cleanup_300n RETURN EXIT
23118         mkdir -p $DIR/$tdir
23119         chmod 777 $DIR/$tdir
23120         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23121                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23122                 error "create striped dir succeeds with gid=0"
23123
23124         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23125         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23126                 error "create striped dir fails with gid=-1"
23127
23128         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23129         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23130                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23131                 error "set default striped dir succeeds with gid=0"
23132
23133
23134         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23135         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23136                 error "set default striped dir fails with gid=-1"
23137
23138
23139         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23140         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23141                                         error "create test_dir fails"
23142         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23143                                         error "create test_dir1 fails"
23144         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23145                                         error "create test_dir2 fails"
23146         cleanup_300n
23147 }
23148 run_test 300n "non-root user to create dir under striped dir with default EA"
23149
23150 test_300o() {
23151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23152         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23153         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23154                 skip "Need MDS version at least 2.7.55"
23155
23156         local numfree1
23157         local numfree2
23158
23159         mkdir -p $DIR/$tdir
23160
23161         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23162         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23163         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23164                 skip "not enough free inodes $numfree1 $numfree2"
23165         fi
23166
23167         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23168         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23169         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23170                 skip "not enough free space $numfree1 $numfree2"
23171         fi
23172
23173         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23174                 error "setdirstripe fails"
23175
23176         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23177                 error "create dirs fails"
23178
23179         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23180         ls $DIR/$tdir/striped_dir > /dev/null ||
23181                 error "ls striped dir fails"
23182         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23183                 error "unlink big striped dir fails"
23184 }
23185 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23186
23187 test_300p() {
23188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23190         remote_mds_nodsh && skip "remote MDS with nodsh"
23191
23192         mkdir_on_mdt0 $DIR/$tdir
23193
23194         #define OBD_FAIL_OUT_ENOSPC     0x1704
23195         do_facet mds2 lctl set_param fail_loc=0x80001704
23196         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23197                  && error "create striped directory should fail"
23198
23199         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23200
23201         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23202         true
23203 }
23204 run_test 300p "create striped directory without space"
23205
23206 test_300q() {
23207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23209
23210         local fd=$(free_fd)
23211         local cmd="exec $fd<$tdir"
23212         cd $DIR
23213         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23214         eval $cmd
23215         cmd="exec $fd<&-"
23216         trap "eval $cmd" EXIT
23217         cd $tdir || error "cd $tdir fails"
23218         rmdir  ../$tdir || error "rmdir $tdir fails"
23219         mkdir local_dir && error "create dir succeeds"
23220         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23221         eval $cmd
23222         return 0
23223 }
23224 run_test 300q "create remote directory under orphan directory"
23225
23226 test_300r() {
23227         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23228                 skip "Need MDS version at least 2.7.55" && return
23229         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23230
23231         mkdir $DIR/$tdir
23232
23233         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23234                 error "set striped dir error"
23235
23236         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23237                 error "getstripeddir fails"
23238
23239         local stripe_count
23240         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23241                       awk '/lmv_stripe_count:/ { print $2 }')
23242
23243         [ $MDSCOUNT -ne $stripe_count ] &&
23244                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23245
23246         rm -rf $DIR/$tdir/striped_dir ||
23247                 error "unlink striped dir fails"
23248 }
23249 run_test 300r "test -1 striped directory"
23250
23251 test_300s_helper() {
23252         local count=$1
23253
23254         local stripe_dir=$DIR/$tdir/striped_dir.$count
23255
23256         $LFS mkdir -c $count $stripe_dir ||
23257                 error "lfs mkdir -c error"
23258
23259         $LFS getdirstripe $stripe_dir ||
23260                 error "lfs getdirstripe fails"
23261
23262         local stripe_count
23263         stripe_count=$($LFS getdirstripe $stripe_dir |
23264                       awk '/lmv_stripe_count:/ { print $2 }')
23265
23266         [ $count -ne $stripe_count ] &&
23267                 error_noexit "bad stripe count $stripe_count expected $count"
23268
23269         local dupe_stripes
23270         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23271                 awk '/0x/ {count[$1] += 1}; END {
23272                         for (idx in count) {
23273                                 if (count[idx]>1) {
23274                                         print "index " idx " count " count[idx]
23275                                 }
23276                         }
23277                 }')
23278
23279         if [[ -n "$dupe_stripes" ]] ; then
23280                 lfs getdirstripe $stripe_dir
23281                 error_noexit "Dupe MDT above: $dupe_stripes "
23282         fi
23283
23284         rm -rf $stripe_dir ||
23285                 error_noexit "unlink $stripe_dir fails"
23286 }
23287
23288 test_300s() {
23289         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23290                 skip "Need MDS version at least 2.7.55" && return
23291         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23292
23293         mkdir $DIR/$tdir
23294         for count in $(seq 2 $MDSCOUNT); do
23295                 test_300s_helper $count
23296         done
23297 }
23298 run_test 300s "test lfs mkdir -c without -i"
23299
23300
23301 prepare_remote_file() {
23302         mkdir $DIR/$tdir/src_dir ||
23303                 error "create remote source failed"
23304
23305         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23306                  error "cp to remote source failed"
23307         touch $DIR/$tdir/src_dir/a
23308
23309         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23310                 error "create remote target dir failed"
23311
23312         touch $DIR/$tdir/tgt_dir/b
23313
23314         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23315                 error "rename dir cross MDT failed!"
23316
23317         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23318                 error "src_child still exists after rename"
23319
23320         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23321                 error "missing file(a) after rename"
23322
23323         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23324                 error "diff after rename"
23325 }
23326
23327 test_310a() {
23328         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23330
23331         local remote_file=$DIR/$tdir/tgt_dir/b
23332
23333         mkdir -p $DIR/$tdir
23334
23335         prepare_remote_file || error "prepare remote file failed"
23336
23337         #open-unlink file
23338         $OPENUNLINK $remote_file $remote_file ||
23339                 error "openunlink $remote_file failed"
23340         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23341 }
23342 run_test 310a "open unlink remote file"
23343
23344 test_310b() {
23345         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23347
23348         local remote_file=$DIR/$tdir/tgt_dir/b
23349
23350         mkdir -p $DIR/$tdir
23351
23352         prepare_remote_file || error "prepare remote file failed"
23353
23354         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23355         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23356         $CHECKSTAT -t file $remote_file || error "check file failed"
23357 }
23358 run_test 310b "unlink remote file with multiple links while open"
23359
23360 test_310c() {
23361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23362         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23363
23364         local remote_file=$DIR/$tdir/tgt_dir/b
23365
23366         mkdir -p $DIR/$tdir
23367
23368         prepare_remote_file || error "prepare remote file failed"
23369
23370         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23371         multiop_bg_pause $remote_file O_uc ||
23372                         error "mulitop failed for remote file"
23373         MULTIPID=$!
23374         $MULTIOP $DIR/$tfile Ouc
23375         kill -USR1 $MULTIPID
23376         wait $MULTIPID
23377 }
23378 run_test 310c "open-unlink remote file with multiple links"
23379
23380 #LU-4825
23381 test_311() {
23382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23383         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23384         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23385                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23386         remote_mds_nodsh && skip "remote MDS with nodsh"
23387
23388         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23389         local mdts=$(comma_list $(mdts_nodes))
23390
23391         mkdir -p $DIR/$tdir
23392         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23393         createmany -o $DIR/$tdir/$tfile. 1000
23394
23395         # statfs data is not real time, let's just calculate it
23396         old_iused=$((old_iused + 1000))
23397
23398         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23399                         osp.*OST0000*MDT0000.create_count")
23400         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23401                                 osp.*OST0000*MDT0000.max_create_count")
23402         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23403
23404         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23405         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23406         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23407
23408         unlinkmany $DIR/$tdir/$tfile. 1000
23409
23410         do_nodes $mdts "$LCTL set_param -n \
23411                         osp.*OST0000*.max_create_count=$max_count"
23412         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23413                 do_nodes $mdts "$LCTL set_param -n \
23414                                 osp.*OST0000*.create_count=$count"
23415         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23416                         grep "=0" && error "create_count is zero"
23417
23418         local new_iused
23419         for i in $(seq 120); do
23420                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23421                 # system may be too busy to destroy all objs in time, use
23422                 # a somewhat small value to not fail autotest
23423                 [ $((old_iused - new_iused)) -gt 400 ] && break
23424                 sleep 1
23425         done
23426
23427         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23428         [ $((old_iused - new_iused)) -gt 400 ] ||
23429                 error "objs not destroyed after unlink"
23430 }
23431 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23432
23433 zfs_oid_to_objid()
23434 {
23435         local ost=$1
23436         local objid=$2
23437
23438         local vdevdir=$(dirname $(facet_vdevice $ost))
23439         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23440         local zfs_zapid=$(do_facet $ost $cmd |
23441                           grep -w "/O/0/d$((objid%32))" -C 5 |
23442                           awk '/Object/{getline; print $1}')
23443         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23444                           awk "/$objid = /"'{printf $3}')
23445
23446         echo $zfs_objid
23447 }
23448
23449 zfs_object_blksz() {
23450         local ost=$1
23451         local objid=$2
23452
23453         local vdevdir=$(dirname $(facet_vdevice $ost))
23454         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23455         local blksz=$(do_facet $ost $cmd $objid |
23456                       awk '/dblk/{getline; printf $4}')
23457
23458         case "${blksz: -1}" in
23459                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23460                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23461                 *) ;;
23462         esac
23463
23464         echo $blksz
23465 }
23466
23467 test_312() { # LU-4856
23468         remote_ost_nodsh && skip "remote OST with nodsh"
23469         [ "$ost1_FSTYPE" = "zfs" ] ||
23470                 skip_env "the test only applies to zfs"
23471
23472         local max_blksz=$(do_facet ost1 \
23473                           $ZFS get -p recordsize $(facet_device ost1) |
23474                           awk '!/VALUE/{print $3}')
23475
23476         # to make life a little bit easier
23477         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23478         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23479
23480         local tf=$DIR/$tdir/$tfile
23481         touch $tf
23482         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23483
23484         # Get ZFS object id
23485         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23486         # block size change by sequential overwrite
23487         local bs
23488
23489         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23490                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23491
23492                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23493                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23494         done
23495         rm -f $tf
23496
23497         # block size change by sequential append write
23498         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23499         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23500         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23501         local count
23502
23503         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23504                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23505                         oflag=sync conv=notrunc
23506
23507                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23508                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23509                         error "blksz error, actual $blksz, " \
23510                                 "expected: 2 * $count * $PAGE_SIZE"
23511         done
23512         rm -f $tf
23513
23514         # random write
23515         touch $tf
23516         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23517         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23518
23519         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23520         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23521         [ $blksz -eq $PAGE_SIZE ] ||
23522                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23523
23524         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23525         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23526         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23527
23528         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23529         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23530         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23531 }
23532 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23533
23534 test_313() {
23535         remote_ost_nodsh && skip "remote OST with nodsh"
23536
23537         local file=$DIR/$tfile
23538
23539         rm -f $file
23540         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23541
23542         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23543         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23544         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23545                 error "write should failed"
23546         do_facet ost1 "$LCTL set_param fail_loc=0"
23547         rm -f $file
23548 }
23549 run_test 313 "io should fail after last_rcvd update fail"
23550
23551 test_314() {
23552         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23553
23554         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23555         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23556         rm -f $DIR/$tfile
23557         wait_delete_completed
23558         do_facet ost1 "$LCTL set_param fail_loc=0"
23559 }
23560 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23561
23562 test_315() { # LU-618
23563         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23564
23565         local file=$DIR/$tfile
23566         rm -f $file
23567
23568         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23569                 error "multiop file write failed"
23570         $MULTIOP $file oO_RDONLY:r4063232_c &
23571         PID=$!
23572
23573         sleep 2
23574
23575         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23576         kill -USR1 $PID
23577
23578         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23579         rm -f $file
23580 }
23581 run_test 315 "read should be accounted"
23582
23583 test_316() {
23584         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23585         large_xattr_enabled || skip_env "ea_inode feature disabled"
23586
23587         rm -rf $DIR/$tdir/d
23588         mkdir -p $DIR/$tdir/d
23589         chown nobody $DIR/$tdir/d
23590         touch $DIR/$tdir/d/file
23591
23592         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23593 }
23594 run_test 316 "lfs mv"
23595
23596 test_317() {
23597         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23598                 skip "Need MDS version at least 2.11.53"
23599         if [ "$ost1_FSTYPE" == "zfs" ]; then
23600                 skip "LU-10370: no implementation for ZFS"
23601         fi
23602
23603         local trunc_sz
23604         local grant_blk_size
23605
23606         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23607                         awk '/grant_block_size:/ { print $2; exit; }')
23608         #
23609         # Create File of size 5M. Truncate it to below size's and verify
23610         # blocks count.
23611         #
23612         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23613                 error "Create file $DIR/$tfile failed"
23614         stack_trap "rm -f $DIR/$tfile" EXIT
23615
23616         for trunc_sz in 2097152 4097 4000 509 0; do
23617                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23618                         error "truncate $tfile to $trunc_sz failed"
23619                 local sz=$(stat --format=%s $DIR/$tfile)
23620                 local blk=$(stat --format=%b $DIR/$tfile)
23621                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23622                                      grant_blk_size) * 8))
23623
23624                 if [[ $blk -ne $trunc_blk ]]; then
23625                         $(which stat) $DIR/$tfile
23626                         error "Expected Block $trunc_blk got $blk for $tfile"
23627                 fi
23628
23629                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23630                         error "Expected Size $trunc_sz got $sz for $tfile"
23631         done
23632
23633         #
23634         # sparse file test
23635         # Create file with a hole and write actual two blocks. Block count
23636         # must be 16.
23637         #
23638         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23639                 conv=fsync || error "Create file : $DIR/$tfile"
23640
23641         # Calculate the final truncate size.
23642         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23643
23644         #
23645         # truncate to size $trunc_sz bytes. Strip the last block
23646         # The block count must drop to 8
23647         #
23648         $TRUNCATE $DIR/$tfile $trunc_sz ||
23649                 error "truncate $tfile to $trunc_sz failed"
23650
23651         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23652         sz=$(stat --format=%s $DIR/$tfile)
23653         blk=$(stat --format=%b $DIR/$tfile)
23654
23655         if [[ $blk -ne $trunc_bsz ]]; then
23656                 $(which stat) $DIR/$tfile
23657                 error "Expected Block $trunc_bsz got $blk for $tfile"
23658         fi
23659
23660         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23661                 error "Expected Size $trunc_sz got $sz for $tfile"
23662 }
23663 run_test 317 "Verify blocks get correctly update after truncate"
23664
23665 test_318() {
23666         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23667         local old_max_active=$($LCTL get_param -n \
23668                             ${llite_name}.max_read_ahead_async_active \
23669                             2>/dev/null)
23670
23671         $LCTL set_param llite.*.max_read_ahead_async_active=256
23672         local max_active=$($LCTL get_param -n \
23673                            ${llite_name}.max_read_ahead_async_active \
23674                            2>/dev/null)
23675         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23676
23677         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23678                 error "set max_read_ahead_async_active should succeed"
23679
23680         $LCTL set_param llite.*.max_read_ahead_async_active=512
23681         max_active=$($LCTL get_param -n \
23682                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23683         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23684
23685         # restore @max_active
23686         [ $old_max_active -ne 0 ] && $LCTL set_param \
23687                 llite.*.max_read_ahead_async_active=$old_max_active
23688
23689         local old_threshold=$($LCTL get_param -n \
23690                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23691         local max_per_file_mb=$($LCTL get_param -n \
23692                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23693
23694         local invalid=$(($max_per_file_mb + 1))
23695         $LCTL set_param \
23696                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23697                         && error "set $invalid should fail"
23698
23699         local valid=$(($invalid - 1))
23700         $LCTL set_param \
23701                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23702                         error "set $valid should succeed"
23703         local threshold=$($LCTL get_param -n \
23704                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23705         [ $threshold -eq $valid ] || error \
23706                 "expect threshold $valid got $threshold"
23707         $LCTL set_param \
23708                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23709 }
23710 run_test 318 "Verify async readahead tunables"
23711
23712 test_319() {
23713         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23714
23715         local before=$(date +%s)
23716         local evict
23717         local mdir=$DIR/$tdir
23718         local file=$mdir/xxx
23719
23720         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23721         touch $file
23722
23723 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23724         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23725         $LFS mv -m1 $file &
23726
23727         sleep 1
23728         dd if=$file of=/dev/null
23729         wait
23730         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23731           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23732
23733         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23734 }
23735 run_test 319 "lost lease lock on migrate error"
23736
23737 test_398a() { # LU-4198
23738         local ost1_imp=$(get_osc_import_name client ost1)
23739         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23740                          cut -d'.' -f2)
23741
23742         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23743         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23744
23745         # request a new lock on client
23746         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23747
23748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23749         local lock_count=$($LCTL get_param -n \
23750                            ldlm.namespaces.$imp_name.lru_size)
23751         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23752
23753         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23754
23755         # no lock cached, should use lockless IO and not enqueue new lock
23756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23757         lock_count=$($LCTL get_param -n \
23758                      ldlm.namespaces.$imp_name.lru_size)
23759         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23760 }
23761 run_test 398a "direct IO should cancel lock otherwise lockless"
23762
23763 test_398b() { # LU-4198
23764         which fio || skip_env "no fio installed"
23765         $LFS setstripe -c -1 $DIR/$tfile
23766
23767         local size=12
23768         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23769
23770         local njobs=4
23771         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23772         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23773                 --numjobs=$njobs --fallocate=none \
23774                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23775                 --filename=$DIR/$tfile &
23776         bg_pid=$!
23777
23778         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23779         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23780                 --numjobs=$njobs --fallocate=none \
23781                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23782                 --filename=$DIR/$tfile || true
23783         wait $bg_pid
23784
23785         rm -f $DIR/$tfile
23786 }
23787 run_test 398b "DIO and buffer IO race"
23788
23789 test_398c() { # LU-4198
23790         local ost1_imp=$(get_osc_import_name client ost1)
23791         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23792                          cut -d'.' -f2)
23793
23794         which fio || skip_env "no fio installed"
23795
23796         saved_debug=$($LCTL get_param -n debug)
23797         $LCTL set_param debug=0
23798
23799         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23800         ((size /= 1024)) # by megabytes
23801         ((size /= 2)) # write half of the OST at most
23802         [ $size -gt 40 ] && size=40 #reduce test time anyway
23803
23804         $LFS setstripe -c 1 $DIR/$tfile
23805
23806         # it seems like ldiskfs reserves more space than necessary if the
23807         # writing blocks are not mapped, so it extends the file firstly
23808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23809         cancel_lru_locks osc
23810
23811         # clear and verify rpc_stats later
23812         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23813
23814         local njobs=4
23815         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23816         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23817                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23818                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23819                 --filename=$DIR/$tfile
23820         [ $? -eq 0 ] || error "fio write error"
23821
23822         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23823                 error "Locks were requested while doing AIO"
23824
23825         # get the percentage of 1-page I/O
23826         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23827                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23828                 awk '{print $7}')
23829         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23830
23831         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23832         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23833                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23834                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23835                 --filename=$DIR/$tfile
23836         [ $? -eq 0 ] || error "fio mixed read write error"
23837
23838         echo "AIO with large block size ${size}M"
23839         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23840                 --numjobs=1 --fallocate=none --ioengine=libaio \
23841                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23842                 --filename=$DIR/$tfile
23843         [ $? -eq 0 ] || error "fio large block size failed"
23844
23845         rm -f $DIR/$tfile
23846         $LCTL set_param debug="$saved_debug"
23847 }
23848 run_test 398c "run fio to test AIO"
23849
23850 test_398d() { #  LU-13846
23851         which aiocp || skip_env "no aiocp installed"
23852         local aio_file=$DIR/$tfile.aio
23853
23854         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23855
23856         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23857         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23858         stack_trap "rm -f $DIR/$tfile $aio_file"
23859
23860         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23861
23862         # make sure we don't crash and fail properly
23863         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23864                 error "aio not aligned with PAGE SIZE should fail"
23865
23866         rm -f $DIR/$tfile $aio_file
23867 }
23868 run_test 398d "run aiocp to verify block size > stripe size"
23869
23870 test_398e() {
23871         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23872         touch $DIR/$tfile.new
23873         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23874 }
23875 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23876
23877 test_398f() { #  LU-14687
23878         which aiocp || skip_env "no aiocp installed"
23879         local aio_file=$DIR/$tfile.aio
23880
23881         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23882
23883         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23884         stack_trap "rm -f $DIR/$tfile $aio_file"
23885
23886         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23887         $LCTL set_param fail_loc=0x1418
23888         # make sure we don't crash and fail properly
23889         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23890                 error "aio with page allocation failure succeeded"
23891         $LCTL set_param fail_loc=0
23892         diff $DIR/$tfile $aio_file
23893         [[ $? != 0 ]] || error "no diff after failed aiocp"
23894 }
23895 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23896
23897 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23898 # stripe and i/o size must be > stripe size
23899 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23900 # single RPC in flight.  This test shows async DIO submission is working by
23901 # showing multiple RPCs in flight.
23902 test_398g() { #  LU-13798
23903         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23904
23905         # We need to do some i/o first to acquire enough grant to put our RPCs
23906         # in flight; otherwise a new connection may not have enough grant
23907         # available
23908         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23909                 error "parallel dio failed"
23910         stack_trap "rm -f $DIR/$tfile"
23911
23912         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23913         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23914         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23915         stack_trap "$LCTL set_param -n $pages_per_rpc"
23916
23917         # Recreate file so it's empty
23918         rm -f $DIR/$tfile
23919         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23920         #Pause rpc completion to guarantee we see multiple rpcs in flight
23921         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23922         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23923         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23924
23925         # Clear rpc stats
23926         $LCTL set_param osc.*.rpc_stats=c
23927
23928         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23929                 error "parallel dio failed"
23930         stack_trap "rm -f $DIR/$tfile"
23931
23932         $LCTL get_param osc.*-OST0000-*.rpc_stats
23933         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23934                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23935                 grep "8:" | awk '{print $8}')
23936         # We look at the "8 rpcs in flight" field, and verify A) it is present
23937         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23938         # as expected for an 8M DIO to a file with 1M stripes.
23939         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23940
23941         # Verify turning off parallel dio works as expected
23942         # Clear rpc stats
23943         $LCTL set_param osc.*.rpc_stats=c
23944         $LCTL set_param llite.*.parallel_dio=0
23945         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23946
23947         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23948                 error "dio with parallel dio disabled failed"
23949
23950         # Ideally, we would see only one RPC in flight here, but there is an
23951         # unavoidable race between i/o completion and RPC in flight counting,
23952         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23953         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23954         # So instead we just verify it's always < 8.
23955         $LCTL get_param osc.*-OST0000-*.rpc_stats
23956         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23957                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23958                 grep '^$' -B1 | grep . | awk '{print $1}')
23959         [ $ret != "8:" ] ||
23960                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23961 }
23962 run_test 398g "verify parallel dio async RPC submission"
23963
23964 test_398h() { #  LU-13798
23965         local dio_file=$DIR/$tfile.dio
23966
23967         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23968
23969         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23970         stack_trap "rm -f $DIR/$tfile $dio_file"
23971
23972         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23973                 error "parallel dio failed"
23974         diff $DIR/$tfile $dio_file
23975         [[ $? == 0 ]] || error "file diff after aiocp"
23976 }
23977 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23978
23979 test_398i() { #  LU-13798
23980         local dio_file=$DIR/$tfile.dio
23981
23982         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23983
23984         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23985         stack_trap "rm -f $DIR/$tfile $dio_file"
23986
23987         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23988         $LCTL set_param fail_loc=0x1418
23989         # make sure we don't crash and fail properly
23990         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23991                 error "parallel dio page allocation failure succeeded"
23992         diff $DIR/$tfile $dio_file
23993         [[ $? != 0 ]] || error "no diff after failed aiocp"
23994 }
23995 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23996
23997 test_398j() { #  LU-13798
23998         # Stripe size > RPC size but less than i/o size tests split across
23999         # stripes and RPCs for individual i/o op
24000         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24001
24002         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24003         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24004         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24005         stack_trap "$LCTL set_param -n $pages_per_rpc"
24006
24007         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24008                 error "parallel dio write failed"
24009         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24010
24011         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24012                 error "parallel dio read failed"
24013         diff $DIR/$tfile $DIR/$tfile.2
24014         [[ $? == 0 ]] || error "file diff after parallel dio read"
24015 }
24016 run_test 398j "test parallel dio where stripe size > rpc_size"
24017
24018 test_398k() { #  LU-13798
24019         wait_delete_completed
24020         wait_mds_ost_sync
24021
24022         # 4 stripe file; we will cause out of space on OST0
24023         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24024
24025         # Fill OST0 (if it's not too large)
24026         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24027                    head -n1)
24028         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24029                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24030         fi
24031         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24032         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24033                 error "dd should fill OST0"
24034         stack_trap "rm -f $DIR/$tfile.1"
24035
24036         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24037         err=$?
24038
24039         ls -la $DIR/$tfile
24040         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24041                 error "file is not 0 bytes in size"
24042
24043         # dd above should not succeed, but don't error until here so we can
24044         # get debug info above
24045         [[ $err != 0 ]] ||
24046                 error "parallel dio write with enospc succeeded"
24047         stack_trap "rm -f $DIR/$tfile"
24048 }
24049 run_test 398k "test enospc on first stripe"
24050
24051 test_398l() { #  LU-13798
24052         wait_delete_completed
24053         wait_mds_ost_sync
24054
24055         # 4 stripe file; we will cause out of space on OST0
24056         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24057         # happens on the second i/o chunk we issue
24058         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24059
24060         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24061         stack_trap "rm -f $DIR/$tfile"
24062
24063         # Fill OST0 (if it's not too large)
24064         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24065                    head -n1)
24066         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24067                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24068         fi
24069         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24070         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24071                 error "dd should fill OST0"
24072         stack_trap "rm -f $DIR/$tfile.1"
24073
24074         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24075         err=$?
24076         stack_trap "rm -f $DIR/$tfile.2"
24077
24078         # Check that short write completed as expected
24079         ls -la $DIR/$tfile.2
24080         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24081                 error "file is not 1M in size"
24082
24083         # dd above should not succeed, but don't error until here so we can
24084         # get debug info above
24085         [[ $err != 0 ]] ||
24086                 error "parallel dio write with enospc succeeded"
24087
24088         # Truncate source file to same length as output file and diff them
24089         $TRUNCATE $DIR/$tfile 1048576
24090         diff $DIR/$tfile $DIR/$tfile.2
24091         [[ $? == 0 ]] || error "data incorrect after short write"
24092 }
24093 run_test 398l "test enospc on intermediate stripe/RPC"
24094
24095 test_398m() { #  LU-13798
24096         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24097
24098         # Set up failure on OST0, the first stripe:
24099         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24100         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24101         # So this fail_val specifies OST0
24102         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24103         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24104
24105         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24106                 error "parallel dio write with failure on first stripe succeeded"
24107         stack_trap "rm -f $DIR/$tfile"
24108         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24109
24110         # Place data in file for read
24111         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24112                 error "parallel dio write failed"
24113
24114         # Fail read on OST0, first stripe
24115         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24116         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24117         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24118                 error "parallel dio read with error on first stripe succeeded"
24119         rm -f $DIR/$tfile.2
24120         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24121
24122         # Switch to testing on OST1, second stripe
24123         # Clear file contents, maintain striping
24124         echo > $DIR/$tfile
24125         # Set up failure on OST1, second stripe:
24126         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24127         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24128
24129         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24130                 error "parallel dio write with failure on first stripe succeeded"
24131         stack_trap "rm -f $DIR/$tfile"
24132         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24133
24134         # Place data in file for read
24135         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24136                 error "parallel dio write failed"
24137
24138         # Fail read on OST1, second stripe
24139         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24140         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24141         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24142                 error "parallel dio read with error on first stripe succeeded"
24143         rm -f $DIR/$tfile.2
24144         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24145 }
24146 run_test 398m "test RPC failures with parallel dio"
24147
24148 # Parallel submission of DIO should not cause problems for append, but it's
24149 # important to verify.
24150 test_398n() { #  LU-13798
24151         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24152
24153         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24154                 error "dd to create source file failed"
24155         stack_trap "rm -f $DIR/$tfile"
24156
24157         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24158                 error "parallel dio write with failure on second stripe succeeded"
24159         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24160         diff $DIR/$tfile $DIR/$tfile.1
24161         [[ $? == 0 ]] || error "data incorrect after append"
24162
24163 }
24164 run_test 398n "test append with parallel DIO"
24165
24166 test_fake_rw() {
24167         local read_write=$1
24168         if [ "$read_write" = "write" ]; then
24169                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24170         elif [ "$read_write" = "read" ]; then
24171                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24172         else
24173                 error "argument error"
24174         fi
24175
24176         # turn off debug for performance testing
24177         local saved_debug=$($LCTL get_param -n debug)
24178         $LCTL set_param debug=0
24179
24180         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24181
24182         # get ost1 size - $FSNAME-OST0000
24183         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24184         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24185         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24186
24187         if [ "$read_write" = "read" ]; then
24188                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24189         fi
24190
24191         local start_time=$(date +%s.%N)
24192         $dd_cmd bs=1M count=$blocks oflag=sync ||
24193                 error "real dd $read_write error"
24194         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24195
24196         if [ "$read_write" = "write" ]; then
24197                 rm -f $DIR/$tfile
24198         fi
24199
24200         # define OBD_FAIL_OST_FAKE_RW           0x238
24201         do_facet ost1 $LCTL set_param fail_loc=0x238
24202
24203         local start_time=$(date +%s.%N)
24204         $dd_cmd bs=1M count=$blocks oflag=sync ||
24205                 error "fake dd $read_write error"
24206         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24207
24208         if [ "$read_write" = "write" ]; then
24209                 # verify file size
24210                 cancel_lru_locks osc
24211                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24212                         error "$tfile size not $blocks MB"
24213         fi
24214         do_facet ost1 $LCTL set_param fail_loc=0
24215
24216         echo "fake $read_write $duration_fake vs. normal $read_write" \
24217                 "$duration in seconds"
24218         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24219                 error_not_in_vm "fake write is slower"
24220
24221         $LCTL set_param -n debug="$saved_debug"
24222         rm -f $DIR/$tfile
24223 }
24224 test_399a() { # LU-7655 for OST fake write
24225         remote_ost_nodsh && skip "remote OST with nodsh"
24226
24227         test_fake_rw write
24228 }
24229 run_test 399a "fake write should not be slower than normal write"
24230
24231 test_399b() { # LU-8726 for OST fake read
24232         remote_ost_nodsh && skip "remote OST with nodsh"
24233         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24234                 skip_env "ldiskfs only test"
24235         fi
24236
24237         test_fake_rw read
24238 }
24239 run_test 399b "fake read should not be slower than normal read"
24240
24241 test_400a() { # LU-1606, was conf-sanity test_74
24242         if ! which $CC > /dev/null 2>&1; then
24243                 skip_env "$CC is not installed"
24244         fi
24245
24246         local extra_flags=''
24247         local out=$TMP/$tfile
24248         local prefix=/usr/include/lustre
24249         local prog
24250
24251         # Oleg removes c files in his test rig so test if any c files exist
24252         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24253                 skip_env "Needed c test files are missing"
24254
24255         if ! [[ -d $prefix ]]; then
24256                 # Assume we're running in tree and fixup the include path.
24257                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24258                 extra_flags+=" -L$LUSTRE/utils/.lib"
24259         fi
24260
24261         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24262                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24263                         error "client api broken"
24264         done
24265         rm -f $out
24266 }
24267 run_test 400a "Lustre client api program can compile and link"
24268
24269 test_400b() { # LU-1606, LU-5011
24270         local header
24271         local out=$TMP/$tfile
24272         local prefix=/usr/include/linux/lustre
24273
24274         # We use a hard coded prefix so that this test will not fail
24275         # when run in tree. There are headers in lustre/include/lustre/
24276         # that are not packaged (like lustre_idl.h) and have more
24277         # complicated include dependencies (like config.h and lnet/types.h).
24278         # Since this test about correct packaging we just skip them when
24279         # they don't exist (see below) rather than try to fixup cppflags.
24280
24281         if ! which $CC > /dev/null 2>&1; then
24282                 skip_env "$CC is not installed"
24283         fi
24284
24285         for header in $prefix/*.h; do
24286                 if ! [[ -f "$header" ]]; then
24287                         continue
24288                 fi
24289
24290                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24291                         continue # lustre_ioctl.h is internal header
24292                 fi
24293
24294                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24295                         error "cannot compile '$header'"
24296         done
24297         rm -f $out
24298 }
24299 run_test 400b "packaged headers can be compiled"
24300
24301 test_401a() { #LU-7437
24302         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24303         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24304
24305         #count the number of parameters by "list_param -R"
24306         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24307         #count the number of parameters by listing proc files
24308         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24309         echo "proc_dirs='$proc_dirs'"
24310         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24311         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24312                       sort -u | wc -l)
24313
24314         [ $params -eq $procs ] ||
24315                 error "found $params parameters vs. $procs proc files"
24316
24317         # test the list_param -D option only returns directories
24318         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24319         #count the number of parameters by listing proc directories
24320         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24321                 sort -u | wc -l)
24322
24323         [ $params -eq $procs ] ||
24324                 error "found $params parameters vs. $procs proc files"
24325 }
24326 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24327
24328 test_401b() {
24329         # jobid_var may not allow arbitrary values, so use jobid_name
24330         # if available
24331         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24332                 local testname=jobid_name tmp='testing%p'
24333         else
24334                 local testname=jobid_var tmp=testing
24335         fi
24336
24337         local save=$($LCTL get_param -n $testname)
24338
24339         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24340                 error "no error returned when setting bad parameters"
24341
24342         local jobid_new=$($LCTL get_param -n foe $testname baz)
24343         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24344
24345         $LCTL set_param -n fog=bam $testname=$save bat=fog
24346         local jobid_old=$($LCTL get_param -n foe $testname bag)
24347         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24348 }
24349 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24350
24351 test_401c() {
24352         # jobid_var may not allow arbitrary values, so use jobid_name
24353         # if available
24354         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24355                 local testname=jobid_name
24356         else
24357                 local testname=jobid_var
24358         fi
24359
24360         local jobid_var_old=$($LCTL get_param -n $testname)
24361         local jobid_var_new
24362
24363         $LCTL set_param $testname= &&
24364                 error "no error returned for 'set_param a='"
24365
24366         jobid_var_new=$($LCTL get_param -n $testname)
24367         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24368                 error "$testname was changed by setting without value"
24369
24370         $LCTL set_param $testname &&
24371                 error "no error returned for 'set_param a'"
24372
24373         jobid_var_new=$($LCTL get_param -n $testname)
24374         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24375                 error "$testname was changed by setting without value"
24376 }
24377 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24378
24379 test_401d() {
24380         # jobid_var may not allow arbitrary values, so use jobid_name
24381         # if available
24382         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24383                 local testname=jobid_name new_value='foo=bar%p'
24384         else
24385                 local testname=jobid_var new_valuie=foo=bar
24386         fi
24387
24388         local jobid_var_old=$($LCTL get_param -n $testname)
24389         local jobid_var_new
24390
24391         $LCTL set_param $testname=$new_value ||
24392                 error "'set_param a=b' did not accept a value containing '='"
24393
24394         jobid_var_new=$($LCTL get_param -n $testname)
24395         [[ "$jobid_var_new" == "$new_value" ]] ||
24396                 error "'set_param a=b' failed on a value containing '='"
24397
24398         # Reset the $testname to test the other format
24399         $LCTL set_param $testname=$jobid_var_old
24400         jobid_var_new=$($LCTL get_param -n $testname)
24401         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24402                 error "failed to reset $testname"
24403
24404         $LCTL set_param $testname $new_value ||
24405                 error "'set_param a b' did not accept a value containing '='"
24406
24407         jobid_var_new=$($LCTL get_param -n $testname)
24408         [[ "$jobid_var_new" == "$new_value" ]] ||
24409                 error "'set_param a b' failed on a value containing '='"
24410
24411         $LCTL set_param $testname $jobid_var_old
24412         jobid_var_new=$($LCTL get_param -n $testname)
24413         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24414                 error "failed to reset $testname"
24415 }
24416 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24417
24418 test_401e() { # LU-14779
24419         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24420                 error "lctl list_param MGC* failed"
24421         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24422         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24423                 error "lctl get_param lru_size failed"
24424 }
24425 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24426
24427 test_402() {
24428         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24429         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24430                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24431         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24432                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24433                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24434         remote_mds_nodsh && skip "remote MDS with nodsh"
24435
24436         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24437 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24438         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24439         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24440                 echo "Touch failed - OK"
24441 }
24442 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24443
24444 test_403() {
24445         local file1=$DIR/$tfile.1
24446         local file2=$DIR/$tfile.2
24447         local tfile=$TMP/$tfile
24448
24449         rm -f $file1 $file2 $tfile
24450
24451         touch $file1
24452         ln $file1 $file2
24453
24454         # 30 sec OBD_TIMEOUT in ll_getattr()
24455         # right before populating st_nlink
24456         $LCTL set_param fail_loc=0x80001409
24457         stat -c %h $file1 > $tfile &
24458
24459         # create an alias, drop all locks and reclaim the dentry
24460         < $file2
24461         cancel_lru_locks mdc
24462         cancel_lru_locks osc
24463         sysctl -w vm.drop_caches=2
24464
24465         wait
24466
24467         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24468
24469         rm -f $tfile $file1 $file2
24470 }
24471 run_test 403 "i_nlink should not drop to zero due to aliasing"
24472
24473 test_404() { # LU-6601
24474         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24475                 skip "Need server version newer than 2.8.52"
24476         remote_mds_nodsh && skip "remote MDS with nodsh"
24477
24478         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24479                 awk '/osp .*-osc-MDT/ { print $4}')
24480
24481         local osp
24482         for osp in $mosps; do
24483                 echo "Deactivate: " $osp
24484                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24485                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24486                         awk -vp=$osp '$4 == p { print $2 }')
24487                 [ $stat = IN ] || {
24488                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24489                         error "deactivate error"
24490                 }
24491                 echo "Activate: " $osp
24492                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24493                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24494                         awk -vp=$osp '$4 == p { print $2 }')
24495                 [ $stat = UP ] || {
24496                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24497                         error "activate error"
24498                 }
24499         done
24500 }
24501 run_test 404 "validate manual {de}activated works properly for OSPs"
24502
24503 test_405() {
24504         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24505         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24506                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24507                         skip "Layout swap lock is not supported"
24508
24509         check_swap_layouts_support
24510         check_swap_layout_no_dom $DIR
24511
24512         test_mkdir $DIR/$tdir
24513         swap_lock_test -d $DIR/$tdir ||
24514                 error "One layout swap locked test failed"
24515 }
24516 run_test 405 "Various layout swap lock tests"
24517
24518 test_406() {
24519         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24520         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24521         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24523         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24524                 skip "Need MDS version at least 2.8.50"
24525
24526         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24527         local test_pool=$TESTNAME
24528
24529         pool_add $test_pool || error "pool_add failed"
24530         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24531                 error "pool_add_targets failed"
24532
24533         save_layout_restore_at_exit $MOUNT
24534
24535         # parent set default stripe count only, child will stripe from both
24536         # parent and fs default
24537         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24538                 error "setstripe $MOUNT failed"
24539         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24540         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24541         for i in $(seq 10); do
24542                 local f=$DIR/$tdir/$tfile.$i
24543                 touch $f || error "touch failed"
24544                 local count=$($LFS getstripe -c $f)
24545                 [ $count -eq $OSTCOUNT ] ||
24546                         error "$f stripe count $count != $OSTCOUNT"
24547                 local offset=$($LFS getstripe -i $f)
24548                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24549                 local size=$($LFS getstripe -S $f)
24550                 [ $size -eq $((def_stripe_size * 2)) ] ||
24551                         error "$f stripe size $size != $((def_stripe_size * 2))"
24552                 local pool=$($LFS getstripe -p $f)
24553                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24554         done
24555
24556         # change fs default striping, delete parent default striping, now child
24557         # will stripe from new fs default striping only
24558         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24559                 error "change $MOUNT default stripe failed"
24560         $LFS setstripe -c 0 $DIR/$tdir ||
24561                 error "delete $tdir default stripe failed"
24562         for i in $(seq 11 20); do
24563                 local f=$DIR/$tdir/$tfile.$i
24564                 touch $f || error "touch $f failed"
24565                 local count=$($LFS getstripe -c $f)
24566                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24567                 local offset=$($LFS getstripe -i $f)
24568                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24569                 local size=$($LFS getstripe -S $f)
24570                 [ $size -eq $def_stripe_size ] ||
24571                         error "$f stripe size $size != $def_stripe_size"
24572                 local pool=$($LFS getstripe -p $f)
24573                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24574         done
24575
24576         unlinkmany $DIR/$tdir/$tfile. 1 20
24577
24578         local f=$DIR/$tdir/$tfile
24579         pool_remove_all_targets $test_pool $f
24580         pool_remove $test_pool $f
24581 }
24582 run_test 406 "DNE support fs default striping"
24583
24584 test_407() {
24585         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24586         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24587                 skip "Need MDS version at least 2.8.55"
24588         remote_mds_nodsh && skip "remote MDS with nodsh"
24589
24590         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24591                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24592         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24593                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24594         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24595
24596         #define OBD_FAIL_DT_TXN_STOP    0x2019
24597         for idx in $(seq $MDSCOUNT); do
24598                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24599         done
24600         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24601         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24602                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24603         true
24604 }
24605 run_test 407 "transaction fail should cause operation fail"
24606
24607 test_408() {
24608         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24609
24610         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24611         lctl set_param fail_loc=0x8000040a
24612         # let ll_prepare_partial_page() fail
24613         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24614
24615         rm -f $DIR/$tfile
24616
24617         # create at least 100 unused inodes so that
24618         # shrink_icache_memory(0) should not return 0
24619         touch $DIR/$tfile-{0..100}
24620         rm -f $DIR/$tfile-{0..100}
24621         sync
24622
24623         echo 2 > /proc/sys/vm/drop_caches
24624 }
24625 run_test 408 "drop_caches should not hang due to page leaks"
24626
24627 test_409()
24628 {
24629         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24630
24631         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24632         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24633         touch $DIR/$tdir/guard || error "(2) Fail to create"
24634
24635         local PREFIX=$(str_repeat 'A' 128)
24636         echo "Create 1K hard links start at $(date)"
24637         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24638                 error "(3) Fail to hard link"
24639
24640         echo "Links count should be right although linkEA overflow"
24641         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24642         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24643         [ $linkcount -eq 1001 ] ||
24644                 error "(5) Unexpected hard links count: $linkcount"
24645
24646         echo "List all links start at $(date)"
24647         ls -l $DIR/$tdir/foo > /dev/null ||
24648                 error "(6) Fail to list $DIR/$tdir/foo"
24649
24650         echo "Unlink hard links start at $(date)"
24651         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24652                 error "(7) Fail to unlink"
24653         echo "Unlink hard links finished at $(date)"
24654 }
24655 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24656
24657 test_410()
24658 {
24659         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24660                 skip "Need client version at least 2.9.59"
24661         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24662                 skip "Need MODULES build"
24663
24664         # Create a file, and stat it from the kernel
24665         local testfile=$DIR/$tfile
24666         touch $testfile
24667
24668         local run_id=$RANDOM
24669         local my_ino=$(stat --format "%i" $testfile)
24670
24671         # Try to insert the module. This will always fail as the
24672         # module is designed to not be inserted.
24673         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24674             &> /dev/null
24675
24676         # Anything but success is a test failure
24677         dmesg | grep -q \
24678             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24679             error "no inode match"
24680 }
24681 run_test 410 "Test inode number returned from kernel thread"
24682
24683 cleanup_test411_cgroup() {
24684         trap 0
24685         rmdir "$1"
24686 }
24687
24688 test_411() {
24689         local cg_basedir=/sys/fs/cgroup/memory
24690         # LU-9966
24691         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24692                 skip "no setup for cgroup"
24693
24694         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24695                 error "test file creation failed"
24696         cancel_lru_locks osc
24697
24698         # Create a very small memory cgroup to force a slab allocation error
24699         local cgdir=$cg_basedir/osc_slab_alloc
24700         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24701         trap "cleanup_test411_cgroup $cgdir" EXIT
24702         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24703         echo 1M > $cgdir/memory.limit_in_bytes
24704
24705         # Should not LBUG, just be killed by oom-killer
24706         # dd will return 0 even allocation failure in some environment.
24707         # So don't check return value
24708         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24709         cleanup_test411_cgroup $cgdir
24710
24711         return 0
24712 }
24713 run_test 411 "Slab allocation error with cgroup does not LBUG"
24714
24715 test_412() {
24716         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24717         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24718                 skip "Need server version at least 2.10.55"
24719         fi
24720
24721         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24722                 error "mkdir failed"
24723         $LFS getdirstripe $DIR/$tdir
24724         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24725         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24726                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24727         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24728         [ $stripe_count -eq 2 ] ||
24729                 error "expect 2 get $stripe_count"
24730 }
24731 run_test 412 "mkdir on specific MDTs"
24732
24733 generate_uneven_mdts() {
24734         local threshold=$1
24735         local ffree
24736         local bavail
24737         local max
24738         local min
24739         local max_index
24740         local min_index
24741         local tmp
24742         local i
24743
24744         echo
24745         echo "Check for uneven MDTs: "
24746
24747         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24748         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24749         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24750
24751         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24752         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24753         max_index=0
24754         min_index=0
24755         for ((i = 1; i < ${#ffree[@]}; i++)); do
24756                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24757                 if [ $tmp -gt $max ]; then
24758                         max=$tmp
24759                         max_index=$i
24760                 fi
24761                 if [ $tmp -lt $min ]; then
24762                         min=$tmp
24763                         min_index=$i
24764                 fi
24765         done
24766
24767         # Check if we need to generate uneven MDTs
24768         local diff=$(((max - min) * 100 / min))
24769         local testdir=$DIR/$tdir-fillmdt
24770
24771         mkdir -p $testdir
24772
24773         i=0
24774         while (( diff < threshold )); do
24775                 # generate uneven MDTs, create till $threshold% diff
24776                 echo -n "weight diff=$diff% must be > $threshold% ..."
24777                 echo "Fill MDT$min_index with 100 files: loop $i"
24778                 testdir=$DIR/$tdir-fillmdt/$i
24779                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24780                         error "mkdir $testdir failed"
24781                 $LFS setstripe -E 1M -L mdt $testdir ||
24782                         error "setstripe $testdir failed"
24783                 for F in f.{0..99}; do
24784                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24785                                 /dev/null 2>&1 || error "dd $F failed"
24786                 done
24787
24788                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24789                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24790                 max=$(((${ffree[max_index]} >> 8) * \
24791                         (${bavail[max_index]} * bsize >> 16)))
24792                 min=$(((${ffree[min_index]} >> 8) * \
24793                         (${bavail[min_index]} * bsize >> 16)))
24794                 diff=$(((max - min) * 100 / min))
24795                 i=$((i + 1))
24796         done
24797
24798         echo "MDT filesfree available: ${ffree[@]}"
24799         echo "MDT blocks available: ${bavail[@]}"
24800         echo "weight diff=$diff%"
24801 }
24802
24803 test_qos_mkdir() {
24804         local mkdir_cmd=$1
24805         local stripe_count=$2
24806         local mdts=$(comma_list $(mdts_nodes))
24807
24808         local testdir
24809         local lmv_qos_prio_free
24810         local lmv_qos_threshold_rr
24811         local lmv_qos_maxage
24812         local lod_qos_prio_free
24813         local lod_qos_threshold_rr
24814         local lod_qos_maxage
24815         local count
24816         local i
24817
24818         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24819         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24820         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24821                 head -n1)
24822         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24823         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24824         stack_trap "$LCTL set_param \
24825                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24826         stack_trap "$LCTL set_param \
24827                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24828         stack_trap "$LCTL set_param \
24829                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24830
24831         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24832                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24833         lod_qos_prio_free=${lod_qos_prio_free%%%}
24834         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24835                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24836         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24837         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24838                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24839         stack_trap "do_nodes $mdts $LCTL set_param \
24840                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24841         stack_trap "do_nodes $mdts $LCTL set_param \
24842                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24843         stack_trap "do_nodes $mdts $LCTL set_param \
24844                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24845
24846         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24847         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24848
24849         testdir=$DIR/$tdir-s$stripe_count/rr
24850
24851         local stripe_index=$($LFS getstripe -m $testdir)
24852         local test_mkdir_rr=true
24853
24854         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24855         getfattr -d -m dmv -e hex $testdir | grep dmv
24856         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24857                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24858                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24859                         test_mkdir_rr=false
24860         fi
24861
24862         echo
24863         $test_mkdir_rr &&
24864                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24865                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24866
24867         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24868         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24869                 eval $mkdir_cmd $testdir/subdir$i ||
24870                         error "$mkdir_cmd subdir$i failed"
24871         done
24872
24873         for (( i = 0; i < $MDSCOUNT; i++ )); do
24874                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24875                 echo "$count directories created on MDT$i"
24876                 if $test_mkdir_rr; then
24877                         (( $count == 100 )) ||
24878                                 error "subdirs are not evenly distributed"
24879                 elif (( $i == $stripe_index )); then
24880                         (( $count == 100 * MDSCOUNT )) ||
24881                                 error "$count subdirs created on MDT$i"
24882                 else
24883                         (( $count == 0 )) ||
24884                                 error "$count subdirs created on MDT$i"
24885                 fi
24886
24887                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24888                         count=$($LFS getdirstripe $testdir/* |
24889                                 grep -c -P "^\s+$i\t")
24890                         echo "$count stripes created on MDT$i"
24891                         # deviation should < 5% of average
24892                         (( $count >= 95 * stripe_count &&
24893                            $count <= 105 * stripe_count)) ||
24894                                 error "stripes are not evenly distributed"
24895                 fi
24896         done
24897
24898         echo
24899         echo "Check for uneven MDTs: "
24900
24901         local ffree
24902         local bavail
24903         local max
24904         local min
24905         local max_index
24906         local min_index
24907         local tmp
24908
24909         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24910         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24911         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24912
24913         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24914         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24915         max_index=0
24916         min_index=0
24917         for ((i = 1; i < ${#ffree[@]}; i++)); do
24918                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24919                 if [ $tmp -gt $max ]; then
24920                         max=$tmp
24921                         max_index=$i
24922                 fi
24923                 if [ $tmp -lt $min ]; then
24924                         min=$tmp
24925                         min_index=$i
24926                 fi
24927         done
24928
24929         (( ${ffree[min_index]} > 0 )) ||
24930                 skip "no free files in MDT$min_index"
24931         (( ${ffree[min_index]} < 100000000 )) ||
24932                 skip "too many free files in MDT$min_index"
24933
24934         echo "MDT filesfree available: ${ffree[@]}"
24935         echo "MDT blocks available: ${bavail[@]}"
24936         echo "weight diff=$(((max - min) * 100 / min))%"
24937         echo
24938         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24939
24940         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24941         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24942         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24943         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24944         # decrease statfs age, so that it can be updated in time
24945         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24946         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24947
24948         sleep 1
24949
24950         testdir=$DIR/$tdir-s$stripe_count/qos
24951         local num=200
24952
24953         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24954         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24955                 eval $mkdir_cmd $testdir/subdir$i ||
24956                         error "$mkdir_cmd subdir$i failed"
24957         done
24958
24959         for (( i = 0; i < $MDSCOUNT; i++ )); do
24960                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24961                 echo "$count directories created on MDT$i"
24962
24963                 if [ $stripe_count -gt 1 ]; then
24964                         count=$($LFS getdirstripe $testdir/* |
24965                                 grep -c -P "^\s+$i\t")
24966                         echo "$count stripes created on MDT$i"
24967                 fi
24968         done
24969
24970         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24971         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24972
24973         # D-value should > 10% of averge
24974         (( max - min >= num / 10 )) ||
24975                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24976
24977         # 5% for stripes
24978         if (( stripe_count > 1 )); then
24979                 max=$($LFS getdirstripe $testdir/* |
24980                       grep -c -P "^\s+$max_index\t")
24981                 min=$($LFS getdirstripe $testdir/* |
24982                         grep -c -P "^\s+$min_index\t")
24983                 (( max - min >= num * stripe_count / 20 )) ||
24984                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24985         fi
24986 }
24987
24988 most_full_mdt() {
24989         local ffree
24990         local bavail
24991         local bsize
24992         local min
24993         local min_index
24994         local tmp
24995
24996         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24997         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24998         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24999
25000         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25001         min_index=0
25002         for ((i = 1; i < ${#ffree[@]}; i++)); do
25003                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25004                 (( tmp < min )) && min=$tmp && min_index=$i
25005         done
25006
25007         echo -n $min_index
25008 }
25009
25010 test_413a() {
25011         [ $MDSCOUNT -lt 2 ] &&
25012                 skip "We need at least 2 MDTs for this test"
25013
25014         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25015                 skip "Need server version at least 2.12.52"
25016
25017         local stripe_count
25018
25019         generate_uneven_mdts 100
25020         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25021                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25022                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25023                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25024                         error "mkdir failed"
25025                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25026         done
25027 }
25028 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25029
25030 test_413b() {
25031         [ $MDSCOUNT -lt 2 ] &&
25032                 skip "We need at least 2 MDTs for this test"
25033
25034         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25035                 skip "Need server version at least 2.12.52"
25036
25037         local testdir
25038         local stripe_count
25039
25040         generate_uneven_mdts 100
25041         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25042                 testdir=$DIR/$tdir-s$stripe_count
25043                 mkdir $testdir || error "mkdir $testdir failed"
25044                 mkdir $testdir/rr || error "mkdir rr failed"
25045                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25046                         error "mkdir qos failed"
25047                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25048                         $testdir/rr || error "setdirstripe rr failed"
25049                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25050                         error "setdirstripe failed"
25051                 test_qos_mkdir "mkdir" $stripe_count
25052         done
25053 }
25054 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25055
25056 test_413c() {
25057         (( $MDSCOUNT >= 2 )) ||
25058                 skip "We need at least 2 MDTs for this test"
25059
25060         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25061                 skip "Need server version at least 2.14.51"
25062
25063         local testdir
25064         local inherit
25065         local inherit_rr
25066
25067         testdir=$DIR/${tdir}-s1
25068         mkdir $testdir || error "mkdir $testdir failed"
25069         mkdir $testdir/rr || error "mkdir rr failed"
25070         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25071         # default max_inherit is -1, default max_inherit_rr is 0
25072         $LFS setdirstripe -D -c 1 $testdir/rr ||
25073                 error "setdirstripe rr failed"
25074         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25075                 error "setdirstripe qos failed"
25076         test_qos_mkdir "mkdir" 1
25077
25078         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25079         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25080         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25081         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25082         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25083
25084         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25085         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25086         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25087         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25088         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25089         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25090         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25091                 error "level2 shouldn't have default LMV" || true
25092 }
25093 run_test 413c "mkdir with default LMV max inherit rr"
25094
25095 test_413d() {
25096         (( MDSCOUNT >= 2 )) ||
25097                 skip "We need at least 2 MDTs for this test"
25098
25099         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25100                 skip "Need server version at least 2.14.51"
25101
25102         local lmv_qos_threshold_rr
25103
25104         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25105                 head -n1)
25106         stack_trap "$LCTL set_param \
25107                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25108
25109         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25110         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25111         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25112                 error "$tdir shouldn't have default LMV"
25113         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25114                 error "mkdir sub failed"
25115
25116         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25117
25118         (( count == 100 )) || error "$count subdirs on MDT0"
25119 }
25120 run_test 413d "inherit ROOT default LMV"
25121
25122 test_413z() {
25123         local pids=""
25124         local subdir
25125         local pid
25126
25127         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25128                 unlinkmany $subdir/f. 100 &
25129                 pids="$pids $!"
25130         done
25131
25132         for pid in $pids; do
25133                 wait $pid
25134         done
25135 }
25136 run_test 413z "413 test cleanup"
25137
25138 test_414() {
25139 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25140         $LCTL set_param fail_loc=0x80000521
25141         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25142         rm -f $DIR/$tfile
25143 }
25144 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25145
25146 test_415() {
25147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25148         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25149                 skip "Need server version at least 2.11.52"
25150
25151         # LU-11102
25152         local total
25153         local setattr_pid
25154         local start_time
25155         local end_time
25156         local duration
25157
25158         total=500
25159         # this test may be slow on ZFS
25160         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25161
25162         # though this test is designed for striped directory, let's test normal
25163         # directory too since lock is always saved as CoS lock.
25164         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25165         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25166
25167         (
25168                 while true; do
25169                         touch $DIR/$tdir
25170                 done
25171         ) &
25172         setattr_pid=$!
25173
25174         start_time=$(date +%s)
25175         for i in $(seq $total); do
25176                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25177                         > /dev/null
25178         done
25179         end_time=$(date +%s)
25180         duration=$((end_time - start_time))
25181
25182         kill -9 $setattr_pid
25183
25184         echo "rename $total files took $duration sec"
25185         [ $duration -lt 100 ] || error "rename took $duration sec"
25186 }
25187 run_test 415 "lock revoke is not missing"
25188
25189 test_416() {
25190         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25191                 skip "Need server version at least 2.11.55"
25192
25193         # define OBD_FAIL_OSD_TXN_START    0x19a
25194         do_facet mds1 lctl set_param fail_loc=0x19a
25195
25196         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25197
25198         true
25199 }
25200 run_test 416 "transaction start failure won't cause system hung"
25201
25202 cleanup_417() {
25203         trap 0
25204         do_nodes $(comma_list $(mdts_nodes)) \
25205                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25206         do_nodes $(comma_list $(mdts_nodes)) \
25207                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25208         do_nodes $(comma_list $(mdts_nodes)) \
25209                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25210 }
25211
25212 test_417() {
25213         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25214         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25215                 skip "Need MDS version at least 2.11.56"
25216
25217         trap cleanup_417 RETURN EXIT
25218
25219         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25220         do_nodes $(comma_list $(mdts_nodes)) \
25221                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25222         $LFS migrate -m 0 $DIR/$tdir.1 &&
25223                 error "migrate dir $tdir.1 should fail"
25224
25225         do_nodes $(comma_list $(mdts_nodes)) \
25226                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25227         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25228                 error "create remote dir $tdir.2 should fail"
25229
25230         do_nodes $(comma_list $(mdts_nodes)) \
25231                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25232         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25233                 error "create striped dir $tdir.3 should fail"
25234         true
25235 }
25236 run_test 417 "disable remote dir, striped dir and dir migration"
25237
25238 # Checks that the outputs of df [-i] and lfs df [-i] match
25239 #
25240 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25241 check_lfs_df() {
25242         local dir=$2
25243         local inodes
25244         local df_out
25245         local lfs_df_out
25246         local count
25247         local passed=false
25248
25249         # blocks or inodes
25250         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25251
25252         for count in {1..100}; do
25253                 do_rpc_nodes "$CLIENTS" cancel_lru_locks
25254                 sync; sleep 0.2
25255
25256                 # read the lines of interest
25257                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25258                         error "df $inodes $dir | tail -n +2 failed"
25259                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25260                         error "lfs df $inodes $dir | grep summary: failed"
25261
25262                 # skip first substrings of each output as they are different
25263                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25264                 # compare the two outputs
25265                 passed=true
25266                 for i in {1..5}; do
25267                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25268                 done
25269                 $passed && break
25270         done
25271
25272         if ! $passed; then
25273                 df -P $inodes $dir
25274                 echo
25275                 lfs df $inodes $dir
25276                 error "df and lfs df $1 output mismatch: "      \
25277                       "df ${inodes}: ${df_out[*]}, "            \
25278                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25279         fi
25280 }
25281
25282 test_418() {
25283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25284
25285         local dir=$DIR/$tdir
25286         local numfiles=$((RANDOM % 4096 + 2))
25287         local numblocks=$((RANDOM % 256 + 1))
25288
25289         wait_delete_completed
25290         test_mkdir $dir
25291
25292         # check block output
25293         check_lfs_df blocks $dir
25294         # check inode output
25295         check_lfs_df inodes $dir
25296
25297         # create a single file and retest
25298         echo "Creating a single file and testing"
25299         createmany -o $dir/$tfile- 1 &>/dev/null ||
25300                 error "creating 1 file in $dir failed"
25301         check_lfs_df blocks $dir
25302         check_lfs_df inodes $dir
25303
25304         # create a random number of files
25305         echo "Creating $((numfiles - 1)) files and testing"
25306         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25307                 error "creating $((numfiles - 1)) files in $dir failed"
25308
25309         # write a random number of blocks to the first test file
25310         echo "Writing $numblocks 4K blocks and testing"
25311         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25312                 count=$numblocks &>/dev/null ||
25313                 error "dd to $dir/${tfile}-0 failed"
25314
25315         # retest
25316         check_lfs_df blocks $dir
25317         check_lfs_df inodes $dir
25318
25319         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25320                 error "unlinking $numfiles files in $dir failed"
25321 }
25322 run_test 418 "df and lfs df outputs match"
25323
25324 test_419()
25325 {
25326         local dir=$DIR/$tdir
25327
25328         mkdir -p $dir
25329         touch $dir/file
25330
25331         cancel_lru_locks mdc
25332
25333         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25334         $LCTL set_param fail_loc=0x1410
25335         cat $dir/file
25336         $LCTL set_param fail_loc=0
25337         rm -rf $dir
25338 }
25339 run_test 419 "Verify open file by name doesn't crash kernel"
25340
25341 test_420()
25342 {
25343         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25344                 skip "Need MDS version at least 2.12.53"
25345
25346         local SAVE_UMASK=$(umask)
25347         local dir=$DIR/$tdir
25348         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25349
25350         mkdir -p $dir
25351         umask 0000
25352         mkdir -m03777 $dir/testdir
25353         ls -dn $dir/testdir
25354         # Need to remove trailing '.' when SELinux is enabled
25355         local dirperms=$(ls -dn $dir/testdir |
25356                          awk '{ sub(/\.$/, "", $1); print $1}')
25357         [ $dirperms == "drwxrwsrwt" ] ||
25358                 error "incorrect perms on $dir/testdir"
25359
25360         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25361                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25362         ls -n $dir/testdir/testfile
25363         local fileperms=$(ls -n $dir/testdir/testfile |
25364                           awk '{ sub(/\.$/, "", $1); print $1}')
25365         [ $fileperms == "-rwxr-xr-x" ] ||
25366                 error "incorrect perms on $dir/testdir/testfile"
25367
25368         umask $SAVE_UMASK
25369 }
25370 run_test 420 "clear SGID bit on non-directories for non-members"
25371
25372 test_421a() {
25373         local cnt
25374         local fid1
25375         local fid2
25376
25377         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25378                 skip "Need MDS version at least 2.12.54"
25379
25380         test_mkdir $DIR/$tdir
25381         createmany -o $DIR/$tdir/f 3
25382         cnt=$(ls -1 $DIR/$tdir | wc -l)
25383         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25384
25385         fid1=$(lfs path2fid $DIR/$tdir/f1)
25386         fid2=$(lfs path2fid $DIR/$tdir/f2)
25387         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25388
25389         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25390         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25391
25392         cnt=$(ls -1 $DIR/$tdir | wc -l)
25393         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25394
25395         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25396         createmany -o $DIR/$tdir/f 3
25397         cnt=$(ls -1 $DIR/$tdir | wc -l)
25398         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25399
25400         fid1=$(lfs path2fid $DIR/$tdir/f1)
25401         fid2=$(lfs path2fid $DIR/$tdir/f2)
25402         echo "remove using fsname $FSNAME"
25403         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25404
25405         cnt=$(ls -1 $DIR/$tdir | wc -l)
25406         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25407 }
25408 run_test 421a "simple rm by fid"
25409
25410 test_421b() {
25411         local cnt
25412         local FID1
25413         local FID2
25414
25415         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25416                 skip "Need MDS version at least 2.12.54"
25417
25418         test_mkdir $DIR/$tdir
25419         createmany -o $DIR/$tdir/f 3
25420         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25421         MULTIPID=$!
25422
25423         FID1=$(lfs path2fid $DIR/$tdir/f1)
25424         FID2=$(lfs path2fid $DIR/$tdir/f2)
25425         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25426
25427         kill -USR1 $MULTIPID
25428         wait
25429
25430         cnt=$(ls $DIR/$tdir | wc -l)
25431         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25432 }
25433 run_test 421b "rm by fid on open file"
25434
25435 test_421c() {
25436         local cnt
25437         local FIDS
25438
25439         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25440                 skip "Need MDS version at least 2.12.54"
25441
25442         test_mkdir $DIR/$tdir
25443         createmany -o $DIR/$tdir/f 3
25444         touch $DIR/$tdir/$tfile
25445         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25446         cnt=$(ls -1 $DIR/$tdir | wc -l)
25447         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25448
25449         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25450         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25451
25452         cnt=$(ls $DIR/$tdir | wc -l)
25453         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25454 }
25455 run_test 421c "rm by fid against hardlinked files"
25456
25457 test_421d() {
25458         local cnt
25459         local FIDS
25460
25461         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25462                 skip "Need MDS version at least 2.12.54"
25463
25464         test_mkdir $DIR/$tdir
25465         createmany -o $DIR/$tdir/f 4097
25466         cnt=$(ls -1 $DIR/$tdir | wc -l)
25467         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25468
25469         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25470         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25471
25472         cnt=$(ls $DIR/$tdir | wc -l)
25473         rm -rf $DIR/$tdir
25474         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25475 }
25476 run_test 421d "rmfid en masse"
25477
25478 test_421e() {
25479         local cnt
25480         local FID
25481
25482         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25483         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25484                 skip "Need MDS version at least 2.12.54"
25485
25486         mkdir -p $DIR/$tdir
25487         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25488         createmany -o $DIR/$tdir/striped_dir/f 512
25489         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25490         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25491
25492         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25493                 sed "s/[/][^:]*://g")
25494         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25495
25496         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25497         rm -rf $DIR/$tdir
25498         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25499 }
25500 run_test 421e "rmfid in DNE"
25501
25502 test_421f() {
25503         local cnt
25504         local FID
25505
25506         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25507                 skip "Need MDS version at least 2.12.54"
25508
25509         test_mkdir $DIR/$tdir
25510         touch $DIR/$tdir/f
25511         cnt=$(ls -1 $DIR/$tdir | wc -l)
25512         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25513
25514         FID=$(lfs path2fid $DIR/$tdir/f)
25515         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25516         # rmfid should fail
25517         cnt=$(ls -1 $DIR/$tdir | wc -l)
25518         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25519
25520         chmod a+rw $DIR/$tdir
25521         ls -la $DIR/$tdir
25522         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25523         # rmfid should fail
25524         cnt=$(ls -1 $DIR/$tdir | wc -l)
25525         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25526
25527         rm -f $DIR/$tdir/f
25528         $RUNAS touch $DIR/$tdir/f
25529         FID=$(lfs path2fid $DIR/$tdir/f)
25530         echo "rmfid as root"
25531         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25532         cnt=$(ls -1 $DIR/$tdir | wc -l)
25533         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25534
25535         rm -f $DIR/$tdir/f
25536         $RUNAS touch $DIR/$tdir/f
25537         cnt=$(ls -1 $DIR/$tdir | wc -l)
25538         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25539         FID=$(lfs path2fid $DIR/$tdir/f)
25540         # rmfid w/o user_fid2path mount option should fail
25541         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25542         cnt=$(ls -1 $DIR/$tdir | wc -l)
25543         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25544
25545         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25546         stack_trap "rmdir $tmpdir"
25547         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25548                 error "failed to mount client'"
25549         stack_trap "umount_client $tmpdir"
25550
25551         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25552         # rmfid should succeed
25553         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25554         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25555
25556         # rmfid shouldn't allow to remove files due to dir's permission
25557         chmod a+rwx $tmpdir/$tdir
25558         touch $tmpdir/$tdir/f
25559         ls -la $tmpdir/$tdir
25560         FID=$(lfs path2fid $tmpdir/$tdir/f)
25561         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25562         return 0
25563 }
25564 run_test 421f "rmfid checks permissions"
25565
25566 test_421g() {
25567         local cnt
25568         local FIDS
25569
25570         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25571         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25572                 skip "Need MDS version at least 2.12.54"
25573
25574         mkdir -p $DIR/$tdir
25575         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25576         createmany -o $DIR/$tdir/striped_dir/f 512
25577         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25578         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25579
25580         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25581                 sed "s/[/][^:]*://g")
25582
25583         rm -f $DIR/$tdir/striped_dir/f1*
25584         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25585         removed=$((512 - cnt))
25586
25587         # few files have been just removed, so we expect
25588         # rmfid to fail on their fids
25589         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25590         [ $removed != $errors ] && error "$errors != $removed"
25591
25592         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25593         rm -rf $DIR/$tdir
25594         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25595 }
25596 run_test 421g "rmfid to return errors properly"
25597
25598 test_422() {
25599         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25600         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25601         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25602         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25603         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25604
25605         local amc=$(at_max_get client)
25606         local amo=$(at_max_get mds1)
25607         local timeout=`lctl get_param -n timeout`
25608
25609         at_max_set 0 client
25610         at_max_set 0 mds1
25611
25612 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25613         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25614                         fail_val=$(((2*timeout + 10)*1000))
25615         touch $DIR/$tdir/d3/file &
25616         sleep 2
25617 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25618         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25619                         fail_val=$((2*timeout + 5))
25620         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25621         local pid=$!
25622         sleep 1
25623         kill -9 $pid
25624         sleep $((2 * timeout))
25625         echo kill $pid
25626         kill -9 $pid
25627         lctl mark touch
25628         touch $DIR/$tdir/d2/file3
25629         touch $DIR/$tdir/d2/file4
25630         touch $DIR/$tdir/d2/file5
25631
25632         wait
25633         at_max_set $amc client
25634         at_max_set $amo mds1
25635
25636         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25637         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25638                 error "Watchdog is always throttled"
25639 }
25640 run_test 422 "kill a process with RPC in progress"
25641
25642 stat_test() {
25643     df -h $MOUNT &
25644     df -h $MOUNT &
25645     df -h $MOUNT &
25646     df -h $MOUNT &
25647     df -h $MOUNT &
25648     df -h $MOUNT &
25649 }
25650
25651 test_423() {
25652     local _stats
25653     # ensure statfs cache is expired
25654     sleep 2;
25655
25656     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25657     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25658
25659     return 0
25660 }
25661 run_test 423 "statfs should return a right data"
25662
25663 test_424() {
25664 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25665         $LCTL set_param fail_loc=0x80000522
25666         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25667         rm -f $DIR/$tfile
25668 }
25669 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25670
25671 test_425() {
25672         test_mkdir -c -1 $DIR/$tdir
25673         $LFS setstripe -c -1 $DIR/$tdir
25674
25675         lru_resize_disable "" 100
25676         stack_trap "lru_resize_enable" EXIT
25677
25678         sleep 5
25679
25680         for i in $(seq $((MDSCOUNT * 125))); do
25681                 local t=$DIR/$tdir/$tfile_$i
25682
25683                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25684                         error_noexit "Create file $t"
25685         done
25686         stack_trap "rm -rf $DIR/$tdir" EXIT
25687
25688         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25689                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25690                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25691
25692                 [ $lock_count -le $lru_size ] ||
25693                         error "osc lock count $lock_count > lru size $lru_size"
25694         done
25695
25696         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25697                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25698                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25699
25700                 [ $lock_count -le $lru_size ] ||
25701                         error "mdc lock count $lock_count > lru size $lru_size"
25702         done
25703 }
25704 run_test 425 "lock count should not exceed lru size"
25705
25706 test_426() {
25707         splice-test -r $DIR/$tfile
25708         splice-test -rd $DIR/$tfile
25709         splice-test $DIR/$tfile
25710         splice-test -d $DIR/$tfile
25711 }
25712 run_test 426 "splice test on Lustre"
25713
25714 test_427() {
25715         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25716         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25717                 skip "Need MDS version at least 2.12.4"
25718         local log
25719
25720         mkdir $DIR/$tdir
25721         mkdir $DIR/$tdir/1
25722         mkdir $DIR/$tdir/2
25723         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25724         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25725
25726         $LFS getdirstripe $DIR/$tdir/1/dir
25727
25728         #first setfattr for creating updatelog
25729         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25730
25731 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25732         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25733         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25734         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25735
25736         sleep 2
25737         fail mds2
25738         wait_recovery_complete mds2 $((2*TIMEOUT))
25739
25740         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25741         echo $log | grep "get update log failed" &&
25742                 error "update log corruption is detected" || true
25743 }
25744 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25745
25746 test_428() {
25747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25748         local cache_limit=$CACHE_MAX
25749
25750         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25751         $LCTL set_param -n llite.*.max_cached_mb=64
25752
25753         mkdir $DIR/$tdir
25754         $LFS setstripe -c 1 $DIR/$tdir
25755         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25756         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25757         #test write
25758         for f in $(seq 4); do
25759                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25760         done
25761         wait
25762
25763         cancel_lru_locks osc
25764         # Test read
25765         for f in $(seq 4); do
25766                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25767         done
25768         wait
25769 }
25770 run_test 428 "large block size IO should not hang"
25771
25772 test_429() { # LU-7915 / LU-10948
25773         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25774         local testfile=$DIR/$tfile
25775         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25776         local new_flag=1
25777         local first_rpc
25778         local second_rpc
25779         local third_rpc
25780
25781         $LCTL get_param $ll_opencache_threshold_count ||
25782                 skip "client does not have opencache parameter"
25783
25784         set_opencache $new_flag
25785         stack_trap "restore_opencache"
25786         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25787                 error "enable opencache failed"
25788         touch $testfile
25789         # drop MDC DLM locks
25790         cancel_lru_locks mdc
25791         # clear MDC RPC stats counters
25792         $LCTL set_param $mdc_rpcstats=clear
25793
25794         # According to the current implementation, we need to run 3 times
25795         # open & close file to verify if opencache is enabled correctly.
25796         # 1st, RPCs are sent for lookup/open and open handle is released on
25797         #      close finally.
25798         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25799         #      so open handle won't be released thereafter.
25800         # 3rd, No RPC is sent out.
25801         $MULTIOP $testfile oc || error "multiop failed"
25802         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25803         echo "1st: $first_rpc RPCs in flight"
25804
25805         $MULTIOP $testfile oc || error "multiop failed"
25806         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25807         echo "2nd: $second_rpc RPCs in flight"
25808
25809         $MULTIOP $testfile oc || error "multiop failed"
25810         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25811         echo "3rd: $third_rpc RPCs in flight"
25812
25813         #verify no MDC RPC is sent
25814         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25815 }
25816 run_test 429 "verify if opencache flag on client side does work"
25817
25818 lseek_test_430() {
25819         local offset
25820         local file=$1
25821
25822         # data at [200K, 400K)
25823         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25824                 error "256K->512K dd fails"
25825         # data at [2M, 3M)
25826         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25827                 error "2M->3M dd fails"
25828         # data at [4M, 5M)
25829         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25830                 error "4M->5M dd fails"
25831         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25832         # start at first component hole #1
25833         printf "Seeking hole from 1000 ... "
25834         offset=$(lseek_test -l 1000 $file)
25835         echo $offset
25836         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25837         printf "Seeking data from 1000 ... "
25838         offset=$(lseek_test -d 1000 $file)
25839         echo $offset
25840         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25841
25842         # start at first component data block
25843         printf "Seeking hole from 300000 ... "
25844         offset=$(lseek_test -l 300000 $file)
25845         echo $offset
25846         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25847         printf "Seeking data from 300000 ... "
25848         offset=$(lseek_test -d 300000 $file)
25849         echo $offset
25850         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25851
25852         # start at the first component but beyond end of object size
25853         printf "Seeking hole from 1000000 ... "
25854         offset=$(lseek_test -l 1000000 $file)
25855         echo $offset
25856         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25857         printf "Seeking data from 1000000 ... "
25858         offset=$(lseek_test -d 1000000 $file)
25859         echo $offset
25860         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25861
25862         # start at second component stripe 2 (empty file)
25863         printf "Seeking hole from 1500000 ... "
25864         offset=$(lseek_test -l 1500000 $file)
25865         echo $offset
25866         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25867         printf "Seeking data from 1500000 ... "
25868         offset=$(lseek_test -d 1500000 $file)
25869         echo $offset
25870         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25871
25872         # start at second component stripe 1 (all data)
25873         printf "Seeking hole from 3000000 ... "
25874         offset=$(lseek_test -l 3000000 $file)
25875         echo $offset
25876         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25877         printf "Seeking data from 3000000 ... "
25878         offset=$(lseek_test -d 3000000 $file)
25879         echo $offset
25880         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25881
25882         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25883                 error "2nd dd fails"
25884         echo "Add data block at 640K...1280K"
25885
25886         # start at before new data block, in hole
25887         printf "Seeking hole from 600000 ... "
25888         offset=$(lseek_test -l 600000 $file)
25889         echo $offset
25890         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25891         printf "Seeking data from 600000 ... "
25892         offset=$(lseek_test -d 600000 $file)
25893         echo $offset
25894         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25895
25896         # start at the first component new data block
25897         printf "Seeking hole from 1000000 ... "
25898         offset=$(lseek_test -l 1000000 $file)
25899         echo $offset
25900         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25901         printf "Seeking data from 1000000 ... "
25902         offset=$(lseek_test -d 1000000 $file)
25903         echo $offset
25904         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25905
25906         # start at second component stripe 2, new data
25907         printf "Seeking hole from 1200000 ... "
25908         offset=$(lseek_test -l 1200000 $file)
25909         echo $offset
25910         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25911         printf "Seeking data from 1200000 ... "
25912         offset=$(lseek_test -d 1200000 $file)
25913         echo $offset
25914         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25915
25916         # start beyond file end
25917         printf "Using offset > filesize ... "
25918         lseek_test -l 4000000 $file && error "lseek should fail"
25919         printf "Using offset > filesize ... "
25920         lseek_test -d 4000000 $file && error "lseek should fail"
25921
25922         printf "Done\n\n"
25923 }
25924
25925 test_430a() {
25926         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25927                 skip "MDT does not support SEEK_HOLE"
25928
25929         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25930                 skip "OST does not support SEEK_HOLE"
25931
25932         local file=$DIR/$tdir/$tfile
25933
25934         mkdir -p $DIR/$tdir
25935
25936         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25937         # OST stripe #1 will have continuous data at [1M, 3M)
25938         # OST stripe #2 is empty
25939         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25940         lseek_test_430 $file
25941         rm $file
25942         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25943         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25944         lseek_test_430 $file
25945         rm $file
25946         $LFS setstripe -c2 -S 512K $file
25947         echo "Two stripes, stripe size 512K"
25948         lseek_test_430 $file
25949         rm $file
25950         # FLR with stale mirror
25951         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25952                        -N -c2 -S 1M $file
25953         echo "Mirrored file:"
25954         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25955         echo "Plain 2 stripes 1M"
25956         lseek_test_430 $file
25957         rm $file
25958 }
25959 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25960
25961 test_430b() {
25962         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25963                 skip "OST does not support SEEK_HOLE"
25964
25965         local offset
25966         local file=$DIR/$tdir/$tfile
25967
25968         mkdir -p $DIR/$tdir
25969         # Empty layout lseek should fail
25970         $MCREATE $file
25971         # seek from 0
25972         printf "Seeking hole from 0 ... "
25973         lseek_test -l 0 $file && error "lseek should fail"
25974         printf "Seeking data from 0 ... "
25975         lseek_test -d 0 $file && error "lseek should fail"
25976         rm $file
25977
25978         # 1M-hole file
25979         $LFS setstripe -E 1M -c2 -E eof $file
25980         $TRUNCATE $file 1048576
25981         printf "Seeking hole from 1000000 ... "
25982         offset=$(lseek_test -l 1000000 $file)
25983         echo $offset
25984         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25985         printf "Seeking data from 1000000 ... "
25986         lseek_test -d 1000000 $file && error "lseek should fail"
25987         rm $file
25988
25989         # full component followed by non-inited one
25990         $LFS setstripe -E 1M -c2 -E eof $file
25991         dd if=/dev/urandom of=$file bs=1M count=1
25992         printf "Seeking hole from 1000000 ... "
25993         offset=$(lseek_test -l 1000000 $file)
25994         echo $offset
25995         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25996         printf "Seeking hole from 1048576 ... "
25997         lseek_test -l 1048576 $file && error "lseek should fail"
25998         # init second component and truncate back
25999         echo "123" >> $file
26000         $TRUNCATE $file 1048576
26001         printf "Seeking hole from 1000000 ... "
26002         offset=$(lseek_test -l 1000000 $file)
26003         echo $offset
26004         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26005         printf "Seeking hole from 1048576 ... "
26006         lseek_test -l 1048576 $file && error "lseek should fail"
26007         # boundary checks for big values
26008         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26009         offset=$(lseek_test -d 0 $file.10g)
26010         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26011         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26012         offset=$(lseek_test -d 0 $file.100g)
26013         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26014         return 0
26015 }
26016 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26017
26018 test_430c() {
26019         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26020                 skip "OST does not support SEEK_HOLE"
26021
26022         local file=$DIR/$tdir/$tfile
26023         local start
26024
26025         mkdir -p $DIR/$tdir
26026         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26027
26028         # cp version 8.33+ prefers lseek over fiemap
26029         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26030                 start=$SECONDS
26031                 time cp $file /dev/null
26032                 (( SECONDS - start < 5 )) ||
26033                         error "cp: too long runtime $((SECONDS - start))"
26034
26035         fi
26036         # tar version 1.29+ supports SEEK_HOLE/DATA
26037         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26038                 start=$SECONDS
26039                 time tar cS $file - | cat > /dev/null
26040                 (( SECONDS - start < 5 )) ||
26041                         error "tar: too long runtime $((SECONDS - start))"
26042         fi
26043 }
26044 run_test 430c "lseek: external tools check"
26045
26046 test_431() { # LU-14187
26047         local file=$DIR/$tdir/$tfile
26048
26049         mkdir -p $DIR/$tdir
26050         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26051         dd if=/dev/urandom of=$file bs=4k count=1
26052         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26053         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26054         #define OBD_FAIL_OST_RESTART_IO 0x251
26055         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26056         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26057         cp $file $file.0
26058         cancel_lru_locks
26059         sync_all_data
26060         echo 3 > /proc/sys/vm/drop_caches
26061         diff  $file $file.0 || error "data diff"
26062 }
26063 run_test 431 "Restart transaction for IO"
26064
26065 cleanup_test_432() {
26066         do_facet mgs $LCTL nodemap_activate 0
26067         wait_nm_sync active
26068 }
26069
26070 test_432() {
26071         local tmpdir=$TMP/dir432
26072
26073         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26074                 skip "Need MDS version at least 2.14.52"
26075
26076         stack_trap cleanup_test_432 EXIT
26077         mkdir $DIR/$tdir
26078         mkdir $tmpdir
26079
26080         do_facet mgs $LCTL nodemap_activate 1
26081         wait_nm_sync active
26082         do_facet mgs $LCTL nodemap_modify --name default \
26083                 --property admin --value 1
26084         do_facet mgs $LCTL nodemap_modify --name default \
26085                 --property trusted --value 1
26086         cancel_lru_locks mdc
26087         wait_nm_sync default admin_nodemap
26088         wait_nm_sync default trusted_nodemap
26089
26090         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26091                grep -ci "Operation not permitted") -ne 0 ]; then
26092                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26093         fi
26094 }
26095 run_test 432 "mv dir from outside Lustre"
26096
26097 prep_801() {
26098         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26099         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26100                 skip "Need server version at least 2.9.55"
26101
26102         start_full_debug_logging
26103 }
26104
26105 post_801() {
26106         stop_full_debug_logging
26107 }
26108
26109 barrier_stat() {
26110         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26111                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26112                            awk '/The barrier for/ { print $7 }')
26113                 echo $st
26114         else
26115                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26116                 echo \'$st\'
26117         fi
26118 }
26119
26120 barrier_expired() {
26121         local expired
26122
26123         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26124                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26125                           awk '/will be expired/ { print $7 }')
26126         else
26127                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26128         fi
26129
26130         echo $expired
26131 }
26132
26133 test_801a() {
26134         prep_801
26135
26136         echo "Start barrier_freeze at: $(date)"
26137         #define OBD_FAIL_BARRIER_DELAY          0x2202
26138         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26139         # Do not reduce barrier time - See LU-11873
26140         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26141
26142         sleep 2
26143         local b_status=$(barrier_stat)
26144         echo "Got barrier status at: $(date)"
26145         [ "$b_status" = "'freezing_p1'" ] ||
26146                 error "(1) unexpected barrier status $b_status"
26147
26148         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26149         wait
26150         b_status=$(barrier_stat)
26151         [ "$b_status" = "'frozen'" ] ||
26152                 error "(2) unexpected barrier status $b_status"
26153
26154         local expired=$(barrier_expired)
26155         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26156         sleep $((expired + 3))
26157
26158         b_status=$(barrier_stat)
26159         [ "$b_status" = "'expired'" ] ||
26160                 error "(3) unexpected barrier status $b_status"
26161
26162         # Do not reduce barrier time - See LU-11873
26163         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26164                 error "(4) fail to freeze barrier"
26165
26166         b_status=$(barrier_stat)
26167         [ "$b_status" = "'frozen'" ] ||
26168                 error "(5) unexpected barrier status $b_status"
26169
26170         echo "Start barrier_thaw at: $(date)"
26171         #define OBD_FAIL_BARRIER_DELAY          0x2202
26172         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26173         do_facet mgs $LCTL barrier_thaw $FSNAME &
26174
26175         sleep 2
26176         b_status=$(barrier_stat)
26177         echo "Got barrier status at: $(date)"
26178         [ "$b_status" = "'thawing'" ] ||
26179                 error "(6) unexpected barrier status $b_status"
26180
26181         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26182         wait
26183         b_status=$(barrier_stat)
26184         [ "$b_status" = "'thawed'" ] ||
26185                 error "(7) unexpected barrier status $b_status"
26186
26187         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26188         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26189         do_facet mgs $LCTL barrier_freeze $FSNAME
26190
26191         b_status=$(barrier_stat)
26192         [ "$b_status" = "'failed'" ] ||
26193                 error "(8) unexpected barrier status $b_status"
26194
26195         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26196         do_facet mgs $LCTL barrier_thaw $FSNAME
26197
26198         post_801
26199 }
26200 run_test 801a "write barrier user interfaces and stat machine"
26201
26202 test_801b() {
26203         prep_801
26204
26205         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26206         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26207         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26208         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26209         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26210
26211         cancel_lru_locks mdc
26212
26213         # 180 seconds should be long enough
26214         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26215
26216         local b_status=$(barrier_stat)
26217         [ "$b_status" = "'frozen'" ] ||
26218                 error "(6) unexpected barrier status $b_status"
26219
26220         mkdir $DIR/$tdir/d0/d10 &
26221         mkdir_pid=$!
26222
26223         touch $DIR/$tdir/d1/f13 &
26224         touch_pid=$!
26225
26226         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26227         ln_pid=$!
26228
26229         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26230         mv_pid=$!
26231
26232         rm -f $DIR/$tdir/d4/f12 &
26233         rm_pid=$!
26234
26235         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26236
26237         # To guarantee taht the 'stat' is not blocked
26238         b_status=$(barrier_stat)
26239         [ "$b_status" = "'frozen'" ] ||
26240                 error "(8) unexpected barrier status $b_status"
26241
26242         # let above commands to run at background
26243         sleep 5
26244
26245         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26246         ps -p $touch_pid || error "(10) touch should be blocked"
26247         ps -p $ln_pid || error "(11) link should be blocked"
26248         ps -p $mv_pid || error "(12) rename should be blocked"
26249         ps -p $rm_pid || error "(13) unlink should be blocked"
26250
26251         b_status=$(barrier_stat)
26252         [ "$b_status" = "'frozen'" ] ||
26253                 error "(14) unexpected barrier status $b_status"
26254
26255         do_facet mgs $LCTL barrier_thaw $FSNAME
26256         b_status=$(barrier_stat)
26257         [ "$b_status" = "'thawed'" ] ||
26258                 error "(15) unexpected barrier status $b_status"
26259
26260         wait $mkdir_pid || error "(16) mkdir should succeed"
26261         wait $touch_pid || error "(17) touch should succeed"
26262         wait $ln_pid || error "(18) link should succeed"
26263         wait $mv_pid || error "(19) rename should succeed"
26264         wait $rm_pid || error "(20) unlink should succeed"
26265
26266         post_801
26267 }
26268 run_test 801b "modification will be blocked by write barrier"
26269
26270 test_801c() {
26271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26272
26273         prep_801
26274
26275         stop mds2 || error "(1) Fail to stop mds2"
26276
26277         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26278
26279         local b_status=$(barrier_stat)
26280         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26281                 do_facet mgs $LCTL barrier_thaw $FSNAME
26282                 error "(2) unexpected barrier status $b_status"
26283         }
26284
26285         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26286                 error "(3) Fail to rescan barrier bitmap"
26287
26288         # Do not reduce barrier time - See LU-11873
26289         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26290
26291         b_status=$(barrier_stat)
26292         [ "$b_status" = "'frozen'" ] ||
26293                 error "(4) unexpected barrier status $b_status"
26294
26295         do_facet mgs $LCTL barrier_thaw $FSNAME
26296         b_status=$(barrier_stat)
26297         [ "$b_status" = "'thawed'" ] ||
26298                 error "(5) unexpected barrier status $b_status"
26299
26300         local devname=$(mdsdevname 2)
26301
26302         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26303
26304         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26305                 error "(7) Fail to rescan barrier bitmap"
26306
26307         post_801
26308 }
26309 run_test 801c "rescan barrier bitmap"
26310
26311 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26312 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26313 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26314 saved_MOUNT_OPTS=$MOUNT_OPTS
26315
26316 cleanup_802a() {
26317         trap 0
26318
26319         stopall
26320         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26321         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26322         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26323         MOUNT_OPTS=$saved_MOUNT_OPTS
26324         setupall
26325 }
26326
26327 test_802a() {
26328         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26329         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26330         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26331                 skip "Need server version at least 2.9.55"
26332
26333         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26334
26335         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26336
26337         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26338                 error "(2) Fail to copy"
26339
26340         trap cleanup_802a EXIT
26341
26342         # sync by force before remount as readonly
26343         sync; sync_all_data; sleep 3; sync_all_data
26344
26345         stopall
26346
26347         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26348         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26349         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26350
26351         echo "Mount the server as read only"
26352         setupall server_only || error "(3) Fail to start servers"
26353
26354         echo "Mount client without ro should fail"
26355         mount_client $MOUNT &&
26356                 error "(4) Mount client without 'ro' should fail"
26357
26358         echo "Mount client with ro should succeed"
26359         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26360         mount_client $MOUNT ||
26361                 error "(5) Mount client with 'ro' should succeed"
26362
26363         echo "Modify should be refused"
26364         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26365
26366         echo "Read should be allowed"
26367         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26368                 error "(7) Read should succeed under ro mode"
26369
26370         cleanup_802a
26371 }
26372 run_test 802a "simulate readonly device"
26373
26374 test_802b() {
26375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26376         remote_mds_nodsh && skip "remote MDS with nodsh"
26377
26378         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26379                 skip "readonly option not available"
26380
26381         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26382
26383         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26384                 error "(2) Fail to copy"
26385
26386         # write back all cached data before setting MDT to readonly
26387         cancel_lru_locks
26388         sync_all_data
26389
26390         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26391         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26392
26393         echo "Modify should be refused"
26394         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26395
26396         echo "Read should be allowed"
26397         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26398                 error "(7) Read should succeed under ro mode"
26399
26400         # disable readonly
26401         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26402 }
26403 run_test 802b "be able to set MDTs to readonly"
26404
26405 test_803a() {
26406         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26407         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26408                 skip "MDS needs to be newer than 2.10.54"
26409
26410         mkdir_on_mdt0 $DIR/$tdir
26411         # Create some objects on all MDTs to trigger related logs objects
26412         for idx in $(seq $MDSCOUNT); do
26413                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26414                         $DIR/$tdir/dir${idx} ||
26415                         error "Fail to create $DIR/$tdir/dir${idx}"
26416         done
26417
26418         sync; sleep 3
26419         wait_delete_completed # ensure old test cleanups are finished
26420         echo "before create:"
26421         $LFS df -i $MOUNT
26422         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26423
26424         for i in {1..10}; do
26425                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26426                         error "Fail to create $DIR/$tdir/foo$i"
26427         done
26428
26429         sync; sleep 3
26430         echo "after create:"
26431         $LFS df -i $MOUNT
26432         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26433
26434         # allow for an llog to be cleaned up during the test
26435         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26436                 error "before ($before_used) + 10 > after ($after_used)"
26437
26438         for i in {1..10}; do
26439                 rm -rf $DIR/$tdir/foo$i ||
26440                         error "Fail to remove $DIR/$tdir/foo$i"
26441         done
26442
26443         sleep 3 # avoid MDT return cached statfs
26444         wait_delete_completed
26445         echo "after unlink:"
26446         $LFS df -i $MOUNT
26447         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26448
26449         # allow for an llog to be created during the test
26450         [ $after_used -le $((before_used + 1)) ] ||
26451                 error "after ($after_used) > before ($before_used) + 1"
26452 }
26453 run_test 803a "verify agent object for remote object"
26454
26455 test_803b() {
26456         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26457         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26458                 skip "MDS needs to be newer than 2.13.56"
26459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26460
26461         for i in $(seq 0 $((MDSCOUNT - 1))); do
26462                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26463         done
26464
26465         local before=0
26466         local after=0
26467
26468         local tmp
26469
26470         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26471         for i in $(seq 0 $((MDSCOUNT - 1))); do
26472                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26473                         awk '/getattr/ { print $2 }')
26474                 before=$((before + tmp))
26475         done
26476         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26477         for i in $(seq 0 $((MDSCOUNT - 1))); do
26478                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26479                         awk '/getattr/ { print $2 }')
26480                 after=$((after + tmp))
26481         done
26482
26483         [ $before -eq $after ] || error "getattr count $before != $after"
26484 }
26485 run_test 803b "remote object can getattr from cache"
26486
26487 test_804() {
26488         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26489         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26490                 skip "MDS needs to be newer than 2.10.54"
26491         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26492
26493         mkdir -p $DIR/$tdir
26494         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26495                 error "Fail to create $DIR/$tdir/dir0"
26496
26497         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26498         local dev=$(mdsdevname 2)
26499
26500         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26501                 grep ${fid} || error "NOT found agent entry for dir0"
26502
26503         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26504                 error "Fail to create $DIR/$tdir/dir1"
26505
26506         touch $DIR/$tdir/dir1/foo0 ||
26507                 error "Fail to create $DIR/$tdir/dir1/foo0"
26508         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26509         local rc=0
26510
26511         for idx in $(seq $MDSCOUNT); do
26512                 dev=$(mdsdevname $idx)
26513                 do_facet mds${idx} \
26514                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26515                         grep ${fid} && rc=$idx
26516         done
26517
26518         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26519                 error "Fail to rename foo0 to foo1"
26520         if [ $rc -eq 0 ]; then
26521                 for idx in $(seq $MDSCOUNT); do
26522                         dev=$(mdsdevname $idx)
26523                         do_facet mds${idx} \
26524                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26525                         grep ${fid} && rc=$idx
26526                 done
26527         fi
26528
26529         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26530                 error "Fail to rename foo1 to foo2"
26531         if [ $rc -eq 0 ]; then
26532                 for idx in $(seq $MDSCOUNT); do
26533                         dev=$(mdsdevname $idx)
26534                         do_facet mds${idx} \
26535                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26536                         grep ${fid} && rc=$idx
26537                 done
26538         fi
26539
26540         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26541
26542         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26543                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26544         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26545                 error "Fail to rename foo2 to foo0"
26546         unlink $DIR/$tdir/dir1/foo0 ||
26547                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26548         rm -rf $DIR/$tdir/dir0 ||
26549                 error "Fail to rm $DIR/$tdir/dir0"
26550
26551         for idx in $(seq $MDSCOUNT); do
26552                 dev=$(mdsdevname $idx)
26553                 rc=0
26554
26555                 stop mds${idx}
26556                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26557                         rc=$?
26558                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26559                         error "mount mds$idx failed"
26560                 df $MOUNT > /dev/null 2>&1
26561
26562                 # e2fsck should not return error
26563                 [ $rc -eq 0 ] ||
26564                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26565         done
26566 }
26567 run_test 804 "verify agent entry for remote entry"
26568
26569 cleanup_805() {
26570         do_facet $SINGLEMDS zfs set quota=$old $fsset
26571         unlinkmany $DIR/$tdir/f- 1000000
26572         trap 0
26573 }
26574
26575 test_805() {
26576         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26577         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26578         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26579                 skip "netfree not implemented before 0.7"
26580         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26581                 skip "Need MDS version at least 2.10.57"
26582
26583         local fsset
26584         local freekb
26585         local usedkb
26586         local old
26587         local quota
26588         local pref="osd-zfs.$FSNAME-MDT0000."
26589
26590         # limit available space on MDS dataset to meet nospace issue
26591         # quickly. then ZFS 0.7.2 can use reserved space if asked
26592         # properly (using netfree flag in osd_declare_destroy()
26593         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26594         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26595                 gawk '{print $3}')
26596         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26597         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26598         let "usedkb=usedkb-freekb"
26599         let "freekb=freekb/2"
26600         if let "freekb > 5000"; then
26601                 let "freekb=5000"
26602         fi
26603         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26604         trap cleanup_805 EXIT
26605         mkdir_on_mdt0 $DIR/$tdir
26606         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26607                 error "Can't set PFL layout"
26608         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26609         rm -rf $DIR/$tdir || error "not able to remove"
26610         do_facet $SINGLEMDS zfs set quota=$old $fsset
26611         trap 0
26612 }
26613 run_test 805 "ZFS can remove from full fs"
26614
26615 # Size-on-MDS test
26616 check_lsom_data()
26617 {
26618         local file=$1
26619         local expect=$(stat -c %s $file)
26620
26621         check_lsom_size $1 $expect
26622
26623         local blocks=$($LFS getsom -b $file)
26624         expect=$(stat -c %b $file)
26625         [[ $blocks == $expect ]] ||
26626                 error "$file expected blocks: $expect, got: $blocks"
26627 }
26628
26629 check_lsom_size()
26630 {
26631         local size
26632         local expect=$2
26633
26634         cancel_lru_locks mdc
26635
26636         size=$($LFS getsom -s $1)
26637         [[ $size == $expect ]] ||
26638                 error "$file expected size: $expect, got: $size"
26639 }
26640
26641 test_806() {
26642         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26643                 skip "Need MDS version at least 2.11.52"
26644
26645         local bs=1048576
26646
26647         touch $DIR/$tfile || error "touch $tfile failed"
26648
26649         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26650         save_lustre_params client "llite.*.xattr_cache" > $save
26651         lctl set_param llite.*.xattr_cache=0
26652         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26653
26654         # single-threaded write
26655         echo "Test SOM for single-threaded write"
26656         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26657                 error "write $tfile failed"
26658         check_lsom_size $DIR/$tfile $bs
26659
26660         local num=32
26661         local size=$(($num * $bs))
26662         local offset=0
26663         local i
26664
26665         echo "Test SOM for single client multi-threaded($num) write"
26666         $TRUNCATE $DIR/$tfile 0
26667         for ((i = 0; i < $num; i++)); do
26668                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26669                 local pids[$i]=$!
26670                 offset=$((offset + $bs))
26671         done
26672         for (( i=0; i < $num; i++ )); do
26673                 wait ${pids[$i]}
26674         done
26675         check_lsom_size $DIR/$tfile $size
26676
26677         $TRUNCATE $DIR/$tfile 0
26678         for ((i = 0; i < $num; i++)); do
26679                 offset=$((offset - $bs))
26680                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26681                 local pids[$i]=$!
26682         done
26683         for (( i=0; i < $num; i++ )); do
26684                 wait ${pids[$i]}
26685         done
26686         check_lsom_size $DIR/$tfile $size
26687
26688         # multi-client writes
26689         num=$(get_node_count ${CLIENTS//,/ })
26690         size=$(($num * $bs))
26691         offset=0
26692         i=0
26693
26694         echo "Test SOM for multi-client ($num) writes"
26695         $TRUNCATE $DIR/$tfile 0
26696         for client in ${CLIENTS//,/ }; do
26697                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26698                 local pids[$i]=$!
26699                 i=$((i + 1))
26700                 offset=$((offset + $bs))
26701         done
26702         for (( i=0; i < $num; i++ )); do
26703                 wait ${pids[$i]}
26704         done
26705         check_lsom_size $DIR/$tfile $offset
26706
26707         i=0
26708         $TRUNCATE $DIR/$tfile 0
26709         for client in ${CLIENTS//,/ }; do
26710                 offset=$((offset - $bs))
26711                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26712                 local pids[$i]=$!
26713                 i=$((i + 1))
26714         done
26715         for (( i=0; i < $num; i++ )); do
26716                 wait ${pids[$i]}
26717         done
26718         check_lsom_size $DIR/$tfile $size
26719
26720         # verify truncate
26721         echo "Test SOM for truncate"
26722         $TRUNCATE $DIR/$tfile 1048576
26723         check_lsom_size $DIR/$tfile 1048576
26724         $TRUNCATE $DIR/$tfile 1234
26725         check_lsom_size $DIR/$tfile 1234
26726
26727         # verify SOM blocks count
26728         echo "Verify SOM block count"
26729         $TRUNCATE $DIR/$tfile 0
26730         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26731                 error "failed to write file $tfile"
26732         check_lsom_data $DIR/$tfile
26733 }
26734 run_test 806 "Verify Lazy Size on MDS"
26735
26736 test_807() {
26737         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26738         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26739                 skip "Need MDS version at least 2.11.52"
26740
26741         # Registration step
26742         changelog_register || error "changelog_register failed"
26743         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26744         changelog_users $SINGLEMDS | grep -q $cl_user ||
26745                 error "User $cl_user not found in changelog_users"
26746
26747         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26748         save_lustre_params client "llite.*.xattr_cache" > $save
26749         lctl set_param llite.*.xattr_cache=0
26750         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26751
26752         rm -rf $DIR/$tdir || error "rm $tdir failed"
26753         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26754         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26755         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26756         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26757                 error "truncate $tdir/trunc failed"
26758
26759         local bs=1048576
26760         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26761                 error "write $tfile failed"
26762
26763         # multi-client wirtes
26764         local num=$(get_node_count ${CLIENTS//,/ })
26765         local offset=0
26766         local i=0
26767
26768         echo "Test SOM for multi-client ($num) writes"
26769         touch $DIR/$tfile || error "touch $tfile failed"
26770         $TRUNCATE $DIR/$tfile 0
26771         for client in ${CLIENTS//,/ }; do
26772                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26773                 local pids[$i]=$!
26774                 i=$((i + 1))
26775                 offset=$((offset + $bs))
26776         done
26777         for (( i=0; i < $num; i++ )); do
26778                 wait ${pids[$i]}
26779         done
26780
26781         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26782         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26783         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26784         check_lsom_data $DIR/$tdir/trunc
26785         check_lsom_data $DIR/$tdir/single_dd
26786         check_lsom_data $DIR/$tfile
26787
26788         rm -rf $DIR/$tdir
26789         # Deregistration step
26790         changelog_deregister || error "changelog_deregister failed"
26791 }
26792 run_test 807 "verify LSOM syncing tool"
26793
26794 check_som_nologged()
26795 {
26796         local lines=$($LFS changelog $FSNAME-MDT0000 |
26797                 grep 'x=trusted.som' | wc -l)
26798         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26799 }
26800
26801 test_808() {
26802         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26803                 skip "Need MDS version at least 2.11.55"
26804
26805         # Registration step
26806         changelog_register || error "changelog_register failed"
26807
26808         touch $DIR/$tfile || error "touch $tfile failed"
26809         check_som_nologged
26810
26811         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26812                 error "write $tfile failed"
26813         check_som_nologged
26814
26815         $TRUNCATE $DIR/$tfile 1234
26816         check_som_nologged
26817
26818         $TRUNCATE $DIR/$tfile 1048576
26819         check_som_nologged
26820
26821         # Deregistration step
26822         changelog_deregister || error "changelog_deregister failed"
26823 }
26824 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26825
26826 check_som_nodata()
26827 {
26828         $LFS getsom $1
26829         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26830 }
26831
26832 test_809() {
26833         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26834                 skip "Need MDS version at least 2.11.56"
26835
26836         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26837                 error "failed to create DoM-only file $DIR/$tfile"
26838         touch $DIR/$tfile || error "touch $tfile failed"
26839         check_som_nodata $DIR/$tfile
26840
26841         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26842                 error "write $tfile failed"
26843         check_som_nodata $DIR/$tfile
26844
26845         $TRUNCATE $DIR/$tfile 1234
26846         check_som_nodata $DIR/$tfile
26847
26848         $TRUNCATE $DIR/$tfile 4097
26849         check_som_nodata $DIR/$file
26850 }
26851 run_test 809 "Verify no SOM xattr store for DoM-only files"
26852
26853 test_810() {
26854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26855         $GSS && skip_env "could not run with gss"
26856         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26857                 skip "OST < 2.12.58 doesn't align checksum"
26858
26859         set_checksums 1
26860         stack_trap "set_checksums $ORIG_CSUM" EXIT
26861         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26862
26863         local csum
26864         local before
26865         local after
26866         for csum in $CKSUM_TYPES; do
26867                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26868                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26869                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26870                         eval set -- $i
26871                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26872                         before=$(md5sum $DIR/$tfile)
26873                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26874                         after=$(md5sum $DIR/$tfile)
26875                         [ "$before" == "$after" ] ||
26876                                 error "$csum: $before != $after bs=$1 seek=$2"
26877                 done
26878         done
26879 }
26880 run_test 810 "partial page writes on ZFS (LU-11663)"
26881
26882 test_812a() {
26883         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26884                 skip "OST < 2.12.51 doesn't support this fail_loc"
26885
26886         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26887         # ensure ost1 is connected
26888         stat $DIR/$tfile >/dev/null || error "can't stat"
26889         wait_osc_import_state client ost1 FULL
26890         # no locks, no reqs to let the connection idle
26891         cancel_lru_locks osc
26892
26893         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26894 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26895         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26896         wait_osc_import_state client ost1 CONNECTING
26897         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26898
26899         stat $DIR/$tfile >/dev/null || error "can't stat file"
26900 }
26901 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26902
26903 test_812b() { # LU-12378
26904         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26905                 skip "OST < 2.12.51 doesn't support this fail_loc"
26906
26907         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26908         # ensure ost1 is connected
26909         stat $DIR/$tfile >/dev/null || error "can't stat"
26910         wait_osc_import_state client ost1 FULL
26911         # no locks, no reqs to let the connection idle
26912         cancel_lru_locks osc
26913
26914         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26915 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26916         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26917         wait_osc_import_state client ost1 CONNECTING
26918         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26919
26920         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26921         wait_osc_import_state client ost1 IDLE
26922 }
26923 run_test 812b "do not drop no resend request for idle connect"
26924
26925 test_812c() {
26926         local old
26927
26928         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26929
26930         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26931         $LFS getstripe $DIR/$tfile
26932         $LCTL set_param osc.*.idle_timeout=10
26933         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26934         # ensure ost1 is connected
26935         stat $DIR/$tfile >/dev/null || error "can't stat"
26936         wait_osc_import_state client ost1 FULL
26937         # no locks, no reqs to let the connection idle
26938         cancel_lru_locks osc
26939
26940 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26941         $LCTL set_param fail_loc=0x80000533
26942         sleep 15
26943         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26944 }
26945 run_test 812c "idle import vs lock enqueue race"
26946
26947 test_813() {
26948         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26949         [ -z "$file_heat_sav" ] && skip "no file heat support"
26950
26951         local readsample
26952         local writesample
26953         local readbyte
26954         local writebyte
26955         local readsample1
26956         local writesample1
26957         local readbyte1
26958         local writebyte1
26959
26960         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26961         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26962
26963         $LCTL set_param -n llite.*.file_heat=1
26964         echo "Turn on file heat"
26965         echo "Period second: $period_second, Decay percentage: $decay_pct"
26966
26967         echo "QQQQ" > $DIR/$tfile
26968         echo "QQQQ" > $DIR/$tfile
26969         echo "QQQQ" > $DIR/$tfile
26970         cat $DIR/$tfile > /dev/null
26971         cat $DIR/$tfile > /dev/null
26972         cat $DIR/$tfile > /dev/null
26973         cat $DIR/$tfile > /dev/null
26974
26975         local out=$($LFS heat_get $DIR/$tfile)
26976
26977         $LFS heat_get $DIR/$tfile
26978         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26979         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26980         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26981         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26982
26983         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26984         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26985         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26986         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26987
26988         sleep $((period_second + 3))
26989         echo "Sleep $((period_second + 3)) seconds..."
26990         # The recursion formula to calculate the heat of the file f is as
26991         # follow:
26992         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26993         # Where Hi is the heat value in the period between time points i*I and
26994         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26995         # to the weight of Ci.
26996         out=$($LFS heat_get $DIR/$tfile)
26997         $LFS heat_get $DIR/$tfile
26998         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26999         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27000         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27001         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27002
27003         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27004                 error "read sample ($readsample) is wrong"
27005         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27006                 error "write sample ($writesample) is wrong"
27007         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27008                 error "read bytes ($readbyte) is wrong"
27009         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27010                 error "write bytes ($writebyte) is wrong"
27011
27012         echo "QQQQ" > $DIR/$tfile
27013         echo "QQQQ" > $DIR/$tfile
27014         echo "QQQQ" > $DIR/$tfile
27015         cat $DIR/$tfile > /dev/null
27016         cat $DIR/$tfile > /dev/null
27017         cat $DIR/$tfile > /dev/null
27018         cat $DIR/$tfile > /dev/null
27019
27020         sleep $((period_second + 3))
27021         echo "Sleep $((period_second + 3)) seconds..."
27022
27023         out=$($LFS heat_get $DIR/$tfile)
27024         $LFS heat_get $DIR/$tfile
27025         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27026         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27027         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27028         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27029
27030         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27031                 4 * $decay_pct) / 100") -eq 1 ] ||
27032                 error "read sample ($readsample1) is wrong"
27033         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27034                 3 * $decay_pct) / 100") -eq 1 ] ||
27035                 error "write sample ($writesample1) is wrong"
27036         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27037                 20 * $decay_pct) / 100") -eq 1 ] ||
27038                 error "read bytes ($readbyte1) is wrong"
27039         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27040                 15 * $decay_pct) / 100") -eq 1 ] ||
27041                 error "write bytes ($writebyte1) is wrong"
27042
27043         echo "Turn off file heat for the file $DIR/$tfile"
27044         $LFS heat_set -o $DIR/$tfile
27045
27046         echo "QQQQ" > $DIR/$tfile
27047         echo "QQQQ" > $DIR/$tfile
27048         echo "QQQQ" > $DIR/$tfile
27049         cat $DIR/$tfile > /dev/null
27050         cat $DIR/$tfile > /dev/null
27051         cat $DIR/$tfile > /dev/null
27052         cat $DIR/$tfile > /dev/null
27053
27054         out=$($LFS heat_get $DIR/$tfile)
27055         $LFS heat_get $DIR/$tfile
27056         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27057         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27058         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27059         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27060
27061         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27062         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27063         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27064         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27065
27066         echo "Trun on file heat for the file $DIR/$tfile"
27067         $LFS heat_set -O $DIR/$tfile
27068
27069         echo "QQQQ" > $DIR/$tfile
27070         echo "QQQQ" > $DIR/$tfile
27071         echo "QQQQ" > $DIR/$tfile
27072         cat $DIR/$tfile > /dev/null
27073         cat $DIR/$tfile > /dev/null
27074         cat $DIR/$tfile > /dev/null
27075         cat $DIR/$tfile > /dev/null
27076
27077         out=$($LFS heat_get $DIR/$tfile)
27078         $LFS heat_get $DIR/$tfile
27079         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27080         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27081         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27082         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27083
27084         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27085         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27086         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27087         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27088
27089         $LFS heat_set -c $DIR/$tfile
27090         $LCTL set_param -n llite.*.file_heat=0
27091         echo "Turn off file heat support for the Lustre filesystem"
27092
27093         echo "QQQQ" > $DIR/$tfile
27094         echo "QQQQ" > $DIR/$tfile
27095         echo "QQQQ" > $DIR/$tfile
27096         cat $DIR/$tfile > /dev/null
27097         cat $DIR/$tfile > /dev/null
27098         cat $DIR/$tfile > /dev/null
27099         cat $DIR/$tfile > /dev/null
27100
27101         out=$($LFS heat_get $DIR/$tfile)
27102         $LFS heat_get $DIR/$tfile
27103         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27104         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27105         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27106         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27107
27108         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27109         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27110         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27111         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27112
27113         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27114         rm -f $DIR/$tfile
27115 }
27116 run_test 813 "File heat verfication"
27117
27118 test_814()
27119 {
27120         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27121         echo -n y >> $DIR/$tfile
27122         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27123         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27124 }
27125 run_test 814 "sparse cp works as expected (LU-12361)"
27126
27127 test_815()
27128 {
27129         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27130         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27131 }
27132 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27133
27134 test_816() {
27135         local ost1_imp=$(get_osc_import_name client ost1)
27136         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27137                          cut -d'.' -f2)
27138
27139         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27140         # ensure ost1 is connected
27141
27142         stat $DIR/$tfile >/dev/null || error "can't stat"
27143         wait_osc_import_state client ost1 FULL
27144         # no locks, no reqs to let the connection idle
27145         cancel_lru_locks osc
27146         lru_resize_disable osc
27147         local before
27148         local now
27149         before=$($LCTL get_param -n \
27150                  ldlm.namespaces.$imp_name.lru_size)
27151
27152         wait_osc_import_state client ost1 IDLE
27153         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27154         now=$($LCTL get_param -n \
27155               ldlm.namespaces.$imp_name.lru_size)
27156         [ $before == $now ] || error "lru_size changed $before != $now"
27157 }
27158 run_test 816 "do not reset lru_resize on idle reconnect"
27159
27160 cleanup_817() {
27161         umount $tmpdir
27162         exportfs -u localhost:$DIR/nfsexp
27163         rm -rf $DIR/nfsexp
27164 }
27165
27166 test_817() {
27167         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27168
27169         mkdir -p $DIR/nfsexp
27170         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27171                 error "failed to export nfs"
27172
27173         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27174         stack_trap cleanup_817 EXIT
27175
27176         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27177                 error "failed to mount nfs to $tmpdir"
27178
27179         cp /bin/true $tmpdir
27180         $DIR/nfsexp/true || error "failed to execute 'true' command"
27181 }
27182 run_test 817 "nfsd won't cache write lock for exec file"
27183
27184 test_818() {
27185         mkdir $DIR/$tdir
27186         $LFS setstripe -c1 -i0 $DIR/$tfile
27187         $LFS setstripe -c1 -i1 $DIR/$tfile
27188         stop $SINGLEMDS
27189         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27190         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27191         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27192                 error "start $SINGLEMDS failed"
27193         rm -rf $DIR/$tdir
27194 }
27195 run_test 818 "unlink with failed llog"
27196
27197 test_819a() {
27198         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27199         cancel_lru_locks osc
27200         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27201         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27202         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27203         rm -f $TDIR/$tfile
27204 }
27205 run_test 819a "too big niobuf in read"
27206
27207 test_819b() {
27208         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27209         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27211         cancel_lru_locks osc
27212         sleep 1
27213         rm -f $TDIR/$tfile
27214 }
27215 run_test 819b "too big niobuf in write"
27216
27217
27218 function test_820_start_ost() {
27219         sleep 5
27220
27221         for num in $(seq $OSTCOUNT); do
27222                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27223         done
27224 }
27225
27226 test_820() {
27227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27228
27229         mkdir $DIR/$tdir
27230         umount_client $MOUNT || error "umount failed"
27231         for num in $(seq $OSTCOUNT); do
27232                 stop ost$num
27233         done
27234
27235         # mount client with no active OSTs
27236         # so that the client can't initialize max LOV EA size
27237         # from OSC notifications
27238         mount_client $MOUNT || error "mount failed"
27239         # delay OST starting to keep this 0 max EA size for a while
27240         test_820_start_ost &
27241
27242         # create a directory on MDS2
27243         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27244                 error "Failed to create directory"
27245         # open intent should update default EA size
27246         # see mdc_update_max_ea_from_body()
27247         # notice this is the very first RPC to MDS2
27248         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27249         ret=$?
27250         echo $out
27251         # With SSK, this situation can lead to -EPERM being returned.
27252         # In that case, simply retry.
27253         if [ $ret -ne 0 ] && $SHARED_KEY; then
27254                 if echo "$out" | grep -q "not permitted"; then
27255                         cp /etc/services $DIR/$tdir/mds2
27256                         ret=$?
27257                 fi
27258         fi
27259         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27260 }
27261 run_test 820 "update max EA from open intent"
27262
27263 test_822() {
27264         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27265
27266         save_lustre_params mds1 \
27267                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27268         do_facet $SINGLEMDS "$LCTL set_param -n \
27269                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27270         do_facet $SINGLEMDS "$LCTL set_param -n \
27271                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27272
27273         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27274         local maxage=$(do_facet mds1 $LCTL get_param -n \
27275                        osp.$FSNAME-OST0000*MDT0000.maxage)
27276         sleep $((maxage + 1))
27277
27278         #define OBD_FAIL_NET_ERROR_RPC          0x532
27279         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27280
27281         stack_trap "restore_lustre_params < $p; rm $p"
27282
27283         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27284                       osp.$FSNAME-OST0000*MDT0000.create_count")
27285         for i in $(seq 1 $count); do
27286                 touch $DIR/$tfile.${i} || error "touch failed"
27287         done
27288 }
27289 run_test 822 "test precreate failure"
27290
27291 #
27292 # tests that do cleanup/setup should be run at the end
27293 #
27294
27295 test_900() {
27296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27297         local ls
27298
27299         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27300         $LCTL set_param fail_loc=0x903
27301
27302         cancel_lru_locks MGC
27303
27304         FAIL_ON_ERROR=true cleanup
27305         FAIL_ON_ERROR=true setup
27306 }
27307 run_test 900 "umount should not race with any mgc requeue thread"
27308
27309 # LUS-6253/LU-11185
27310 test_901() {
27311         local oldc
27312         local newc
27313         local olds
27314         local news
27315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27316
27317         # some get_param have a bug to handle dot in param name
27318         cancel_lru_locks MGC
27319         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27320         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27321         umount_client $MOUNT || error "umount failed"
27322         mount_client $MOUNT || error "mount failed"
27323         cancel_lru_locks MGC
27324         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27325         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27326
27327         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27328         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27329
27330         return 0
27331 }
27332 run_test 901 "don't leak a mgc lock on client umount"
27333
27334 # LU-13377
27335 test_902() {
27336         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27337                 skip "client does not have LU-13377 fix"
27338         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27339         $LCTL set_param fail_loc=0x1415
27340         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27341         cancel_lru_locks osc
27342         rm -f $DIR/$tfile
27343 }
27344 run_test 902 "test short write doesn't hang lustre"
27345
27346 # LU-14711
27347 test_903() {
27348         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27349         echo "blah" > $DIR/${tfile}-2
27350         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27351         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27352         $LCTL set_param fail_loc=0x417 fail_val=20
27353
27354         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27355         sleep 1 # To start the destroy
27356         wait_destroy_complete 150 || error "Destroy taking too long"
27357         cat $DIR/$tfile > /dev/null || error "Evicted"
27358 }
27359 run_test 903 "Test long page discard does not cause evictions"
27360
27361 complete $SECONDS
27362 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27363 check_and_cleanup_lustre
27364 if [ "$I_MOUNTED" != "yes" ]; then
27365         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27366 fi
27367 exit_status