Whamcloud - gitweb
LU-13997 tests: sanity/418 to cancel all client locks
[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 test_56y() {
7648         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7649                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7650
7651         local res=""
7652         local dir=$DIR/$tdir
7653         local f1=$dir/file1
7654         local f2=$dir/file2
7655
7656         test_mkdir -p $dir || error "creating dir $dir"
7657         touch $f1 || error "creating std file $f1"
7658         $MULTIOP $f2 H2c || error "creating released file $f2"
7659
7660         # a directory can be raid0, so ask only for files
7661         res=$($LFS find $dir -L raid0 -type f | wc -l)
7662         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7663
7664         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7665         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7666
7667         # only files can be released, so no need to force file search
7668         res=$($LFS find $dir -L released)
7669         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7670
7671         res=$($LFS find $dir -type f \! -L released)
7672         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7673 }
7674 run_test 56y "lfs find -L raid0|released"
7675
7676 test_56z() { # LU-4824
7677         # This checks to make sure 'lfs find' continues after errors
7678         # There are two classes of errors that should be caught:
7679         # - If multiple paths are provided, all should be searched even if one
7680         #   errors out
7681         # - If errors are encountered during the search, it should not terminate
7682         #   early
7683         local dir=$DIR/$tdir
7684         local i
7685
7686         test_mkdir $dir
7687         for i in d{0..9}; do
7688                 test_mkdir $dir/$i
7689                 touch $dir/$i/$tfile
7690         done
7691         $LFS find $DIR/non_existent_dir $dir &&
7692                 error "$LFS find did not return an error"
7693         # Make a directory unsearchable. This should NOT be the last entry in
7694         # directory order.  Arbitrarily pick the 6th entry
7695         chmod 700 $($LFS find $dir -type d | sed '6!d')
7696
7697         $RUNAS $LFS find $DIR/non_existent $dir
7698         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7699
7700         # The user should be able to see 10 directories and 9 files
7701         (( count == 19 )) ||
7702                 error "$LFS find found $count != 19 entries after error"
7703 }
7704 run_test 56z "lfs find should continue after an error"
7705
7706 test_56aa() { # LU-5937
7707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7708
7709         local dir=$DIR/$tdir
7710
7711         mkdir $dir
7712         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7713
7714         createmany -o $dir/striped_dir/${tfile}- 1024
7715         local dirs=$($LFS find --size +8k $dir/)
7716
7717         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7718 }
7719 run_test 56aa "lfs find --size under striped dir"
7720
7721 test_56ab() { # LU-10705
7722         test_mkdir $DIR/$tdir
7723         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7724         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7725         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7726         # Flush writes to ensure valid blocks.  Need to be more thorough for
7727         # ZFS, since blocks are not allocated/returned to client immediately.
7728         sync_all_data
7729         wait_zfs_commit ost1 2
7730         cancel_lru_locks osc
7731         ls -ls $DIR/$tdir
7732
7733         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7734
7735         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7736
7737         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7738         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7739
7740         rm -f $DIR/$tdir/$tfile.[123]
7741 }
7742 run_test 56ab "lfs find --blocks"
7743
7744 # LU-11188
7745 test_56aca() {
7746         local dir="$DIR/$tdir"
7747         local perms=(001 002 003 004 005 006 007
7748                      010 020 030 040 050 060 070
7749                      100 200 300 400 500 600 700
7750                      111 222 333 444 555 666 777)
7751         local perm_minus=(8 8 4 8 4 4 2
7752                           8 8 4 8 4 4 2
7753                           8 8 4 8 4 4 2
7754                           4 4 2 4 2 2 1)
7755         local perm_slash=(8  8 12  8 12 12 14
7756                           8  8 12  8 12 12 14
7757                           8  8 12  8 12 12 14
7758                          16 16 24 16 24 24 28)
7759
7760         test_mkdir "$dir"
7761         for perm in ${perms[*]}; do
7762                 touch "$dir/$tfile.$perm"
7763                 chmod $perm "$dir/$tfile.$perm"
7764         done
7765
7766         for ((i = 0; i < ${#perms[*]}; i++)); do
7767                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7768                 (( $num == 1 )) ||
7769                         error "lfs find -perm ${perms[i]}:"\
7770                               "$num != 1"
7771
7772                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7773                 (( $num == ${perm_minus[i]} )) ||
7774                         error "lfs find -perm -${perms[i]}:"\
7775                               "$num != ${perm_minus[i]}"
7776
7777                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7778                 (( $num == ${perm_slash[i]} )) ||
7779                         error "lfs find -perm /${perms[i]}:"\
7780                               "$num != ${perm_slash[i]}"
7781         done
7782 }
7783 run_test 56aca "check lfs find -perm with octal representation"
7784
7785 test_56acb() {
7786         local dir=$DIR/$tdir
7787         # p is the permission of write and execute for user, group and other
7788         # without the umask. It is used to test +wx.
7789         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7790         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7791         local symbolic=(+t  a+t u+t g+t o+t
7792                         g+s u+s o+s +s o+sr
7793                         o=r,ug+o,u+w
7794                         u+ g+ o+ a+ ugo+
7795                         u- g- o- a- ugo-
7796                         u= g= o= a= ugo=
7797                         o=r,ug+o,u+w u=r,a+u,u+w
7798                         g=r,ugo=g,u+w u+x,+X +X
7799                         u+x,u+X u+X u+x,g+X o+r,+X
7800                         u+x,go+X +wx +rwx)
7801
7802         test_mkdir $dir
7803         for perm in ${perms[*]}; do
7804                 touch "$dir/$tfile.$perm"
7805                 chmod $perm "$dir/$tfile.$perm"
7806         done
7807
7808         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7809                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7810
7811                 (( $num == 1 )) ||
7812                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7813         done
7814 }
7815 run_test 56acb "check lfs find -perm with symbolic representation"
7816
7817 test_56acc() {
7818         local dir=$DIR/$tdir
7819         local tests="17777 787 789 abcd
7820                 ug=uu ug=a ug=gu uo=ou urw
7821                 u+xg+x a=r,u+x,"
7822
7823         test_mkdir $dir
7824         for err in $tests; do
7825                 if $LFS find $dir -perm $err 2>/dev/null; then
7826                         error "lfs find -perm $err: parsing should have failed"
7827                 fi
7828         done
7829 }
7830 run_test 56acc "check parsing error for lfs find -perm"
7831
7832 test_56ba() {
7833         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7834                 skip "Need MDS version at least 2.10.50"
7835
7836         # Create composite files with one component
7837         local dir=$DIR/$tdir
7838
7839         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7840         # Create composite files with three components
7841         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7842         # Create non-composite files
7843         createmany -o $dir/${tfile}- 10
7844
7845         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7846
7847         [[ $nfiles == 10 ]] ||
7848                 error "lfs find -E 1M found $nfiles != 10 files"
7849
7850         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7851         [[ $nfiles == 25 ]] ||
7852                 error "lfs find ! -E 1M found $nfiles != 25 files"
7853
7854         # All files have a component that starts at 0
7855         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7856         [[ $nfiles == 35 ]] ||
7857                 error "lfs find --component-start 0 - $nfiles != 35 files"
7858
7859         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7860         [[ $nfiles == 15 ]] ||
7861                 error "lfs find --component-start 2M - $nfiles != 15 files"
7862
7863         # All files created here have a componenet that does not starts at 2M
7864         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7865         [[ $nfiles == 35 ]] ||
7866                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7867
7868         # Find files with a specified number of components
7869         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7870         [[ $nfiles == 15 ]] ||
7871                 error "lfs find --component-count 3 - $nfiles != 15 files"
7872
7873         # Remember non-composite files have a component count of zero
7874         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7875         [[ $nfiles == 10 ]] ||
7876                 error "lfs find --component-count 0 - $nfiles != 10 files"
7877
7878         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7879         [[ $nfiles == 20 ]] ||
7880                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7881
7882         # All files have a flag called "init"
7883         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7884         [[ $nfiles == 35 ]] ||
7885                 error "lfs find --component-flags init - $nfiles != 35 files"
7886
7887         # Multi-component files will have a component not initialized
7888         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7889         [[ $nfiles == 15 ]] ||
7890                 error "lfs find !--component-flags init - $nfiles != 15 files"
7891
7892         rm -rf $dir
7893
7894 }
7895 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7896
7897 test_56ca() {
7898         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7899                 skip "Need MDS version at least 2.10.57"
7900
7901         local td=$DIR/$tdir
7902         local tf=$td/$tfile
7903         local dir
7904         local nfiles
7905         local cmd
7906         local i
7907         local j
7908
7909         # create mirrored directories and mirrored files
7910         mkdir $td || error "mkdir $td failed"
7911         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7912         createmany -o $tf- 10 || error "create $tf- failed"
7913
7914         for i in $(seq 2); do
7915                 dir=$td/dir$i
7916                 mkdir $dir || error "mkdir $dir failed"
7917                 $LFS mirror create -N$((3 + i)) $dir ||
7918                         error "create mirrored dir $dir failed"
7919                 createmany -o $dir/$tfile- 10 ||
7920                         error "create $dir/$tfile- failed"
7921         done
7922
7923         # change the states of some mirrored files
7924         echo foo > $tf-6
7925         for i in $(seq 2); do
7926                 dir=$td/dir$i
7927                 for j in $(seq 4 9); do
7928                         echo foo > $dir/$tfile-$j
7929                 done
7930         done
7931
7932         # find mirrored files with specific mirror count
7933         cmd="$LFS find --mirror-count 3 --type f $td"
7934         nfiles=$($cmd | wc -l)
7935         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7936
7937         cmd="$LFS find ! --mirror-count 3 --type f $td"
7938         nfiles=$($cmd | wc -l)
7939         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7940
7941         cmd="$LFS find --mirror-count +2 --type f $td"
7942         nfiles=$($cmd | wc -l)
7943         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7944
7945         cmd="$LFS find --mirror-count -6 --type f $td"
7946         nfiles=$($cmd | wc -l)
7947         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7948
7949         # find mirrored files with specific file state
7950         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7951         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7952
7953         cmd="$LFS find --mirror-state=ro --type f $td"
7954         nfiles=$($cmd | wc -l)
7955         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7956
7957         cmd="$LFS find ! --mirror-state=ro --type f $td"
7958         nfiles=$($cmd | wc -l)
7959         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7960
7961         cmd="$LFS find --mirror-state=wp --type f $td"
7962         nfiles=$($cmd | wc -l)
7963         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7964
7965         cmd="$LFS find ! --mirror-state=sp --type f $td"
7966         nfiles=$($cmd | wc -l)
7967         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7968 }
7969 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7970
7971 test_56da() { # LU-14179
7972         local path=$DIR/$tdir
7973
7974         test_mkdir $path
7975         cd $path
7976
7977         local longdir=$(str_repeat 'a' 255)
7978
7979         for i in {1..15}; do
7980                 path=$path/$longdir
7981                 test_mkdir $longdir
7982                 cd $longdir
7983         done
7984
7985         local len=${#path}
7986         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7987
7988         test_mkdir $lastdir
7989         cd $lastdir
7990         # PATH_MAX-1
7991         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7992
7993         # NAME_MAX
7994         touch $(str_repeat 'f' 255)
7995
7996         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7997                 error "lfs find reported an error"
7998
7999         rm -rf $DIR/$tdir
8000 }
8001 run_test 56da "test lfs find with long paths"
8002
8003 test_57a() {
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005         # note test will not do anything if MDS is not local
8006         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8007                 skip_env "ldiskfs only test"
8008         fi
8009         remote_mds_nodsh && skip "remote MDS with nodsh"
8010
8011         local MNTDEV="osd*.*MDT*.mntdev"
8012         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8013         [ -z "$DEV" ] && error "can't access $MNTDEV"
8014         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8015                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8016                         error "can't access $DEV"
8017                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8018                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8019                 rm $TMP/t57a.dump
8020         done
8021 }
8022 run_test 57a "verify MDS filesystem created with large inodes =="
8023
8024 test_57b() {
8025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8026         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8027                 skip_env "ldiskfs only test"
8028         fi
8029         remote_mds_nodsh && skip "remote MDS with nodsh"
8030
8031         local dir=$DIR/$tdir
8032         local filecount=100
8033         local file1=$dir/f1
8034         local fileN=$dir/f$filecount
8035
8036         rm -rf $dir || error "removing $dir"
8037         test_mkdir -c1 $dir
8038         local mdtidx=$($LFS getstripe -m $dir)
8039         local mdtname=MDT$(printf %04x $mdtidx)
8040         local facet=mds$((mdtidx + 1))
8041
8042         echo "mcreating $filecount files"
8043         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8044
8045         # verify that files do not have EAs yet
8046         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8047                 error "$file1 has an EA"
8048         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8049                 error "$fileN has an EA"
8050
8051         sync
8052         sleep 1
8053         df $dir  #make sure we get new statfs data
8054         local mdsfree=$(do_facet $facet \
8055                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8056         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8057         local file
8058
8059         echo "opening files to create objects/EAs"
8060         for file in $(seq -f $dir/f%g 1 $filecount); do
8061                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8062                         error "opening $file"
8063         done
8064
8065         # verify that files have EAs now
8066         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8067         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8068
8069         sleep 1  #make sure we get new statfs data
8070         df $dir
8071         local mdsfree2=$(do_facet $facet \
8072                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8073         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8074
8075         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8076                 if [ "$mdsfree" != "$mdsfree2" ]; then
8077                         error "MDC before $mdcfree != after $mdcfree2"
8078                 else
8079                         echo "MDC before $mdcfree != after $mdcfree2"
8080                         echo "unable to confirm if MDS has large inodes"
8081                 fi
8082         fi
8083         rm -rf $dir
8084 }
8085 run_test 57b "default LOV EAs are stored inside large inodes ==="
8086
8087 test_58() {
8088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8089         [ -z "$(which wiretest 2>/dev/null)" ] &&
8090                         skip_env "could not find wiretest"
8091
8092         wiretest
8093 }
8094 run_test 58 "verify cross-platform wire constants =============="
8095
8096 test_59() {
8097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8098
8099         echo "touch 130 files"
8100         createmany -o $DIR/f59- 130
8101         echo "rm 130 files"
8102         unlinkmany $DIR/f59- 130
8103         sync
8104         # wait for commitment of removal
8105         wait_delete_completed
8106 }
8107 run_test 59 "verify cancellation of llog records async ========="
8108
8109 TEST60_HEAD="test_60 run $RANDOM"
8110 test_60a() {
8111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8112         remote_mgs_nodsh && skip "remote MGS with nodsh"
8113         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8114                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8115                         skip_env "missing subtest run-llog.sh"
8116
8117         log "$TEST60_HEAD - from kernel mode"
8118         do_facet mgs "$LCTL dk > /dev/null"
8119         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8120         do_facet mgs $LCTL dk > $TMP/$tfile
8121
8122         # LU-6388: test llog_reader
8123         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8124         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8125         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8126                         skip_env "missing llog_reader"
8127         local fstype=$(facet_fstype mgs)
8128         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8129                 skip_env "Only for ldiskfs or zfs type mgs"
8130
8131         local mntpt=$(facet_mntpt mgs)
8132         local mgsdev=$(mgsdevname 1)
8133         local fid_list
8134         local fid
8135         local rec_list
8136         local rec
8137         local rec_type
8138         local obj_file
8139         local path
8140         local seq
8141         local oid
8142         local pass=true
8143
8144         #get fid and record list
8145         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8146                 tail -n 4))
8147         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8148                 tail -n 4))
8149         #remount mgs as ldiskfs or zfs type
8150         stop mgs || error "stop mgs failed"
8151         mount_fstype mgs || error "remount mgs failed"
8152         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8153                 fid=${fid_list[i]}
8154                 rec=${rec_list[i]}
8155                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8156                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8157                 oid=$((16#$oid))
8158
8159                 case $fstype in
8160                         ldiskfs )
8161                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8162                         zfs )
8163                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8164                 esac
8165                 echo "obj_file is $obj_file"
8166                 do_facet mgs $llog_reader $obj_file
8167
8168                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8169                         awk '{ print $3 }' | sed -e "s/^type=//g")
8170                 if [ $rec_type != $rec ]; then
8171                         echo "FAILED test_60a wrong record type $rec_type," \
8172                               "should be $rec"
8173                         pass=false
8174                         break
8175                 fi
8176
8177                 #check obj path if record type is LLOG_LOGID_MAGIC
8178                 if [ "$rec" == "1064553b" ]; then
8179                         path=$(do_facet mgs $llog_reader $obj_file |
8180                                 grep "path=" | awk '{ print $NF }' |
8181                                 sed -e "s/^path=//g")
8182                         if [ $obj_file != $mntpt/$path ]; then
8183                                 echo "FAILED test_60a wrong obj path" \
8184                                       "$montpt/$path, should be $obj_file"
8185                                 pass=false
8186                                 break
8187                         fi
8188                 fi
8189         done
8190         rm -f $TMP/$tfile
8191         #restart mgs before "error", otherwise it will block the next test
8192         stop mgs || error "stop mgs failed"
8193         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8194         $pass || error "test failed, see FAILED test_60a messages for specifics"
8195 }
8196 run_test 60a "llog_test run from kernel module and test llog_reader"
8197
8198 test_60b() { # bug 6411
8199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8200
8201         dmesg > $DIR/$tfile
8202         LLOG_COUNT=$(do_facet mgs dmesg |
8203                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8204                           /llog_[a-z]*.c:[0-9]/ {
8205                                 if (marker)
8206                                         from_marker++
8207                                 from_begin++
8208                           }
8209                           END {
8210                                 if (marker)
8211                                         print from_marker
8212                                 else
8213                                         print from_begin
8214                           }")
8215
8216         [[ $LLOG_COUNT -gt 120 ]] &&
8217                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8218 }
8219 run_test 60b "limit repeated messages from CERROR/CWARN"
8220
8221 test_60c() {
8222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8223
8224         echo "create 5000 files"
8225         createmany -o $DIR/f60c- 5000
8226 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8227         lctl set_param fail_loc=0x80000137
8228         unlinkmany $DIR/f60c- 5000
8229         lctl set_param fail_loc=0
8230 }
8231 run_test 60c "unlink file when mds full"
8232
8233 test_60d() {
8234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8235
8236         SAVEPRINTK=$(lctl get_param -n printk)
8237         # verify "lctl mark" is even working"
8238         MESSAGE="test message ID $RANDOM $$"
8239         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8240         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8241
8242         lctl set_param printk=0 || error "set lnet.printk failed"
8243         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8244         MESSAGE="new test message ID $RANDOM $$"
8245         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8246         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8247         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8248
8249         lctl set_param -n printk="$SAVEPRINTK"
8250 }
8251 run_test 60d "test printk console message masking"
8252
8253 test_60e() {
8254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8255         remote_mds_nodsh && skip "remote MDS with nodsh"
8256
8257         touch $DIR/$tfile
8258 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8259         do_facet mds1 lctl set_param fail_loc=0x15b
8260         rm $DIR/$tfile
8261 }
8262 run_test 60e "no space while new llog is being created"
8263
8264 test_60f() {
8265         local old_path=$($LCTL get_param -n debug_path)
8266
8267         stack_trap "$LCTL set_param debug_path=$old_path"
8268         stack_trap "rm -f $TMP/$tfile*"
8269         rm -f $TMP/$tfile* 2> /dev/null
8270         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8271         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8272         test_mkdir $DIR/$tdir
8273         # retry in case the open is cached and not released
8274         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8275                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8276                 sleep 0.1
8277         done
8278         ls $TMP/$tfile*
8279         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8280 }
8281 run_test 60f "change debug_path works"
8282
8283 test_60g() {
8284         local pid
8285         local i
8286
8287         test_mkdir -c $MDSCOUNT $DIR/$tdir
8288
8289         (
8290                 local index=0
8291                 while true; do
8292                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8293                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8294                                 2>/dev/null
8295                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8296                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8297                         index=$((index + 1))
8298                 done
8299         ) &
8300
8301         pid=$!
8302
8303         for i in {0..100}; do
8304                 # define OBD_FAIL_OSD_TXN_START    0x19a
8305                 local index=$((i % MDSCOUNT + 1))
8306
8307                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8308                         > /dev/null
8309                 sleep 0.01
8310         done
8311
8312         kill -9 $pid
8313
8314         for i in $(seq $MDSCOUNT); do
8315                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8316         done
8317
8318         mkdir $DIR/$tdir/new || error "mkdir failed"
8319         rmdir $DIR/$tdir/new || error "rmdir failed"
8320
8321         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8322                 -t namespace
8323         for i in $(seq $MDSCOUNT); do
8324                 wait_update_facet mds$i "$LCTL get_param -n \
8325                         mdd.$(facet_svc mds$i).lfsck_namespace |
8326                         awk '/^status/ { print \\\$2 }'" "completed"
8327         done
8328
8329         ls -R $DIR/$tdir || error "ls failed"
8330         rm -rf $DIR/$tdir || error "rmdir failed"
8331 }
8332 run_test 60g "transaction abort won't cause MDT hung"
8333
8334 test_60h() {
8335         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8336                 skip "Need MDS version at least 2.12.52"
8337         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8338
8339         local f
8340
8341         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8342         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8343         for fail_loc in 0x80000188 0x80000189; do
8344                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8345                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8346                         error "mkdir $dir-$fail_loc failed"
8347                 for i in {0..10}; do
8348                         # create may fail on missing stripe
8349                         echo $i > $DIR/$tdir-$fail_loc/$i
8350                 done
8351                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8352                         error "getdirstripe $tdir-$fail_loc failed"
8353                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8354                         error "migrate $tdir-$fail_loc failed"
8355                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8356                         error "getdirstripe $tdir-$fail_loc failed"
8357                 pushd $DIR/$tdir-$fail_loc
8358                 for f in *; do
8359                         echo $f | cmp $f - || error "$f data mismatch"
8360                 done
8361                 popd
8362                 rm -rf $DIR/$tdir-$fail_loc
8363         done
8364 }
8365 run_test 60h "striped directory with missing stripes can be accessed"
8366
8367 function t60i_load() {
8368         mkdir $DIR/$tdir
8369         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8370         $LCTL set_param fail_loc=0x131c fail_val=1
8371         for ((i=0; i<5000; i++)); do
8372                 touch $DIR/$tdir/f$i
8373         done
8374 }
8375
8376 test_60i() {
8377         changelog_register || error "changelog_register failed"
8378         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8379         changelog_users $SINGLEMDS | grep -q $cl_user ||
8380                 error "User $cl_user not found in changelog_users"
8381         changelog_chmask "ALL"
8382         t60i_load &
8383         local PID=$!
8384         for((i=0; i<100; i++)); do
8385                 changelog_dump >/dev/null ||
8386                         error "can't read changelog"
8387         done
8388         kill $PID
8389         wait $PID
8390         changelog_deregister || error "changelog_deregister failed"
8391         $LCTL set_param fail_loc=0
8392 }
8393 run_test 60i "llog: new record vs reader race"
8394
8395 test_61a() {
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397
8398         f="$DIR/f61"
8399         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8400         cancel_lru_locks osc
8401         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8402         sync
8403 }
8404 run_test 61a "mmap() writes don't make sync hang ================"
8405
8406 test_61b() {
8407         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8408 }
8409 run_test 61b "mmap() of unstriped file is successful"
8410
8411 # bug 2330 - insufficient obd_match error checking causes LBUG
8412 test_62() {
8413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8414
8415         f="$DIR/f62"
8416         echo foo > $f
8417         cancel_lru_locks osc
8418         lctl set_param fail_loc=0x405
8419         cat $f && error "cat succeeded, expect -EIO"
8420         lctl set_param fail_loc=0
8421 }
8422 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8423 # match every page all of the time.
8424 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8425
8426 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8427 # Though this test is irrelevant anymore, it helped to reveal some
8428 # other grant bugs (LU-4482), let's keep it.
8429 test_63a() {   # was test_63
8430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8431
8432         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8433
8434         for i in `seq 10` ; do
8435                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8436                 sleep 5
8437                 kill $!
8438                 sleep 1
8439         done
8440
8441         rm -f $DIR/f63 || true
8442 }
8443 run_test 63a "Verify oig_wait interruption does not crash ======="
8444
8445 # bug 2248 - async write errors didn't return to application on sync
8446 # bug 3677 - async write errors left page locked
8447 test_63b() {
8448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8449
8450         debugsave
8451         lctl set_param debug=-1
8452
8453         # ensure we have a grant to do async writes
8454         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8455         rm $DIR/$tfile
8456
8457         sync    # sync lest earlier test intercept the fail_loc
8458
8459         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8460         lctl set_param fail_loc=0x80000406
8461         $MULTIOP $DIR/$tfile Owy && \
8462                 error "sync didn't return ENOMEM"
8463         sync; sleep 2; sync     # do a real sync this time to flush page
8464         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8465                 error "locked page left in cache after async error" || true
8466         debugrestore
8467 }
8468 run_test 63b "async write errors should be returned to fsync ==="
8469
8470 test_64a () {
8471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8472
8473         lfs df $DIR
8474         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8475 }
8476 run_test 64a "verify filter grant calculations (in kernel) ====="
8477
8478 test_64b () {
8479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8480
8481         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8482 }
8483 run_test 64b "check out-of-space detection on client"
8484
8485 test_64c() {
8486         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8487 }
8488 run_test 64c "verify grant shrink"
8489
8490 import_param() {
8491         local tgt=$1
8492         local param=$2
8493
8494         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8495 }
8496
8497 # this does exactly what osc_request.c:osc_announce_cached() does in
8498 # order to calculate max amount of grants to ask from server
8499 want_grant() {
8500         local tgt=$1
8501
8502         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8503         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8504
8505         ((rpc_in_flight++));
8506         nrpages=$((nrpages * rpc_in_flight))
8507
8508         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8509
8510         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8511
8512         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8513         local undirty=$((nrpages * PAGE_SIZE))
8514
8515         local max_extent_pages
8516         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8517         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8518         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8519         local grant_extent_tax
8520         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8521
8522         undirty=$((undirty + nrextents * grant_extent_tax))
8523
8524         echo $undirty
8525 }
8526
8527 # this is size of unit for grant allocation. It should be equal to
8528 # what tgt_grant.c:tgt_grant_chunk() calculates
8529 grant_chunk() {
8530         local tgt=$1
8531         local max_brw_size
8532         local grant_extent_tax
8533
8534         max_brw_size=$(import_param $tgt max_brw_size)
8535
8536         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8537
8538         echo $(((max_brw_size + grant_extent_tax) * 2))
8539 }
8540
8541 test_64d() {
8542         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8543                 skip "OST < 2.10.55 doesn't limit grants enough"
8544
8545         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8546
8547         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8548                 skip "no grant_param connect flag"
8549
8550         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8551
8552         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8553         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8554
8555
8556         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8557         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8558
8559         $LFS setstripe $DIR/$tfile -i 0 -c 1
8560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8561         ddpid=$!
8562
8563         while kill -0 $ddpid; do
8564                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8565
8566                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8567                         kill $ddpid
8568                         error "cur_grant $cur_grant > $max_cur_granted"
8569                 fi
8570
8571                 sleep 1
8572         done
8573 }
8574 run_test 64d "check grant limit exceed"
8575
8576 check_grants() {
8577         local tgt=$1
8578         local expected=$2
8579         local msg=$3
8580         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8581
8582         ((cur_grants == expected)) ||
8583                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8584 }
8585
8586 round_up_p2() {
8587         echo $((($1 + $2 - 1) & ~($2 - 1)))
8588 }
8589
8590 test_64e() {
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8593                 skip "Need OSS version at least 2.11.56"
8594
8595         # Remount client to reset grant
8596         remount_client $MOUNT || error "failed to remount client"
8597         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8598
8599         local init_grants=$(import_param $osc_tgt initial_grant)
8600
8601         check_grants $osc_tgt $init_grants "init grants"
8602
8603         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8604         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8605         local gbs=$(import_param $osc_tgt grant_block_size)
8606
8607         # write random number of bytes from max_brw_size / 4 to max_brw_size
8608         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8609         # align for direct io
8610         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8611         # round to grant consumption unit
8612         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8613
8614         local grants=$((wb_round_up + extent_tax))
8615
8616         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8617
8618         # define OBD_FAIL_TGT_NO_GRANT 0x725
8619         # make the server not grant more back
8620         do_facet ost1 $LCTL set_param fail_loc=0x725
8621         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8622
8623         do_facet ost1 $LCTL set_param fail_loc=0
8624
8625         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8626
8627         rm -f $DIR/$tfile || error "rm failed"
8628
8629         # Remount client to reset grant
8630         remount_client $MOUNT || error "failed to remount client"
8631         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8632
8633         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8634
8635         # define OBD_FAIL_TGT_NO_GRANT 0x725
8636         # make the server not grant more back
8637         do_facet ost1 $LCTL set_param fail_loc=0x725
8638         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8639         do_facet ost1 $LCTL set_param fail_loc=0
8640
8641         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8642 }
8643 run_test 64e "check grant consumption (no grant allocation)"
8644
8645 test_64f() {
8646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8647
8648         # Remount client to reset grant
8649         remount_client $MOUNT || error "failed to remount client"
8650         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8651
8652         local init_grants=$(import_param $osc_tgt initial_grant)
8653         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8654         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8655         local gbs=$(import_param $osc_tgt grant_block_size)
8656         local chunk=$(grant_chunk $osc_tgt)
8657
8658         # write random number of bytes from max_brw_size / 4 to max_brw_size
8659         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8660         # align for direct io
8661         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8662         # round to grant consumption unit
8663         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8664
8665         local grants=$((wb_round_up + extent_tax))
8666
8667         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8668         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8669                 error "error writing to $DIR/$tfile"
8670
8671         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8672                 "direct io with grant allocation"
8673
8674         rm -f $DIR/$tfile || error "rm failed"
8675
8676         # Remount client to reset grant
8677         remount_client $MOUNT || error "failed to remount client"
8678         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8679
8680         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8681
8682         local cmd="oO_WRONLY:w${write_bytes}_yc"
8683
8684         $MULTIOP $DIR/$tfile $cmd &
8685         MULTIPID=$!
8686         sleep 1
8687
8688         check_grants $osc_tgt $((init_grants - grants)) \
8689                 "buffered io, not write rpc"
8690
8691         kill -USR1 $MULTIPID
8692         wait
8693
8694         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8695                 "buffered io, one RPC"
8696 }
8697 run_test 64f "check grant consumption (with grant allocation)"
8698
8699 # bug 1414 - set/get directories' stripe info
8700 test_65a() {
8701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8702
8703         test_mkdir $DIR/$tdir
8704         touch $DIR/$tdir/f1
8705         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8706 }
8707 run_test 65a "directory with no stripe info"
8708
8709 test_65b() {
8710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8711
8712         test_mkdir $DIR/$tdir
8713         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8714
8715         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8716                                                 error "setstripe"
8717         touch $DIR/$tdir/f2
8718         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8719 }
8720 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8721
8722 test_65c() {
8723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8724         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8725
8726         test_mkdir $DIR/$tdir
8727         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8728
8729         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8730                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8731         touch $DIR/$tdir/f3
8732         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8733 }
8734 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8735
8736 test_65d() {
8737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8738
8739         test_mkdir $DIR/$tdir
8740         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8741         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8742
8743         if [[ $STRIPECOUNT -le 0 ]]; then
8744                 sc=1
8745         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8746                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8747                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8748         else
8749                 sc=$(($STRIPECOUNT - 1))
8750         fi
8751         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8752         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8753         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8754                 error "lverify failed"
8755 }
8756 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8757
8758 test_65e() {
8759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8760
8761         test_mkdir $DIR/$tdir
8762
8763         $LFS setstripe $DIR/$tdir || error "setstripe"
8764         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8765                                         error "no stripe info failed"
8766         touch $DIR/$tdir/f6
8767         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8768 }
8769 run_test 65e "directory setstripe defaults"
8770
8771 test_65f() {
8772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8773
8774         test_mkdir $DIR/${tdir}f
8775         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8776                 error "setstripe succeeded" || true
8777 }
8778 run_test 65f "dir setstripe permission (should return error) ==="
8779
8780 test_65g() {
8781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8782
8783         test_mkdir $DIR/$tdir
8784         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8785
8786         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8787                 error "setstripe -S failed"
8788         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8789         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8790                 error "delete default stripe failed"
8791 }
8792 run_test 65g "directory setstripe -d"
8793
8794 test_65h() {
8795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8796
8797         test_mkdir $DIR/$tdir
8798         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8799
8800         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8801                 error "setstripe -S failed"
8802         test_mkdir $DIR/$tdir/dd1
8803         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8804                 error "stripe info inherit failed"
8805 }
8806 run_test 65h "directory stripe info inherit ===================="
8807
8808 test_65i() {
8809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8810
8811         save_layout_restore_at_exit $MOUNT
8812
8813         # bug6367: set non-default striping on root directory
8814         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8815
8816         # bug12836: getstripe on -1 default directory striping
8817         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8818
8819         # bug12836: getstripe -v on -1 default directory striping
8820         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8821
8822         # bug12836: new find on -1 default directory striping
8823         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8824 }
8825 run_test 65i "various tests to set root directory striping"
8826
8827 test_65j() { # bug6367
8828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8829
8830         sync; sleep 1
8831
8832         # if we aren't already remounting for each test, do so for this test
8833         if [ "$I_MOUNTED" = "yes" ]; then
8834                 cleanup || error "failed to unmount"
8835                 setup
8836         fi
8837
8838         save_layout_restore_at_exit $MOUNT
8839
8840         $LFS setstripe -d $MOUNT || error "setstripe failed"
8841 }
8842 run_test 65j "set default striping on root directory (bug 6367)="
8843
8844 cleanup_65k() {
8845         rm -rf $DIR/$tdir
8846         wait_delete_completed
8847         do_facet $SINGLEMDS "lctl set_param -n \
8848                 osp.$ost*MDT0000.max_create_count=$max_count"
8849         do_facet $SINGLEMDS "lctl set_param -n \
8850                 osp.$ost*MDT0000.create_count=$count"
8851         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8852         echo $INACTIVE_OSC "is Activate"
8853
8854         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8855 }
8856
8857 test_65k() { # bug11679
8858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8859         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8860         remote_mds_nodsh && skip "remote MDS with nodsh"
8861
8862         local disable_precreate=true
8863         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8864                 disable_precreate=false
8865
8866         echo "Check OST status: "
8867         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8868                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8869
8870         for OSC in $MDS_OSCS; do
8871                 echo $OSC "is active"
8872                 do_facet $SINGLEMDS lctl --device %$OSC activate
8873         done
8874
8875         for INACTIVE_OSC in $MDS_OSCS; do
8876                 local ost=$(osc_to_ost $INACTIVE_OSC)
8877                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8878                                lov.*md*.target_obd |
8879                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8880
8881                 mkdir -p $DIR/$tdir
8882                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8883                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8884
8885                 echo "Deactivate: " $INACTIVE_OSC
8886                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8887
8888                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8889                               osp.$ost*MDT0000.create_count")
8890                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8891                                   osp.$ost*MDT0000.max_create_count")
8892                 $disable_precreate &&
8893                         do_facet $SINGLEMDS "lctl set_param -n \
8894                                 osp.$ost*MDT0000.max_create_count=0"
8895
8896                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8897                         [ -f $DIR/$tdir/$idx ] && continue
8898                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8899                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8900                                 { cleanup_65k;
8901                                   error "setstripe $idx should succeed"; }
8902                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8903                 done
8904                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8905                 rmdir $DIR/$tdir
8906
8907                 do_facet $SINGLEMDS "lctl set_param -n \
8908                         osp.$ost*MDT0000.max_create_count=$max_count"
8909                 do_facet $SINGLEMDS "lctl set_param -n \
8910                         osp.$ost*MDT0000.create_count=$count"
8911                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8912                 echo $INACTIVE_OSC "is Activate"
8913
8914                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8915         done
8916 }
8917 run_test 65k "validate manual striping works properly with deactivated OSCs"
8918
8919 test_65l() { # bug 12836
8920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8921
8922         test_mkdir -p $DIR/$tdir/test_dir
8923         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8924         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8925 }
8926 run_test 65l "lfs find on -1 stripe dir ========================"
8927
8928 test_65m() {
8929         local layout=$(save_layout $MOUNT)
8930         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8931                 restore_layout $MOUNT $layout
8932                 error "setstripe should fail by non-root users"
8933         }
8934         true
8935 }
8936 run_test 65m "normal user can't set filesystem default stripe"
8937
8938 test_65n() {
8939         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8940         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8941                 skip "Need MDS version at least 2.12.50"
8942         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8943
8944         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8945         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8946         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8947
8948         save_layout_restore_at_exit $MOUNT
8949
8950         # new subdirectory under root directory should not inherit
8951         # the default layout from root
8952         local dir1=$MOUNT/$tdir-1
8953         mkdir $dir1 || error "mkdir $dir1 failed"
8954         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8955                 error "$dir1 shouldn't have LOV EA"
8956
8957         # delete the default layout on root directory
8958         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8959
8960         local dir2=$MOUNT/$tdir-2
8961         mkdir $dir2 || error "mkdir $dir2 failed"
8962         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8963                 error "$dir2 shouldn't have LOV EA"
8964
8965         # set a new striping pattern on root directory
8966         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8967         local new_def_stripe_size=$((def_stripe_size * 2))
8968         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8969                 error "set stripe size on $MOUNT failed"
8970
8971         # new file created in $dir2 should inherit the new stripe size from
8972         # the filesystem default
8973         local file2=$dir2/$tfile-2
8974         touch $file2 || error "touch $file2 failed"
8975
8976         local file2_stripe_size=$($LFS getstripe -S $file2)
8977         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8978         {
8979                 echo "file2_stripe_size: '$file2_stripe_size'"
8980                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8981                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8982         }
8983
8984         local dir3=$MOUNT/$tdir-3
8985         mkdir $dir3 || error "mkdir $dir3 failed"
8986         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8987         # the root layout, which is the actual default layout that will be used
8988         # when new files are created in $dir3.
8989         local dir3_layout=$(get_layout_param $dir3)
8990         local root_dir_layout=$(get_layout_param $MOUNT)
8991         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8992         {
8993                 echo "dir3_layout: '$dir3_layout'"
8994                 echo "root_dir_layout: '$root_dir_layout'"
8995                 error "$dir3 should show the default layout from $MOUNT"
8996         }
8997
8998         # set OST pool on root directory
8999         local pool=$TESTNAME
9000         pool_add $pool || error "add $pool failed"
9001         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9002                 error "add targets to $pool failed"
9003
9004         $LFS setstripe -p $pool $MOUNT ||
9005                 error "set OST pool on $MOUNT failed"
9006
9007         # new file created in $dir3 should inherit the pool from
9008         # the filesystem default
9009         local file3=$dir3/$tfile-3
9010         touch $file3 || error "touch $file3 failed"
9011
9012         local file3_pool=$($LFS getstripe -p $file3)
9013         [[ "$file3_pool" = "$pool" ]] ||
9014                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9015
9016         local dir4=$MOUNT/$tdir-4
9017         mkdir $dir4 || error "mkdir $dir4 failed"
9018         local dir4_layout=$(get_layout_param $dir4)
9019         root_dir_layout=$(get_layout_param $MOUNT)
9020         echo "$LFS getstripe -d $dir4"
9021         $LFS getstripe -d $dir4
9022         echo "$LFS getstripe -d $MOUNT"
9023         $LFS getstripe -d $MOUNT
9024         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9025         {
9026                 echo "dir4_layout: '$dir4_layout'"
9027                 echo "root_dir_layout: '$root_dir_layout'"
9028                 error "$dir4 should show the default layout from $MOUNT"
9029         }
9030
9031         # new file created in $dir4 should inherit the pool from
9032         # the filesystem default
9033         local file4=$dir4/$tfile-4
9034         touch $file4 || error "touch $file4 failed"
9035
9036         local file4_pool=$($LFS getstripe -p $file4)
9037         [[ "$file4_pool" = "$pool" ]] ||
9038                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9039
9040         # new subdirectory under non-root directory should inherit
9041         # the default layout from its parent directory
9042         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9043                 error "set directory layout on $dir4 failed"
9044
9045         local dir5=$dir4/$tdir-5
9046         mkdir $dir5 || error "mkdir $dir5 failed"
9047
9048         dir4_layout=$(get_layout_param $dir4)
9049         local dir5_layout=$(get_layout_param $dir5)
9050         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9051         {
9052                 echo "dir4_layout: '$dir4_layout'"
9053                 echo "dir5_layout: '$dir5_layout'"
9054                 error "$dir5 should inherit the default layout from $dir4"
9055         }
9056
9057         # though subdir under ROOT doesn't inherit default layout, but
9058         # its sub dir/file should be created with default layout.
9059         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9060         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9061                 skip "Need MDS version at least 2.12.59"
9062
9063         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9064         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9065         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9066
9067         if [ $default_lmv_hash == "none" ]; then
9068                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9069         else
9070                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9071                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9072         fi
9073
9074         $LFS setdirstripe -D -c 2 $MOUNT ||
9075                 error "setdirstripe -D -c 2 failed"
9076         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9077         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9078         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9079 }
9080 run_test 65n "don't inherit default layout from root for new subdirectories"
9081
9082 # bug 2543 - update blocks count on client
9083 test_66() {
9084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9085
9086         COUNT=${COUNT:-8}
9087         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9088         sync; sync_all_data; sync; sync_all_data
9089         cancel_lru_locks osc
9090         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9091         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9092 }
9093 run_test 66 "update inode blocks count on client ==============="
9094
9095 meminfo() {
9096         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9097 }
9098
9099 swap_used() {
9100         swapon -s | awk '($1 == "'$1'") { print $4 }'
9101 }
9102
9103 # bug5265, obdfilter oa2dentry return -ENOENT
9104 # #define OBD_FAIL_SRV_ENOENT 0x217
9105 test_69() {
9106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9107         remote_ost_nodsh && skip "remote OST with nodsh"
9108
9109         f="$DIR/$tfile"
9110         $LFS setstripe -c 1 -i 0 $f
9111
9112         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9113
9114         do_facet ost1 lctl set_param fail_loc=0x217
9115         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9116         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9117
9118         do_facet ost1 lctl set_param fail_loc=0
9119         $DIRECTIO write $f 0 2 || error "write error"
9120
9121         cancel_lru_locks osc
9122         $DIRECTIO read $f 0 1 || error "read error"
9123
9124         do_facet ost1 lctl set_param fail_loc=0x217
9125         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9126
9127         do_facet ost1 lctl set_param fail_loc=0
9128         rm -f $f
9129 }
9130 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9131
9132 test_71() {
9133         test_mkdir $DIR/$tdir
9134         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9135         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9136 }
9137 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9138
9139 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9141         [ "$RUNAS_ID" = "$UID" ] &&
9142                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9143         # Check that testing environment is properly set up. Skip if not
9144         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9145                 skip_env "User $RUNAS_ID does not exist - skipping"
9146
9147         touch $DIR/$tfile
9148         chmod 777 $DIR/$tfile
9149         chmod ug+s $DIR/$tfile
9150         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9151                 error "$RUNAS dd $DIR/$tfile failed"
9152         # See if we are still setuid/sgid
9153         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9154                 error "S/gid is not dropped on write"
9155         # Now test that MDS is updated too
9156         cancel_lru_locks mdc
9157         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9158                 error "S/gid is not dropped on MDS"
9159         rm -f $DIR/$tfile
9160 }
9161 run_test 72a "Test that remove suid works properly (bug5695) ===="
9162
9163 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9164         local perm
9165
9166         [ "$RUNAS_ID" = "$UID" ] &&
9167                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9168         [ "$RUNAS_ID" -eq 0 ] &&
9169                 skip_env "RUNAS_ID = 0 -- skipping"
9170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9171         # Check that testing environment is properly set up. Skip if not
9172         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9173                 skip_env "User $RUNAS_ID does not exist - skipping"
9174
9175         touch $DIR/${tfile}-f{g,u}
9176         test_mkdir $DIR/${tfile}-dg
9177         test_mkdir $DIR/${tfile}-du
9178         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9179         chmod g+s $DIR/${tfile}-{f,d}g
9180         chmod u+s $DIR/${tfile}-{f,d}u
9181         for perm in 777 2777 4777; do
9182                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9183                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9184                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9185                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9186         done
9187         true
9188 }
9189 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9190
9191 # bug 3462 - multiple simultaneous MDC requests
9192 test_73() {
9193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9194
9195         test_mkdir $DIR/d73-1
9196         test_mkdir $DIR/d73-2
9197         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9198         pid1=$!
9199
9200         lctl set_param fail_loc=0x80000129
9201         $MULTIOP $DIR/d73-1/f73-2 Oc &
9202         sleep 1
9203         lctl set_param fail_loc=0
9204
9205         $MULTIOP $DIR/d73-2/f73-3 Oc &
9206         pid3=$!
9207
9208         kill -USR1 $pid1
9209         wait $pid1 || return 1
9210
9211         sleep 25
9212
9213         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9214         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9215         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9216
9217         rm -rf $DIR/d73-*
9218 }
9219 run_test 73 "multiple MDC requests (should not deadlock)"
9220
9221 test_74a() { # bug 6149, 6184
9222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9223
9224         touch $DIR/f74a
9225         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9226         #
9227         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9228         # will spin in a tight reconnection loop
9229         $LCTL set_param fail_loc=0x8000030e
9230         # get any lock that won't be difficult - lookup works.
9231         ls $DIR/f74a
9232         $LCTL set_param fail_loc=0
9233         rm -f $DIR/f74a
9234         true
9235 }
9236 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9237
9238 test_74b() { # bug 13310
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240
9241         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9242         #
9243         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9244         # will spin in a tight reconnection loop
9245         $LCTL set_param fail_loc=0x8000030e
9246         # get a "difficult" lock
9247         touch $DIR/f74b
9248         $LCTL set_param fail_loc=0
9249         rm -f $DIR/f74b
9250         true
9251 }
9252 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9253
9254 test_74c() {
9255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9256
9257         #define OBD_FAIL_LDLM_NEW_LOCK
9258         $LCTL set_param fail_loc=0x319
9259         touch $DIR/$tfile && error "touch successful"
9260         $LCTL set_param fail_loc=0
9261         true
9262 }
9263 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9264
9265 slab_lic=/sys/kernel/slab/lustre_inode_cache
9266 num_objects() {
9267         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9268         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9269                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9270 }
9271
9272 test_76a() { # Now for b=20433, added originally in b=1443
9273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9274
9275         cancel_lru_locks osc
9276         # there may be some slab objects cached per core
9277         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9278         local before=$(num_objects)
9279         local count=$((512 * cpus))
9280         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9281         local margin=$((count / 10))
9282         if [[ -f $slab_lic/aliases ]]; then
9283                 local aliases=$(cat $slab_lic/aliases)
9284                 (( aliases > 0 )) && margin=$((margin * aliases))
9285         fi
9286
9287         echo "before slab objects: $before"
9288         for i in $(seq $count); do
9289                 touch $DIR/$tfile
9290                 rm -f $DIR/$tfile
9291         done
9292         cancel_lru_locks osc
9293         local after=$(num_objects)
9294         echo "created: $count, after slab objects: $after"
9295         # shared slab counts are not very accurate, allow significant margin
9296         # the main goal is that the cache growth is not permanently > $count
9297         while (( after > before + margin )); do
9298                 sleep 1
9299                 after=$(num_objects)
9300                 wait=$((wait + 1))
9301                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9302                 if (( wait > 60 )); then
9303                         error "inode slab grew from $before+$margin to $after"
9304                 fi
9305         done
9306 }
9307 run_test 76a "confirm clients recycle inodes properly ===="
9308
9309 test_76b() {
9310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9311         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9312
9313         local count=512
9314         local before=$(num_objects)
9315
9316         for i in $(seq $count); do
9317                 mkdir $DIR/$tdir
9318                 rmdir $DIR/$tdir
9319         done
9320
9321         local after=$(num_objects)
9322         local wait=0
9323
9324         while (( after > before )); do
9325                 sleep 1
9326                 after=$(num_objects)
9327                 wait=$((wait + 1))
9328                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9329                 if (( wait > 60 )); then
9330                         error "inode slab grew from $before to $after"
9331                 fi
9332         done
9333
9334         echo "slab objects before: $before, after: $after"
9335 }
9336 run_test 76b "confirm clients recycle directory inodes properly ===="
9337
9338 export ORIG_CSUM=""
9339 set_checksums()
9340 {
9341         # Note: in sptlrpc modes which enable its own bulk checksum, the
9342         # original crc32_le bulk checksum will be automatically disabled,
9343         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9344         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9345         # In this case set_checksums() will not be no-op, because sptlrpc
9346         # bulk checksum will be enabled all through the test.
9347
9348         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9349         lctl set_param -n osc.*.checksums $1
9350         return 0
9351 }
9352
9353 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9354                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9355 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9356                              tr -d [] | head -n1)}
9357 set_checksum_type()
9358 {
9359         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9360         rc=$?
9361         log "set checksum type to $1, rc = $rc"
9362         return $rc
9363 }
9364
9365 get_osc_checksum_type()
9366 {
9367         # arugment 1: OST name, like OST0000
9368         ost=$1
9369         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9370                         sed 's/.*\[\(.*\)\].*/\1/g')
9371         rc=$?
9372         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9373         echo $checksum_type
9374 }
9375
9376 F77_TMP=$TMP/f77-temp
9377 F77SZ=8
9378 setup_f77() {
9379         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9380                 error "error writing to $F77_TMP"
9381 }
9382
9383 test_77a() { # bug 10889
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385         $GSS && skip_env "could not run with gss"
9386
9387         [ ! -f $F77_TMP ] && setup_f77
9388         set_checksums 1
9389         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9390         set_checksums 0
9391         rm -f $DIR/$tfile
9392 }
9393 run_test 77a "normal checksum read/write operation"
9394
9395 test_77b() { # bug 10889
9396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9397         $GSS && skip_env "could not run with gss"
9398
9399         [ ! -f $F77_TMP ] && setup_f77
9400         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9401         $LCTL set_param fail_loc=0x80000409
9402         set_checksums 1
9403
9404         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9405                 error "dd error: $?"
9406         $LCTL set_param fail_loc=0
9407
9408         for algo in $CKSUM_TYPES; do
9409                 cancel_lru_locks osc
9410                 set_checksum_type $algo
9411                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9412                 $LCTL set_param fail_loc=0x80000408
9413                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9414                 $LCTL set_param fail_loc=0
9415         done
9416         set_checksums 0
9417         set_checksum_type $ORIG_CSUM_TYPE
9418         rm -f $DIR/$tfile
9419 }
9420 run_test 77b "checksum error on client write, read"
9421
9422 cleanup_77c() {
9423         trap 0
9424         set_checksums 0
9425         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9426         $check_ost &&
9427                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9428         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9429         $check_ost && [ -n "$ost_file_prefix" ] &&
9430                 do_facet ost1 rm -f ${ost_file_prefix}\*
9431 }
9432
9433 test_77c() {
9434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9435         $GSS && skip_env "could not run with gss"
9436         remote_ost_nodsh && skip "remote OST with nodsh"
9437
9438         local bad1
9439         local osc_file_prefix
9440         local osc_file
9441         local check_ost=false
9442         local ost_file_prefix
9443         local ost_file
9444         local orig_cksum
9445         local dump_cksum
9446         local fid
9447
9448         # ensure corruption will occur on first OSS/OST
9449         $LFS setstripe -i 0 $DIR/$tfile
9450
9451         [ ! -f $F77_TMP ] && setup_f77
9452         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9453                 error "dd write error: $?"
9454         fid=$($LFS path2fid $DIR/$tfile)
9455
9456         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9457         then
9458                 check_ost=true
9459                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9460                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9461         else
9462                 echo "OSS do not support bulk pages dump upon error"
9463         fi
9464
9465         osc_file_prefix=$($LCTL get_param -n debug_path)
9466         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9467
9468         trap cleanup_77c EXIT
9469
9470         set_checksums 1
9471         # enable bulk pages dump upon error on Client
9472         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9473         # enable bulk pages dump upon error on OSS
9474         $check_ost &&
9475                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9476
9477         # flush Client cache to allow next read to reach OSS
9478         cancel_lru_locks osc
9479
9480         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9481         $LCTL set_param fail_loc=0x80000408
9482         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9483         $LCTL set_param fail_loc=0
9484
9485         rm -f $DIR/$tfile
9486
9487         # check cksum dump on Client
9488         osc_file=$(ls ${osc_file_prefix}*)
9489         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9490         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9491         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9492         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9493         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9494                      cksum)
9495         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9496         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9497                 error "dump content does not match on Client"
9498
9499         $check_ost || skip "No need to check cksum dump on OSS"
9500
9501         # check cksum dump on OSS
9502         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9503         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9504         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9505         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9506         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9507                 error "dump content does not match on OSS"
9508
9509         cleanup_77c
9510 }
9511 run_test 77c "checksum error on client read with debug"
9512
9513 test_77d() { # bug 10889
9514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9515         $GSS && skip_env "could not run with gss"
9516
9517         stack_trap "rm -f $DIR/$tfile"
9518         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9519         $LCTL set_param fail_loc=0x80000409
9520         set_checksums 1
9521         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9522                 error "direct write: rc=$?"
9523         $LCTL set_param fail_loc=0
9524         set_checksums 0
9525
9526         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9527         $LCTL set_param fail_loc=0x80000408
9528         set_checksums 1
9529         cancel_lru_locks osc
9530         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9531                 error "direct read: rc=$?"
9532         $LCTL set_param fail_loc=0
9533         set_checksums 0
9534 }
9535 run_test 77d "checksum error on OST direct write, read"
9536
9537 test_77f() { # bug 10889
9538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9539         $GSS && skip_env "could not run with gss"
9540
9541         set_checksums 1
9542         stack_trap "rm -f $DIR/$tfile"
9543         for algo in $CKSUM_TYPES; do
9544                 cancel_lru_locks osc
9545                 set_checksum_type $algo
9546                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9547                 $LCTL set_param fail_loc=0x409
9548                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9549                         error "direct write succeeded"
9550                 $LCTL set_param fail_loc=0
9551         done
9552         set_checksum_type $ORIG_CSUM_TYPE
9553         set_checksums 0
9554 }
9555 run_test 77f "repeat checksum error on write (expect error)"
9556
9557 test_77g() { # bug 10889
9558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9559         $GSS && skip_env "could not run with gss"
9560         remote_ost_nodsh && skip "remote OST with nodsh"
9561
9562         [ ! -f $F77_TMP ] && setup_f77
9563
9564         local file=$DIR/$tfile
9565         stack_trap "rm -f $file" EXIT
9566
9567         $LFS setstripe -c 1 -i 0 $file
9568         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9569         do_facet ost1 lctl set_param fail_loc=0x8000021a
9570         set_checksums 1
9571         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9572                 error "write error: rc=$?"
9573         do_facet ost1 lctl set_param fail_loc=0
9574         set_checksums 0
9575
9576         cancel_lru_locks osc
9577         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9578         do_facet ost1 lctl set_param fail_loc=0x8000021b
9579         set_checksums 1
9580         cmp $F77_TMP $file || error "file compare failed"
9581         do_facet ost1 lctl set_param fail_loc=0
9582         set_checksums 0
9583 }
9584 run_test 77g "checksum error on OST write, read"
9585
9586 test_77k() { # LU-10906
9587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9588         $GSS && skip_env "could not run with gss"
9589
9590         local cksum_param="osc.$FSNAME*.checksums"
9591         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9592         local checksum
9593         local i
9594
9595         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9596         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9597         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9598
9599         for i in 0 1; do
9600                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9601                         error "failed to set checksum=$i on MGS"
9602                 wait_update $HOSTNAME "$get_checksum" $i
9603                 #remount
9604                 echo "remount client, checksum should be $i"
9605                 remount_client $MOUNT || error "failed to remount client"
9606                 checksum=$(eval $get_checksum)
9607                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9608         done
9609         # remove persistent param to avoid races with checksum mountopt below
9610         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9611                 error "failed to delete checksum on MGS"
9612
9613         for opt in "checksum" "nochecksum"; do
9614                 #remount with mount option
9615                 echo "remount client with option $opt, checksum should be $i"
9616                 umount_client $MOUNT || error "failed to umount client"
9617                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9618                         error "failed to mount client with option '$opt'"
9619                 checksum=$(eval $get_checksum)
9620                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9621                 i=$((i - 1))
9622         done
9623
9624         remount_client $MOUNT || error "failed to remount client"
9625 }
9626 run_test 77k "enable/disable checksum correctly"
9627
9628 test_77l() {
9629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9630         $GSS && skip_env "could not run with gss"
9631
9632         set_checksums 1
9633         stack_trap "set_checksums $ORIG_CSUM" EXIT
9634         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9635
9636         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9637
9638         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9639         for algo in $CKSUM_TYPES; do
9640                 set_checksum_type $algo || error "fail to set checksum type $algo"
9641                 osc_algo=$(get_osc_checksum_type OST0000)
9642                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9643
9644                 # no locks, no reqs to let the connection idle
9645                 cancel_lru_locks osc
9646                 lru_resize_disable osc
9647                 wait_osc_import_state client ost1 IDLE
9648
9649                 # ensure ost1 is connected
9650                 stat $DIR/$tfile >/dev/null || error "can't stat"
9651                 wait_osc_import_state client ost1 FULL
9652
9653                 osc_algo=$(get_osc_checksum_type OST0000)
9654                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9655         done
9656         return 0
9657 }
9658 run_test 77l "preferred checksum type is remembered after reconnected"
9659
9660 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9661 rm -f $F77_TMP
9662 unset F77_TMP
9663
9664 test_77m() {
9665         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9666                 skip "Need at least version 2.14.52"
9667         local param=checksum_speed
9668
9669         $LCTL get_param $param || error "reading $param failed"
9670
9671         csum_speeds=$($LCTL get_param -n $param)
9672
9673         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9674                 error "known checksum types are missing"
9675 }
9676 run_test 77m "Verify checksum_speed is correctly read"
9677
9678 check_filefrag_77n() {
9679         local nr_ext=0
9680         local starts=()
9681         local ends=()
9682
9683         while read extidx a b start end rest; do
9684                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9685                         nr_ext=$(( $nr_ext + 1 ))
9686                         starts+=( ${start%..} )
9687                         ends+=( ${end%:} )
9688                 fi
9689         done < <( filefrag -sv $1 )
9690
9691         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9692         return 1
9693 }
9694
9695 test_77n() {
9696         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9697
9698         touch $DIR/$tfile
9699         $TRUNCATE $DIR/$tfile 0
9700         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9701         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9702         check_filefrag_77n $DIR/$tfile ||
9703                 skip "$tfile blocks not contiguous around hole"
9704
9705         set_checksums 1
9706         stack_trap "set_checksums $ORIG_CSUM" EXIT
9707         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9708         stack_trap "rm -f $DIR/$tfile"
9709
9710         for algo in $CKSUM_TYPES; do
9711                 if [[ "$algo" =~ ^t10 ]]; then
9712                         set_checksum_type $algo ||
9713                                 error "fail to set checksum type $algo"
9714                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9715                                 error "fail to read $tfile with $algo"
9716                 fi
9717         done
9718         rm -f $DIR/$tfile
9719         return 0
9720 }
9721 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9722
9723 cleanup_test_78() {
9724         trap 0
9725         rm -f $DIR/$tfile
9726 }
9727
9728 test_78() { # bug 10901
9729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9730         remote_ost || skip_env "local OST"
9731
9732         NSEQ=5
9733         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9734         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9735         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9736         echo "MemTotal: $MEMTOTAL"
9737
9738         # reserve 256MB of memory for the kernel and other running processes,
9739         # and then take 1/2 of the remaining memory for the read/write buffers.
9740         if [ $MEMTOTAL -gt 512 ] ;then
9741                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9742         else
9743                 # for those poor memory-starved high-end clusters...
9744                 MEMTOTAL=$((MEMTOTAL / 2))
9745         fi
9746         echo "Mem to use for directio: $MEMTOTAL"
9747
9748         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9749         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9750         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9751         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9752                 head -n1)
9753         echo "Smallest OST: $SMALLESTOST"
9754         [[ $SMALLESTOST -lt 10240 ]] &&
9755                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9756
9757         trap cleanup_test_78 EXIT
9758
9759         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9760                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9761
9762         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9763         echo "File size: $F78SIZE"
9764         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9765         for i in $(seq 1 $NSEQ); do
9766                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9767                 echo directIO rdwr round $i of $NSEQ
9768                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9769         done
9770
9771         cleanup_test_78
9772 }
9773 run_test 78 "handle large O_DIRECT writes correctly ============"
9774
9775 test_79() { # bug 12743
9776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9777
9778         wait_delete_completed
9779
9780         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9781         BKFREE=$(calc_osc_kbytes kbytesfree)
9782         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9783
9784         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9785         DFTOTAL=`echo $STRING | cut -d, -f1`
9786         DFUSED=`echo $STRING  | cut -d, -f2`
9787         DFAVAIL=`echo $STRING | cut -d, -f3`
9788         DFFREE=$(($DFTOTAL - $DFUSED))
9789
9790         ALLOWANCE=$((64 * $OSTCOUNT))
9791
9792         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9793            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9794                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9795         fi
9796         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9797            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9798                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9799         fi
9800         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9801            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9802                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9803         fi
9804 }
9805 run_test 79 "df report consistency check ======================="
9806
9807 test_80() { # bug 10718
9808         remote_ost_nodsh && skip "remote OST with nodsh"
9809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9810
9811         # relax strong synchronous semantics for slow backends like ZFS
9812         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9813                 local soc="obdfilter.*.sync_lock_cancel"
9814                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9815
9816                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9817                 if [ -z "$save" ]; then
9818                         soc="obdfilter.*.sync_on_lock_cancel"
9819                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9820                 fi
9821
9822                 if [ "$save" != "never" ]; then
9823                         local hosts=$(comma_list $(osts_nodes))
9824
9825                         do_nodes $hosts $LCTL set_param $soc=never
9826                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9827                 fi
9828         fi
9829
9830         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9831         sync; sleep 1; sync
9832         local before=$(date +%s)
9833         cancel_lru_locks osc
9834         local after=$(date +%s)
9835         local diff=$((after - before))
9836         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9837
9838         rm -f $DIR/$tfile
9839 }
9840 run_test 80 "Page eviction is equally fast at high offsets too"
9841
9842 test_81a() { # LU-456
9843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9844         remote_ost_nodsh && skip "remote OST with nodsh"
9845
9846         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9847         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9848         do_facet ost1 lctl set_param fail_loc=0x80000228
9849
9850         # write should trigger a retry and success
9851         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9853         RC=$?
9854         if [ $RC -ne 0 ] ; then
9855                 error "write should success, but failed for $RC"
9856         fi
9857 }
9858 run_test 81a "OST should retry write when get -ENOSPC ==============="
9859
9860 test_81b() { # LU-456
9861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9862         remote_ost_nodsh && skip "remote OST with nodsh"
9863
9864         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9865         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9866         do_facet ost1 lctl set_param fail_loc=0x228
9867
9868         # write should retry several times and return -ENOSPC finally
9869         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9870         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9871         RC=$?
9872         ENOSPC=28
9873         if [ $RC -ne $ENOSPC ] ; then
9874                 error "dd should fail for -ENOSPC, but succeed."
9875         fi
9876 }
9877 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9878
9879 test_99() {
9880         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9881
9882         test_mkdir $DIR/$tdir.cvsroot
9883         chown $RUNAS_ID $DIR/$tdir.cvsroot
9884
9885         cd $TMP
9886         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9887
9888         cd /etc/init.d
9889         # some versions of cvs import exit(1) when asked to import links or
9890         # files they can't read.  ignore those files.
9891         local toignore=$(find . -type l -printf '-I %f\n' -o \
9892                          ! -perm /4 -printf '-I %f\n')
9893         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9894                 $tdir.reposname vtag rtag
9895
9896         cd $DIR
9897         test_mkdir $DIR/$tdir.reposname
9898         chown $RUNAS_ID $DIR/$tdir.reposname
9899         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9900
9901         cd $DIR/$tdir.reposname
9902         $RUNAS touch foo99
9903         $RUNAS cvs add -m 'addmsg' foo99
9904         $RUNAS cvs update
9905         $RUNAS cvs commit -m 'nomsg' foo99
9906         rm -fr $DIR/$tdir.cvsroot
9907 }
9908 run_test 99 "cvs strange file/directory operations"
9909
9910 test_100() {
9911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9912         [[ "$NETTYPE" =~ tcp ]] ||
9913                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9914         remote_ost_nodsh && skip "remote OST with nodsh"
9915         remote_mds_nodsh && skip "remote MDS with nodsh"
9916         remote_servers ||
9917                 skip "useless for local single node setup"
9918
9919         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9920                 [ "$PROT" != "tcp" ] && continue
9921                 RPORT=$(echo $REMOTE | cut -d: -f2)
9922                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9923
9924                 rc=0
9925                 LPORT=`echo $LOCAL | cut -d: -f2`
9926                 if [ $LPORT -ge 1024 ]; then
9927                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9928                         netstat -tna
9929                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9930                 fi
9931         done
9932         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9933 }
9934 run_test 100 "check local port using privileged port ==========="
9935
9936 function get_named_value()
9937 {
9938     local tag=$1
9939
9940     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9941 }
9942
9943 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9944                    awk '/^max_cached_mb/ { print $2 }')
9945
9946 cleanup_101a() {
9947         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9948         trap 0
9949 }
9950
9951 test_101a() {
9952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9953
9954         local s
9955         local discard
9956         local nreads=10000
9957         local cache_limit=32
9958
9959         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9960         trap cleanup_101a EXIT
9961         $LCTL set_param -n llite.*.read_ahead_stats=0
9962         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9963
9964         #
9965         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9966         #
9967         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9968         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9969
9970         discard=0
9971         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9972                    get_named_value 'read.but.discarded'); do
9973                         discard=$(($discard + $s))
9974         done
9975         cleanup_101a
9976
9977         $LCTL get_param osc.*-osc*.rpc_stats
9978         $LCTL get_param llite.*.read_ahead_stats
9979
9980         # Discard is generally zero, but sometimes a few random reads line up
9981         # and trigger larger readahead, which is wasted & leads to discards.
9982         if [[ $(($discard)) -gt $nreads ]]; then
9983                 error "too many ($discard) discarded pages"
9984         fi
9985         rm -f $DIR/$tfile || true
9986 }
9987 run_test 101a "check read-ahead for random reads"
9988
9989 setup_test101bc() {
9990         test_mkdir $DIR/$tdir
9991         local ssize=$1
9992         local FILE_LENGTH=$2
9993         STRIPE_OFFSET=0
9994
9995         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9996
9997         local list=$(comma_list $(osts_nodes))
9998         set_osd_param $list '' read_cache_enable 0
9999         set_osd_param $list '' writethrough_cache_enable 0
10000
10001         trap cleanup_test101bc EXIT
10002         # prepare the read-ahead file
10003         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10004
10005         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10006                                 count=$FILE_SIZE_MB 2> /dev/null
10007
10008 }
10009
10010 cleanup_test101bc() {
10011         trap 0
10012         rm -rf $DIR/$tdir
10013         rm -f $DIR/$tfile
10014
10015         local list=$(comma_list $(osts_nodes))
10016         set_osd_param $list '' read_cache_enable 1
10017         set_osd_param $list '' writethrough_cache_enable 1
10018 }
10019
10020 calc_total() {
10021         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10022 }
10023
10024 ra_check_101() {
10025         local READ_SIZE=$1
10026         local STRIPE_SIZE=$2
10027         local FILE_LENGTH=$3
10028         local RA_INC=1048576
10029         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10030         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10031                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10032         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10033                   get_named_value 'read.but.discarded' | calc_total)
10034         if [[ $DISCARD -gt $discard_limit ]]; then
10035                 $LCTL get_param llite.*.read_ahead_stats
10036                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10037         else
10038                 echo "Read-ahead success for size ${READ_SIZE}"
10039         fi
10040 }
10041
10042 test_101b() {
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10045
10046         local STRIPE_SIZE=1048576
10047         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10048
10049         if [ $SLOW == "yes" ]; then
10050                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10051         else
10052                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10053         fi
10054
10055         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10056
10057         # prepare the read-ahead file
10058         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10059         cancel_lru_locks osc
10060         for BIDX in 2 4 8 16 32 64 128 256
10061         do
10062                 local BSIZE=$((BIDX*4096))
10063                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10064                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10065                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10066                 $LCTL set_param -n llite.*.read_ahead_stats=0
10067                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10068                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10069                 cancel_lru_locks osc
10070                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10071         done
10072         cleanup_test101bc
10073         true
10074 }
10075 run_test 101b "check stride-io mode read-ahead ================="
10076
10077 test_101c() {
10078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10079
10080         local STRIPE_SIZE=1048576
10081         local FILE_LENGTH=$((STRIPE_SIZE*100))
10082         local nreads=10000
10083         local rsize=65536
10084         local osc_rpc_stats
10085
10086         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10087
10088         cancel_lru_locks osc
10089         $LCTL set_param osc.*.rpc_stats=0
10090         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10091         $LCTL get_param osc.*.rpc_stats
10092         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10093                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10094                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10095                 local size
10096
10097                 if [ $lines -le 20 ]; then
10098                         echo "continue debug"
10099                         continue
10100                 fi
10101                 for size in 1 2 4 8; do
10102                         local rpc=$(echo "$stats" |
10103                                     awk '($1 == "'$size':") {print $2; exit; }')
10104                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10105                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10106                 done
10107                 echo "$osc_rpc_stats check passed!"
10108         done
10109         cleanup_test101bc
10110         true
10111 }
10112 run_test 101c "check stripe_size aligned read-ahead"
10113
10114 test_101d() {
10115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10116
10117         local file=$DIR/$tfile
10118         local sz_MB=${FILESIZE_101d:-80}
10119         local ra_MB=${READAHEAD_MB:-40}
10120
10121         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10122         [ $free_MB -lt $sz_MB ] &&
10123                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10124
10125         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10126         $LFS setstripe -c -1 $file || error "setstripe failed"
10127
10128         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10129         echo Cancel LRU locks on lustre client to flush the client cache
10130         cancel_lru_locks osc
10131
10132         echo Disable read-ahead
10133         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10134         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10135         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10136         $LCTL get_param -n llite.*.max_read_ahead_mb
10137
10138         echo "Reading the test file $file with read-ahead disabled"
10139         local sz_KB=$((sz_MB * 1024 / 4))
10140         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10141         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10142         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10143                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10144
10145         echo "Cancel LRU locks on lustre client to flush the client cache"
10146         cancel_lru_locks osc
10147         echo Enable read-ahead with ${ra_MB}MB
10148         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10149
10150         echo "Reading the test file $file with read-ahead enabled"
10151         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10152                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10153
10154         echo "read-ahead disabled time read $raOFF"
10155         echo "read-ahead enabled time read $raON"
10156
10157         rm -f $file
10158         wait_delete_completed
10159
10160         # use awk for this check instead of bash because it handles decimals
10161         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10162                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10163 }
10164 run_test 101d "file read with and without read-ahead enabled"
10165
10166 test_101e() {
10167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10168
10169         local file=$DIR/$tfile
10170         local size_KB=500  #KB
10171         local count=100
10172         local bsize=1024
10173
10174         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10175         local need_KB=$((count * size_KB))
10176         [[ $free_KB -le $need_KB ]] &&
10177                 skip_env "Need free space $need_KB, have $free_KB"
10178
10179         echo "Creating $count ${size_KB}K test files"
10180         for ((i = 0; i < $count; i++)); do
10181                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10182         done
10183
10184         echo "Cancel LRU locks on lustre client to flush the client cache"
10185         cancel_lru_locks $OSC
10186
10187         echo "Reset readahead stats"
10188         $LCTL set_param -n llite.*.read_ahead_stats=0
10189
10190         for ((i = 0; i < $count; i++)); do
10191                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10192         done
10193
10194         $LCTL get_param llite.*.max_cached_mb
10195         $LCTL get_param llite.*.read_ahead_stats
10196         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10197                      get_named_value 'misses' | calc_total)
10198
10199         for ((i = 0; i < $count; i++)); do
10200                 rm -rf $file.$i 2>/dev/null
10201         done
10202
10203         #10000 means 20% reads are missing in readahead
10204         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10205 }
10206 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10207
10208 test_101f() {
10209         which iozone || skip_env "no iozone installed"
10210
10211         local old_debug=$($LCTL get_param debug)
10212         old_debug=${old_debug#*=}
10213         $LCTL set_param debug="reada mmap"
10214
10215         # create a test file
10216         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10217
10218         echo Cancel LRU locks on lustre client to flush the client cache
10219         cancel_lru_locks osc
10220
10221         echo Reset readahead stats
10222         $LCTL set_param -n llite.*.read_ahead_stats=0
10223
10224         echo mmap read the file with small block size
10225         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10226                 > /dev/null 2>&1
10227
10228         echo checking missing pages
10229         $LCTL get_param llite.*.read_ahead_stats
10230         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10231                         get_named_value 'misses' | calc_total)
10232
10233         $LCTL set_param debug="$old_debug"
10234         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10235         rm -f $DIR/$tfile
10236 }
10237 run_test 101f "check mmap read performance"
10238
10239 test_101g_brw_size_test() {
10240         local mb=$1
10241         local pages=$((mb * 1048576 / PAGE_SIZE))
10242         local file=$DIR/$tfile
10243
10244         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10245                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10246         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10247                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10248                         return 2
10249         done
10250
10251         stack_trap "rm -f $file" EXIT
10252         $LCTL set_param -n osc.*.rpc_stats=0
10253
10254         # 10 RPCs should be enough for the test
10255         local count=10
10256         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10257                 { error "dd write ${mb} MB blocks failed"; return 3; }
10258         cancel_lru_locks osc
10259         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10260                 { error "dd write ${mb} MB blocks failed"; return 4; }
10261
10262         # calculate number of full-sized read and write RPCs
10263         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10264                 sed -n '/pages per rpc/,/^$/p' |
10265                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10266                 END { print reads,writes }'))
10267         # allow one extra full-sized read RPC for async readahead
10268         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10269                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10270         [[ ${rpcs[1]} == $count ]] ||
10271                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10272 }
10273
10274 test_101g() {
10275         remote_ost_nodsh && skip "remote OST with nodsh"
10276
10277         local rpcs
10278         local osts=$(get_facets OST)
10279         local list=$(comma_list $(osts_nodes))
10280         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10281         local brw_size="obdfilter.*.brw_size"
10282
10283         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10284
10285         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10286
10287         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10288                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10289                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10290            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10291                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10292                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10293
10294                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10295                         suffix="M"
10296
10297                 if [[ $orig_mb -lt 16 ]]; then
10298                         save_lustre_params $osts "$brw_size" > $p
10299                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10300                                 error "set 16MB RPC size failed"
10301
10302                         echo "remount client to enable new RPC size"
10303                         remount_client $MOUNT || error "remount_client failed"
10304                 fi
10305
10306                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10307                 # should be able to set brw_size=12, but no rpc_stats for that
10308                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10309         fi
10310
10311         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10312
10313         if [[ $orig_mb -lt 16 ]]; then
10314                 restore_lustre_params < $p
10315                 remount_client $MOUNT || error "remount_client restore failed"
10316         fi
10317
10318         rm -f $p $DIR/$tfile
10319 }
10320 run_test 101g "Big bulk(4/16 MiB) readahead"
10321
10322 test_101h() {
10323         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10324
10325         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10326                 error "dd 70M file failed"
10327         echo Cancel LRU locks on lustre client to flush the client cache
10328         cancel_lru_locks osc
10329
10330         echo "Reset readahead stats"
10331         $LCTL set_param -n llite.*.read_ahead_stats 0
10332
10333         echo "Read 10M of data but cross 64M bundary"
10334         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10335         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10336                      get_named_value 'misses' | calc_total)
10337         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10338         rm -f $p $DIR/$tfile
10339 }
10340 run_test 101h "Readahead should cover current read window"
10341
10342 test_101i() {
10343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10344                 error "dd 10M file failed"
10345
10346         local max_per_file_mb=$($LCTL get_param -n \
10347                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10348         cancel_lru_locks osc
10349         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10350         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10351                 error "set max_read_ahead_per_file_mb to 1 failed"
10352
10353         echo "Reset readahead stats"
10354         $LCTL set_param llite.*.read_ahead_stats=0
10355
10356         dd if=$DIR/$tfile of=/dev/null bs=2M
10357
10358         $LCTL get_param llite.*.read_ahead_stats
10359         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10360                      awk '/misses/ { print $2 }')
10361         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10362         rm -f $DIR/$tfile
10363 }
10364 run_test 101i "allow current readahead to exceed reservation"
10365
10366 test_101j() {
10367         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10368                 error "setstripe $DIR/$tfile failed"
10369         local file_size=$((1048576 * 16))
10370         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10371         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10372
10373         echo Disable read-ahead
10374         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10375
10376         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10377         for blk in $PAGE_SIZE 1048576 $file_size; do
10378                 cancel_lru_locks osc
10379                 echo "Reset readahead stats"
10380                 $LCTL set_param -n llite.*.read_ahead_stats=0
10381                 local count=$(($file_size / $blk))
10382                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10383                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10384                              get_named_value 'failed.to.fast.read' | calc_total)
10385                 $LCTL get_param -n llite.*.read_ahead_stats
10386                 [ $miss -eq $count ] || error "expected $count got $miss"
10387         done
10388
10389         rm -f $p $DIR/$tfile
10390 }
10391 run_test 101j "A complete read block should be submitted when no RA"
10392
10393 setup_test102() {
10394         test_mkdir $DIR/$tdir
10395         chown $RUNAS_ID $DIR/$tdir
10396         STRIPE_SIZE=65536
10397         STRIPE_OFFSET=1
10398         STRIPE_COUNT=$OSTCOUNT
10399         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10400
10401         trap cleanup_test102 EXIT
10402         cd $DIR
10403         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10404         cd $DIR/$tdir
10405         for num in 1 2 3 4; do
10406                 for count in $(seq 1 $STRIPE_COUNT); do
10407                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10408                                 local size=`expr $STRIPE_SIZE \* $num`
10409                                 local file=file"$num-$idx-$count"
10410                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10411                         done
10412                 done
10413         done
10414
10415         cd $DIR
10416         $1 tar cf $TMP/f102.tar $tdir --xattrs
10417 }
10418
10419 cleanup_test102() {
10420         trap 0
10421         rm -f $TMP/f102.tar
10422         rm -rf $DIR/d0.sanity/d102
10423 }
10424
10425 test_102a() {
10426         [ "$UID" != 0 ] && skip "must run as root"
10427         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10428                 skip_env "must have user_xattr"
10429
10430         [ -z "$(which setfattr 2>/dev/null)" ] &&
10431                 skip_env "could not find setfattr"
10432
10433         local testfile=$DIR/$tfile
10434
10435         touch $testfile
10436         echo "set/get xattr..."
10437         setfattr -n trusted.name1 -v value1 $testfile ||
10438                 error "setfattr -n trusted.name1=value1 $testfile failed"
10439         getfattr -n trusted.name1 $testfile 2> /dev/null |
10440           grep "trusted.name1=.value1" ||
10441                 error "$testfile missing trusted.name1=value1"
10442
10443         setfattr -n user.author1 -v author1 $testfile ||
10444                 error "setfattr -n user.author1=author1 $testfile failed"
10445         getfattr -n user.author1 $testfile 2> /dev/null |
10446           grep "user.author1=.author1" ||
10447                 error "$testfile missing trusted.author1=author1"
10448
10449         echo "listxattr..."
10450         setfattr -n trusted.name2 -v value2 $testfile ||
10451                 error "$testfile unable to set trusted.name2"
10452         setfattr -n trusted.name3 -v value3 $testfile ||
10453                 error "$testfile unable to set trusted.name3"
10454         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10455             grep "trusted.name" | wc -l) -eq 3 ] ||
10456                 error "$testfile missing 3 trusted.name xattrs"
10457
10458         setfattr -n user.author2 -v author2 $testfile ||
10459                 error "$testfile unable to set user.author2"
10460         setfattr -n user.author3 -v author3 $testfile ||
10461                 error "$testfile unable to set user.author3"
10462         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10463             grep "user.author" | wc -l) -eq 3 ] ||
10464                 error "$testfile missing 3 user.author xattrs"
10465
10466         echo "remove xattr..."
10467         setfattr -x trusted.name1 $testfile ||
10468                 error "$testfile error deleting trusted.name1"
10469         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10470                 error "$testfile did not delete trusted.name1 xattr"
10471
10472         setfattr -x user.author1 $testfile ||
10473                 error "$testfile error deleting user.author1"
10474         echo "set lustre special xattr ..."
10475         $LFS setstripe -c1 $testfile
10476         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10477                 awk -F "=" '/trusted.lov/ { print $2 }' )
10478         setfattr -n "trusted.lov" -v $lovea $testfile ||
10479                 error "$testfile doesn't ignore setting trusted.lov again"
10480         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10481                 error "$testfile allow setting invalid trusted.lov"
10482         rm -f $testfile
10483 }
10484 run_test 102a "user xattr test =================================="
10485
10486 check_102b_layout() {
10487         local layout="$*"
10488         local testfile=$DIR/$tfile
10489
10490         echo "test layout '$layout'"
10491         $LFS setstripe $layout $testfile || error "setstripe failed"
10492         $LFS getstripe -y $testfile
10493
10494         echo "get/set/list trusted.lov xattr ..." # b=10930
10495         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10496         [[ "$value" =~ "trusted.lov" ]] ||
10497                 error "can't get trusted.lov from $testfile"
10498         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10499                 error "getstripe failed"
10500
10501         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10502
10503         value=$(cut -d= -f2 <<<$value)
10504         # LU-13168: truncated xattr should fail if short lov_user_md header
10505         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10506                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10507         for len in $lens; do
10508                 echo "setfattr $len $testfile.2"
10509                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10510                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10511         done
10512         local stripe_size=$($LFS getstripe -S $testfile.2)
10513         local stripe_count=$($LFS getstripe -c $testfile.2)
10514         [[ $stripe_size -eq 65536 ]] ||
10515                 error "stripe size $stripe_size != 65536"
10516         [[ $stripe_count -eq $stripe_count_orig ]] ||
10517                 error "stripe count $stripe_count != $stripe_count_orig"
10518         rm $testfile $testfile.2
10519 }
10520
10521 test_102b() {
10522         [ -z "$(which setfattr 2>/dev/null)" ] &&
10523                 skip_env "could not find setfattr"
10524         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10525
10526         # check plain layout
10527         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10528
10529         # and also check composite layout
10530         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10531
10532 }
10533 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10534
10535 test_102c() {
10536         [ -z "$(which setfattr 2>/dev/null)" ] &&
10537                 skip_env "could not find setfattr"
10538         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10539
10540         # b10930: get/set/list lustre.lov xattr
10541         echo "get/set/list lustre.lov xattr ..."
10542         test_mkdir $DIR/$tdir
10543         chown $RUNAS_ID $DIR/$tdir
10544         local testfile=$DIR/$tdir/$tfile
10545         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10546                 error "setstripe failed"
10547         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10548                 error "getstripe failed"
10549         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10550         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10551
10552         local testfile2=${testfile}2
10553         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10554                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10555
10556         $RUNAS $MCREATE $testfile2
10557         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10558         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10559         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10560         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10561         [ $stripe_count -eq $STRIPECOUNT ] ||
10562                 error "stripe count $stripe_count != $STRIPECOUNT"
10563 }
10564 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10565
10566 compare_stripe_info1() {
10567         local stripe_index_all_zero=true
10568
10569         for num in 1 2 3 4; do
10570                 for count in $(seq 1 $STRIPE_COUNT); do
10571                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10572                                 local size=$((STRIPE_SIZE * num))
10573                                 local file=file"$num-$offset-$count"
10574                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10575                                 [[ $stripe_size -ne $size ]] &&
10576                                     error "$file: size $stripe_size != $size"
10577                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10578                                 # allow fewer stripes to be created, ORI-601
10579                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10580                                     error "$file: count $stripe_count != $count"
10581                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10582                                 [[ $stripe_index -ne 0 ]] &&
10583                                         stripe_index_all_zero=false
10584                         done
10585                 done
10586         done
10587         $stripe_index_all_zero &&
10588                 error "all files are being extracted starting from OST index 0"
10589         return 0
10590 }
10591
10592 have_xattrs_include() {
10593         tar --help | grep -q xattrs-include &&
10594                 echo --xattrs-include="lustre.*"
10595 }
10596
10597 test_102d() {
10598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10599         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10600
10601         XINC=$(have_xattrs_include)
10602         setup_test102
10603         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10604         cd $DIR/$tdir/$tdir
10605         compare_stripe_info1
10606 }
10607 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10608
10609 test_102f() {
10610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10611         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10612
10613         XINC=$(have_xattrs_include)
10614         setup_test102
10615         test_mkdir $DIR/$tdir.restore
10616         cd $DIR
10617         tar cf - --xattrs $tdir | tar xf - \
10618                 -C $DIR/$tdir.restore --xattrs $XINC
10619         cd $DIR/$tdir.restore/$tdir
10620         compare_stripe_info1
10621 }
10622 run_test 102f "tar copy files, not keep osts"
10623
10624 grow_xattr() {
10625         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10626                 skip "must have user_xattr"
10627         [ -z "$(which setfattr 2>/dev/null)" ] &&
10628                 skip_env "could not find setfattr"
10629         [ -z "$(which getfattr 2>/dev/null)" ] &&
10630                 skip_env "could not find getfattr"
10631
10632         local xsize=${1:-1024}  # in bytes
10633         local file=$DIR/$tfile
10634         local value="$(generate_string $xsize)"
10635         local xbig=trusted.big
10636         local toobig=$2
10637
10638         touch $file
10639         log "save $xbig on $file"
10640         if [ -z "$toobig" ]
10641         then
10642                 setfattr -n $xbig -v $value $file ||
10643                         error "saving $xbig on $file failed"
10644         else
10645                 setfattr -n $xbig -v $value $file &&
10646                         error "saving $xbig on $file succeeded"
10647                 return 0
10648         fi
10649
10650         local orig=$(get_xattr_value $xbig $file)
10651         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10652
10653         local xsml=trusted.sml
10654         log "save $xsml on $file"
10655         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10656
10657         local new=$(get_xattr_value $xbig $file)
10658         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10659
10660         log "grow $xsml on $file"
10661         setfattr -n $xsml -v "$value" $file ||
10662                 error "growing $xsml on $file failed"
10663
10664         new=$(get_xattr_value $xbig $file)
10665         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10666         log "$xbig still valid after growing $xsml"
10667
10668         rm -f $file
10669 }
10670
10671 test_102h() { # bug 15777
10672         grow_xattr 1024
10673 }
10674 run_test 102h "grow xattr from inside inode to external block"
10675
10676 test_102ha() {
10677         large_xattr_enabled || skip_env "ea_inode feature disabled"
10678
10679         echo "setting xattr of max xattr size: $(max_xattr_size)"
10680         grow_xattr $(max_xattr_size)
10681
10682         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10683         echo "This should fail:"
10684         grow_xattr $(($(max_xattr_size) + 10)) 1
10685 }
10686 run_test 102ha "grow xattr from inside inode to external inode"
10687
10688 test_102i() { # bug 17038
10689         [ -z "$(which getfattr 2>/dev/null)" ] &&
10690                 skip "could not find getfattr"
10691
10692         touch $DIR/$tfile
10693         ln -s $DIR/$tfile $DIR/${tfile}link
10694         getfattr -n trusted.lov $DIR/$tfile ||
10695                 error "lgetxattr on $DIR/$tfile failed"
10696         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10697                 grep -i "no such attr" ||
10698                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10699         rm -f $DIR/$tfile $DIR/${tfile}link
10700 }
10701 run_test 102i "lgetxattr test on symbolic link ============"
10702
10703 test_102j() {
10704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10705         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10706
10707         XINC=$(have_xattrs_include)
10708         setup_test102 "$RUNAS"
10709         chown $RUNAS_ID $DIR/$tdir
10710         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10711         cd $DIR/$tdir/$tdir
10712         compare_stripe_info1 "$RUNAS"
10713 }
10714 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10715
10716 test_102k() {
10717         [ -z "$(which setfattr 2>/dev/null)" ] &&
10718                 skip "could not find setfattr"
10719
10720         touch $DIR/$tfile
10721         # b22187 just check that does not crash for regular file.
10722         setfattr -n trusted.lov $DIR/$tfile
10723         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10724         local test_kdir=$DIR/$tdir
10725         test_mkdir $test_kdir
10726         local default_size=$($LFS getstripe -S $test_kdir)
10727         local default_count=$($LFS getstripe -c $test_kdir)
10728         local default_offset=$($LFS getstripe -i $test_kdir)
10729         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10730                 error 'dir setstripe failed'
10731         setfattr -n trusted.lov $test_kdir
10732         local stripe_size=$($LFS getstripe -S $test_kdir)
10733         local stripe_count=$($LFS getstripe -c $test_kdir)
10734         local stripe_offset=$($LFS getstripe -i $test_kdir)
10735         [ $stripe_size -eq $default_size ] ||
10736                 error "stripe size $stripe_size != $default_size"
10737         [ $stripe_count -eq $default_count ] ||
10738                 error "stripe count $stripe_count != $default_count"
10739         [ $stripe_offset -eq $default_offset ] ||
10740                 error "stripe offset $stripe_offset != $default_offset"
10741         rm -rf $DIR/$tfile $test_kdir
10742 }
10743 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10744
10745 test_102l() {
10746         [ -z "$(which getfattr 2>/dev/null)" ] &&
10747                 skip "could not find getfattr"
10748
10749         # LU-532 trusted. xattr is invisible to non-root
10750         local testfile=$DIR/$tfile
10751
10752         touch $testfile
10753
10754         echo "listxattr as user..."
10755         chown $RUNAS_ID $testfile
10756         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10757             grep -q "trusted" &&
10758                 error "$testfile trusted xattrs are user visible"
10759
10760         return 0;
10761 }
10762 run_test 102l "listxattr size test =================================="
10763
10764 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10765         local path=$DIR/$tfile
10766         touch $path
10767
10768         listxattr_size_check $path || error "listattr_size_check $path failed"
10769 }
10770 run_test 102m "Ensure listxattr fails on small bufffer ========"
10771
10772 cleanup_test102
10773
10774 getxattr() { # getxattr path name
10775         # Return the base64 encoding of the value of xattr name on path.
10776         local path=$1
10777         local name=$2
10778
10779         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10780         # file: $path
10781         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10782         #
10783         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10784
10785         getfattr --absolute-names --encoding=base64 --name=$name $path |
10786                 awk -F= -v name=$name '$1 == name {
10787                         print substr($0, index($0, "=") + 1);
10788         }'
10789 }
10790
10791 test_102n() { # LU-4101 mdt: protect internal xattrs
10792         [ -z "$(which setfattr 2>/dev/null)" ] &&
10793                 skip "could not find setfattr"
10794         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10795         then
10796                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10797         fi
10798
10799         local file0=$DIR/$tfile.0
10800         local file1=$DIR/$tfile.1
10801         local xattr0=$TMP/$tfile.0
10802         local xattr1=$TMP/$tfile.1
10803         local namelist="lov lma lmv link fid version som hsm"
10804         local name
10805         local value
10806
10807         rm -rf $file0 $file1 $xattr0 $xattr1
10808         touch $file0 $file1
10809
10810         # Get 'before' xattrs of $file1.
10811         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10812
10813         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10814                 namelist+=" lfsck_namespace"
10815         for name in $namelist; do
10816                 # Try to copy xattr from $file0 to $file1.
10817                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10818
10819                 setfattr --name=trusted.$name --value="$value" $file1 ||
10820                         error "setxattr 'trusted.$name' failed"
10821
10822                 # Try to set a garbage xattr.
10823                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10824
10825                 if [[ x$name == "xlov" ]]; then
10826                         setfattr --name=trusted.lov --value="$value" $file1 &&
10827                         error "setxattr invalid 'trusted.lov' success"
10828                 else
10829                         setfattr --name=trusted.$name --value="$value" $file1 ||
10830                                 error "setxattr invalid 'trusted.$name' failed"
10831                 fi
10832
10833                 # Try to remove the xattr from $file1. We don't care if this
10834                 # appears to succeed or fail, we just don't want there to be
10835                 # any changes or crashes.
10836                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10837         done
10838
10839         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10840         then
10841                 name="lfsck_ns"
10842                 # Try to copy xattr from $file0 to $file1.
10843                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10844
10845                 setfattr --name=trusted.$name --value="$value" $file1 ||
10846                         error "setxattr 'trusted.$name' failed"
10847
10848                 # Try to set a garbage xattr.
10849                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10850
10851                 setfattr --name=trusted.$name --value="$value" $file1 ||
10852                         error "setxattr 'trusted.$name' failed"
10853
10854                 # Try to remove the xattr from $file1. We don't care if this
10855                 # appears to succeed or fail, we just don't want there to be
10856                 # any changes or crashes.
10857                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10858         fi
10859
10860         # Get 'after' xattrs of file1.
10861         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10862
10863         if ! diff $xattr0 $xattr1; then
10864                 error "before and after xattrs of '$file1' differ"
10865         fi
10866
10867         rm -rf $file0 $file1 $xattr0 $xattr1
10868
10869         return 0
10870 }
10871 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10872
10873 test_102p() { # LU-4703 setxattr did not check ownership
10874         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10875                 skip "MDS needs to be at least 2.5.56"
10876
10877         local testfile=$DIR/$tfile
10878
10879         touch $testfile
10880
10881         echo "setfacl as user..."
10882         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10883         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10884
10885         echo "setfattr as user..."
10886         setfacl -m "u:$RUNAS_ID:---" $testfile
10887         $RUNAS setfattr -x system.posix_acl_access $testfile
10888         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10889 }
10890 run_test 102p "check setxattr(2) correctly fails without permission"
10891
10892 test_102q() {
10893         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10894                 skip "MDS needs to be at least 2.6.92"
10895
10896         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10897 }
10898 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10899
10900 test_102r() {
10901         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10902                 skip "MDS needs to be at least 2.6.93"
10903
10904         touch $DIR/$tfile || error "touch"
10905         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10906         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10907         rm $DIR/$tfile || error "rm"
10908
10909         #normal directory
10910         mkdir -p $DIR/$tdir || error "mkdir"
10911         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10912         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10913         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10914                 error "$testfile error deleting user.author1"
10915         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10916                 grep "user.$(basename $tdir)" &&
10917                 error "$tdir did not delete user.$(basename $tdir)"
10918         rmdir $DIR/$tdir || error "rmdir"
10919
10920         #striped directory
10921         test_mkdir $DIR/$tdir
10922         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10923         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10924         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10925                 error "$testfile error deleting user.author1"
10926         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10927                 grep "user.$(basename $tdir)" &&
10928                 error "$tdir did not delete user.$(basename $tdir)"
10929         rmdir $DIR/$tdir || error "rm striped dir"
10930 }
10931 run_test 102r "set EAs with empty values"
10932
10933 test_102s() {
10934         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10935                 skip "MDS needs to be at least 2.11.52"
10936
10937         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10938
10939         save_lustre_params client "llite.*.xattr_cache" > $save
10940
10941         for cache in 0 1; do
10942                 lctl set_param llite.*.xattr_cache=$cache
10943
10944                 rm -f $DIR/$tfile
10945                 touch $DIR/$tfile || error "touch"
10946                 for prefix in lustre security system trusted user; do
10947                         # Note getxattr() may fail with 'Operation not
10948                         # supported' or 'No such attribute' depending
10949                         # on prefix and cache.
10950                         getfattr -n $prefix.n102s $DIR/$tfile &&
10951                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10952                 done
10953         done
10954
10955         restore_lustre_params < $save
10956 }
10957 run_test 102s "getting nonexistent xattrs should fail"
10958
10959 test_102t() {
10960         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10961                 skip "MDS needs to be at least 2.11.52"
10962
10963         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10964
10965         save_lustre_params client "llite.*.xattr_cache" > $save
10966
10967         for cache in 0 1; do
10968                 lctl set_param llite.*.xattr_cache=$cache
10969
10970                 for buf_size in 0 256; do
10971                         rm -f $DIR/$tfile
10972                         touch $DIR/$tfile || error "touch"
10973                         setfattr -n user.multiop $DIR/$tfile
10974                         $MULTIOP $DIR/$tfile oa$buf_size ||
10975                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10976                 done
10977         done
10978
10979         restore_lustre_params < $save
10980 }
10981 run_test 102t "zero length xattr values handled correctly"
10982
10983 run_acl_subtest()
10984 {
10985     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10986     return $?
10987 }
10988
10989 test_103a() {
10990         [ "$UID" != 0 ] && skip "must run as root"
10991         $GSS && skip_env "could not run under gss"
10992         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10993                 skip_env "must have acl enabled"
10994         [ -z "$(which setfacl 2>/dev/null)" ] &&
10995                 skip_env "could not find setfacl"
10996         remote_mds_nodsh && skip "remote MDS with nodsh"
10997
10998         gpasswd -a daemon bin                           # LU-5641
10999         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11000
11001         declare -a identity_old
11002
11003         for num in $(seq $MDSCOUNT); do
11004                 switch_identity $num true || identity_old[$num]=$?
11005         done
11006
11007         SAVE_UMASK=$(umask)
11008         umask 0022
11009         mkdir -p $DIR/$tdir
11010         cd $DIR/$tdir
11011
11012         echo "performing cp ..."
11013         run_acl_subtest cp || error "run_acl_subtest cp failed"
11014         echo "performing getfacl-noacl..."
11015         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11016         echo "performing misc..."
11017         run_acl_subtest misc || error  "misc test failed"
11018         echo "performing permissions..."
11019         run_acl_subtest permissions || error "permissions failed"
11020         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11021         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11022                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11023                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11024         then
11025                 echo "performing permissions xattr..."
11026                 run_acl_subtest permissions_xattr ||
11027                         error "permissions_xattr failed"
11028         fi
11029         echo "performing setfacl..."
11030         run_acl_subtest setfacl || error  "setfacl test failed"
11031
11032         # inheritance test got from HP
11033         echo "performing inheritance..."
11034         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11035         chmod +x make-tree || error "chmod +x failed"
11036         run_acl_subtest inheritance || error "inheritance test failed"
11037         rm -f make-tree
11038
11039         echo "LU-974 ignore umask when acl is enabled..."
11040         run_acl_subtest 974 || error "LU-974 umask test failed"
11041         if [ $MDSCOUNT -ge 2 ]; then
11042                 run_acl_subtest 974_remote ||
11043                         error "LU-974 umask test failed under remote dir"
11044         fi
11045
11046         echo "LU-2561 newly created file is same size as directory..."
11047         if [ "$mds1_FSTYPE" != "zfs" ]; then
11048                 run_acl_subtest 2561 || error "LU-2561 test failed"
11049         else
11050                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11051         fi
11052
11053         run_acl_subtest 4924 || error "LU-4924 test failed"
11054
11055         cd $SAVE_PWD
11056         umask $SAVE_UMASK
11057
11058         for num in $(seq $MDSCOUNT); do
11059                 if [ "${identity_old[$num]}" = 1 ]; then
11060                         switch_identity $num false || identity_old[$num]=$?
11061                 fi
11062         done
11063 }
11064 run_test 103a "acl test"
11065
11066 test_103b() {
11067         declare -a pids
11068         local U
11069
11070         for U in {0..511}; do
11071                 {
11072                 local O=$(printf "%04o" $U)
11073
11074                 umask $(printf "%04o" $((511 ^ $O)))
11075                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11076                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11077
11078                 (( $S == ($O & 0666) )) ||
11079                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11080
11081                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11082                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11083                 (( $S == ($O & 0666) )) ||
11084                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11085
11086                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11087                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11088                 (( $S == ($O & 0666) )) ||
11089                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11090                 rm -f $DIR/$tfile.[smp]$0
11091                 } &
11092                 local pid=$!
11093
11094                 # limit the concurrently running threads to 64. LU-11878
11095                 local idx=$((U % 64))
11096                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11097                 pids[idx]=$pid
11098         done
11099         wait
11100 }
11101 run_test 103b "umask lfs setstripe"
11102
11103 test_103c() {
11104         mkdir -p $DIR/$tdir
11105         cp -rp $DIR/$tdir $DIR/$tdir.bak
11106
11107         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11108                 error "$DIR/$tdir shouldn't contain default ACL"
11109         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11110                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11111         true
11112 }
11113 run_test 103c "'cp -rp' won't set empty acl"
11114
11115 test_103e() {
11116         local numacl
11117         local fileacl
11118         local saved_debug=$($LCTL get_param -n debug)
11119
11120         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11121                 skip "MDS needs to be at least 2.14.0"
11122
11123         large_xattr_enabled || skip_env "ea_inode feature disabled"
11124
11125         mkdir -p $DIR/$tdir
11126         # add big LOV EA to cause reply buffer overflow earlier
11127         $LFS setstripe -C 1000 $DIR/$tdir
11128         lctl set_param mdc.*-mdc*.stats=clear
11129
11130         $LCTL set_param debug=0
11131         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11132         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11133
11134         # add a large number of default ACLs (expect 8000+ for 2.13+)
11135         for U in {2..7000}; do
11136                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11137                         error "Able to add just $U default ACLs"
11138         done
11139         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11140         echo "$numacl default ACLs created"
11141
11142         stat $DIR/$tdir || error "Cannot stat directory"
11143         # check file creation
11144         touch $DIR/$tdir/$tfile ||
11145                 error "failed to create $tfile with $numacl default ACLs"
11146         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11147         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11148         echo "$fileacl ACLs were inherited"
11149         (( $fileacl == $numacl )) ||
11150                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11151         # check that new ACLs creation adds new ACLs to inherited ACLs
11152         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11153                 error "Cannot set new ACL"
11154         numacl=$((numacl + 1))
11155         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11156         (( $fileacl == $numacl )) ||
11157                 error "failed to add new ACL: $fileacl != $numacl as expected"
11158         # adds more ACLs to a file to reach their maximum at 8000+
11159         numacl=0
11160         for U in {20000..25000}; do
11161                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11162                 numacl=$((numacl + 1))
11163         done
11164         echo "Added $numacl more ACLs to the file"
11165         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11166         echo "Total $fileacl ACLs in file"
11167         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11168         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11169         rmdir $DIR/$tdir || error "Cannot remove directory"
11170 }
11171 run_test 103e "inheritance of big amount of default ACLs"
11172
11173 test_103f() {
11174         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11175                 skip "MDS needs to be at least 2.14.51"
11176
11177         large_xattr_enabled || skip_env "ea_inode feature disabled"
11178
11179         # enable changelog to consume more internal MDD buffers
11180         changelog_register
11181
11182         mkdir -p $DIR/$tdir
11183         # add big LOV EA
11184         $LFS setstripe -C 1000 $DIR/$tdir
11185         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11186         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11187         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11188         rmdir $DIR/$tdir || error "Cannot remove directory"
11189 }
11190 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11191
11192 test_104a() {
11193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11194
11195         touch $DIR/$tfile
11196         lfs df || error "lfs df failed"
11197         lfs df -ih || error "lfs df -ih failed"
11198         lfs df -h $DIR || error "lfs df -h $DIR failed"
11199         lfs df -i $DIR || error "lfs df -i $DIR failed"
11200         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11201         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11202
11203         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11204         lctl --device %$OSC deactivate
11205         lfs df || error "lfs df with deactivated OSC failed"
11206         lctl --device %$OSC activate
11207         # wait the osc back to normal
11208         wait_osc_import_ready client ost
11209
11210         lfs df || error "lfs df with reactivated OSC failed"
11211         rm -f $DIR/$tfile
11212 }
11213 run_test 104a "lfs df [-ih] [path] test ========================="
11214
11215 test_104b() {
11216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11217         [ $RUNAS_ID -eq $UID ] &&
11218                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11219
11220         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11221                         grep "Permission denied" | wc -l)))
11222         if [ $denied_cnt -ne 0 ]; then
11223                 error "lfs check servers test failed"
11224         fi
11225 }
11226 run_test 104b "$RUNAS lfs check servers test ===================="
11227
11228 #
11229 # Verify $1 is within range of $2.
11230 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11231 # $1 is <= 2% of $2. Else Fail.
11232 #
11233 value_in_range() {
11234         # Strip all units (M, G, T)
11235         actual=$(echo $1 | tr -d A-Z)
11236         expect=$(echo $2 | tr -d A-Z)
11237
11238         expect_lo=$(($expect * 98 / 100)) # 2% below
11239         expect_hi=$(($expect * 102 / 100)) # 2% above
11240
11241         # permit 2% drift above and below
11242         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11243 }
11244
11245 test_104c() {
11246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11247         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11248
11249         local ost_param="osd-zfs.$FSNAME-OST0000."
11250         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11251         local ofacets=$(get_facets OST)
11252         local mfacets=$(get_facets MDS)
11253         local saved_ost_blocks=
11254         local saved_mdt_blocks=
11255
11256         echo "Before recordsize change"
11257         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11258         df=($(df -h | grep "/mnt/lustre"$))
11259
11260         # For checking.
11261         echo "lfs output : ${lfs_df[*]}"
11262         echo "df  output : ${df[*]}"
11263
11264         for facet in ${ofacets//,/ }; do
11265                 if [ -z $saved_ost_blocks ]; then
11266                         saved_ost_blocks=$(do_facet $facet \
11267                                 lctl get_param -n $ost_param.blocksize)
11268                         echo "OST Blocksize: $saved_ost_blocks"
11269                 fi
11270                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11271                 do_facet $facet zfs set recordsize=32768 $ost
11272         done
11273
11274         # BS too small. Sufficient for functional testing.
11275         for facet in ${mfacets//,/ }; do
11276                 if [ -z $saved_mdt_blocks ]; then
11277                         saved_mdt_blocks=$(do_facet $facet \
11278                                 lctl get_param -n $mdt_param.blocksize)
11279                         echo "MDT Blocksize: $saved_mdt_blocks"
11280                 fi
11281                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11282                 do_facet $facet zfs set recordsize=32768 $mdt
11283         done
11284
11285         # Give new values chance to reflect change
11286         sleep 2
11287
11288         echo "After recordsize change"
11289         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11290         df_after=($(df -h | grep "/mnt/lustre"$))
11291
11292         # For checking.
11293         echo "lfs output : ${lfs_df_after[*]}"
11294         echo "df  output : ${df_after[*]}"
11295
11296         # Verify lfs df
11297         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11298                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11299         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11300                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11301         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11302                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11303
11304         # Verify df
11305         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11306                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11307         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11308                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11309         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11310                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11311
11312         # Restore MDT recordize back to original
11313         for facet in ${mfacets//,/ }; do
11314                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11315                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11316         done
11317
11318         # Restore OST recordize back to original
11319         for facet in ${ofacets//,/ }; do
11320                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11321                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11322         done
11323
11324         return 0
11325 }
11326 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11327
11328 test_105a() {
11329         # doesn't work on 2.4 kernels
11330         touch $DIR/$tfile
11331         if $(flock_is_enabled); then
11332                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11333         else
11334                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11335         fi
11336         rm -f $DIR/$tfile
11337 }
11338 run_test 105a "flock when mounted without -o flock test ========"
11339
11340 test_105b() {
11341         touch $DIR/$tfile
11342         if $(flock_is_enabled); then
11343                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11344         else
11345                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11346         fi
11347         rm -f $DIR/$tfile
11348 }
11349 run_test 105b "fcntl when mounted without -o flock test ========"
11350
11351 test_105c() {
11352         touch $DIR/$tfile
11353         if $(flock_is_enabled); then
11354                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11355         else
11356                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11357         fi
11358         rm -f $DIR/$tfile
11359 }
11360 run_test 105c "lockf when mounted without -o flock test"
11361
11362 test_105d() { # bug 15924
11363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11364
11365         test_mkdir $DIR/$tdir
11366         flock_is_enabled || skip_env "mount w/o flock enabled"
11367         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11368         $LCTL set_param fail_loc=0x80000315
11369         flocks_test 2 $DIR/$tdir
11370 }
11371 run_test 105d "flock race (should not freeze) ========"
11372
11373 test_105e() { # bug 22660 && 22040
11374         flock_is_enabled || skip_env "mount w/o flock enabled"
11375
11376         touch $DIR/$tfile
11377         flocks_test 3 $DIR/$tfile
11378 }
11379 run_test 105e "Two conflicting flocks from same process"
11380
11381 test_106() { #bug 10921
11382         test_mkdir $DIR/$tdir
11383         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11384         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11385 }
11386 run_test 106 "attempt exec of dir followed by chown of that dir"
11387
11388 test_107() {
11389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11390
11391         CDIR=`pwd`
11392         local file=core
11393
11394         cd $DIR
11395         rm -f $file
11396
11397         local save_pattern=$(sysctl -n kernel.core_pattern)
11398         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11399         sysctl -w kernel.core_pattern=$file
11400         sysctl -w kernel.core_uses_pid=0
11401
11402         ulimit -c unlimited
11403         sleep 60 &
11404         SLEEPPID=$!
11405
11406         sleep 1
11407
11408         kill -s 11 $SLEEPPID
11409         wait $SLEEPPID
11410         if [ -e $file ]; then
11411                 size=`stat -c%s $file`
11412                 [ $size -eq 0 ] && error "Fail to create core file $file"
11413         else
11414                 error "Fail to create core file $file"
11415         fi
11416         rm -f $file
11417         sysctl -w kernel.core_pattern=$save_pattern
11418         sysctl -w kernel.core_uses_pid=$save_uses_pid
11419         cd $CDIR
11420 }
11421 run_test 107 "Coredump on SIG"
11422
11423 test_110() {
11424         test_mkdir $DIR/$tdir
11425         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11426         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11427                 error "mkdir with 256 char should fail, but did not"
11428         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11429                 error "create with 255 char failed"
11430         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11431                 error "create with 256 char should fail, but did not"
11432
11433         ls -l $DIR/$tdir
11434         rm -rf $DIR/$tdir
11435 }
11436 run_test 110 "filename length checking"
11437
11438 #
11439 # Purpose: To verify dynamic thread (OSS) creation.
11440 #
11441 test_115() {
11442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11443         remote_ost_nodsh && skip "remote OST with nodsh"
11444
11445         # Lustre does not stop service threads once they are started.
11446         # Reset number of running threads to default.
11447         stopall
11448         setupall
11449
11450         local OSTIO_pre
11451         local save_params="$TMP/sanity-$TESTNAME.parameters"
11452
11453         # Get ll_ost_io count before I/O
11454         OSTIO_pre=$(do_facet ost1 \
11455                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11456         # Exit if lustre is not running (ll_ost_io not running).
11457         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11458
11459         echo "Starting with $OSTIO_pre threads"
11460         local thread_max=$((OSTIO_pre * 2))
11461         local rpc_in_flight=$((thread_max * 2))
11462         # Number of I/O Process proposed to be started.
11463         local nfiles
11464         local facets=$(get_facets OST)
11465
11466         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11467         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11468
11469         # Set in_flight to $rpc_in_flight
11470         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11471                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11472         nfiles=${rpc_in_flight}
11473         # Set ost thread_max to $thread_max
11474         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11475
11476         # 5 Minutes should be sufficient for max number of OSS
11477         # threads(thread_max) to be created.
11478         local timeout=300
11479
11480         # Start I/O.
11481         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11482         test_mkdir $DIR/$tdir
11483         for i in $(seq $nfiles); do
11484                 local file=$DIR/$tdir/${tfile}-$i
11485                 $LFS setstripe -c -1 -i 0 $file
11486                 ($WTL $file $timeout)&
11487         done
11488
11489         # I/O Started - Wait for thread_started to reach thread_max or report
11490         # error if thread_started is more than thread_max.
11491         echo "Waiting for thread_started to reach thread_max"
11492         local thread_started=0
11493         local end_time=$((SECONDS + timeout))
11494
11495         while [ $SECONDS -le $end_time ] ; do
11496                 echo -n "."
11497                 # Get ost i/o thread_started count.
11498                 thread_started=$(do_facet ost1 \
11499                         "$LCTL get_param \
11500                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11501                 # Break out if thread_started is equal/greater than thread_max
11502                 if [[ $thread_started -ge $thread_max ]]; then
11503                         echo ll_ost_io thread_started $thread_started, \
11504                                 equal/greater than thread_max $thread_max
11505                         break
11506                 fi
11507                 sleep 1
11508         done
11509
11510         # Cleanup - We have the numbers, Kill i/o jobs if running.
11511         jobcount=($(jobs -p))
11512         for i in $(seq 0 $((${#jobcount[@]}-1)))
11513         do
11514                 kill -9 ${jobcount[$i]}
11515                 if [ $? -ne 0 ] ; then
11516                         echo Warning: \
11517                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11518                 fi
11519         done
11520
11521         # Cleanup files left by WTL binary.
11522         for i in $(seq $nfiles); do
11523                 local file=$DIR/$tdir/${tfile}-$i
11524                 rm -rf $file
11525                 if [ $? -ne 0 ] ; then
11526                         echo "Warning: Failed to delete file $file"
11527                 fi
11528         done
11529
11530         restore_lustre_params <$save_params
11531         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11532
11533         # Error out if no new thread has started or Thread started is greater
11534         # than thread max.
11535         if [[ $thread_started -le $OSTIO_pre ||
11536                         $thread_started -gt $thread_max ]]; then
11537                 error "ll_ost_io: thread_started $thread_started" \
11538                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11539                       "No new thread started or thread started greater " \
11540                       "than thread_max."
11541         fi
11542 }
11543 run_test 115 "verify dynamic thread creation===================="
11544
11545 free_min_max () {
11546         wait_delete_completed
11547         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11548         echo "OST kbytes available: ${AVAIL[@]}"
11549         MAXV=${AVAIL[0]}
11550         MAXI=0
11551         MINV=${AVAIL[0]}
11552         MINI=0
11553         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11554                 #echo OST $i: ${AVAIL[i]}kb
11555                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11556                         MAXV=${AVAIL[i]}
11557                         MAXI=$i
11558                 fi
11559                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11560                         MINV=${AVAIL[i]}
11561                         MINI=$i
11562                 fi
11563         done
11564         echo "Min free space: OST $MINI: $MINV"
11565         echo "Max free space: OST $MAXI: $MAXV"
11566 }
11567
11568 test_116a() { # was previously test_116()
11569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11570         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11571         remote_mds_nodsh && skip "remote MDS with nodsh"
11572
11573         echo -n "Free space priority "
11574         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11575                 head -n1
11576         declare -a AVAIL
11577         free_min_max
11578
11579         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11580         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11581         trap simple_cleanup_common EXIT
11582
11583         # Check if we need to generate uneven OSTs
11584         test_mkdir -p $DIR/$tdir/OST${MINI}
11585         local FILL=$((MINV / 4))
11586         local DIFF=$((MAXV - MINV))
11587         local DIFF2=$((DIFF * 100 / MINV))
11588
11589         local threshold=$(do_facet $SINGLEMDS \
11590                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11591         threshold=${threshold%%%}
11592         echo -n "Check for uneven OSTs: "
11593         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11594
11595         if [[ $DIFF2 -gt $threshold ]]; then
11596                 echo "ok"
11597                 echo "Don't need to fill OST$MINI"
11598         else
11599                 # generate uneven OSTs. Write 2% over the QOS threshold value
11600                 echo "no"
11601                 DIFF=$((threshold - DIFF2 + 2))
11602                 DIFF2=$((MINV * DIFF / 100))
11603                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11604                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11605                         error "setstripe failed"
11606                 DIFF=$((DIFF2 / 2048))
11607                 i=0
11608                 while [ $i -lt $DIFF ]; do
11609                         i=$((i + 1))
11610                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11611                                 bs=2M count=1 2>/dev/null
11612                         echo -n .
11613                 done
11614                 echo .
11615                 sync
11616                 sleep_maxage
11617                 free_min_max
11618         fi
11619
11620         DIFF=$((MAXV - MINV))
11621         DIFF2=$((DIFF * 100 / MINV))
11622         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11623         if [ $DIFF2 -gt $threshold ]; then
11624                 echo "ok"
11625         else
11626                 echo "failed - QOS mode won't be used"
11627                 simple_cleanup_common
11628                 skip "QOS imbalance criteria not met"
11629         fi
11630
11631         MINI1=$MINI
11632         MINV1=$MINV
11633         MAXI1=$MAXI
11634         MAXV1=$MAXV
11635
11636         # now fill using QOS
11637         $LFS setstripe -c 1 $DIR/$tdir
11638         FILL=$((FILL / 200))
11639         if [ $FILL -gt 600 ]; then
11640                 FILL=600
11641         fi
11642         echo "writing $FILL files to QOS-assigned OSTs"
11643         i=0
11644         while [ $i -lt $FILL ]; do
11645                 i=$((i + 1))
11646                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11647                         count=1 2>/dev/null
11648                 echo -n .
11649         done
11650         echo "wrote $i 200k files"
11651         sync
11652         sleep_maxage
11653
11654         echo "Note: free space may not be updated, so measurements might be off"
11655         free_min_max
11656         DIFF2=$((MAXV - MINV))
11657         echo "free space delta: orig $DIFF final $DIFF2"
11658         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11659         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11660         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11661         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11662         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11663         if [[ $DIFF -gt 0 ]]; then
11664                 FILL=$((DIFF2 * 100 / DIFF - 100))
11665                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11666         fi
11667
11668         # Figure out which files were written where
11669         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11670                awk '/'$MINI1': / {print $2; exit}')
11671         echo $UUID
11672         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11673         echo "$MINC files created on smaller OST $MINI1"
11674         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11675                awk '/'$MAXI1': / {print $2; exit}')
11676         echo $UUID
11677         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11678         echo "$MAXC files created on larger OST $MAXI1"
11679         if [[ $MINC -gt 0 ]]; then
11680                 FILL=$((MAXC * 100 / MINC - 100))
11681                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11682         fi
11683         [[ $MAXC -gt $MINC ]] ||
11684                 error_ignore LU-9 "stripe QOS didn't balance free space"
11685         simple_cleanup_common
11686 }
11687 run_test 116a "stripe QOS: free space balance ==================="
11688
11689 test_116b() { # LU-2093
11690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11691         remote_mds_nodsh && skip "remote MDS with nodsh"
11692
11693 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11694         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11695                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11696         [ -z "$old_rr" ] && skip "no QOS"
11697         do_facet $SINGLEMDS lctl set_param \
11698                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11699         mkdir -p $DIR/$tdir
11700         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11701         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11702         do_facet $SINGLEMDS lctl set_param fail_loc=0
11703         rm -rf $DIR/$tdir
11704         do_facet $SINGLEMDS lctl set_param \
11705                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11706 }
11707 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11708
11709 test_117() # bug 10891
11710 {
11711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11712
11713         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11714         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11715         lctl set_param fail_loc=0x21e
11716         > $DIR/$tfile || error "truncate failed"
11717         lctl set_param fail_loc=0
11718         echo "Truncate succeeded."
11719         rm -f $DIR/$tfile
11720 }
11721 run_test 117 "verify osd extend =========="
11722
11723 NO_SLOW_RESENDCOUNT=4
11724 export OLD_RESENDCOUNT=""
11725 set_resend_count () {
11726         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11727         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11728         lctl set_param -n $PROC_RESENDCOUNT $1
11729         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11730 }
11731
11732 # for reduce test_118* time (b=14842)
11733 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11734
11735 # Reset async IO behavior after error case
11736 reset_async() {
11737         FILE=$DIR/reset_async
11738
11739         # Ensure all OSCs are cleared
11740         $LFS setstripe -c -1 $FILE
11741         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11742         sync
11743         rm $FILE
11744 }
11745
11746 test_118a() #bug 11710
11747 {
11748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11749
11750         reset_async
11751
11752         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11753         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11754         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11755
11756         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11757                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11758                 return 1;
11759         fi
11760         rm -f $DIR/$tfile
11761 }
11762 run_test 118a "verify O_SYNC works =========="
11763
11764 test_118b()
11765 {
11766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11767         remote_ost_nodsh && skip "remote OST with nodsh"
11768
11769         reset_async
11770
11771         #define OBD_FAIL_SRV_ENOENT 0x217
11772         set_nodes_failloc "$(osts_nodes)" 0x217
11773         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11774         RC=$?
11775         set_nodes_failloc "$(osts_nodes)" 0
11776         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11777         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11778                     grep -c writeback)
11779
11780         if [[ $RC -eq 0 ]]; then
11781                 error "Must return error due to dropped pages, rc=$RC"
11782                 return 1;
11783         fi
11784
11785         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11786                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11787                 return 1;
11788         fi
11789
11790         echo "Dirty pages not leaked on ENOENT"
11791
11792         # Due to the above error the OSC will issue all RPCs syncronously
11793         # until a subsequent RPC completes successfully without error.
11794         $MULTIOP $DIR/$tfile Ow4096yc
11795         rm -f $DIR/$tfile
11796
11797         return 0
11798 }
11799 run_test 118b "Reclaim dirty pages on fatal error =========="
11800
11801 test_118c()
11802 {
11803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11804
11805         # for 118c, restore the original resend count, LU-1940
11806         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11807                                 set_resend_count $OLD_RESENDCOUNT
11808         remote_ost_nodsh && skip "remote OST with nodsh"
11809
11810         reset_async
11811
11812         #define OBD_FAIL_OST_EROFS               0x216
11813         set_nodes_failloc "$(osts_nodes)" 0x216
11814
11815         # multiop should block due to fsync until pages are written
11816         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11817         MULTIPID=$!
11818         sleep 1
11819
11820         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11821                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11822         fi
11823
11824         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11825                     grep -c writeback)
11826         if [[ $WRITEBACK -eq 0 ]]; then
11827                 error "No page in writeback, writeback=$WRITEBACK"
11828         fi
11829
11830         set_nodes_failloc "$(osts_nodes)" 0
11831         wait $MULTIPID
11832         RC=$?
11833         if [[ $RC -ne 0 ]]; then
11834                 error "Multiop fsync failed, rc=$RC"
11835         fi
11836
11837         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11838         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11839                     grep -c writeback)
11840         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11841                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11842         fi
11843
11844         rm -f $DIR/$tfile
11845         echo "Dirty pages flushed via fsync on EROFS"
11846         return 0
11847 }
11848 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11849
11850 # continue to use small resend count to reduce test_118* time (b=14842)
11851 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11852
11853 test_118d()
11854 {
11855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11856         remote_ost_nodsh && skip "remote OST with nodsh"
11857
11858         reset_async
11859
11860         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11861         set_nodes_failloc "$(osts_nodes)" 0x214
11862         # multiop should block due to fsync until pages are written
11863         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11864         MULTIPID=$!
11865         sleep 1
11866
11867         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11868                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11869         fi
11870
11871         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11872                     grep -c writeback)
11873         if [[ $WRITEBACK -eq 0 ]]; then
11874                 error "No page in writeback, writeback=$WRITEBACK"
11875         fi
11876
11877         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11878         set_nodes_failloc "$(osts_nodes)" 0
11879
11880         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11881         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11882                     grep -c writeback)
11883         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11884                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11885         fi
11886
11887         rm -f $DIR/$tfile
11888         echo "Dirty pages gaurenteed flushed via fsync"
11889         return 0
11890 }
11891 run_test 118d "Fsync validation inject a delay of the bulk =========="
11892
11893 test_118f() {
11894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11895
11896         reset_async
11897
11898         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11899         lctl set_param fail_loc=0x8000040a
11900
11901         # Should simulate EINVAL error which is fatal
11902         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11903         RC=$?
11904         if [[ $RC -eq 0 ]]; then
11905                 error "Must return error due to dropped pages, rc=$RC"
11906         fi
11907
11908         lctl set_param fail_loc=0x0
11909
11910         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11911         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11912         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11913                     grep -c writeback)
11914         if [[ $LOCKED -ne 0 ]]; then
11915                 error "Locked pages remain in cache, locked=$LOCKED"
11916         fi
11917
11918         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11919                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11920         fi
11921
11922         rm -f $DIR/$tfile
11923         echo "No pages locked after fsync"
11924
11925         reset_async
11926         return 0
11927 }
11928 run_test 118f "Simulate unrecoverable OSC side error =========="
11929
11930 test_118g() {
11931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11932
11933         reset_async
11934
11935         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11936         lctl set_param fail_loc=0x406
11937
11938         # simulate local -ENOMEM
11939         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11940         RC=$?
11941
11942         lctl set_param fail_loc=0
11943         if [[ $RC -eq 0 ]]; then
11944                 error "Must return error due to dropped pages, rc=$RC"
11945         fi
11946
11947         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11948         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11949         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11950                         grep -c writeback)
11951         if [[ $LOCKED -ne 0 ]]; then
11952                 error "Locked pages remain in cache, locked=$LOCKED"
11953         fi
11954
11955         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11956                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11957         fi
11958
11959         rm -f $DIR/$tfile
11960         echo "No pages locked after fsync"
11961
11962         reset_async
11963         return 0
11964 }
11965 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11966
11967 test_118h() {
11968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11969         remote_ost_nodsh && skip "remote OST with nodsh"
11970
11971         reset_async
11972
11973         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11974         set_nodes_failloc "$(osts_nodes)" 0x20e
11975         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11976         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11977         RC=$?
11978
11979         set_nodes_failloc "$(osts_nodes)" 0
11980         if [[ $RC -eq 0 ]]; then
11981                 error "Must return error due to dropped pages, rc=$RC"
11982         fi
11983
11984         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11985         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11986         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11987                     grep -c writeback)
11988         if [[ $LOCKED -ne 0 ]]; then
11989                 error "Locked pages remain in cache, locked=$LOCKED"
11990         fi
11991
11992         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11993                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11994         fi
11995
11996         rm -f $DIR/$tfile
11997         echo "No pages locked after fsync"
11998
11999         return 0
12000 }
12001 run_test 118h "Verify timeout in handling recoverables errors  =========="
12002
12003 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12004
12005 test_118i() {
12006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12007         remote_ost_nodsh && skip "remote OST with nodsh"
12008
12009         reset_async
12010
12011         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12012         set_nodes_failloc "$(osts_nodes)" 0x20e
12013
12014         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12015         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12016         PID=$!
12017         sleep 5
12018         set_nodes_failloc "$(osts_nodes)" 0
12019
12020         wait $PID
12021         RC=$?
12022         if [[ $RC -ne 0 ]]; then
12023                 error "got error, but should be not, rc=$RC"
12024         fi
12025
12026         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12027         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12028         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12029         if [[ $LOCKED -ne 0 ]]; then
12030                 error "Locked pages remain in cache, locked=$LOCKED"
12031         fi
12032
12033         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12034                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12035         fi
12036
12037         rm -f $DIR/$tfile
12038         echo "No pages locked after fsync"
12039
12040         return 0
12041 }
12042 run_test 118i "Fix error before timeout in recoverable error  =========="
12043
12044 [ "$SLOW" = "no" ] && set_resend_count 4
12045
12046 test_118j() {
12047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12048         remote_ost_nodsh && skip "remote OST with nodsh"
12049
12050         reset_async
12051
12052         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12053         set_nodes_failloc "$(osts_nodes)" 0x220
12054
12055         # return -EIO from OST
12056         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12057         RC=$?
12058         set_nodes_failloc "$(osts_nodes)" 0x0
12059         if [[ $RC -eq 0 ]]; then
12060                 error "Must return error due to dropped pages, rc=$RC"
12061         fi
12062
12063         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12064         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12065         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12066         if [[ $LOCKED -ne 0 ]]; then
12067                 error "Locked pages remain in cache, locked=$LOCKED"
12068         fi
12069
12070         # in recoverable error on OST we want resend and stay until it finished
12071         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12072                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12073         fi
12074
12075         rm -f $DIR/$tfile
12076         echo "No pages locked after fsync"
12077
12078         return 0
12079 }
12080 run_test 118j "Simulate unrecoverable OST side error =========="
12081
12082 test_118k()
12083 {
12084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12085         remote_ost_nodsh && skip "remote OSTs with nodsh"
12086
12087         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12088         set_nodes_failloc "$(osts_nodes)" 0x20e
12089         test_mkdir $DIR/$tdir
12090
12091         for ((i=0;i<10;i++)); do
12092                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12093                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12094                 SLEEPPID=$!
12095                 sleep 0.500s
12096                 kill $SLEEPPID
12097                 wait $SLEEPPID
12098         done
12099
12100         set_nodes_failloc "$(osts_nodes)" 0
12101         rm -rf $DIR/$tdir
12102 }
12103 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12104
12105 test_118l() # LU-646
12106 {
12107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12108
12109         test_mkdir $DIR/$tdir
12110         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12111         rm -rf $DIR/$tdir
12112 }
12113 run_test 118l "fsync dir"
12114
12115 test_118m() # LU-3066
12116 {
12117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12118
12119         test_mkdir $DIR/$tdir
12120         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12121         rm -rf $DIR/$tdir
12122 }
12123 run_test 118m "fdatasync dir ========="
12124
12125 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12126
12127 test_118n()
12128 {
12129         local begin
12130         local end
12131
12132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12133         remote_ost_nodsh && skip "remote OSTs with nodsh"
12134
12135         # Sleep to avoid a cached response.
12136         #define OBD_STATFS_CACHE_SECONDS 1
12137         sleep 2
12138
12139         # Inject a 10 second delay in the OST_STATFS handler.
12140         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12141         set_nodes_failloc "$(osts_nodes)" 0x242
12142
12143         begin=$SECONDS
12144         stat --file-system $MOUNT > /dev/null
12145         end=$SECONDS
12146
12147         set_nodes_failloc "$(osts_nodes)" 0
12148
12149         if ((end - begin > 20)); then
12150             error "statfs took $((end - begin)) seconds, expected 10"
12151         fi
12152 }
12153 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12154
12155 test_119a() # bug 11737
12156 {
12157         BSIZE=$((512 * 1024))
12158         directio write $DIR/$tfile 0 1 $BSIZE
12159         # We ask to read two blocks, which is more than a file size.
12160         # directio will indicate an error when requested and actual
12161         # sizes aren't equeal (a normal situation in this case) and
12162         # print actual read amount.
12163         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12164         if [ "$NOB" != "$BSIZE" ]; then
12165                 error "read $NOB bytes instead of $BSIZE"
12166         fi
12167         rm -f $DIR/$tfile
12168 }
12169 run_test 119a "Short directIO read must return actual read amount"
12170
12171 test_119b() # bug 11737
12172 {
12173         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12174
12175         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12176         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12177         sync
12178         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12179                 error "direct read failed"
12180         rm -f $DIR/$tfile
12181 }
12182 run_test 119b "Sparse directIO read must return actual read amount"
12183
12184 test_119c() # bug 13099
12185 {
12186         BSIZE=1048576
12187         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12188         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12189         rm -f $DIR/$tfile
12190 }
12191 run_test 119c "Testing for direct read hitting hole"
12192
12193 test_119d() # bug 15950
12194 {
12195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12196
12197         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12198         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12199         BSIZE=1048576
12200         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12201         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12202         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12203         lctl set_param fail_loc=0x40d
12204         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12205         pid_dio=$!
12206         sleep 1
12207         cat $DIR/$tfile > /dev/null &
12208         lctl set_param fail_loc=0
12209         pid_reads=$!
12210         wait $pid_dio
12211         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12212         sleep 2
12213         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12214         error "the read rpcs have not completed in 2s"
12215         rm -f $DIR/$tfile
12216         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12217 }
12218 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12219
12220 test_120a() {
12221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12222         remote_mds_nodsh && skip "remote MDS with nodsh"
12223         test_mkdir -i0 -c1 $DIR/$tdir
12224         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12225                 skip_env "no early lock cancel on server"
12226
12227         lru_resize_disable mdc
12228         lru_resize_disable osc
12229         cancel_lru_locks mdc
12230         # asynchronous object destroy at MDT could cause bl ast to client
12231         cancel_lru_locks osc
12232
12233         stat $DIR/$tdir > /dev/null
12234         can1=$(do_facet mds1 \
12235                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12236                awk '/ldlm_cancel/ {print $2}')
12237         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12238                awk '/ldlm_bl_callback/ {print $2}')
12239         test_mkdir -i0 -c1 $DIR/$tdir/d1
12240         can2=$(do_facet mds1 \
12241                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12242                awk '/ldlm_cancel/ {print $2}')
12243         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12244                awk '/ldlm_bl_callback/ {print $2}')
12245         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12246         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12247         lru_resize_enable mdc
12248         lru_resize_enable osc
12249 }
12250 run_test 120a "Early Lock Cancel: mkdir test"
12251
12252 test_120b() {
12253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12254         remote_mds_nodsh && skip "remote MDS with nodsh"
12255         test_mkdir $DIR/$tdir
12256         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12257                 skip_env "no early lock cancel on server"
12258
12259         lru_resize_disable mdc
12260         lru_resize_disable osc
12261         cancel_lru_locks mdc
12262         stat $DIR/$tdir > /dev/null
12263         can1=$(do_facet $SINGLEMDS \
12264                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12265                awk '/ldlm_cancel/ {print $2}')
12266         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12267                awk '/ldlm_bl_callback/ {print $2}')
12268         touch $DIR/$tdir/f1
12269         can2=$(do_facet $SINGLEMDS \
12270                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12271                awk '/ldlm_cancel/ {print $2}')
12272         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12273                awk '/ldlm_bl_callback/ {print $2}')
12274         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12275         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12276         lru_resize_enable mdc
12277         lru_resize_enable osc
12278 }
12279 run_test 120b "Early Lock Cancel: create test"
12280
12281 test_120c() {
12282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12283         remote_mds_nodsh && skip "remote MDS with nodsh"
12284         test_mkdir -i0 -c1 $DIR/$tdir
12285         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12286                 skip "no early lock cancel on server"
12287
12288         lru_resize_disable mdc
12289         lru_resize_disable osc
12290         test_mkdir -i0 -c1 $DIR/$tdir/d1
12291         test_mkdir -i0 -c1 $DIR/$tdir/d2
12292         touch $DIR/$tdir/d1/f1
12293         cancel_lru_locks mdc
12294         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12295         can1=$(do_facet mds1 \
12296                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12297                awk '/ldlm_cancel/ {print $2}')
12298         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12299                awk '/ldlm_bl_callback/ {print $2}')
12300         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12301         can2=$(do_facet mds1 \
12302                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12303                awk '/ldlm_cancel/ {print $2}')
12304         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12305                awk '/ldlm_bl_callback/ {print $2}')
12306         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12307         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12308         lru_resize_enable mdc
12309         lru_resize_enable osc
12310 }
12311 run_test 120c "Early Lock Cancel: link test"
12312
12313 test_120d() {
12314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12315         remote_mds_nodsh && skip "remote MDS with nodsh"
12316         test_mkdir -i0 -c1 $DIR/$tdir
12317         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12318                 skip_env "no early lock cancel on server"
12319
12320         lru_resize_disable mdc
12321         lru_resize_disable osc
12322         touch $DIR/$tdir
12323         cancel_lru_locks mdc
12324         stat $DIR/$tdir > /dev/null
12325         can1=$(do_facet mds1 \
12326                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12327                awk '/ldlm_cancel/ {print $2}')
12328         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12329                awk '/ldlm_bl_callback/ {print $2}')
12330         chmod a+x $DIR/$tdir
12331         can2=$(do_facet mds1 \
12332                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12333                awk '/ldlm_cancel/ {print $2}')
12334         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12335                awk '/ldlm_bl_callback/ {print $2}')
12336         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12337         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12338         lru_resize_enable mdc
12339         lru_resize_enable osc
12340 }
12341 run_test 120d "Early Lock Cancel: setattr test"
12342
12343 test_120e() {
12344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12345         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12346                 skip_env "no early lock cancel on server"
12347         remote_mds_nodsh && skip "remote MDS with nodsh"
12348
12349         local dlmtrace_set=false
12350
12351         test_mkdir -i0 -c1 $DIR/$tdir
12352         lru_resize_disable mdc
12353         lru_resize_disable osc
12354         ! $LCTL get_param debug | grep -q dlmtrace &&
12355                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12356         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12357         cancel_lru_locks mdc
12358         cancel_lru_locks osc
12359         dd if=$DIR/$tdir/f1 of=/dev/null
12360         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12361         # XXX client can not do early lock cancel of OST lock
12362         # during unlink (LU-4206), so cancel osc lock now.
12363         sleep 2
12364         cancel_lru_locks osc
12365         can1=$(do_facet mds1 \
12366                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12367                awk '/ldlm_cancel/ {print $2}')
12368         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12369                awk '/ldlm_bl_callback/ {print $2}')
12370         unlink $DIR/$tdir/f1
12371         sleep 5
12372         can2=$(do_facet mds1 \
12373                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12374                awk '/ldlm_cancel/ {print $2}')
12375         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12376                awk '/ldlm_bl_callback/ {print $2}')
12377         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12378                 $LCTL dk $TMP/cancel.debug.txt
12379         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12380                 $LCTL dk $TMP/blocking.debug.txt
12381         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12382         lru_resize_enable mdc
12383         lru_resize_enable osc
12384 }
12385 run_test 120e "Early Lock Cancel: unlink test"
12386
12387 test_120f() {
12388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12389         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12390                 skip_env "no early lock cancel on server"
12391         remote_mds_nodsh && skip "remote MDS with nodsh"
12392
12393         test_mkdir -i0 -c1 $DIR/$tdir
12394         lru_resize_disable mdc
12395         lru_resize_disable osc
12396         test_mkdir -i0 -c1 $DIR/$tdir/d1
12397         test_mkdir -i0 -c1 $DIR/$tdir/d2
12398         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12399         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12400         cancel_lru_locks mdc
12401         cancel_lru_locks osc
12402         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12403         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12404         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12405         # XXX client can not do early lock cancel of OST lock
12406         # during rename (LU-4206), so cancel osc lock now.
12407         sleep 2
12408         cancel_lru_locks osc
12409         can1=$(do_facet mds1 \
12410                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12411                awk '/ldlm_cancel/ {print $2}')
12412         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12413                awk '/ldlm_bl_callback/ {print $2}')
12414         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12415         sleep 5
12416         can2=$(do_facet mds1 \
12417                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12418                awk '/ldlm_cancel/ {print $2}')
12419         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12420                awk '/ldlm_bl_callback/ {print $2}')
12421         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12422         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12423         lru_resize_enable mdc
12424         lru_resize_enable osc
12425 }
12426 run_test 120f "Early Lock Cancel: rename test"
12427
12428 test_120g() {
12429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12430         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12431                 skip_env "no early lock cancel on server"
12432         remote_mds_nodsh && skip "remote MDS with nodsh"
12433
12434         lru_resize_disable mdc
12435         lru_resize_disable osc
12436         count=10000
12437         echo create $count files
12438         test_mkdir $DIR/$tdir
12439         cancel_lru_locks mdc
12440         cancel_lru_locks osc
12441         t0=$(date +%s)
12442
12443         can0=$(do_facet $SINGLEMDS \
12444                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12445                awk '/ldlm_cancel/ {print $2}')
12446         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12447                awk '/ldlm_bl_callback/ {print $2}')
12448         createmany -o $DIR/$tdir/f $count
12449         sync
12450         can1=$(do_facet $SINGLEMDS \
12451                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12452                awk '/ldlm_cancel/ {print $2}')
12453         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12454                awk '/ldlm_bl_callback/ {print $2}')
12455         t1=$(date +%s)
12456         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12457         echo rm $count files
12458         rm -r $DIR/$tdir
12459         sync
12460         can2=$(do_facet $SINGLEMDS \
12461                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12462                awk '/ldlm_cancel/ {print $2}')
12463         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12464                awk '/ldlm_bl_callback/ {print $2}')
12465         t2=$(date +%s)
12466         echo total: $count removes in $((t2-t1))
12467         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12468         sleep 2
12469         # wait for commitment of removal
12470         lru_resize_enable mdc
12471         lru_resize_enable osc
12472 }
12473 run_test 120g "Early Lock Cancel: performance test"
12474
12475 test_121() { #bug #10589
12476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12477
12478         rm -rf $DIR/$tfile
12479         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12480 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12481         lctl set_param fail_loc=0x310
12482         cancel_lru_locks osc > /dev/null
12483         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12484         lctl set_param fail_loc=0
12485         [[ $reads -eq $writes ]] ||
12486                 error "read $reads blocks, must be $writes blocks"
12487 }
12488 run_test 121 "read cancel race ========="
12489
12490 test_123a_base() { # was test 123, statahead(bug 11401)
12491         local lsx="$1"
12492
12493         SLOWOK=0
12494         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12495                 log "testing UP system. Performance may be lower than expected."
12496                 SLOWOK=1
12497         fi
12498
12499         rm -rf $DIR/$tdir
12500         test_mkdir $DIR/$tdir
12501         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12502         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12503         MULT=10
12504         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12505                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12506
12507                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12508                 lctl set_param -n llite.*.statahead_max 0
12509                 lctl get_param llite.*.statahead_max
12510                 cancel_lru_locks mdc
12511                 cancel_lru_locks osc
12512                 stime=$(date +%s)
12513                 time $lsx $DIR/$tdir | wc -l
12514                 etime=$(date +%s)
12515                 delta=$((etime - stime))
12516                 log "$lsx $i files without statahead: $delta sec"
12517                 lctl set_param llite.*.statahead_max=$max
12518
12519                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12520                         grep "statahead wrong:" | awk '{print $3}')
12521                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12522                 cancel_lru_locks mdc
12523                 cancel_lru_locks osc
12524                 stime=$(date +%s)
12525                 time $lsx $DIR/$tdir | wc -l
12526                 etime=$(date +%s)
12527                 delta_sa=$((etime - stime))
12528                 log "$lsx $i files with statahead: $delta_sa sec"
12529                 lctl get_param -n llite.*.statahead_stats
12530                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12531                         grep "statahead wrong:" | awk '{print $3}')
12532
12533                 [[ $swrong -lt $ewrong ]] &&
12534                         log "statahead was stopped, maybe too many locks held!"
12535                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12536
12537                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12538                         max=$(lctl get_param -n llite.*.statahead_max |
12539                                 head -n 1)
12540                         lctl set_param -n llite.*.statahead_max 0
12541                         lctl get_param llite.*.statahead_max
12542                         cancel_lru_locks mdc
12543                         cancel_lru_locks osc
12544                         stime=$(date +%s)
12545                         time $lsx $DIR/$tdir | wc -l
12546                         etime=$(date +%s)
12547                         delta=$((etime - stime))
12548                         log "$lsx $i files again without statahead: $delta sec"
12549                         lctl set_param llite.*.statahead_max=$max
12550                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12551                                 if [  $SLOWOK -eq 0 ]; then
12552                                         error "$lsx $i files is slower with statahead!"
12553                                 else
12554                                         log "$lsx $i files is slower with statahead!"
12555                                 fi
12556                                 break
12557                         fi
12558                 fi
12559
12560                 [ $delta -gt 20 ] && break
12561                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12562                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12563         done
12564         log "$lsx done"
12565
12566         stime=$(date +%s)
12567         rm -r $DIR/$tdir
12568         sync
12569         etime=$(date +%s)
12570         delta=$((etime - stime))
12571         log "rm -r $DIR/$tdir/: $delta seconds"
12572         log "rm done"
12573         lctl get_param -n llite.*.statahead_stats
12574 }
12575
12576 test_123aa() {
12577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12578
12579         test_123a_base "ls -l"
12580 }
12581 run_test 123aa "verify statahead work"
12582
12583 test_123ab() {
12584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12585
12586         statx_supported || skip_env "Test must be statx() syscall supported"
12587
12588         test_123a_base "$STATX -l"
12589 }
12590 run_test 123ab "verify statahead work by using statx"
12591
12592 test_123ac() {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594
12595         statx_supported || skip_env "Test must be statx() syscall supported"
12596
12597         local rpcs_before
12598         local rpcs_after
12599         local agl_before
12600         local agl_after
12601
12602         cancel_lru_locks $OSC
12603         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12604         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12605                 awk '/agl.total:/ {print $3}')
12606         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12607         test_123a_base "$STATX --cached=always -D"
12608         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12609                 awk '/agl.total:/ {print $3}')
12610         [ $agl_before -eq $agl_after ] ||
12611                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12612         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12613         [ $rpcs_after -eq $rpcs_before ] ||
12614                 error "$STATX should not send glimpse RPCs to $OSC"
12615 }
12616 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12617
12618 test_123b () { # statahead(bug 15027)
12619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12620
12621         test_mkdir $DIR/$tdir
12622         createmany -o $DIR/$tdir/$tfile-%d 1000
12623
12624         cancel_lru_locks mdc
12625         cancel_lru_locks osc
12626
12627 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12628         lctl set_param fail_loc=0x80000803
12629         ls -lR $DIR/$tdir > /dev/null
12630         log "ls done"
12631         lctl set_param fail_loc=0x0
12632         lctl get_param -n llite.*.statahead_stats
12633         rm -r $DIR/$tdir
12634         sync
12635
12636 }
12637 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12638
12639 test_123c() {
12640         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12641
12642         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12643         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12644         touch $DIR/$tdir.1/{1..3}
12645         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12646
12647         remount_client $MOUNT
12648
12649         $MULTIOP $DIR/$tdir.0 Q
12650
12651         # let statahead to complete
12652         ls -l $DIR/$tdir.0 > /dev/null
12653
12654         testid=$(echo $TESTNAME | tr '_' ' ')
12655         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12656                 error "statahead warning" || true
12657 }
12658 run_test 123c "Can not initialize inode warning on DNE statahead"
12659
12660 test_124a() {
12661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12662         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12663                 skip_env "no lru resize on server"
12664
12665         local NR=2000
12666
12667         test_mkdir $DIR/$tdir
12668
12669         log "create $NR files at $DIR/$tdir"
12670         createmany -o $DIR/$tdir/f $NR ||
12671                 error "failed to create $NR files in $DIR/$tdir"
12672
12673         cancel_lru_locks mdc
12674         ls -l $DIR/$tdir > /dev/null
12675
12676         local NSDIR=""
12677         local LRU_SIZE=0
12678         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12679                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12680                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12681                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12682                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12683                         log "NSDIR=$NSDIR"
12684                         log "NS=$(basename $NSDIR)"
12685                         break
12686                 fi
12687         done
12688
12689         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12690                 skip "Not enough cached locks created!"
12691         fi
12692         log "LRU=$LRU_SIZE"
12693
12694         local SLEEP=30
12695
12696         # We know that lru resize allows one client to hold $LIMIT locks
12697         # for 10h. After that locks begin to be killed by client.
12698         local MAX_HRS=10
12699         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12700         log "LIMIT=$LIMIT"
12701         if [ $LIMIT -lt $LRU_SIZE ]; then
12702                 skip "Limit is too small $LIMIT"
12703         fi
12704
12705         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12706         # killing locks. Some time was spent for creating locks. This means
12707         # that up to the moment of sleep finish we must have killed some of
12708         # them (10-100 locks). This depends on how fast ther were created.
12709         # Many of them were touched in almost the same moment and thus will
12710         # be killed in groups.
12711         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12712
12713         # Use $LRU_SIZE_B here to take into account real number of locks
12714         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12715         local LRU_SIZE_B=$LRU_SIZE
12716         log "LVF=$LVF"
12717         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12718         log "OLD_LVF=$OLD_LVF"
12719         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12720
12721         # Let's make sure that we really have some margin. Client checks
12722         # cached locks every 10 sec.
12723         SLEEP=$((SLEEP+20))
12724         log "Sleep ${SLEEP} sec"
12725         local SEC=0
12726         while ((SEC<$SLEEP)); do
12727                 echo -n "..."
12728                 sleep 5
12729                 SEC=$((SEC+5))
12730                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12731                 echo -n "$LRU_SIZE"
12732         done
12733         echo ""
12734         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12735         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12736
12737         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12738                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12739                 unlinkmany $DIR/$tdir/f $NR
12740                 return
12741         }
12742
12743         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12744         log "unlink $NR files at $DIR/$tdir"
12745         unlinkmany $DIR/$tdir/f $NR
12746 }
12747 run_test 124a "lru resize ======================================="
12748
12749 get_max_pool_limit()
12750 {
12751         local limit=$($LCTL get_param \
12752                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12753         local max=0
12754         for l in $limit; do
12755                 if [[ $l -gt $max ]]; then
12756                         max=$l
12757                 fi
12758         done
12759         echo $max
12760 }
12761
12762 test_124b() {
12763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12764         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12765                 skip_env "no lru resize on server"
12766
12767         LIMIT=$(get_max_pool_limit)
12768
12769         NR=$(($(default_lru_size)*20))
12770         if [[ $NR -gt $LIMIT ]]; then
12771                 log "Limit lock number by $LIMIT locks"
12772                 NR=$LIMIT
12773         fi
12774
12775         IFree=$(mdsrate_inodes_available)
12776         if [ $IFree -lt $NR ]; then
12777                 log "Limit lock number by $IFree inodes"
12778                 NR=$IFree
12779         fi
12780
12781         lru_resize_disable mdc
12782         test_mkdir -p $DIR/$tdir/disable_lru_resize
12783
12784         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12785         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12786         cancel_lru_locks mdc
12787         stime=`date +%s`
12788         PID=""
12789         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12790         PID="$PID $!"
12791         sleep 2
12792         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12793         PID="$PID $!"
12794         sleep 2
12795         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12796         PID="$PID $!"
12797         wait $PID
12798         etime=`date +%s`
12799         nolruresize_delta=$((etime-stime))
12800         log "ls -la time: $nolruresize_delta seconds"
12801         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12802         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12803
12804         lru_resize_enable mdc
12805         test_mkdir -p $DIR/$tdir/enable_lru_resize
12806
12807         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12808         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12809         cancel_lru_locks mdc
12810         stime=`date +%s`
12811         PID=""
12812         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12813         PID="$PID $!"
12814         sleep 2
12815         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12816         PID="$PID $!"
12817         sleep 2
12818         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12819         PID="$PID $!"
12820         wait $PID
12821         etime=`date +%s`
12822         lruresize_delta=$((etime-stime))
12823         log "ls -la time: $lruresize_delta seconds"
12824         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12825
12826         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12827                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12828         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12829                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12830         else
12831                 log "lru resize performs the same with no lru resize"
12832         fi
12833         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12834 }
12835 run_test 124b "lru resize (performance test) ======================="
12836
12837 test_124c() {
12838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12839         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12840                 skip_env "no lru resize on server"
12841
12842         # cache ununsed locks on client
12843         local nr=100
12844         cancel_lru_locks mdc
12845         test_mkdir $DIR/$tdir
12846         createmany -o $DIR/$tdir/f $nr ||
12847                 error "failed to create $nr files in $DIR/$tdir"
12848         ls -l $DIR/$tdir > /dev/null
12849
12850         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12851         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12852         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12853         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12854         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12855
12856         # set lru_max_age to 1 sec
12857         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12858         echo "sleep $((recalc_p * 2)) seconds..."
12859         sleep $((recalc_p * 2))
12860
12861         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12862         # restore lru_max_age
12863         $LCTL set_param -n $nsdir.lru_max_age $max_age
12864         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12865         unlinkmany $DIR/$tdir/f $nr
12866 }
12867 run_test 124c "LRUR cancel very aged locks"
12868
12869 test_124d() {
12870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12871         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12872                 skip_env "no lru resize on server"
12873
12874         # cache ununsed locks on client
12875         local nr=100
12876
12877         lru_resize_disable mdc
12878         stack_trap "lru_resize_enable mdc" EXIT
12879
12880         cancel_lru_locks mdc
12881
12882         # asynchronous object destroy at MDT could cause bl ast to client
12883         test_mkdir $DIR/$tdir
12884         createmany -o $DIR/$tdir/f $nr ||
12885                 error "failed to create $nr files in $DIR/$tdir"
12886         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12887
12888         ls -l $DIR/$tdir > /dev/null
12889
12890         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12891         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12892         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12893         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12894
12895         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12896
12897         # set lru_max_age to 1 sec
12898         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12899         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12900
12901         echo "sleep $((recalc_p * 2)) seconds..."
12902         sleep $((recalc_p * 2))
12903
12904         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12905
12906         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12907 }
12908 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12909
12910 test_125() { # 13358
12911         $LCTL get_param -n llite.*.client_type | grep -q local ||
12912                 skip "must run as local client"
12913         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12914                 skip_env "must have acl enabled"
12915         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12916
12917         test_mkdir $DIR/$tdir
12918         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12919         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12920         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12921 }
12922 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12923
12924 test_126() { # bug 12829/13455
12925         $GSS && skip_env "must run as gss disabled"
12926         $LCTL get_param -n llite.*.client_type | grep -q local ||
12927                 skip "must run as local client"
12928         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12929
12930         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12931         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12932         rm -f $DIR/$tfile
12933         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12934 }
12935 run_test 126 "check that the fsgid provided by the client is taken into account"
12936
12937 test_127a() { # bug 15521
12938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12939         local name count samp unit min max sum sumsq
12940
12941         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12942         echo "stats before reset"
12943         $LCTL get_param osc.*.stats
12944         $LCTL set_param osc.*.stats=0
12945         local fsize=$((2048 * 1024))
12946
12947         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12948         cancel_lru_locks osc
12949         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12950
12951         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12952         stack_trap "rm -f $TMP/$tfile.tmp"
12953         while read name count samp unit min max sum sumsq; do
12954                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12955                 [ ! $min ] && error "Missing min value for $name proc entry"
12956                 eval $name=$count || error "Wrong proc format"
12957
12958                 case $name in
12959                 read_bytes|write_bytes)
12960                         [[ "$unit" =~ "bytes" ]] ||
12961                                 error "unit is not 'bytes': $unit"
12962                         (( $min >= 4096 )) || error "min is too small: $min"
12963                         (( $min <= $fsize )) || error "min is too big: $min"
12964                         (( $max >= 4096 )) || error "max is too small: $max"
12965                         (( $max <= $fsize )) || error "max is too big: $max"
12966                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12967                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12968                                 error "sumsquare is too small: $sumsq"
12969                         (( $sumsq <= $fsize * $fsize )) ||
12970                                 error "sumsquare is too big: $sumsq"
12971                         ;;
12972                 ost_read|ost_write)
12973                         [[ "$unit" =~ "usec" ]] ||
12974                                 error "unit is not 'usec': $unit"
12975                         ;;
12976                 *)      ;;
12977                 esac
12978         done < $DIR/$tfile.tmp
12979
12980         #check that we actually got some stats
12981         [ "$read_bytes" ] || error "Missing read_bytes stats"
12982         [ "$write_bytes" ] || error "Missing write_bytes stats"
12983         [ "$read_bytes" != 0 ] || error "no read done"
12984         [ "$write_bytes" != 0 ] || error "no write done"
12985 }
12986 run_test 127a "verify the client stats are sane"
12987
12988 test_127b() { # bug LU-333
12989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12990         local name count samp unit min max sum sumsq
12991
12992         echo "stats before reset"
12993         $LCTL get_param llite.*.stats
12994         $LCTL set_param llite.*.stats=0
12995
12996         # perform 2 reads and writes so MAX is different from SUM.
12997         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12998         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12999         cancel_lru_locks osc
13000         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13001         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13002
13003         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13004         stack_trap "rm -f $TMP/$tfile.tmp"
13005         while read name count samp unit min max sum sumsq; do
13006                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13007                 eval $name=$count || error "Wrong proc format"
13008
13009                 case $name in
13010                 read_bytes|write_bytes)
13011                         [[ "$unit" =~ "bytes" ]] ||
13012                                 error "unit is not 'bytes': $unit"
13013                         (( $count == 2 )) || error "count is not 2: $count"
13014                         (( $min == $PAGE_SIZE )) ||
13015                                 error "min is not $PAGE_SIZE: $min"
13016                         (( $max == $PAGE_SIZE )) ||
13017                                 error "max is not $PAGE_SIZE: $max"
13018                         (( $sum == $PAGE_SIZE * 2 )) ||
13019                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13020                         ;;
13021                 read|write)
13022                         [[ "$unit" =~ "usec" ]] ||
13023                                 error "unit is not 'usec': $unit"
13024                         ;;
13025                 *)      ;;
13026                 esac
13027         done < $TMP/$tfile.tmp
13028
13029         #check that we actually got some stats
13030         [ "$read_bytes" ] || error "Missing read_bytes stats"
13031         [ "$write_bytes" ] || error "Missing write_bytes stats"
13032         [ "$read_bytes" != 0 ] || error "no read done"
13033         [ "$write_bytes" != 0 ] || error "no write done"
13034 }
13035 run_test 127b "verify the llite client stats are sane"
13036
13037 test_127c() { # LU-12394
13038         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13039         local size
13040         local bsize
13041         local reads
13042         local writes
13043         local count
13044
13045         $LCTL set_param llite.*.extents_stats=1
13046         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13047
13048         # Use two stripes so there is enough space in default config
13049         $LFS setstripe -c 2 $DIR/$tfile
13050
13051         # Extent stats start at 0-4K and go in power of two buckets
13052         # LL_HIST_START = 12 --> 2^12 = 4K
13053         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13054         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13055         # small configs
13056         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13057                 do
13058                 # Write and read, 2x each, second time at a non-zero offset
13059                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13060                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13061                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13062                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13063                 rm -f $DIR/$tfile
13064         done
13065
13066         $LCTL get_param llite.*.extents_stats
13067
13068         count=2
13069         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13070                 do
13071                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13072                                 grep -m 1 $bsize)
13073                 reads=$(echo $bucket | awk '{print $5}')
13074                 writes=$(echo $bucket | awk '{print $9}')
13075                 [ "$reads" -eq $count ] ||
13076                         error "$reads reads in < $bsize bucket, expect $count"
13077                 [ "$writes" -eq $count ] ||
13078                         error "$writes writes in < $bsize bucket, expect $count"
13079         done
13080
13081         # Test mmap write and read
13082         $LCTL set_param llite.*.extents_stats=c
13083         size=512
13084         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13085         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13086         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13087
13088         $LCTL get_param llite.*.extents_stats
13089
13090         count=$(((size*1024) / PAGE_SIZE))
13091
13092         bsize=$((2 * PAGE_SIZE / 1024))K
13093
13094         bucket=$($LCTL get_param -n llite.*.extents_stats |
13095                         grep -m 1 $bsize)
13096         reads=$(echo $bucket | awk '{print $5}')
13097         writes=$(echo $bucket | awk '{print $9}')
13098         # mmap writes fault in the page first, creating an additonal read
13099         [ "$reads" -eq $((2 * count)) ] ||
13100                 error "$reads reads in < $bsize bucket, expect $count"
13101         [ "$writes" -eq $count ] ||
13102                 error "$writes writes in < $bsize bucket, expect $count"
13103 }
13104 run_test 127c "test llite extent stats with regular & mmap i/o"
13105
13106 test_128() { # bug 15212
13107         touch $DIR/$tfile
13108         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13109                 find $DIR/$tfile
13110                 find $DIR/$tfile
13111         EOF
13112
13113         result=$(grep error $TMP/$tfile.log)
13114         rm -f $DIR/$tfile $TMP/$tfile.log
13115         [ -z "$result" ] ||
13116                 error "consecutive find's under interactive lfs failed"
13117 }
13118 run_test 128 "interactive lfs for 2 consecutive find's"
13119
13120 set_dir_limits () {
13121         local mntdev
13122         local canondev
13123         local node
13124
13125         local ldproc=/proc/fs/ldiskfs
13126         local facets=$(get_facets MDS)
13127
13128         for facet in ${facets//,/ }; do
13129                 canondev=$(ldiskfs_canon \
13130                            *.$(convert_facet2label $facet).mntdev $facet)
13131                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13132                         ldproc=/sys/fs/ldiskfs
13133                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13134                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13135         done
13136 }
13137
13138 check_mds_dmesg() {
13139         local facets=$(get_facets MDS)
13140         for facet in ${facets//,/ }; do
13141                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13142         done
13143         return 1
13144 }
13145
13146 test_129() {
13147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13148         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13149                 skip "Need MDS version with at least 2.5.56"
13150         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13151                 skip_env "ldiskfs only test"
13152         fi
13153         remote_mds_nodsh && skip "remote MDS with nodsh"
13154
13155         local ENOSPC=28
13156         local has_warning=false
13157
13158         rm -rf $DIR/$tdir
13159         mkdir -p $DIR/$tdir
13160
13161         # block size of mds1
13162         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13163         set_dir_limits $maxsize $((maxsize * 6 / 8))
13164         stack_trap "set_dir_limits 0 0"
13165         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13166         local dirsize=$(stat -c%s "$DIR/$tdir")
13167         local nfiles=0
13168         while (( $dirsize <= $maxsize )); do
13169                 $MCREATE $DIR/$tdir/file_base_$nfiles
13170                 rc=$?
13171                 # check two errors:
13172                 # ENOSPC for ext4 max_dir_size, which has been used since
13173                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13174                 if (( rc == ENOSPC )); then
13175                         set_dir_limits 0 0
13176                         echo "rc=$rc returned as expected after $nfiles files"
13177
13178                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13179                                 error "create failed w/o dir size limit"
13180
13181                         # messages may be rate limited if test is run repeatedly
13182                         check_mds_dmesg '"is approaching max"' ||
13183                                 echo "warning message should be output"
13184                         check_mds_dmesg '"has reached max"' ||
13185                                 echo "reached message should be output"
13186
13187                         dirsize=$(stat -c%s "$DIR/$tdir")
13188
13189                         [[ $dirsize -ge $maxsize ]] && return 0
13190                         error "dirsize $dirsize < $maxsize after $nfiles files"
13191                 elif (( rc != 0 )); then
13192                         break
13193                 fi
13194                 nfiles=$((nfiles + 1))
13195                 dirsize=$(stat -c%s "$DIR/$tdir")
13196         done
13197
13198         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13199 }
13200 run_test 129 "test directory size limit ========================"
13201
13202 OLDIFS="$IFS"
13203 cleanup_130() {
13204         trap 0
13205         IFS="$OLDIFS"
13206 }
13207
13208 test_130a() {
13209         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13210         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13211
13212         trap cleanup_130 EXIT RETURN
13213
13214         local fm_file=$DIR/$tfile
13215         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13216         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13217                 error "dd failed for $fm_file"
13218
13219         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13220         filefrag -ves $fm_file
13221         RC=$?
13222         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13223                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13224         [ $RC != 0 ] && error "filefrag $fm_file failed"
13225
13226         filefrag_op=$(filefrag -ve -k $fm_file |
13227                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13228         lun=$($LFS getstripe -i $fm_file)
13229
13230         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13231         IFS=$'\n'
13232         tot_len=0
13233         for line in $filefrag_op
13234         do
13235                 frag_lun=`echo $line | cut -d: -f5`
13236                 ext_len=`echo $line | cut -d: -f4`
13237                 if (( $frag_lun != $lun )); then
13238                         cleanup_130
13239                         error "FIEMAP on 1-stripe file($fm_file) failed"
13240                         return
13241                 fi
13242                 (( tot_len += ext_len ))
13243         done
13244
13245         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13246                 cleanup_130
13247                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13248                 return
13249         fi
13250
13251         cleanup_130
13252
13253         echo "FIEMAP on single striped file succeeded"
13254 }
13255 run_test 130a "FIEMAP (1-stripe file)"
13256
13257 test_130b() {
13258         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13259
13260         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13261         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13262
13263         trap cleanup_130 EXIT RETURN
13264
13265         local fm_file=$DIR/$tfile
13266         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13267                         error "setstripe on $fm_file"
13268         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13269                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13270
13271         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13272                 error "dd failed on $fm_file"
13273
13274         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13275         filefrag_op=$(filefrag -ve -k $fm_file |
13276                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13277
13278         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13279                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13280
13281         IFS=$'\n'
13282         tot_len=0
13283         num_luns=1
13284         for line in $filefrag_op
13285         do
13286                 frag_lun=$(echo $line | cut -d: -f5 |
13287                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13288                 ext_len=$(echo $line | cut -d: -f4)
13289                 if (( $frag_lun != $last_lun )); then
13290                         if (( tot_len != 1024 )); then
13291                                 cleanup_130
13292                                 error "FIEMAP on $fm_file failed; returned " \
13293                                 "len $tot_len for OST $last_lun instead of 1024"
13294                                 return
13295                         else
13296                                 (( num_luns += 1 ))
13297                                 tot_len=0
13298                         fi
13299                 fi
13300                 (( tot_len += ext_len ))
13301                 last_lun=$frag_lun
13302         done
13303         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13304                 cleanup_130
13305                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13306                         "luns or wrong len for OST $last_lun"
13307                 return
13308         fi
13309
13310         cleanup_130
13311
13312         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13313 }
13314 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13315
13316 test_130c() {
13317         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13318
13319         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13320         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13321
13322         trap cleanup_130 EXIT RETURN
13323
13324         local fm_file=$DIR/$tfile
13325         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13326         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13327                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13328
13329         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13330                         error "dd failed on $fm_file"
13331
13332         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13333         filefrag_op=$(filefrag -ve -k $fm_file |
13334                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13335
13336         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13337                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13338
13339         IFS=$'\n'
13340         tot_len=0
13341         num_luns=1
13342         for line in $filefrag_op
13343         do
13344                 frag_lun=$(echo $line | cut -d: -f5 |
13345                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13346                 ext_len=$(echo $line | cut -d: -f4)
13347                 if (( $frag_lun != $last_lun )); then
13348                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13349                         if (( logical != 512 )); then
13350                                 cleanup_130
13351                                 error "FIEMAP on $fm_file failed; returned " \
13352                                 "logical start for lun $logical instead of 512"
13353                                 return
13354                         fi
13355                         if (( tot_len != 512 )); then
13356                                 cleanup_130
13357                                 error "FIEMAP on $fm_file failed; returned " \
13358                                 "len $tot_len for OST $last_lun instead of 1024"
13359                                 return
13360                         else
13361                                 (( num_luns += 1 ))
13362                                 tot_len=0
13363                         fi
13364                 fi
13365                 (( tot_len += ext_len ))
13366                 last_lun=$frag_lun
13367         done
13368         if (( num_luns != 2 || tot_len != 512 )); then
13369                 cleanup_130
13370                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13371                         "luns or wrong len for OST $last_lun"
13372                 return
13373         fi
13374
13375         cleanup_130
13376
13377         echo "FIEMAP on 2-stripe file with hole succeeded"
13378 }
13379 run_test 130c "FIEMAP (2-stripe file with hole)"
13380
13381 test_130d() {
13382         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13383
13384         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13385         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13386
13387         trap cleanup_130 EXIT RETURN
13388
13389         local fm_file=$DIR/$tfile
13390         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13391                         error "setstripe on $fm_file"
13392         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13393                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13394
13395         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13396         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13397                 error "dd failed on $fm_file"
13398
13399         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13400         filefrag_op=$(filefrag -ve -k $fm_file |
13401                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13402
13403         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13404                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13405
13406         IFS=$'\n'
13407         tot_len=0
13408         num_luns=1
13409         for line in $filefrag_op
13410         do
13411                 frag_lun=$(echo $line | cut -d: -f5 |
13412                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13413                 ext_len=$(echo $line | cut -d: -f4)
13414                 if (( $frag_lun != $last_lun )); then
13415                         if (( tot_len != 1024 )); then
13416                                 cleanup_130
13417                                 error "FIEMAP on $fm_file failed; returned " \
13418                                 "len $tot_len for OST $last_lun instead of 1024"
13419                                 return
13420                         else
13421                                 (( num_luns += 1 ))
13422                                 tot_len=0
13423                         fi
13424                 fi
13425                 (( tot_len += ext_len ))
13426                 last_lun=$frag_lun
13427         done
13428         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13429                 cleanup_130
13430                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13431                         "luns or wrong len for OST $last_lun"
13432                 return
13433         fi
13434
13435         cleanup_130
13436
13437         echo "FIEMAP on N-stripe file succeeded"
13438 }
13439 run_test 130d "FIEMAP (N-stripe file)"
13440
13441 test_130e() {
13442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13443
13444         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13445         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13446
13447         trap cleanup_130 EXIT RETURN
13448
13449         local fm_file=$DIR/$tfile
13450         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13451
13452         NUM_BLKS=512
13453         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13454         for ((i = 0; i < $NUM_BLKS; i++)); do
13455                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13456                         conv=notrunc > /dev/null 2>&1
13457         done
13458
13459         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13460         filefrag_op=$(filefrag -ve -k $fm_file |
13461                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13462
13463         last_lun=$(echo $filefrag_op | cut -d: -f5)
13464
13465         IFS=$'\n'
13466         tot_len=0
13467         num_luns=1
13468         for line in $filefrag_op; do
13469                 frag_lun=$(echo $line | cut -d: -f5)
13470                 ext_len=$(echo $line | cut -d: -f4)
13471                 if [[ "$frag_lun" != "$last_lun" ]]; then
13472                         if (( tot_len != $EXPECTED_LEN )); then
13473                                 cleanup_130
13474                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13475                         else
13476                                 (( num_luns += 1 ))
13477                                 tot_len=0
13478                         fi
13479                 fi
13480                 (( tot_len += ext_len ))
13481                 last_lun=$frag_lun
13482         done
13483         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13484                 cleanup_130
13485                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13486         fi
13487
13488         echo "FIEMAP with continuation calls succeeded"
13489 }
13490 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13491
13492 test_130f() {
13493         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13494         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13495
13496         local fm_file=$DIR/$tfile
13497         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13498                 error "multiop create with lov_delay_create on $fm_file"
13499
13500         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13501         filefrag_extents=$(filefrag -vek $fm_file |
13502                            awk '/extents? found/ { print $2 }')
13503         if [[ "$filefrag_extents" != "0" ]]; then
13504                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13505         fi
13506
13507         rm -f $fm_file
13508 }
13509 run_test 130f "FIEMAP (unstriped file)"
13510
13511 test_130g() {
13512         local file=$DIR/$tfile
13513         local nr=$((OSTCOUNT * 100))
13514
13515         $LFS setstripe -C $nr $file ||
13516                 error "failed to setstripe -C $nr $file"
13517
13518         dd if=/dev/zero of=$file count=$nr bs=1M
13519         sync
13520         nr=$($LFS getstripe -c $file)
13521
13522         local extents=$(filefrag -v $file |
13523                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13524
13525         echo "filefrag list $extents extents in file with stripecount $nr"
13526         if (( extents < nr )); then
13527                 $LFS getstripe $file
13528                 filefrag -v $file
13529                 error "filefrag printed $extents < $nr extents"
13530         fi
13531
13532         rm -f $file
13533 }
13534 run_test 130g "FIEMAP (overstripe file)"
13535
13536 # Test for writev/readv
13537 test_131a() {
13538         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13539                 error "writev test failed"
13540         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13541                 error "readv failed"
13542         rm -f $DIR/$tfile
13543 }
13544 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13545
13546 test_131b() {
13547         local fsize=$((524288 + 1048576 + 1572864))
13548         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13549                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13550                         error "append writev test failed"
13551
13552         ((fsize += 1572864 + 1048576))
13553         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13554                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13555                         error "append writev test failed"
13556         rm -f $DIR/$tfile
13557 }
13558 run_test 131b "test append writev"
13559
13560 test_131c() {
13561         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13562         error "NOT PASS"
13563 }
13564 run_test 131c "test read/write on file w/o objects"
13565
13566 test_131d() {
13567         rwv -f $DIR/$tfile -w -n 1 1572864
13568         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13569         if [ "$NOB" != 1572864 ]; then
13570                 error "Short read filed: read $NOB bytes instead of 1572864"
13571         fi
13572         rm -f $DIR/$tfile
13573 }
13574 run_test 131d "test short read"
13575
13576 test_131e() {
13577         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13578         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13579         error "read hitting hole failed"
13580         rm -f $DIR/$tfile
13581 }
13582 run_test 131e "test read hitting hole"
13583
13584 check_stats() {
13585         local facet=$1
13586         local op=$2
13587         local want=${3:-0}
13588         local res
13589
13590         case $facet in
13591         mds*) res=$(do_facet $facet \
13592                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13593                  ;;
13594         ost*) res=$(do_facet $facet \
13595                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13596                  ;;
13597         *) error "Wrong facet '$facet'" ;;
13598         esac
13599         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13600         # if the argument $3 is zero, it means any stat increment is ok.
13601         if [[ $want -gt 0 ]]; then
13602                 local count=$(echo $res | awk '{ print $2 }')
13603                 [[ $count -ne $want ]] &&
13604                         error "The $op counter on $facet is $count, not $want"
13605         fi
13606 }
13607
13608 test_133a() {
13609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13610         remote_ost_nodsh && skip "remote OST with nodsh"
13611         remote_mds_nodsh && skip "remote MDS with nodsh"
13612         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13613                 skip_env "MDS doesn't support rename stats"
13614
13615         local testdir=$DIR/${tdir}/stats_testdir
13616
13617         mkdir -p $DIR/${tdir}
13618
13619         # clear stats.
13620         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13621         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13622
13623         # verify mdt stats first.
13624         mkdir ${testdir} || error "mkdir failed"
13625         check_stats $SINGLEMDS "mkdir" 1
13626         touch ${testdir}/${tfile} || error "touch failed"
13627         check_stats $SINGLEMDS "open" 1
13628         check_stats $SINGLEMDS "close" 1
13629         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13630                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13631                 check_stats $SINGLEMDS "mknod" 2
13632         }
13633         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13634         check_stats $SINGLEMDS "unlink" 1
13635         rm -f ${testdir}/${tfile} || error "file remove failed"
13636         check_stats $SINGLEMDS "unlink" 2
13637
13638         # remove working dir and check mdt stats again.
13639         rmdir ${testdir} || error "rmdir failed"
13640         check_stats $SINGLEMDS "rmdir" 1
13641
13642         local testdir1=$DIR/${tdir}/stats_testdir1
13643         mkdir -p ${testdir}
13644         mkdir -p ${testdir1}
13645         touch ${testdir1}/test1
13646         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13647         check_stats $SINGLEMDS "crossdir_rename" 1
13648
13649         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13650         check_stats $SINGLEMDS "samedir_rename" 1
13651
13652         rm -rf $DIR/${tdir}
13653 }
13654 run_test 133a "Verifying MDT stats ========================================"
13655
13656 test_133b() {
13657         local res
13658
13659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13660         remote_ost_nodsh && skip "remote OST with nodsh"
13661         remote_mds_nodsh && skip "remote MDS with nodsh"
13662
13663         local testdir=$DIR/${tdir}/stats_testdir
13664
13665         mkdir -p ${testdir} || error "mkdir failed"
13666         touch ${testdir}/${tfile} || error "touch failed"
13667         cancel_lru_locks mdc
13668
13669         # clear stats.
13670         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13671         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13672
13673         # extra mdt stats verification.
13674         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13675         check_stats $SINGLEMDS "setattr" 1
13676         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13677         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13678         then            # LU-1740
13679                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13680                 check_stats $SINGLEMDS "getattr" 1
13681         fi
13682         rm -rf $DIR/${tdir}
13683
13684         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13685         # so the check below is not reliable
13686         [ $MDSCOUNT -eq 1 ] || return 0
13687
13688         # Sleep to avoid a cached response.
13689         #define OBD_STATFS_CACHE_SECONDS 1
13690         sleep 2
13691         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13692         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13693         $LFS df || error "lfs failed"
13694         check_stats $SINGLEMDS "statfs" 1
13695
13696         # check aggregated statfs (LU-10018)
13697         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13698                 return 0
13699         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13700                 return 0
13701         sleep 2
13702         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13703         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13704         df $DIR
13705         check_stats $SINGLEMDS "statfs" 1
13706
13707         # We want to check that the client didn't send OST_STATFS to
13708         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13709         # extra care is needed here.
13710         if remote_mds; then
13711                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13712                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13713
13714                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13715                 [ "$res" ] && error "OST got STATFS"
13716         fi
13717
13718         return 0
13719 }
13720 run_test 133b "Verifying extra MDT stats =================================="
13721
13722 test_133c() {
13723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13724         remote_ost_nodsh && skip "remote OST with nodsh"
13725         remote_mds_nodsh && skip "remote MDS with nodsh"
13726
13727         local testdir=$DIR/$tdir/stats_testdir
13728
13729         test_mkdir -p $testdir
13730
13731         # verify obdfilter stats.
13732         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13733         sync
13734         cancel_lru_locks osc
13735         wait_delete_completed
13736
13737         # clear stats.
13738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13739         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13740
13741         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13742                 error "dd failed"
13743         sync
13744         cancel_lru_locks osc
13745         check_stats ost1 "write" 1
13746
13747         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13748         check_stats ost1 "read" 1
13749
13750         > $testdir/$tfile || error "truncate failed"
13751         check_stats ost1 "punch" 1
13752
13753         rm -f $testdir/$tfile || error "file remove failed"
13754         wait_delete_completed
13755         check_stats ost1 "destroy" 1
13756
13757         rm -rf $DIR/$tdir
13758 }
13759 run_test 133c "Verifying OST stats ========================================"
13760
13761 order_2() {
13762         local value=$1
13763         local orig=$value
13764         local order=1
13765
13766         while [ $value -ge 2 ]; do
13767                 order=$((order*2))
13768                 value=$((value/2))
13769         done
13770
13771         if [ $orig -gt $order ]; then
13772                 order=$((order*2))
13773         fi
13774         echo $order
13775 }
13776
13777 size_in_KMGT() {
13778     local value=$1
13779     local size=('K' 'M' 'G' 'T');
13780     local i=0
13781     local size_string=$value
13782
13783     while [ $value -ge 1024 ]; do
13784         if [ $i -gt 3 ]; then
13785             #T is the biggest unit we get here, if that is bigger,
13786             #just return XXXT
13787             size_string=${value}T
13788             break
13789         fi
13790         value=$((value >> 10))
13791         if [ $value -lt 1024 ]; then
13792             size_string=${value}${size[$i]}
13793             break
13794         fi
13795         i=$((i + 1))
13796     done
13797
13798     echo $size_string
13799 }
13800
13801 get_rename_size() {
13802         local size=$1
13803         local context=${2:-.}
13804         local sample=$(do_facet $SINGLEMDS $LCTL \
13805                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13806                 grep -A1 $context |
13807                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13808         echo $sample
13809 }
13810
13811 test_133d() {
13812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13813         remote_ost_nodsh && skip "remote OST with nodsh"
13814         remote_mds_nodsh && skip "remote MDS with nodsh"
13815         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13816                 skip_env "MDS doesn't support rename stats"
13817
13818         local testdir1=$DIR/${tdir}/stats_testdir1
13819         local testdir2=$DIR/${tdir}/stats_testdir2
13820         mkdir -p $DIR/${tdir}
13821
13822         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13823
13824         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13825         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13826
13827         createmany -o $testdir1/test 512 || error "createmany failed"
13828
13829         # check samedir rename size
13830         mv ${testdir1}/test0 ${testdir1}/test_0
13831
13832         local testdir1_size=$(ls -l $DIR/${tdir} |
13833                 awk '/stats_testdir1/ {print $5}')
13834         local testdir2_size=$(ls -l $DIR/${tdir} |
13835                 awk '/stats_testdir2/ {print $5}')
13836
13837         testdir1_size=$(order_2 $testdir1_size)
13838         testdir2_size=$(order_2 $testdir2_size)
13839
13840         testdir1_size=$(size_in_KMGT $testdir1_size)
13841         testdir2_size=$(size_in_KMGT $testdir2_size)
13842
13843         echo "source rename dir size: ${testdir1_size}"
13844         echo "target rename dir size: ${testdir2_size}"
13845
13846         local cmd="do_facet $SINGLEMDS $LCTL "
13847         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13848
13849         eval $cmd || error "$cmd failed"
13850         local samedir=$($cmd | grep 'same_dir')
13851         local same_sample=$(get_rename_size $testdir1_size)
13852         [ -z "$samedir" ] && error "samedir_rename_size count error"
13853         [[ $same_sample -eq 1 ]] ||
13854                 error "samedir_rename_size error $same_sample"
13855         echo "Check same dir rename stats success"
13856
13857         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13858
13859         # check crossdir rename size
13860         mv ${testdir1}/test_0 ${testdir2}/test_0
13861
13862         testdir1_size=$(ls -l $DIR/${tdir} |
13863                 awk '/stats_testdir1/ {print $5}')
13864         testdir2_size=$(ls -l $DIR/${tdir} |
13865                 awk '/stats_testdir2/ {print $5}')
13866
13867         testdir1_size=$(order_2 $testdir1_size)
13868         testdir2_size=$(order_2 $testdir2_size)
13869
13870         testdir1_size=$(size_in_KMGT $testdir1_size)
13871         testdir2_size=$(size_in_KMGT $testdir2_size)
13872
13873         echo "source rename dir size: ${testdir1_size}"
13874         echo "target rename dir size: ${testdir2_size}"
13875
13876         eval $cmd || error "$cmd failed"
13877         local crossdir=$($cmd | grep 'crossdir')
13878         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13879         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13880         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13881         [[ $src_sample -eq 1 ]] ||
13882                 error "crossdir_rename_size error $src_sample"
13883         [[ $tgt_sample -eq 1 ]] ||
13884                 error "crossdir_rename_size error $tgt_sample"
13885         echo "Check cross dir rename stats success"
13886         rm -rf $DIR/${tdir}
13887 }
13888 run_test 133d "Verifying rename_stats ========================================"
13889
13890 test_133e() {
13891         remote_mds_nodsh && skip "remote MDS with nodsh"
13892         remote_ost_nodsh && skip "remote OST with nodsh"
13893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13894
13895         local testdir=$DIR/${tdir}/stats_testdir
13896         local ctr f0 f1 bs=32768 count=42 sum
13897
13898         mkdir -p ${testdir} || error "mkdir failed"
13899
13900         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13901
13902         for ctr in {write,read}_bytes; do
13903                 sync
13904                 cancel_lru_locks osc
13905
13906                 do_facet ost1 $LCTL set_param -n \
13907                         "obdfilter.*.exports.clear=clear"
13908
13909                 if [ $ctr = write_bytes ]; then
13910                         f0=/dev/zero
13911                         f1=${testdir}/${tfile}
13912                 else
13913                         f0=${testdir}/${tfile}
13914                         f1=/dev/null
13915                 fi
13916
13917                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13918                         error "dd failed"
13919                 sync
13920                 cancel_lru_locks osc
13921
13922                 sum=$(do_facet ost1 $LCTL get_param \
13923                         "obdfilter.*.exports.*.stats" |
13924                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13925                                 $1 == ctr { sum += $7 }
13926                                 END { printf("%0.0f", sum) }')
13927
13928                 if ((sum != bs * count)); then
13929                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13930                 fi
13931         done
13932
13933         rm -rf $DIR/${tdir}
13934 }
13935 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13936
13937 test_133f() {
13938         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13939                 skip "too old lustre for get_param -R ($facet_ver)"
13940
13941         # verifying readability.
13942         $LCTL get_param -R '*' &> /dev/null
13943
13944         # Verifing writability with badarea_io.
13945         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13946         local skipped_params='force_lbug|changelog_mask|daemon_file'
13947         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13948                 egrep -v "$skipped_params" |
13949                 xargs -n 1 find $proc_dirs -name |
13950                 xargs -n 1 badarea_io ||
13951                 error "client badarea_io failed"
13952
13953         # remount the FS in case writes/reads /proc break the FS
13954         cleanup || error "failed to unmount"
13955         setup || error "failed to setup"
13956 }
13957 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13958
13959 test_133g() {
13960         remote_mds_nodsh && skip "remote MDS with nodsh"
13961         remote_ost_nodsh && skip "remote OST with nodsh"
13962
13963         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13964         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
13965         local facet
13966         for facet in mds1 ost1; do
13967                 local facet_ver=$(lustre_version_code $facet)
13968                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13969                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13970                 else
13971                         log "$facet: too old lustre for get_param -R"
13972                 fi
13973                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13974                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13975                                 tr -d = | egrep -v $skipped_params |
13976                                 xargs -n 1 find $proc_dirs -name |
13977                                 xargs -n 1 badarea_io" ||
13978                                         error "$facet badarea_io failed"
13979                 else
13980                         skip_noexit "$facet: too old lustre for get_param -R"
13981                 fi
13982         done
13983
13984         # remount the FS in case writes/reads /proc break the FS
13985         cleanup || error "failed to unmount"
13986         setup || error "failed to setup"
13987 }
13988 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13989
13990 test_133h() {
13991         remote_mds_nodsh && skip "remote MDS with nodsh"
13992         remote_ost_nodsh && skip "remote OST with nodsh"
13993         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13994                 skip "Need MDS version at least 2.9.54"
13995
13996         local facet
13997         for facet in client mds1 ost1; do
13998                 # Get the list of files that are missing the terminating newline
13999                 local plist=$(do_facet $facet
14000                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14001                 local ent
14002                 for ent in $plist; do
14003                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14004                                 awk -v FS='\v' -v RS='\v\v' \
14005                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14006                                         print FILENAME}'" 2>/dev/null)
14007                         [ -z $missing ] || {
14008                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14009                                 error "file does not end with newline: $facet-$ent"
14010                         }
14011                 done
14012         done
14013 }
14014 run_test 133h "Proc files should end with newlines"
14015
14016 test_134a() {
14017         remote_mds_nodsh && skip "remote MDS with nodsh"
14018         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14019                 skip "Need MDS version at least 2.7.54"
14020
14021         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14022         cancel_lru_locks mdc
14023
14024         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14025         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14026         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14027
14028         local nr=1000
14029         createmany -o $DIR/$tdir/f $nr ||
14030                 error "failed to create $nr files in $DIR/$tdir"
14031         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14032
14033         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14034         do_facet mds1 $LCTL set_param fail_loc=0x327
14035         do_facet mds1 $LCTL set_param fail_val=500
14036         touch $DIR/$tdir/m
14037
14038         echo "sleep 10 seconds ..."
14039         sleep 10
14040         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14041
14042         do_facet mds1 $LCTL set_param fail_loc=0
14043         do_facet mds1 $LCTL set_param fail_val=0
14044         [ $lck_cnt -lt $unused ] ||
14045                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14046
14047         rm $DIR/$tdir/m
14048         unlinkmany $DIR/$tdir/f $nr
14049 }
14050 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14051
14052 test_134b() {
14053         remote_mds_nodsh && skip "remote MDS with nodsh"
14054         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14055                 skip "Need MDS version at least 2.7.54"
14056
14057         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14058         cancel_lru_locks mdc
14059
14060         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14061                         ldlm.lock_reclaim_threshold_mb)
14062         # disable reclaim temporarily
14063         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14064
14065         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14066         do_facet mds1 $LCTL set_param fail_loc=0x328
14067         do_facet mds1 $LCTL set_param fail_val=500
14068
14069         $LCTL set_param debug=+trace
14070
14071         local nr=600
14072         createmany -o $DIR/$tdir/f $nr &
14073         local create_pid=$!
14074
14075         echo "Sleep $TIMEOUT seconds ..."
14076         sleep $TIMEOUT
14077         if ! ps -p $create_pid  > /dev/null 2>&1; then
14078                 do_facet mds1 $LCTL set_param fail_loc=0
14079                 do_facet mds1 $LCTL set_param fail_val=0
14080                 do_facet mds1 $LCTL set_param \
14081                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14082                 error "createmany finished incorrectly!"
14083         fi
14084         do_facet mds1 $LCTL set_param fail_loc=0
14085         do_facet mds1 $LCTL set_param fail_val=0
14086         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14087         wait $create_pid || return 1
14088
14089         unlinkmany $DIR/$tdir/f $nr
14090 }
14091 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14092
14093 test_135() {
14094         remote_mds_nodsh && skip "remote MDS with nodsh"
14095         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14096                 skip "Need MDS version at least 2.13.50"
14097         local fname
14098
14099         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14100
14101 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14102         #set only one record at plain llog
14103         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14104
14105         #fill already existed plain llog each 64767
14106         #wrapping whole catalog
14107         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14108
14109         createmany -o $DIR/$tdir/$tfile_ 64700
14110         for (( i = 0; i < 64700; i = i + 2 ))
14111         do
14112                 rm $DIR/$tdir/$tfile_$i &
14113                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14114                 local pid=$!
14115                 wait $pid
14116         done
14117
14118         #waiting osp synchronization
14119         wait_delete_completed
14120 }
14121 run_test 135 "Race catalog processing"
14122
14123 test_136() {
14124         remote_mds_nodsh && skip "remote MDS with nodsh"
14125         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14126                 skip "Need MDS version at least 2.13.50"
14127         local fname
14128
14129         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14130         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14131         #set only one record at plain llog
14132 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14133         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14134
14135         #fill already existed 2 plain llogs each 64767
14136         #wrapping whole catalog
14137         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14138         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14139         wait_delete_completed
14140
14141         createmany -o $DIR/$tdir/$tfile_ 10
14142         sleep 25
14143
14144         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14145         for (( i = 0; i < 10; i = i + 3 ))
14146         do
14147                 rm $DIR/$tdir/$tfile_$i &
14148                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14149                 local pid=$!
14150                 wait $pid
14151                 sleep 7
14152                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14153         done
14154
14155         #waiting osp synchronization
14156         wait_delete_completed
14157 }
14158 run_test 136 "Race catalog processing 2"
14159
14160 test_140() { #bug-17379
14161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14162
14163         test_mkdir $DIR/$tdir
14164         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14165         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14166
14167         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14168         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14169         local i=0
14170         while i=$((i + 1)); do
14171                 test_mkdir $i
14172                 cd $i || error "Changing to $i"
14173                 ln -s ../stat stat || error "Creating stat symlink"
14174                 # Read the symlink until ELOOP present,
14175                 # not LBUGing the system is considered success,
14176                 # we didn't overrun the stack.
14177                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14178                 if [ $ret -ne 0 ]; then
14179                         if [ $ret -eq 40 ]; then
14180                                 break  # -ELOOP
14181                         else
14182                                 error "Open stat symlink"
14183                                         return
14184                         fi
14185                 fi
14186         done
14187         i=$((i - 1))
14188         echo "The symlink depth = $i"
14189         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14190                 error "Invalid symlink depth"
14191
14192         # Test recursive symlink
14193         ln -s symlink_self symlink_self
14194         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14195         echo "open symlink_self returns $ret"
14196         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14197 }
14198 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14199
14200 test_150a() {
14201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14202
14203         local TF="$TMP/$tfile"
14204
14205         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14206         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14207         cp $TF $DIR/$tfile
14208         cancel_lru_locks $OSC
14209         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14210         remount_client $MOUNT
14211         df -P $MOUNT
14212         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14213
14214         $TRUNCATE $TF 6000
14215         $TRUNCATE $DIR/$tfile 6000
14216         cancel_lru_locks $OSC
14217         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14218
14219         echo "12345" >>$TF
14220         echo "12345" >>$DIR/$tfile
14221         cancel_lru_locks $OSC
14222         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14223
14224         echo "12345" >>$TF
14225         echo "12345" >>$DIR/$tfile
14226         cancel_lru_locks $OSC
14227         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14228 }
14229 run_test 150a "truncate/append tests"
14230
14231 test_150b() {
14232         check_set_fallocate_or_skip
14233
14234         touch $DIR/$tfile
14235         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14236         check_fallocate $DIR/$tfile || error "fallocate failed"
14237 }
14238 run_test 150b "Verify fallocate (prealloc) functionality"
14239
14240 test_150bb() {
14241         check_set_fallocate_or_skip
14242
14243         touch $DIR/$tfile
14244         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14245         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14246         > $DIR/$tfile
14247         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14248         # precomputed md5sum for 20MB of zeroes
14249         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14250         local sum=($(md5sum $DIR/$tfile))
14251
14252         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14253
14254         check_set_fallocate 1
14255
14256         > $DIR/$tfile
14257         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14258         sum=($(md5sum $DIR/$tfile))
14259
14260         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14261 }
14262 run_test 150bb "Verify fallocate modes both zero space"
14263
14264 test_150c() {
14265         check_set_fallocate_or_skip
14266         local striping="-c2"
14267
14268         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14269         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14270         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14271         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14272         local want=$((OSTCOUNT * 1048576))
14273
14274         # Must allocate all requested space, not more than 5% extra
14275         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14276                 error "bytes $bytes is not $want"
14277
14278         rm -f $DIR/$tfile
14279
14280         echo "verify fallocate on PFL file"
14281
14282         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14283
14284         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14285                 error "Create $DIR/$tfile failed"
14286         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14287                         error "fallocate failed"
14288         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14289         want=$((512 * 1048576))
14290
14291         # Must allocate all requested space, not more than 5% extra
14292         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14293                 error "bytes $bytes is not $want"
14294 }
14295 run_test 150c "Verify fallocate Size and Blocks"
14296
14297 test_150d() {
14298         check_set_fallocate_or_skip
14299         local striping="-c2"
14300
14301         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14302
14303         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14304         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14305                 error "setstripe failed"
14306         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14307         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14308         local want=$((OSTCOUNT * 1048576))
14309
14310         # Must allocate all requested space, not more than 5% extra
14311         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14312                 error "bytes $bytes is not $want"
14313 }
14314 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14315
14316 test_150e() {
14317         check_set_fallocate_or_skip
14318
14319         echo "df before:"
14320         $LFS df
14321         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14322         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14323                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14324
14325         # Find OST with Minimum Size
14326         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14327                        sort -un | head -1)
14328
14329         # Get 100MB per OST of the available space to reduce run time
14330         # else 60% of the available space if we are running SLOW tests
14331         if [ $SLOW == "no" ]; then
14332                 local space=$((1024 * 100 * OSTCOUNT))
14333         else
14334                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14335         fi
14336
14337         fallocate -l${space}k $DIR/$tfile ||
14338                 error "fallocate ${space}k $DIR/$tfile failed"
14339         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14340
14341         # get size immediately after fallocate. This should be correctly
14342         # updated
14343         local size=$(stat -c '%s' $DIR/$tfile)
14344         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14345
14346         # Sleep for a while for statfs to get updated. And not pull from cache.
14347         sleep 2
14348
14349         echo "df after fallocate:"
14350         $LFS df
14351
14352         (( size / 1024 == space )) || error "size $size != requested $space"
14353         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14354                 error "used $used < space $space"
14355
14356         rm $DIR/$tfile || error "rm failed"
14357         sync
14358         wait_delete_completed
14359
14360         echo "df after unlink:"
14361         $LFS df
14362 }
14363 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14364
14365 test_150f() {
14366         local size
14367         local blocks
14368         local want_size_before=20480 # in bytes
14369         local want_blocks_before=40 # 512 sized blocks
14370         local want_blocks_after=24  # 512 sized blocks
14371         local length=$(((want_blocks_before - want_blocks_after) * 512))
14372
14373         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14374                 skip "need at least 2.14.0 for fallocate punch"
14375
14376         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14377                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14378         fi
14379
14380         check_set_fallocate_or_skip
14381         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14382
14383         [[ "x$DOM" == "xyes" ]] &&
14384                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14385
14386         echo "Verify fallocate punch: Range within the file range"
14387         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14388                 error "dd failed for bs 4096 and count 5"
14389
14390         # Call fallocate with punch range which is within the file range
14391         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14392                 error "fallocate failed: offset 4096 and length $length"
14393         # client must see changes immediately after fallocate
14394         size=$(stat -c '%s' $DIR/$tfile)
14395         blocks=$(stat -c '%b' $DIR/$tfile)
14396
14397         # Verify punch worked.
14398         (( blocks == want_blocks_after )) ||
14399                 error "punch failed: blocks $blocks != $want_blocks_after"
14400
14401         (( size == want_size_before )) ||
14402                 error "punch failed: size $size != $want_size_before"
14403
14404         # Verify there is hole in file
14405         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14406         # precomputed md5sum
14407         local expect="4a9a834a2db02452929c0a348273b4aa"
14408
14409         cksum=($(md5sum $DIR/$tfile))
14410         [[ "${cksum[0]}" == "$expect" ]] ||
14411                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14412
14413         # Start second sub-case for fallocate punch.
14414         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14415         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14416                 error "dd failed for bs 4096 and count 5"
14417
14418         # Punch range less than block size will have no change in block count
14419         want_blocks_after=40  # 512 sized blocks
14420
14421         # Punch overlaps two blocks and less than blocksize
14422         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14423                 error "fallocate failed: offset 4000 length 3000"
14424         size=$(stat -c '%s' $DIR/$tfile)
14425         blocks=$(stat -c '%b' $DIR/$tfile)
14426
14427         # Verify punch worked.
14428         (( blocks == want_blocks_after )) ||
14429                 error "punch failed: blocks $blocks != $want_blocks_after"
14430
14431         (( size == want_size_before )) ||
14432                 error "punch failed: size $size != $want_size_before"
14433
14434         # Verify if range is really zero'ed out. We expect Zeros.
14435         # precomputed md5sum
14436         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14437         cksum=($(md5sum $DIR/$tfile))
14438         [[ "${cksum[0]}" == "$expect" ]] ||
14439                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14440 }
14441 run_test 150f "Verify fallocate punch functionality"
14442
14443 test_150g() {
14444         local space
14445         local size
14446         local blocks
14447         local blocks_after
14448         local size_after
14449         local BS=4096 # Block size in bytes
14450
14451         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14452                 skip "need at least 2.14.0 for fallocate punch"
14453
14454         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14455                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14456         fi
14457
14458         check_set_fallocate_or_skip
14459         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14460
14461         if [[ "x$DOM" == "xyes" ]]; then
14462                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14463                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14464         else
14465                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14466                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14467         fi
14468
14469         # Get 100MB per OST of the available space to reduce run time
14470         # else 60% of the available space if we are running SLOW tests
14471         if [ $SLOW == "no" ]; then
14472                 space=$((1024 * 100 * OSTCOUNT))
14473         else
14474                 # Find OST with Minimum Size
14475                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14476                         sort -un | head -1)
14477                 echo "min size OST: $space"
14478                 space=$(((space * 60)/100 * OSTCOUNT))
14479         fi
14480         # space in 1k units, round to 4k blocks
14481         local blkcount=$((space * 1024 / $BS))
14482
14483         echo "Verify fallocate punch: Very large Range"
14484         fallocate -l${space}k $DIR/$tfile ||
14485                 error "fallocate ${space}k $DIR/$tfile failed"
14486         # write 1M at the end, start and in the middle
14487         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14488                 error "dd failed: bs $BS count 256"
14489         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14490                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14491         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14492                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14493
14494         # Gather stats.
14495         size=$(stat -c '%s' $DIR/$tfile)
14496
14497         # gather punch length.
14498         local punch_size=$((size - (BS * 2)))
14499
14500         echo "punch_size = $punch_size"
14501         echo "size - punch_size: $((size - punch_size))"
14502         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14503
14504         # Call fallocate to punch all except 2 blocks. We leave the
14505         # first and the last block
14506         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14507         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14508                 error "fallocate failed: offset $BS length $punch_size"
14509
14510         size_after=$(stat -c '%s' $DIR/$tfile)
14511         blocks_after=$(stat -c '%b' $DIR/$tfile)
14512
14513         # Verify punch worked.
14514         # Size should be kept
14515         (( size == size_after )) ||
14516                 error "punch failed: size $size != $size_after"
14517
14518         # two 4k data blocks to remain plus possible 1 extra extent block
14519         (( blocks_after <= ((BS / 512) * 3) )) ||
14520                 error "too many blocks remains: $blocks_after"
14521
14522         # Verify that file has hole between the first and the last blocks
14523         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14524         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14525
14526         echo "Hole at [$hole_start, $hole_end)"
14527         (( hole_start == BS )) ||
14528                 error "no hole at offset $BS after punch"
14529
14530         (( hole_end == BS + punch_size )) ||
14531                 error "data at offset $hole_end < $((BS + punch_size))"
14532 }
14533 run_test 150g "Verify fallocate punch on large range"
14534
14535 #LU-2902 roc_hit was not able to read all values from lproc
14536 function roc_hit_init() {
14537         local list=$(comma_list $(osts_nodes))
14538         local dir=$DIR/$tdir-check
14539         local file=$dir/$tfile
14540         local BEFORE
14541         local AFTER
14542         local idx
14543
14544         test_mkdir $dir
14545         #use setstripe to do a write to every ost
14546         for i in $(seq 0 $((OSTCOUNT-1))); do
14547                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14548                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14549                 idx=$(printf %04x $i)
14550                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14551                         awk '$1 == "cache_access" {sum += $7}
14552                                 END { printf("%0.0f", sum) }')
14553
14554                 cancel_lru_locks osc
14555                 cat $file >/dev/null
14556
14557                 AFTER=$(get_osd_param $list *OST*$idx stats |
14558                         awk '$1 == "cache_access" {sum += $7}
14559                                 END { printf("%0.0f", sum) }')
14560
14561                 echo BEFORE:$BEFORE AFTER:$AFTER
14562                 if ! let "AFTER - BEFORE == 4"; then
14563                         rm -rf $dir
14564                         error "roc_hit is not safe to use"
14565                 fi
14566                 rm $file
14567         done
14568
14569         rm -rf $dir
14570 }
14571
14572 function roc_hit() {
14573         local list=$(comma_list $(osts_nodes))
14574         echo $(get_osd_param $list '' stats |
14575                 awk '$1 == "cache_hit" {sum += $7}
14576                         END { printf("%0.0f", sum) }')
14577 }
14578
14579 function set_cache() {
14580         local on=1
14581
14582         if [ "$2" == "off" ]; then
14583                 on=0;
14584         fi
14585         local list=$(comma_list $(osts_nodes))
14586         set_osd_param $list '' $1_cache_enable $on
14587
14588         cancel_lru_locks osc
14589 }
14590
14591 test_151() {
14592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14593         remote_ost_nodsh && skip "remote OST with nodsh"
14594
14595         local CPAGES=3
14596         local list=$(comma_list $(osts_nodes))
14597
14598         # check whether obdfilter is cache capable at all
14599         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14600                 skip "not cache-capable obdfilter"
14601         fi
14602
14603         # check cache is enabled on all obdfilters
14604         if get_osd_param $list '' read_cache_enable | grep 0; then
14605                 skip "oss cache is disabled"
14606         fi
14607
14608         set_osd_param $list '' writethrough_cache_enable 1
14609
14610         # check write cache is enabled on all obdfilters
14611         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14612                 skip "oss write cache is NOT enabled"
14613         fi
14614
14615         roc_hit_init
14616
14617         #define OBD_FAIL_OBD_NO_LRU  0x609
14618         do_nodes $list $LCTL set_param fail_loc=0x609
14619
14620         # pages should be in the case right after write
14621         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14622                 error "dd failed"
14623
14624         local BEFORE=$(roc_hit)
14625         cancel_lru_locks osc
14626         cat $DIR/$tfile >/dev/null
14627         local AFTER=$(roc_hit)
14628
14629         do_nodes $list $LCTL set_param fail_loc=0
14630
14631         if ! let "AFTER - BEFORE == CPAGES"; then
14632                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14633         fi
14634
14635         cancel_lru_locks osc
14636         # invalidates OST cache
14637         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14638         set_osd_param $list '' read_cache_enable 0
14639         cat $DIR/$tfile >/dev/null
14640
14641         # now data shouldn't be found in the cache
14642         BEFORE=$(roc_hit)
14643         cancel_lru_locks osc
14644         cat $DIR/$tfile >/dev/null
14645         AFTER=$(roc_hit)
14646         if let "AFTER - BEFORE != 0"; then
14647                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14648         fi
14649
14650         set_osd_param $list '' read_cache_enable 1
14651         rm -f $DIR/$tfile
14652 }
14653 run_test 151 "test cache on oss and controls ==============================="
14654
14655 test_152() {
14656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14657
14658         local TF="$TMP/$tfile"
14659
14660         # simulate ENOMEM during write
14661 #define OBD_FAIL_OST_NOMEM      0x226
14662         lctl set_param fail_loc=0x80000226
14663         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14664         cp $TF $DIR/$tfile
14665         sync || error "sync failed"
14666         lctl set_param fail_loc=0
14667
14668         # discard client's cache
14669         cancel_lru_locks osc
14670
14671         # simulate ENOMEM during read
14672         lctl set_param fail_loc=0x80000226
14673         cmp $TF $DIR/$tfile || error "cmp failed"
14674         lctl set_param fail_loc=0
14675
14676         rm -f $TF
14677 }
14678 run_test 152 "test read/write with enomem ============================"
14679
14680 test_153() {
14681         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14682 }
14683 run_test 153 "test if fdatasync does not crash ======================="
14684
14685 dot_lustre_fid_permission_check() {
14686         local fid=$1
14687         local ffid=$MOUNT/.lustre/fid/$fid
14688         local test_dir=$2
14689
14690         echo "stat fid $fid"
14691         stat $ffid > /dev/null || error "stat $ffid failed."
14692         echo "touch fid $fid"
14693         touch $ffid || error "touch $ffid failed."
14694         echo "write to fid $fid"
14695         cat /etc/hosts > $ffid || error "write $ffid failed."
14696         echo "read fid $fid"
14697         diff /etc/hosts $ffid || error "read $ffid failed."
14698         echo "append write to fid $fid"
14699         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14700         echo "rename fid $fid"
14701         mv $ffid $test_dir/$tfile.1 &&
14702                 error "rename $ffid to $tfile.1 should fail."
14703         touch $test_dir/$tfile.1
14704         mv $test_dir/$tfile.1 $ffid &&
14705                 error "rename $tfile.1 to $ffid should fail."
14706         rm -f $test_dir/$tfile.1
14707         echo "truncate fid $fid"
14708         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14709         echo "link fid $fid"
14710         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14711         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14712                 echo "setfacl fid $fid"
14713                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14714                 echo "getfacl fid $fid"
14715                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14716         fi
14717         echo "unlink fid $fid"
14718         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14719         echo "mknod fid $fid"
14720         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14721
14722         fid=[0xf00000400:0x1:0x0]
14723         ffid=$MOUNT/.lustre/fid/$fid
14724
14725         echo "stat non-exist fid $fid"
14726         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14727         echo "write to non-exist fid $fid"
14728         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14729         echo "link new fid $fid"
14730         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14731
14732         mkdir -p $test_dir/$tdir
14733         touch $test_dir/$tdir/$tfile
14734         fid=$($LFS path2fid $test_dir/$tdir)
14735         rc=$?
14736         [ $rc -ne 0 ] &&
14737                 error "error: could not get fid for $test_dir/$dir/$tfile."
14738
14739         ffid=$MOUNT/.lustre/fid/$fid
14740
14741         echo "ls $fid"
14742         ls $ffid > /dev/null || error "ls $ffid failed."
14743         echo "touch $fid/$tfile.1"
14744         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14745
14746         echo "touch $MOUNT/.lustre/fid/$tfile"
14747         touch $MOUNT/.lustre/fid/$tfile && \
14748                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14749
14750         echo "setxattr to $MOUNT/.lustre/fid"
14751         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14752
14753         echo "listxattr for $MOUNT/.lustre/fid"
14754         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14755
14756         echo "delxattr from $MOUNT/.lustre/fid"
14757         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14758
14759         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14760         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14761                 error "touch invalid fid should fail."
14762
14763         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14764         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14765                 error "touch non-normal fid should fail."
14766
14767         echo "rename $tdir to $MOUNT/.lustre/fid"
14768         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14769                 error "rename to $MOUNT/.lustre/fid should fail."
14770
14771         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14772         then            # LU-3547
14773                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14774                 local new_obf_mode=777
14775
14776                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14777                 chmod $new_obf_mode $DIR/.lustre/fid ||
14778                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14779
14780                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14781                 [ $obf_mode -eq $new_obf_mode ] ||
14782                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14783
14784                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14785                 chmod $old_obf_mode $DIR/.lustre/fid ||
14786                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14787         fi
14788
14789         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14790         fid=$($LFS path2fid $test_dir/$tfile-2)
14791
14792         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14793         then # LU-5424
14794                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14795                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14796                         error "create lov data thru .lustre failed"
14797         fi
14798         echo "cp /etc/passwd $test_dir/$tfile-2"
14799         cp /etc/passwd $test_dir/$tfile-2 ||
14800                 error "copy to $test_dir/$tfile-2 failed."
14801         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14802         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14803                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14804
14805         rm -rf $test_dir/tfile.lnk
14806         rm -rf $test_dir/$tfile-2
14807 }
14808
14809 test_154A() {
14810         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14811                 skip "Need MDS version at least 2.4.1"
14812
14813         local tf=$DIR/$tfile
14814         touch $tf
14815
14816         local fid=$($LFS path2fid $tf)
14817         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14818
14819         # check that we get the same pathname back
14820         local rootpath
14821         local found
14822         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14823                 echo "$rootpath $fid"
14824                 found=$($LFS fid2path $rootpath "$fid")
14825                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14826                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14827         done
14828
14829         # check wrong root path format
14830         rootpath=$MOUNT"_wrong"
14831         found=$($LFS fid2path $rootpath "$fid")
14832         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14833 }
14834 run_test 154A "lfs path2fid and fid2path basic checks"
14835
14836 test_154B() {
14837         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14838                 skip "Need MDS version at least 2.4.1"
14839
14840         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14841         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14842         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14843         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14844
14845         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14846         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14847
14848         # check that we get the same pathname
14849         echo "PFID: $PFID, name: $name"
14850         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14851         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14852         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14853                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14854
14855         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14856 }
14857 run_test 154B "verify the ll_decode_linkea tool"
14858
14859 test_154a() {
14860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14861         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14862         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14863                 skip "Need MDS version at least 2.2.51"
14864         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14865
14866         cp /etc/hosts $DIR/$tfile
14867
14868         fid=$($LFS path2fid $DIR/$tfile)
14869         rc=$?
14870         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14871
14872         dot_lustre_fid_permission_check "$fid" $DIR ||
14873                 error "dot lustre permission check $fid failed"
14874
14875         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14876
14877         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14878
14879         touch $MOUNT/.lustre/file &&
14880                 error "creation is not allowed under .lustre"
14881
14882         mkdir $MOUNT/.lustre/dir &&
14883                 error "mkdir is not allowed under .lustre"
14884
14885         rm -rf $DIR/$tfile
14886 }
14887 run_test 154a "Open-by-FID"
14888
14889 test_154b() {
14890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14891         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14893         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14894                 skip "Need MDS version at least 2.2.51"
14895
14896         local remote_dir=$DIR/$tdir/remote_dir
14897         local MDTIDX=1
14898         local rc=0
14899
14900         mkdir -p $DIR/$tdir
14901         $LFS mkdir -i $MDTIDX $remote_dir ||
14902                 error "create remote directory failed"
14903
14904         cp /etc/hosts $remote_dir/$tfile
14905
14906         fid=$($LFS path2fid $remote_dir/$tfile)
14907         rc=$?
14908         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14909
14910         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14911                 error "dot lustre permission check $fid failed"
14912         rm -rf $DIR/$tdir
14913 }
14914 run_test 154b "Open-by-FID for remote directory"
14915
14916 test_154c() {
14917         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14918                 skip "Need MDS version at least 2.4.1"
14919
14920         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14921         local FID1=$($LFS path2fid $DIR/$tfile.1)
14922         local FID2=$($LFS path2fid $DIR/$tfile.2)
14923         local FID3=$($LFS path2fid $DIR/$tfile.3)
14924
14925         local N=1
14926         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14927                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14928                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14929                 local want=FID$N
14930                 [ "$FID" = "${!want}" ] ||
14931                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14932                 N=$((N + 1))
14933         done
14934
14935         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14936         do
14937                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14938                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14939                 N=$((N + 1))
14940         done
14941 }
14942 run_test 154c "lfs path2fid and fid2path multiple arguments"
14943
14944 test_154d() {
14945         remote_mds_nodsh && skip "remote MDS with nodsh"
14946         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14947                 skip "Need MDS version at least 2.5.53"
14948
14949         if remote_mds; then
14950                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14951         else
14952                 nid="0@lo"
14953         fi
14954         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14955         local fd
14956         local cmd
14957
14958         rm -f $DIR/$tfile
14959         touch $DIR/$tfile
14960
14961         local fid=$($LFS path2fid $DIR/$tfile)
14962         # Open the file
14963         fd=$(free_fd)
14964         cmd="exec $fd<$DIR/$tfile"
14965         eval $cmd
14966         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14967         echo "$fid_list" | grep "$fid"
14968         rc=$?
14969
14970         cmd="exec $fd>/dev/null"
14971         eval $cmd
14972         if [ $rc -ne 0 ]; then
14973                 error "FID $fid not found in open files list $fid_list"
14974         fi
14975 }
14976 run_test 154d "Verify open file fid"
14977
14978 test_154e()
14979 {
14980         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14981                 skip "Need MDS version at least 2.6.50"
14982
14983         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14984                 error ".lustre returned by readdir"
14985         fi
14986 }
14987 run_test 154e ".lustre is not returned by readdir"
14988
14989 test_154f() {
14990         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14991
14992         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14993         mkdir_on_mdt0 $DIR/$tdir
14994         # test dirs inherit from its stripe
14995         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
14996         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
14997         cp /etc/hosts $DIR/$tdir/foo1/$tfile
14998         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
14999         touch $DIR/f
15000
15001         # get fid of parents
15002         local FID0=$($LFS path2fid $DIR/$tdir)
15003         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15004         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15005         local FID3=$($LFS path2fid $DIR)
15006
15007         # check that path2fid --parents returns expected <parent_fid>/name
15008         # 1) test for a directory (single parent)
15009         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15010         [ "$parent" == "$FID0/foo1" ] ||
15011                 error "expected parent: $FID0/foo1, got: $parent"
15012
15013         # 2) test for a file with nlink > 1 (multiple parents)
15014         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15015         echo "$parent" | grep -F "$FID1/$tfile" ||
15016                 error "$FID1/$tfile not returned in parent list"
15017         echo "$parent" | grep -F "$FID2/link" ||
15018                 error "$FID2/link not returned in parent list"
15019
15020         # 3) get parent by fid
15021         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15022         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15023         echo "$parent" | grep -F "$FID1/$tfile" ||
15024                 error "$FID1/$tfile not returned in parent list (by fid)"
15025         echo "$parent" | grep -F "$FID2/link" ||
15026                 error "$FID2/link not returned in parent list (by fid)"
15027
15028         # 4) test for entry in root directory
15029         parent=$($LFS path2fid --parents $DIR/f)
15030         echo "$parent" | grep -F "$FID3/f" ||
15031                 error "$FID3/f not returned in parent list"
15032
15033         # 5) test it on root directory
15034         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15035                 error "$MOUNT should not have parents"
15036
15037         # enable xattr caching and check that linkea is correctly updated
15038         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15039         save_lustre_params client "llite.*.xattr_cache" > $save
15040         lctl set_param llite.*.xattr_cache 1
15041
15042         # 6.1) linkea update on rename
15043         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15044
15045         # get parents by fid
15046         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15047         # foo1 should no longer be returned in parent list
15048         echo "$parent" | grep -F "$FID1" &&
15049                 error "$FID1 should no longer be in parent list"
15050         # the new path should appear
15051         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15052                 error "$FID2/$tfile.moved is not in parent list"
15053
15054         # 6.2) linkea update on unlink
15055         rm -f $DIR/$tdir/foo2/link
15056         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15057         # foo2/link should no longer be returned in parent list
15058         echo "$parent" | grep -F "$FID2/link" &&
15059                 error "$FID2/link should no longer be in parent list"
15060         true
15061
15062         rm -f $DIR/f
15063         restore_lustre_params < $save
15064         rm -f $save
15065 }
15066 run_test 154f "get parent fids by reading link ea"
15067
15068 test_154g()
15069 {
15070         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15071         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15072            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15073                 skip "Need MDS version at least 2.6.92"
15074
15075         mkdir_on_mdt0 $DIR/$tdir
15076         llapi_fid_test -d $DIR/$tdir
15077 }
15078 run_test 154g "various llapi FID tests"
15079
15080 test_155_small_load() {
15081     local temp=$TMP/$tfile
15082     local file=$DIR/$tfile
15083
15084     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15085         error "dd of=$temp bs=6096 count=1 failed"
15086     cp $temp $file
15087     cancel_lru_locks $OSC
15088     cmp $temp $file || error "$temp $file differ"
15089
15090     $TRUNCATE $temp 6000
15091     $TRUNCATE $file 6000
15092     cmp $temp $file || error "$temp $file differ (truncate1)"
15093
15094     echo "12345" >>$temp
15095     echo "12345" >>$file
15096     cmp $temp $file || error "$temp $file differ (append1)"
15097
15098     echo "12345" >>$temp
15099     echo "12345" >>$file
15100     cmp $temp $file || error "$temp $file differ (append2)"
15101
15102     rm -f $temp $file
15103     true
15104 }
15105
15106 test_155_big_load() {
15107         remote_ost_nodsh && skip "remote OST with nodsh"
15108
15109         local temp=$TMP/$tfile
15110         local file=$DIR/$tfile
15111
15112         free_min_max
15113         local cache_size=$(do_facet ost$((MAXI+1)) \
15114                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15115         local large_file_size=$((cache_size * 2))
15116
15117         echo "OSS cache size: $cache_size KB"
15118         echo "Large file size: $large_file_size KB"
15119
15120         [ $MAXV -le $large_file_size ] &&
15121                 skip_env "max available OST size needs > $large_file_size KB"
15122
15123         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15124
15125         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15126                 error "dd of=$temp bs=$large_file_size count=1k failed"
15127         cp $temp $file
15128         ls -lh $temp $file
15129         cancel_lru_locks osc
15130         cmp $temp $file || error "$temp $file differ"
15131
15132         rm -f $temp $file
15133         true
15134 }
15135
15136 save_writethrough() {
15137         local facets=$(get_facets OST)
15138
15139         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15140 }
15141
15142 test_155a() {
15143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15144
15145         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15146
15147         save_writethrough $p
15148
15149         set_cache read on
15150         set_cache writethrough on
15151         test_155_small_load
15152         restore_lustre_params < $p
15153         rm -f $p
15154 }
15155 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15156
15157 test_155b() {
15158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15159
15160         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15161
15162         save_writethrough $p
15163
15164         set_cache read on
15165         set_cache writethrough off
15166         test_155_small_load
15167         restore_lustre_params < $p
15168         rm -f $p
15169 }
15170 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15171
15172 test_155c() {
15173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15174
15175         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15176
15177         save_writethrough $p
15178
15179         set_cache read off
15180         set_cache writethrough on
15181         test_155_small_load
15182         restore_lustre_params < $p
15183         rm -f $p
15184 }
15185 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15186
15187 test_155d() {
15188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15189
15190         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15191
15192         save_writethrough $p
15193
15194         set_cache read off
15195         set_cache writethrough off
15196         test_155_small_load
15197         restore_lustre_params < $p
15198         rm -f $p
15199 }
15200 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15201
15202 test_155e() {
15203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15204
15205         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15206
15207         save_writethrough $p
15208
15209         set_cache read on
15210         set_cache writethrough on
15211         test_155_big_load
15212         restore_lustre_params < $p
15213         rm -f $p
15214 }
15215 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15216
15217 test_155f() {
15218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15219
15220         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15221
15222         save_writethrough $p
15223
15224         set_cache read on
15225         set_cache writethrough off
15226         test_155_big_load
15227         restore_lustre_params < $p
15228         rm -f $p
15229 }
15230 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15231
15232 test_155g() {
15233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15234
15235         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15236
15237         save_writethrough $p
15238
15239         set_cache read off
15240         set_cache writethrough on
15241         test_155_big_load
15242         restore_lustre_params < $p
15243         rm -f $p
15244 }
15245 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15246
15247 test_155h() {
15248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15249
15250         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15251
15252         save_writethrough $p
15253
15254         set_cache read off
15255         set_cache writethrough off
15256         test_155_big_load
15257         restore_lustre_params < $p
15258         rm -f $p
15259 }
15260 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15261
15262 test_156() {
15263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15264         remote_ost_nodsh && skip "remote OST with nodsh"
15265         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15266                 skip "stats not implemented on old servers"
15267         [ "$ost1_FSTYPE" = "zfs" ] &&
15268                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15269
15270         local CPAGES=3
15271         local BEFORE
15272         local AFTER
15273         local file="$DIR/$tfile"
15274         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15275
15276         save_writethrough $p
15277         roc_hit_init
15278
15279         log "Turn on read and write cache"
15280         set_cache read on
15281         set_cache writethrough on
15282
15283         log "Write data and read it back."
15284         log "Read should be satisfied from the cache."
15285         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15286         BEFORE=$(roc_hit)
15287         cancel_lru_locks osc
15288         cat $file >/dev/null
15289         AFTER=$(roc_hit)
15290         if ! let "AFTER - BEFORE == CPAGES"; then
15291                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15292         else
15293                 log "cache hits: before: $BEFORE, after: $AFTER"
15294         fi
15295
15296         log "Read again; it should be satisfied from the cache."
15297         BEFORE=$AFTER
15298         cancel_lru_locks osc
15299         cat $file >/dev/null
15300         AFTER=$(roc_hit)
15301         if ! let "AFTER - BEFORE == CPAGES"; then
15302                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15303         else
15304                 log "cache hits:: before: $BEFORE, after: $AFTER"
15305         fi
15306
15307         log "Turn off the read cache and turn on the write cache"
15308         set_cache read off
15309         set_cache writethrough on
15310
15311         log "Read again; it should be satisfied from the cache."
15312         BEFORE=$(roc_hit)
15313         cancel_lru_locks osc
15314         cat $file >/dev/null
15315         AFTER=$(roc_hit)
15316         if ! let "AFTER - BEFORE == CPAGES"; then
15317                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15318         else
15319                 log "cache hits:: before: $BEFORE, after: $AFTER"
15320         fi
15321
15322         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15323                 # > 2.12.56 uses pagecache if cached
15324                 log "Read again; it should not be satisfied from the cache."
15325                 BEFORE=$AFTER
15326                 cancel_lru_locks osc
15327                 cat $file >/dev/null
15328                 AFTER=$(roc_hit)
15329                 if ! let "AFTER - BEFORE == 0"; then
15330                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15331                 else
15332                         log "cache hits:: before: $BEFORE, after: $AFTER"
15333                 fi
15334         fi
15335
15336         log "Write data and read it back."
15337         log "Read should be satisfied from the cache."
15338         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15339         BEFORE=$(roc_hit)
15340         cancel_lru_locks osc
15341         cat $file >/dev/null
15342         AFTER=$(roc_hit)
15343         if ! let "AFTER - BEFORE == CPAGES"; then
15344                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15345         else
15346                 log "cache hits:: before: $BEFORE, after: $AFTER"
15347         fi
15348
15349         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15350                 # > 2.12.56 uses pagecache if cached
15351                 log "Read again; it should not be satisfied from the cache."
15352                 BEFORE=$AFTER
15353                 cancel_lru_locks osc
15354                 cat $file >/dev/null
15355                 AFTER=$(roc_hit)
15356                 if ! let "AFTER - BEFORE == 0"; then
15357                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15358                 else
15359                         log "cache hits:: before: $BEFORE, after: $AFTER"
15360                 fi
15361         fi
15362
15363         log "Turn off read and write cache"
15364         set_cache read off
15365         set_cache writethrough off
15366
15367         log "Write data and read it back"
15368         log "It should not be satisfied from the cache."
15369         rm -f $file
15370         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15371         cancel_lru_locks osc
15372         BEFORE=$(roc_hit)
15373         cat $file >/dev/null
15374         AFTER=$(roc_hit)
15375         if ! let "AFTER - BEFORE == 0"; then
15376                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15377         else
15378                 log "cache hits:: before: $BEFORE, after: $AFTER"
15379         fi
15380
15381         log "Turn on the read cache and turn off the write cache"
15382         set_cache read on
15383         set_cache writethrough off
15384
15385         log "Write data and read it back"
15386         log "It should not be satisfied from the cache."
15387         rm -f $file
15388         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15389         BEFORE=$(roc_hit)
15390         cancel_lru_locks osc
15391         cat $file >/dev/null
15392         AFTER=$(roc_hit)
15393         if ! let "AFTER - BEFORE == 0"; then
15394                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15395         else
15396                 log "cache hits:: before: $BEFORE, after: $AFTER"
15397         fi
15398
15399         log "Read again; it should be satisfied from the cache."
15400         BEFORE=$(roc_hit)
15401         cancel_lru_locks osc
15402         cat $file >/dev/null
15403         AFTER=$(roc_hit)
15404         if ! let "AFTER - BEFORE == CPAGES"; then
15405                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15406         else
15407                 log "cache hits:: before: $BEFORE, after: $AFTER"
15408         fi
15409
15410         restore_lustre_params < $p
15411         rm -f $p $file
15412 }
15413 run_test 156 "Verification of tunables"
15414
15415 test_160a() {
15416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15417         remote_mds_nodsh && skip "remote MDS with nodsh"
15418         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15419                 skip "Need MDS version at least 2.2.0"
15420
15421         changelog_register || error "changelog_register failed"
15422         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15423         changelog_users $SINGLEMDS | grep -q $cl_user ||
15424                 error "User $cl_user not found in changelog_users"
15425
15426         mkdir_on_mdt0 $DIR/$tdir
15427
15428         # change something
15429         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15430         changelog_clear 0 || error "changelog_clear failed"
15431         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15432         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15433         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15434         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15435         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15436         rm $DIR/$tdir/pics/desktop.jpg
15437
15438         echo "verifying changelog mask"
15439         changelog_chmask "-MKDIR"
15440         changelog_chmask "-CLOSE"
15441
15442         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15443         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15444
15445         changelog_chmask "+MKDIR"
15446         changelog_chmask "+CLOSE"
15447
15448         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15449         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15450
15451         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15452         CLOSES=$(changelog_dump | grep -c "CLOSE")
15453         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15454         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15455
15456         # verify contents
15457         echo "verifying target fid"
15458         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15459         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15460         [ "$fidc" == "$fidf" ] ||
15461                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15462         echo "verifying parent fid"
15463         # The FID returned from the Changelog may be the directory shard on
15464         # a different MDT, and not the FID returned by path2fid on the parent.
15465         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15466         # since this is what will matter when recreating this file in the tree.
15467         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15468         local pathp=$($LFS fid2path $MOUNT "$fidp")
15469         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15470                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15471
15472         echo "getting records for $cl_user"
15473         changelog_users $SINGLEMDS
15474         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15475         local nclr=3
15476         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15477                 error "changelog_clear failed"
15478         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15479         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15480         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15481                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15482
15483         local min0_rec=$(changelog_users $SINGLEMDS |
15484                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15485         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15486                           awk '{ print $1; exit; }')
15487
15488         changelog_dump | tail -n 5
15489         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15490         [ $first_rec == $((min0_rec + 1)) ] ||
15491                 error "first index should be $min0_rec + 1 not $first_rec"
15492
15493         # LU-3446 changelog index reset on MDT restart
15494         local cur_rec1=$(changelog_users $SINGLEMDS |
15495                          awk '/^current.index:/ { print $NF }')
15496         changelog_clear 0 ||
15497                 error "clear all changelog records for $cl_user failed"
15498         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15499         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15500                 error "Fail to start $SINGLEMDS"
15501         local cur_rec2=$(changelog_users $SINGLEMDS |
15502                          awk '/^current.index:/ { print $NF }')
15503         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15504         [ $cur_rec1 == $cur_rec2 ] ||
15505                 error "current index should be $cur_rec1 not $cur_rec2"
15506
15507         echo "verifying users from this test are deregistered"
15508         changelog_deregister || error "changelog_deregister failed"
15509         changelog_users $SINGLEMDS | grep -q $cl_user &&
15510                 error "User '$cl_user' still in changelog_users"
15511
15512         # lctl get_param -n mdd.*.changelog_users
15513         # current_index: 144
15514         # ID    index (idle seconds)
15515         # cl3   144   (2) mask=<list>
15516         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15517                 # this is the normal case where all users were deregistered
15518                 # make sure no new records are added when no users are present
15519                 local last_rec1=$(changelog_users $SINGLEMDS |
15520                                   awk '/^current.index:/ { print $NF }')
15521                 touch $DIR/$tdir/chloe
15522                 local last_rec2=$(changelog_users $SINGLEMDS |
15523                                   awk '/^current.index:/ { print $NF }')
15524                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15525                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15526         else
15527                 # any changelog users must be leftovers from a previous test
15528                 changelog_users $SINGLEMDS
15529                 echo "other changelog users; can't verify off"
15530         fi
15531 }
15532 run_test 160a "changelog sanity"
15533
15534 test_160b() { # LU-3587
15535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15536         remote_mds_nodsh && skip "remote MDS with nodsh"
15537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15538                 skip "Need MDS version at least 2.2.0"
15539
15540         changelog_register || error "changelog_register failed"
15541         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15542         changelog_users $SINGLEMDS | grep -q $cl_user ||
15543                 error "User '$cl_user' not found in changelog_users"
15544
15545         local longname1=$(str_repeat a 255)
15546         local longname2=$(str_repeat b 255)
15547
15548         cd $DIR
15549         echo "creating very long named file"
15550         touch $longname1 || error "create of '$longname1' failed"
15551         echo "renaming very long named file"
15552         mv $longname1 $longname2
15553
15554         changelog_dump | grep RENME | tail -n 5
15555         rm -f $longname2
15556 }
15557 run_test 160b "Verify that very long rename doesn't crash in changelog"
15558
15559 test_160c() {
15560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15561         remote_mds_nodsh && skip "remote MDS with nodsh"
15562
15563         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15564                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15565                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15566                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15567
15568         local rc=0
15569
15570         # Registration step
15571         changelog_register || error "changelog_register failed"
15572
15573         rm -rf $DIR/$tdir
15574         mkdir -p $DIR/$tdir
15575         $MCREATE $DIR/$tdir/foo_160c
15576         changelog_chmask "-TRUNC"
15577         $TRUNCATE $DIR/$tdir/foo_160c 200
15578         changelog_chmask "+TRUNC"
15579         $TRUNCATE $DIR/$tdir/foo_160c 199
15580         changelog_dump | tail -n 5
15581         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15582         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15583 }
15584 run_test 160c "verify that changelog log catch the truncate event"
15585
15586 test_160d() {
15587         remote_mds_nodsh && skip "remote MDS with nodsh"
15588         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15590         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15591                 skip "Need MDS version at least 2.7.60"
15592
15593         # Registration step
15594         changelog_register || error "changelog_register failed"
15595
15596         mkdir -p $DIR/$tdir/migrate_dir
15597         changelog_clear 0 || error "changelog_clear failed"
15598
15599         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15600         changelog_dump | tail -n 5
15601         local migrates=$(changelog_dump | grep -c "MIGRT")
15602         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15603 }
15604 run_test 160d "verify that changelog log catch the migrate event"
15605
15606 test_160e() {
15607         remote_mds_nodsh && skip "remote MDS with nodsh"
15608
15609         # Create a user
15610         changelog_register || error "changelog_register failed"
15611
15612         local MDT0=$(facet_svc $SINGLEMDS)
15613         local rc
15614
15615         # No user (expect fail)
15616         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15617         rc=$?
15618         if [ $rc -eq 0 ]; then
15619                 error "Should fail without user"
15620         elif [ $rc -ne 4 ]; then
15621                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15622         fi
15623
15624         # Delete a future user (expect fail)
15625         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15626         rc=$?
15627         if [ $rc -eq 0 ]; then
15628                 error "Deleted non-existant user cl77"
15629         elif [ $rc -ne 2 ]; then
15630                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15631         fi
15632
15633         # Clear to a bad index (1 billion should be safe)
15634         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15635         rc=$?
15636
15637         if [ $rc -eq 0 ]; then
15638                 error "Successfully cleared to invalid CL index"
15639         elif [ $rc -ne 22 ]; then
15640                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15641         fi
15642 }
15643 run_test 160e "changelog negative testing (should return errors)"
15644
15645 test_160f() {
15646         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15647         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15648                 skip "Need MDS version at least 2.10.56"
15649
15650         local mdts=$(comma_list $(mdts_nodes))
15651
15652         # Create a user
15653         changelog_register || error "first changelog_register failed"
15654         changelog_register || error "second changelog_register failed"
15655         local cl_users
15656         declare -A cl_user1
15657         declare -A cl_user2
15658         local user_rec1
15659         local user_rec2
15660         local i
15661
15662         # generate some changelog records to accumulate on each MDT
15663         # use all_char because created files should be evenly distributed
15664         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15665                 error "test_mkdir $tdir failed"
15666         log "$(date +%s): creating first files"
15667         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15668                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15669                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15670         done
15671
15672         # check changelogs have been generated
15673         local start=$SECONDS
15674         local idle_time=$((MDSCOUNT * 5 + 5))
15675         local nbcl=$(changelog_dump | wc -l)
15676         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15677
15678         for param in "changelog_max_idle_time=$idle_time" \
15679                      "changelog_gc=1" \
15680                      "changelog_min_gc_interval=2" \
15681                      "changelog_min_free_cat_entries=3"; do
15682                 local MDT0=$(facet_svc $SINGLEMDS)
15683                 local var="${param%=*}"
15684                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15685
15686                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15687                 do_nodes $mdts $LCTL set_param mdd.*.$param
15688         done
15689
15690         # force cl_user2 to be idle (1st part), but also cancel the
15691         # cl_user1 records so that it is not evicted later in the test.
15692         local sleep1=$((idle_time / 2))
15693         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15694         sleep $sleep1
15695
15696         # simulate changelog catalog almost full
15697         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15698         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15699
15700         for i in $(seq $MDSCOUNT); do
15701                 cl_users=(${CL_USERS[mds$i]})
15702                 cl_user1[mds$i]="${cl_users[0]}"
15703                 cl_user2[mds$i]="${cl_users[1]}"
15704
15705                 [ -n "${cl_user1[mds$i]}" ] ||
15706                         error "mds$i: no user registered"
15707                 [ -n "${cl_user2[mds$i]}" ] ||
15708                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15709
15710                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15711                 [ -n "$user_rec1" ] ||
15712                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15713                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15714                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15715                 [ -n "$user_rec2" ] ||
15716                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15717                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15718                      "$user_rec1 + 2 == $user_rec2"
15719                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15720                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15721                               "$user_rec1 + 2, but is $user_rec2"
15722                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15723                 [ -n "$user_rec2" ] ||
15724                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15725                 [ $user_rec1 == $user_rec2 ] ||
15726                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15727                               "$user_rec1, but is $user_rec2"
15728         done
15729
15730         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15731         local sleep2=$((idle_time - (SECONDS - start) + 1))
15732         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15733         sleep $sleep2
15734
15735         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15736         # cl_user1 should be OK because it recently processed records.
15737         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15738         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15739                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15740                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15741         done
15742
15743         # ensure gc thread is done
15744         for i in $(mdts_nodes); do
15745                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15746                         error "$i: GC-thread not done"
15747         done
15748
15749         local first_rec
15750         for (( i = 1; i <= MDSCOUNT; i++ )); do
15751                 # check cl_user1 still registered
15752                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15753                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15754                 # check cl_user2 unregistered
15755                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15756                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15757
15758                 # check changelogs are present and starting at $user_rec1 + 1
15759                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15760                 [ -n "$user_rec1" ] ||
15761                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15762                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15763                             awk '{ print $1; exit; }')
15764
15765                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15766                 [ $((user_rec1 + 1)) == $first_rec ] ||
15767                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15768         done
15769 }
15770 run_test 160f "changelog garbage collect (timestamped users)"
15771
15772 test_160g() {
15773         remote_mds_nodsh && skip "remote MDS with nodsh"
15774         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15775                 skip "Need MDS version at least 2.10.56"
15776
15777         local mdts=$(comma_list $(mdts_nodes))
15778
15779         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15780         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15781
15782         # Create a user
15783         changelog_register || error "first changelog_register failed"
15784         changelog_register || error "second changelog_register failed"
15785         local cl_users
15786         declare -A cl_user1
15787         declare -A cl_user2
15788         local user_rec1
15789         local user_rec2
15790         local i
15791
15792         # generate some changelog records to accumulate on each MDT
15793         # use all_char because created files should be evenly distributed
15794         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15795                 error "test_mkdir $tdir failed"
15796         for ((i = 0; i < MDSCOUNT; i++)); do
15797                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15798                         error "create $DIR/$tdir/d$i.1 failed"
15799         done
15800
15801         # check changelogs have been generated
15802         local nbcl=$(changelog_dump | wc -l)
15803         (( $nbcl > 0 )) || error "no changelogs found"
15804
15805         # reduce the max_idle_indexes value to make sure we exceed it
15806         for param in "changelog_max_idle_indexes=1" \
15807                      "changelog_gc=1" \
15808                      "changelog_min_gc_interval=2" \
15809                      "changelog_min_free_cat_entries=3"; do
15810                 local MDT0=$(facet_svc $SINGLEMDS)
15811                 local var="${param%=*}"
15812                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15813
15814                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15815                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15816                         error "unable to set mdd.*.$param"
15817         done
15818
15819         # simulate changelog catalog almost full
15820         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15821         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15822
15823         local start=$SECONDS
15824         for i in $(seq $MDSCOUNT); do
15825                 cl_users=(${CL_USERS[mds$i]})
15826                 cl_user1[mds$i]="${cl_users[0]}"
15827                 cl_user2[mds$i]="${cl_users[1]}"
15828
15829                 [ -n "${cl_user1[mds$i]}" ] ||
15830                         error "mds$i: no user registered"
15831                 [ -n "${cl_user2[mds$i]}" ] ||
15832                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15833
15834                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15835                 [ -n "$user_rec1" ] ||
15836                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15837                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15838                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15839                 [ -n "$user_rec2" ] ||
15840                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15841                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15842                      "$user_rec1 + 2 == $user_rec2"
15843                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15844                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15845                               "$user_rec1 + 2, but is $user_rec2"
15846                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15847                 [ -n "$user_rec2" ] ||
15848                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15849                 [ $user_rec1 == $user_rec2 ] ||
15850                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15851                               "$user_rec1, but is $user_rec2"
15852         done
15853
15854         # ensure we are past the previous changelog_min_gc_interval set above
15855         local sleep2=$((start + 2 - SECONDS))
15856         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15857
15858         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15859         # cl_user1 should be OK because it recently processed records.
15860         for ((i = 0; i < MDSCOUNT; i++)); do
15861                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15862                         error "create $DIR/$tdir/d$i.3 failed"
15863         done
15864
15865         # ensure gc thread is done
15866         for i in $(mdts_nodes); do
15867                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15868                         error "$i: GC-thread not done"
15869         done
15870
15871         local first_rec
15872         for (( i = 1; i <= MDSCOUNT; i++ )); do
15873                 # check cl_user1 still registered
15874                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15875                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15876                 # check cl_user2 unregistered
15877                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15878                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15879
15880                 # check changelogs are present and starting at $user_rec1 + 1
15881                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15882                 [ -n "$user_rec1" ] ||
15883                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15884                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15885                             awk '{ print $1; exit; }')
15886
15887                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15888                 [ $((user_rec1 + 1)) == $first_rec ] ||
15889                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15890         done
15891 }
15892 run_test 160g "changelog garbage collect (old users)"
15893
15894 test_160h() {
15895         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15896         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15897                 skip "Need MDS version at least 2.10.56"
15898
15899         local mdts=$(comma_list $(mdts_nodes))
15900
15901         # Create a user
15902         changelog_register || error "first changelog_register failed"
15903         changelog_register || error "second changelog_register failed"
15904         local cl_users
15905         declare -A cl_user1
15906         declare -A cl_user2
15907         local user_rec1
15908         local user_rec2
15909         local i
15910
15911         # generate some changelog records to accumulate on each MDT
15912         # use all_char because created files should be evenly distributed
15913         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15914                 error "test_mkdir $tdir failed"
15915         for ((i = 0; i < MDSCOUNT; i++)); do
15916                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15917                         error "create $DIR/$tdir/d$i.1 failed"
15918         done
15919
15920         # check changelogs have been generated
15921         local nbcl=$(changelog_dump | wc -l)
15922         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15923
15924         for param in "changelog_max_idle_time=10" \
15925                      "changelog_gc=1" \
15926                      "changelog_min_gc_interval=2"; do
15927                 local MDT0=$(facet_svc $SINGLEMDS)
15928                 local var="${param%=*}"
15929                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15930
15931                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15932                 do_nodes $mdts $LCTL set_param mdd.*.$param
15933         done
15934
15935         # force cl_user2 to be idle (1st part)
15936         sleep 9
15937
15938         for i in $(seq $MDSCOUNT); do
15939                 cl_users=(${CL_USERS[mds$i]})
15940                 cl_user1[mds$i]="${cl_users[0]}"
15941                 cl_user2[mds$i]="${cl_users[1]}"
15942
15943                 [ -n "${cl_user1[mds$i]}" ] ||
15944                         error "mds$i: no user registered"
15945                 [ -n "${cl_user2[mds$i]}" ] ||
15946                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15947
15948                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15949                 [ -n "$user_rec1" ] ||
15950                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15951                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15952                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15953                 [ -n "$user_rec2" ] ||
15954                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15955                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15956                      "$user_rec1 + 2 == $user_rec2"
15957                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15958                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15959                               "$user_rec1 + 2, but is $user_rec2"
15960                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15961                 [ -n "$user_rec2" ] ||
15962                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15963                 [ $user_rec1 == $user_rec2 ] ||
15964                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15965                               "$user_rec1, but is $user_rec2"
15966         done
15967
15968         # force cl_user2 to be idle (2nd part) and to reach
15969         # changelog_max_idle_time
15970         sleep 2
15971
15972         # force each GC-thread start and block then
15973         # one per MDT/MDD, set fail_val accordingly
15974         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15975         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15976
15977         # generate more changelogs to trigger fail_loc
15978         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15979                 error "create $DIR/$tdir/${tfile}bis failed"
15980
15981         # stop MDT to stop GC-thread, should be done in back-ground as it will
15982         # block waiting for the thread to be released and exit
15983         declare -A stop_pids
15984         for i in $(seq $MDSCOUNT); do
15985                 stop mds$i &
15986                 stop_pids[mds$i]=$!
15987         done
15988
15989         for i in $(mdts_nodes); do
15990                 local facet
15991                 local nb=0
15992                 local facets=$(facets_up_on_host $i)
15993
15994                 for facet in ${facets//,/ }; do
15995                         if [[ $facet == mds* ]]; then
15996                                 nb=$((nb + 1))
15997                         fi
15998                 done
15999                 # ensure each MDS's gc threads are still present and all in "R"
16000                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16001                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16002                         error "$i: expected $nb GC-thread"
16003                 wait_update $i \
16004                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16005                         "R" 20 ||
16006                         error "$i: GC-thread not found in R-state"
16007                 # check umounts of each MDT on MDS have reached kthread_stop()
16008                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16009                         error "$i: expected $nb umount"
16010                 wait_update $i \
16011                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16012                         error "$i: umount not found in D-state"
16013         done
16014
16015         # release all GC-threads
16016         do_nodes $mdts $LCTL set_param fail_loc=0
16017
16018         # wait for MDT stop to complete
16019         for i in $(seq $MDSCOUNT); do
16020                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16021         done
16022
16023         # XXX
16024         # may try to check if any orphan changelog records are present
16025         # via ldiskfs/zfs and llog_reader...
16026
16027         # re-start/mount MDTs
16028         for i in $(seq $MDSCOUNT); do
16029                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16030                         error "Fail to start mds$i"
16031         done
16032
16033         local first_rec
16034         for i in $(seq $MDSCOUNT); do
16035                 # check cl_user1 still registered
16036                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16037                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16038                 # check cl_user2 unregistered
16039                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16040                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16041
16042                 # check changelogs are present and starting at $user_rec1 + 1
16043                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16044                 [ -n "$user_rec1" ] ||
16045                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16046                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16047                             awk '{ print $1; exit; }')
16048
16049                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16050                 [ $((user_rec1 + 1)) == $first_rec ] ||
16051                         error "mds$i: first index should be $user_rec1 + 1, " \
16052                               "but is $first_rec"
16053         done
16054 }
16055 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16056               "during mount"
16057
16058 test_160i() {
16059
16060         local mdts=$(comma_list $(mdts_nodes))
16061
16062         changelog_register || error "first changelog_register failed"
16063
16064         # generate some changelog records to accumulate on each MDT
16065         # use all_char because created files should be evenly distributed
16066         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16067                 error "test_mkdir $tdir failed"
16068         for ((i = 0; i < MDSCOUNT; i++)); do
16069                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16070                         error "create $DIR/$tdir/d$i.1 failed"
16071         done
16072
16073         # check changelogs have been generated
16074         local nbcl=$(changelog_dump | wc -l)
16075         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16076
16077         # simulate race between register and unregister
16078         # XXX as fail_loc is set per-MDS, with DNE configs the race
16079         # simulation will only occur for one MDT per MDS and for the
16080         # others the normal race scenario will take place
16081         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16082         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16083         do_nodes $mdts $LCTL set_param fail_val=1
16084
16085         # unregister 1st user
16086         changelog_deregister &
16087         local pid1=$!
16088         # wait some time for deregister work to reach race rdv
16089         sleep 2
16090         # register 2nd user
16091         changelog_register || error "2nd user register failed"
16092
16093         wait $pid1 || error "1st user deregister failed"
16094
16095         local i
16096         local last_rec
16097         declare -A LAST_REC
16098         for i in $(seq $MDSCOUNT); do
16099                 if changelog_users mds$i | grep "^cl"; then
16100                         # make sure new records are added with one user present
16101                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16102                                           awk '/^current.index:/ { print $NF }')
16103                 else
16104                         error "mds$i has no user registered"
16105                 fi
16106         done
16107
16108         # generate more changelog records to accumulate on each MDT
16109         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16110                 error "create $DIR/$tdir/${tfile}bis failed"
16111
16112         for i in $(seq $MDSCOUNT); do
16113                 last_rec=$(changelog_users $SINGLEMDS |
16114                            awk '/^current.index:/ { print $NF }')
16115                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16116                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16117                         error "changelogs are off on mds$i"
16118         done
16119 }
16120 run_test 160i "changelog user register/unregister race"
16121
16122 test_160j() {
16123         remote_mds_nodsh && skip "remote MDS with nodsh"
16124         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16125                 skip "Need MDS version at least 2.12.56"
16126
16127         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16128         stack_trap "umount $MOUNT2" EXIT
16129
16130         changelog_register || error "first changelog_register failed"
16131         stack_trap "changelog_deregister" EXIT
16132
16133         # generate some changelog
16134         # use all_char because created files should be evenly distributed
16135         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16136                 error "mkdir $tdir failed"
16137         for ((i = 0; i < MDSCOUNT; i++)); do
16138                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16139                         error "create $DIR/$tdir/d$i.1 failed"
16140         done
16141
16142         # open the changelog device
16143         exec 3>/dev/changelog-$FSNAME-MDT0000
16144         stack_trap "exec 3>&-" EXIT
16145         exec 4</dev/changelog-$FSNAME-MDT0000
16146         stack_trap "exec 4<&-" EXIT
16147
16148         # umount the first lustre mount
16149         umount $MOUNT
16150         stack_trap "mount_client $MOUNT" EXIT
16151
16152         # read changelog, which may or may not fail, but should not crash
16153         cat <&4 >/dev/null
16154
16155         # clear changelog
16156         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16157         changelog_users $SINGLEMDS | grep -q $cl_user ||
16158                 error "User $cl_user not found in changelog_users"
16159
16160         printf 'clear:'$cl_user':0' >&3
16161 }
16162 run_test 160j "client can be umounted while its chanangelog is being used"
16163
16164 test_160k() {
16165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16166         remote_mds_nodsh && skip "remote MDS with nodsh"
16167
16168         mkdir -p $DIR/$tdir/1/1
16169
16170         changelog_register || error "changelog_register failed"
16171         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16172
16173         changelog_users $SINGLEMDS | grep -q $cl_user ||
16174                 error "User '$cl_user' not found in changelog_users"
16175 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16176         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16177         rmdir $DIR/$tdir/1/1 & sleep 1
16178         mkdir $DIR/$tdir/2
16179         touch $DIR/$tdir/2/2
16180         rm -rf $DIR/$tdir/2
16181
16182         wait
16183         sleep 4
16184
16185         changelog_dump | grep rmdir || error "rmdir not recorded"
16186 }
16187 run_test 160k "Verify that changelog records are not lost"
16188
16189 # Verifies that a file passed as a parameter has recently had an operation
16190 # performed on it that has generated an MTIME changelog which contains the
16191 # correct parent FID. As files might reside on a different MDT from the
16192 # parent directory in DNE configurations, the FIDs are translated to paths
16193 # before being compared, which should be identical
16194 compare_mtime_changelog() {
16195         local file="${1}"
16196         local mdtidx
16197         local mtime
16198         local cl_fid
16199         local pdir
16200         local dir
16201
16202         mdtidx=$($LFS getstripe --mdt-index $file)
16203         mdtidx=$(printf "%04x" $mdtidx)
16204
16205         # Obtain the parent FID from the MTIME changelog
16206         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16207         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16208
16209         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16210         [ -z "$cl_fid" ] && error "parent FID not present"
16211
16212         # Verify that the path for the parent FID is the same as the path for
16213         # the test directory
16214         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16215
16216         dir=$(dirname $1)
16217
16218         [[ "${pdir%/}" == "$dir" ]] ||
16219                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16220 }
16221
16222 test_160l() {
16223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16224
16225         remote_mds_nodsh && skip "remote MDS with nodsh"
16226         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16227                 skip "Need MDS version at least 2.13.55"
16228
16229         local cl_user
16230
16231         changelog_register || error "changelog_register failed"
16232         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16233
16234         changelog_users $SINGLEMDS | grep -q $cl_user ||
16235                 error "User '$cl_user' not found in changelog_users"
16236
16237         # Clear some types so that MTIME changelogs are generated
16238         changelog_chmask "-CREAT"
16239         changelog_chmask "-CLOSE"
16240
16241         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16242
16243         # Test CL_MTIME during setattr
16244         touch $DIR/$tdir/$tfile
16245         compare_mtime_changelog $DIR/$tdir/$tfile
16246
16247         # Test CL_MTIME during close
16248         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16249         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16250 }
16251 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16252
16253 test_160m() {
16254         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16255         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16256                 skip "Need MDS version at least 2.14.51"
16257         local cl_users
16258         local cl_user1
16259         local cl_user2
16260         local pid1
16261
16262         # Create a user
16263         changelog_register || error "first changelog_register failed"
16264         changelog_register || error "second changelog_register failed"
16265
16266         cl_users=(${CL_USERS[mds1]})
16267         cl_user1="${cl_users[0]}"
16268         cl_user2="${cl_users[1]}"
16269         # generate some changelog records to accumulate on MDT0
16270         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16271         createmany -m $DIR/$tdir/$tfile 50 ||
16272                 error "create $DIR/$tdir/$tfile failed"
16273         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16274         rm -f $DIR/$tdir
16275
16276         # check changelogs have been generated
16277         local nbcl=$(changelog_dump | wc -l)
16278         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16279
16280 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16281         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16282
16283         __changelog_clear mds1 $cl_user1 +10
16284         __changelog_clear mds1 $cl_user2 0 &
16285         pid1=$!
16286         sleep 2
16287         __changelog_clear mds1 $cl_user1 0 ||
16288                 error "fail to cancel record for $cl_user1"
16289         wait $pid1
16290         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16291 }
16292 run_test 160m "Changelog clear race"
16293
16294 test_160n() {
16295         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16296         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16297                 skip "Need MDS version at least 2.14.51"
16298         local cl_users
16299         local cl_user1
16300         local cl_user2
16301         local pid1
16302         local first_rec
16303         local last_rec=0
16304
16305         # Create a user
16306         changelog_register || error "first changelog_register failed"
16307
16308         cl_users=(${CL_USERS[mds1]})
16309         cl_user1="${cl_users[0]}"
16310
16311         # generate some changelog records to accumulate on MDT0
16312         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16313         first_rec=$(changelog_users $SINGLEMDS |
16314                         awk '/^current.index:/ { print $NF }')
16315         while (( last_rec < (( first_rec + 65000)) )); do
16316                 createmany -m $DIR/$tdir/$tfile 10000 ||
16317                         error "create $DIR/$tdir/$tfile failed"
16318
16319                 for i in $(seq 0 10000); do
16320                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16321                                 > /dev/null
16322                 done
16323
16324                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16325                         error "unlinkmany failed unlink"
16326                 last_rec=$(changelog_users $SINGLEMDS |
16327                         awk '/^current.index:/ { print $NF }')
16328                 echo last record $last_rec
16329                 (( last_rec == 0 )) && error "no changelog found"
16330         done
16331
16332 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16333         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16334
16335         __changelog_clear mds1 $cl_user1 0 &
16336         pid1=$!
16337         sleep 2
16338         __changelog_clear mds1 $cl_user1 0 ||
16339                 error "fail to cancel record for $cl_user1"
16340         wait $pid1
16341         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16342 }
16343 run_test 160n "Changelog destroy race"
16344
16345 test_160o() {
16346         local mdt="$(facet_svc $SINGLEMDS)"
16347
16348         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16349         remote_mds_nodsh && skip "remote MDS with nodsh"
16350         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16351                 skip "Need MDS version at least 2.14.52"
16352
16353         changelog_register --user test_160o -m unlnk+close+open ||
16354                 error "changelog_register failed"
16355         # drop server mask so it doesn't interfere
16356         do_facet $SINGLEMDS $LCTL --device $mdt \
16357                                 changelog_register -u "Tt3_-#" &&
16358                 error "bad symbols in name should fail"
16359
16360         do_facet $SINGLEMDS $LCTL --device $mdt \
16361                                 changelog_register -u test_160o &&
16362                 error "the same name registration should fail"
16363
16364         do_facet $SINGLEMDS $LCTL --device $mdt \
16365                         changelog_register -u test_160toolongname &&
16366                 error "too long name registration should fail"
16367
16368         changelog_chmask "MARK+HSM"
16369         lctl get_param mdd.*.changelog*mask
16370         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16371         changelog_users $SINGLEMDS | grep -q $cl_user ||
16372                 error "User $cl_user not found in changelog_users"
16373         #verify username
16374         echo $cl_user | grep -q test_160o ||
16375                 error "User $cl_user has no specific name 'test160o'"
16376
16377         # change something
16378         changelog_clear 0 || error "changelog_clear failed"
16379         # generate some changelog records to accumulate on MDT0
16380         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16381         touch $DIR/$tdir/$tfile                 # open 1
16382
16383         OPENS=$(changelog_dump | grep -c "OPEN")
16384         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16385
16386         # must be no MKDIR it wasn't set as user mask
16387         MKDIR=$(changelog_dump | grep -c "MKDIR")
16388         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16389
16390         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16391                                 mdd.$mdt.changelog_current_mask -n)
16392         # register maskless user
16393         changelog_register || error "changelog_register failed"
16394         # effective mask should be not changed because it is not minimal
16395         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16396                                 mdd.$mdt.changelog_current_mask -n)
16397         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16398         # set server mask to minimal value
16399         changelog_chmask "MARK"
16400         # check effective mask again, should be treated as DEFMASK now
16401         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16402                                 mdd.$mdt.changelog_current_mask -n)
16403         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16404
16405         do_facet $SINGLEMDS $LCTL --device $mdt \
16406                                 changelog_deregister -u test_160o ||
16407                 error "cannot deregister by name"
16408 }
16409 run_test 160o "changelog user name and mask"
16410
16411 test_160p() {
16412         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16413         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16414                 skip "Need MDS version at least 2.14.51"
16415         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16416         local cl_users
16417         local cl_user1
16418         local entry_count
16419
16420         # Create a user
16421         changelog_register || error "first changelog_register failed"
16422
16423         cl_users=(${CL_USERS[mds1]})
16424         cl_user1="${cl_users[0]}"
16425
16426         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16427         createmany -m $DIR/$tdir/$tfile 50 ||
16428                 error "create $DIR/$tdir/$tfile failed"
16429         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16430         rm -rf $DIR/$tdir
16431
16432         # check changelogs have been generated
16433         entry_count=$(changelog_dump | wc -l)
16434         ((entry_count != 0)) || error "no changelog entries found"
16435
16436         # remove changelog_users and check that orphan entries are removed
16437         stop mds1
16438         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16439         start mds1 || error "cannot start mdt"
16440         entry_count=$(changelog_dump | wc -l)
16441         ((entry_count == 0)) ||
16442                 error "found $entry_count changelog entries, expected none"
16443 }
16444 run_test 160p "Changelog orphan cleanup with no users"
16445
16446 test_161a() {
16447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16448
16449         test_mkdir -c1 $DIR/$tdir
16450         cp /etc/hosts $DIR/$tdir/$tfile
16451         test_mkdir -c1 $DIR/$tdir/foo1
16452         test_mkdir -c1 $DIR/$tdir/foo2
16453         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16454         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16455         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16456         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16457         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16458         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16459                 $LFS fid2path $DIR $FID
16460                 error "bad link ea"
16461         fi
16462         # middle
16463         rm $DIR/$tdir/foo2/zachary
16464         # last
16465         rm $DIR/$tdir/foo2/thor
16466         # first
16467         rm $DIR/$tdir/$tfile
16468         # rename
16469         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16470         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16471                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16472         rm $DIR/$tdir/foo2/maggie
16473
16474         # overflow the EA
16475         local longname=$tfile.avg_len_is_thirty_two_
16476         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16477                 error_noexit 'failed to unlink many hardlinks'" EXIT
16478         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16479                 error "failed to hardlink many files"
16480         links=$($LFS fid2path $DIR $FID | wc -l)
16481         echo -n "${links}/1000 links in link EA"
16482         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16483 }
16484 run_test 161a "link ea sanity"
16485
16486 test_161b() {
16487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16488         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16489
16490         local MDTIDX=1
16491         local remote_dir=$DIR/$tdir/remote_dir
16492
16493         mkdir -p $DIR/$tdir
16494         $LFS mkdir -i $MDTIDX $remote_dir ||
16495                 error "create remote directory failed"
16496
16497         cp /etc/hosts $remote_dir/$tfile
16498         mkdir -p $remote_dir/foo1
16499         mkdir -p $remote_dir/foo2
16500         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16501         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16502         ln $remote_dir/$tfile $remote_dir/foo1/luna
16503         ln $remote_dir/$tfile $remote_dir/foo2/thor
16504
16505         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16506                      tr -d ']')
16507         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16508                 $LFS fid2path $DIR $FID
16509                 error "bad link ea"
16510         fi
16511         # middle
16512         rm $remote_dir/foo2/zachary
16513         # last
16514         rm $remote_dir/foo2/thor
16515         # first
16516         rm $remote_dir/$tfile
16517         # rename
16518         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16519         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16520         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16521                 $LFS fid2path $DIR $FID
16522                 error "bad link rename"
16523         fi
16524         rm $remote_dir/foo2/maggie
16525
16526         # overflow the EA
16527         local longname=filename_avg_len_is_thirty_two_
16528         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16529                 error "failed to hardlink many files"
16530         links=$($LFS fid2path $DIR $FID | wc -l)
16531         echo -n "${links}/1000 links in link EA"
16532         [[ ${links} -gt 60 ]] ||
16533                 error "expected at least 60 links in link EA"
16534         unlinkmany $remote_dir/foo2/$longname 1000 ||
16535         error "failed to unlink many hardlinks"
16536 }
16537 run_test 161b "link ea sanity under remote directory"
16538
16539 test_161c() {
16540         remote_mds_nodsh && skip "remote MDS with nodsh"
16541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16542         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16543                 skip "Need MDS version at least 2.1.5"
16544
16545         # define CLF_RENAME_LAST 0x0001
16546         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16547         changelog_register || error "changelog_register failed"
16548
16549         rm -rf $DIR/$tdir
16550         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16551         touch $DIR/$tdir/foo_161c
16552         touch $DIR/$tdir/bar_161c
16553         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16554         changelog_dump | grep RENME | tail -n 5
16555         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16556         changelog_clear 0 || error "changelog_clear failed"
16557         if [ x$flags != "x0x1" ]; then
16558                 error "flag $flags is not 0x1"
16559         fi
16560
16561         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16562         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16563         touch $DIR/$tdir/foo_161c
16564         touch $DIR/$tdir/bar_161c
16565         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16566         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16567         changelog_dump | grep RENME | tail -n 5
16568         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16569         changelog_clear 0 || error "changelog_clear failed"
16570         if [ x$flags != "x0x0" ]; then
16571                 error "flag $flags is not 0x0"
16572         fi
16573         echo "rename overwrite a target having nlink > 1," \
16574                 "changelog record has flags of $flags"
16575
16576         # rename doesn't overwrite a target (changelog flag 0x0)
16577         touch $DIR/$tdir/foo_161c
16578         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16579         changelog_dump | grep RENME | tail -n 5
16580         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16581         changelog_clear 0 || error "changelog_clear failed"
16582         if [ x$flags != "x0x0" ]; then
16583                 error "flag $flags is not 0x0"
16584         fi
16585         echo "rename doesn't overwrite a target," \
16586                 "changelog record has flags of $flags"
16587
16588         # define CLF_UNLINK_LAST 0x0001
16589         # unlink a file having nlink = 1 (changelog flag 0x1)
16590         rm -f $DIR/$tdir/foo2_161c
16591         changelog_dump | grep UNLNK | tail -n 5
16592         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16593         changelog_clear 0 || error "changelog_clear failed"
16594         if [ x$flags != "x0x1" ]; then
16595                 error "flag $flags is not 0x1"
16596         fi
16597         echo "unlink a file having nlink = 1," \
16598                 "changelog record has flags of $flags"
16599
16600         # unlink a file having nlink > 1 (changelog flag 0x0)
16601         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16602         rm -f $DIR/$tdir/foobar_161c
16603         changelog_dump | grep UNLNK | tail -n 5
16604         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16605         changelog_clear 0 || error "changelog_clear failed"
16606         if [ x$flags != "x0x0" ]; then
16607                 error "flag $flags is not 0x0"
16608         fi
16609         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16610 }
16611 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16612
16613 test_161d() {
16614         remote_mds_nodsh && skip "remote MDS with nodsh"
16615         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16616
16617         local pid
16618         local fid
16619
16620         changelog_register || error "changelog_register failed"
16621
16622         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16623         # interfer with $MOUNT/.lustre/fid/ access
16624         mkdir $DIR/$tdir
16625         [[ $? -eq 0 ]] || error "mkdir failed"
16626
16627         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16628         $LCTL set_param fail_loc=0x8000140c
16629         # 5s pause
16630         $LCTL set_param fail_val=5
16631
16632         # create file
16633         echo foofoo > $DIR/$tdir/$tfile &
16634         pid=$!
16635
16636         # wait for create to be delayed
16637         sleep 2
16638
16639         ps -p $pid
16640         [[ $? -eq 0 ]] || error "create should be blocked"
16641
16642         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16643         stack_trap "rm -f $tempfile"
16644         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16645         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16646         # some delay may occur during ChangeLog publishing and file read just
16647         # above, that could allow file write to happen finally
16648         [[ -s $tempfile ]] && echo "file should be empty"
16649
16650         $LCTL set_param fail_loc=0
16651
16652         wait $pid
16653         [[ $? -eq 0 ]] || error "create failed"
16654 }
16655 run_test 161d "create with concurrent .lustre/fid access"
16656
16657 check_path() {
16658         local expected="$1"
16659         shift
16660         local fid="$2"
16661
16662         local path
16663         path=$($LFS fid2path "$@")
16664         local rc=$?
16665
16666         if [ $rc -ne 0 ]; then
16667                 error "path looked up of '$expected' failed: rc=$rc"
16668         elif [ "$path" != "$expected" ]; then
16669                 error "path looked up '$path' instead of '$expected'"
16670         else
16671                 echo "FID '$fid' resolves to path '$path' as expected"
16672         fi
16673 }
16674
16675 test_162a() { # was test_162
16676         test_mkdir -p -c1 $DIR/$tdir/d2
16677         touch $DIR/$tdir/d2/$tfile
16678         touch $DIR/$tdir/d2/x1
16679         touch $DIR/$tdir/d2/x2
16680         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16681         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16682         # regular file
16683         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16684         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16685
16686         # softlink
16687         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16688         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16689         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16690
16691         # softlink to wrong file
16692         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16693         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16694         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16695
16696         # hardlink
16697         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16698         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16699         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16700         # fid2path dir/fsname should both work
16701         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16702         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16703
16704         # hardlink count: check that there are 2 links
16705         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16706         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16707
16708         # hardlink indexing: remove the first link
16709         rm $DIR/$tdir/d2/p/q/r/hlink
16710         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16711 }
16712 run_test 162a "path lookup sanity"
16713
16714 test_162b() {
16715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16716         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16717
16718         mkdir $DIR/$tdir
16719         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16720                                 error "create striped dir failed"
16721
16722         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16723                                         tail -n 1 | awk '{print $2}')
16724         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16725
16726         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16727         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16728
16729         # regular file
16730         for ((i=0;i<5;i++)); do
16731                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16732                         error "get fid for f$i failed"
16733                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16734
16735                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16736                         error "get fid for d$i failed"
16737                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16738         done
16739
16740         return 0
16741 }
16742 run_test 162b "striped directory path lookup sanity"
16743
16744 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16745 test_162c() {
16746         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16747                 skip "Need MDS version at least 2.7.51"
16748
16749         local lpath=$tdir.local
16750         local rpath=$tdir.remote
16751
16752         test_mkdir $DIR/$lpath
16753         test_mkdir $DIR/$rpath
16754
16755         for ((i = 0; i <= 101; i++)); do
16756                 lpath="$lpath/$i"
16757                 mkdir $DIR/$lpath
16758                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16759                         error "get fid for local directory $DIR/$lpath failed"
16760                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16761
16762                 rpath="$rpath/$i"
16763                 test_mkdir $DIR/$rpath
16764                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16765                         error "get fid for remote directory $DIR/$rpath failed"
16766                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16767         done
16768
16769         return 0
16770 }
16771 run_test 162c "fid2path works with paths 100 or more directories deep"
16772
16773 oalr_event_count() {
16774         local event="${1}"
16775         local trace="${2}"
16776
16777         awk -v name="${FSNAME}-OST0000" \
16778             -v event="${event}" \
16779             '$1 == "TRACE" && $2 == event && $3 == name' \
16780             "${trace}" |
16781         wc -l
16782 }
16783
16784 oalr_expect_event_count() {
16785         local event="${1}"
16786         local trace="${2}"
16787         local expect="${3}"
16788         local count
16789
16790         count=$(oalr_event_count "${event}" "${trace}")
16791         if ((count == expect)); then
16792                 return 0
16793         fi
16794
16795         error_noexit "${event} event count was '${count}', expected ${expect}"
16796         cat "${trace}" >&2
16797         exit 1
16798 }
16799
16800 cleanup_165() {
16801         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16802         stop ost1
16803         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16804 }
16805
16806 setup_165() {
16807         sync # Flush previous IOs so we can count log entries.
16808         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16809         stack_trap cleanup_165 EXIT
16810 }
16811
16812 test_165a() {
16813         local trace="/tmp/${tfile}.trace"
16814         local rc
16815         local count
16816
16817         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16818                 skip "OFD access log unsupported"
16819
16820         setup_165
16821         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16822         sleep 5
16823
16824         do_facet ost1 ofd_access_log_reader --list
16825         stop ost1
16826
16827         do_facet ost1 killall -TERM ofd_access_log_reader
16828         wait
16829         rc=$?
16830
16831         if ((rc != 0)); then
16832                 error "ofd_access_log_reader exited with rc = '${rc}'"
16833         fi
16834
16835         # Parse trace file for discovery events:
16836         oalr_expect_event_count alr_log_add "${trace}" 1
16837         oalr_expect_event_count alr_log_eof "${trace}" 1
16838         oalr_expect_event_count alr_log_free "${trace}" 1
16839 }
16840 run_test 165a "ofd access log discovery"
16841
16842 test_165b() {
16843         local trace="/tmp/${tfile}.trace"
16844         local file="${DIR}/${tfile}"
16845         local pfid1
16846         local pfid2
16847         local -a entry
16848         local rc
16849         local count
16850         local size
16851         local flags
16852
16853         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16854                 skip "OFD access log unsupported"
16855
16856         setup_165
16857         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16858         sleep 5
16859
16860         do_facet ost1 ofd_access_log_reader --list
16861
16862         lfs setstripe -c 1 -i 0 "${file}"
16863         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16864                 error "cannot create '${file}'"
16865
16866         sleep 5
16867         do_facet ost1 killall -TERM ofd_access_log_reader
16868         wait
16869         rc=$?
16870
16871         if ((rc != 0)); then
16872                 error "ofd_access_log_reader exited with rc = '${rc}'"
16873         fi
16874
16875         oalr_expect_event_count alr_log_entry "${trace}" 1
16876
16877         pfid1=$($LFS path2fid "${file}")
16878
16879         # 1     2             3   4    5     6   7    8    9     10
16880         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16881         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16882
16883         echo "entry = '${entry[*]}'" >&2
16884
16885         pfid2=${entry[4]}
16886         if [[ "${pfid1}" != "${pfid2}" ]]; then
16887                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16888         fi
16889
16890         size=${entry[8]}
16891         if ((size != 1048576)); then
16892                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16893         fi
16894
16895         flags=${entry[10]}
16896         if [[ "${flags}" != "w" ]]; then
16897                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16898         fi
16899
16900         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16901         sleep 5
16902
16903         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16904                 error "cannot read '${file}'"
16905         sleep 5
16906
16907         do_facet ost1 killall -TERM ofd_access_log_reader
16908         wait
16909         rc=$?
16910
16911         if ((rc != 0)); then
16912                 error "ofd_access_log_reader exited with rc = '${rc}'"
16913         fi
16914
16915         oalr_expect_event_count alr_log_entry "${trace}" 1
16916
16917         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16918         echo "entry = '${entry[*]}'" >&2
16919
16920         pfid2=${entry[4]}
16921         if [[ "${pfid1}" != "${pfid2}" ]]; then
16922                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16923         fi
16924
16925         size=${entry[8]}
16926         if ((size != 524288)); then
16927                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16928         fi
16929
16930         flags=${entry[10]}
16931         if [[ "${flags}" != "r" ]]; then
16932                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16933         fi
16934 }
16935 run_test 165b "ofd access log entries are produced and consumed"
16936
16937 test_165c() {
16938         local trace="/tmp/${tfile}.trace"
16939         local file="${DIR}/${tdir}/${tfile}"
16940
16941         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16942                 skip "OFD access log unsupported"
16943
16944         test_mkdir "${DIR}/${tdir}"
16945
16946         setup_165
16947         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16948         sleep 5
16949
16950         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16951
16952         # 4096 / 64 = 64. Create twice as many entries.
16953         for ((i = 0; i < 128; i++)); do
16954                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16955                         error "cannot create file"
16956         done
16957
16958         sync
16959
16960         do_facet ost1 killall -TERM ofd_access_log_reader
16961         wait
16962         rc=$?
16963         if ((rc != 0)); then
16964                 error "ofd_access_log_reader exited with rc = '${rc}'"
16965         fi
16966
16967         unlinkmany  "${file}-%d" 128
16968 }
16969 run_test 165c "full ofd access logs do not block IOs"
16970
16971 oal_get_read_count() {
16972         local stats="$1"
16973
16974         # STATS lustre-OST0001 alr_read_count 1
16975
16976         do_facet ost1 cat "${stats}" |
16977         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16978              END { print count; }'
16979 }
16980
16981 oal_expect_read_count() {
16982         local stats="$1"
16983         local count
16984         local expect="$2"
16985
16986         # Ask ofd_access_log_reader to write stats.
16987         do_facet ost1 killall -USR1 ofd_access_log_reader
16988
16989         # Allow some time for things to happen.
16990         sleep 1
16991
16992         count=$(oal_get_read_count "${stats}")
16993         if ((count == expect)); then
16994                 return 0
16995         fi
16996
16997         error_noexit "bad read count, got ${count}, expected ${expect}"
16998         do_facet ost1 cat "${stats}" >&2
16999         exit 1
17000 }
17001
17002 test_165d() {
17003         local stats="/tmp/${tfile}.stats"
17004         local file="${DIR}/${tdir}/${tfile}"
17005         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17006
17007         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17008                 skip "OFD access log unsupported"
17009
17010         test_mkdir "${DIR}/${tdir}"
17011
17012         setup_165
17013         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17014         sleep 5
17015
17016         lfs setstripe -c 1 -i 0 "${file}"
17017
17018         do_facet ost1 lctl set_param "${param}=rw"
17019         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17020                 error "cannot create '${file}'"
17021         oal_expect_read_count "${stats}" 1
17022
17023         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17024                 error "cannot read '${file}'"
17025         oal_expect_read_count "${stats}" 2
17026
17027         do_facet ost1 lctl set_param "${param}=r"
17028         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17029                 error "cannot create '${file}'"
17030         oal_expect_read_count "${stats}" 2
17031
17032         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17033                 error "cannot read '${file}'"
17034         oal_expect_read_count "${stats}" 3
17035
17036         do_facet ost1 lctl set_param "${param}=w"
17037         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17038                 error "cannot create '${file}'"
17039         oal_expect_read_count "${stats}" 4
17040
17041         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17042                 error "cannot read '${file}'"
17043         oal_expect_read_count "${stats}" 4
17044
17045         do_facet ost1 lctl set_param "${param}=0"
17046         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17047                 error "cannot create '${file}'"
17048         oal_expect_read_count "${stats}" 4
17049
17050         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17051                 error "cannot read '${file}'"
17052         oal_expect_read_count "${stats}" 4
17053
17054         do_facet ost1 killall -TERM ofd_access_log_reader
17055         wait
17056         rc=$?
17057         if ((rc != 0)); then
17058                 error "ofd_access_log_reader exited with rc = '${rc}'"
17059         fi
17060 }
17061 run_test 165d "ofd_access_log mask works"
17062
17063 test_165e() {
17064         local stats="/tmp/${tfile}.stats"
17065         local file0="${DIR}/${tdir}-0/${tfile}"
17066         local file1="${DIR}/${tdir}-1/${tfile}"
17067
17068         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17069                 skip "OFD access log unsupported"
17070
17071         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17072
17073         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17074         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17075
17076         lfs setstripe -c 1 -i 0 "${file0}"
17077         lfs setstripe -c 1 -i 0 "${file1}"
17078
17079         setup_165
17080         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17081         sleep 5
17082
17083         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17084                 error "cannot create '${file0}'"
17085         sync
17086         oal_expect_read_count "${stats}" 0
17087
17088         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17089                 error "cannot create '${file1}'"
17090         sync
17091         oal_expect_read_count "${stats}" 1
17092
17093         do_facet ost1 killall -TERM ofd_access_log_reader
17094         wait
17095         rc=$?
17096         if ((rc != 0)); then
17097                 error "ofd_access_log_reader exited with rc = '${rc}'"
17098         fi
17099 }
17100 run_test 165e "ofd_access_log MDT index filter works"
17101
17102 test_165f() {
17103         local trace="/tmp/${tfile}.trace"
17104         local rc
17105         local count
17106
17107         setup_165
17108         do_facet ost1 timeout 60 ofd_access_log_reader \
17109                 --exit-on-close --debug=- --trace=- > "${trace}" &
17110         sleep 5
17111         stop ost1
17112
17113         wait
17114         rc=$?
17115
17116         if ((rc != 0)); then
17117                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17118                 cat "${trace}"
17119                 exit 1
17120         fi
17121 }
17122 run_test 165f "ofd_access_log_reader --exit-on-close works"
17123
17124 test_169() {
17125         # do directio so as not to populate the page cache
17126         log "creating a 10 Mb file"
17127         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17128                 error "multiop failed while creating a file"
17129         log "starting reads"
17130         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17131         log "truncating the file"
17132         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17133                 error "multiop failed while truncating the file"
17134         log "killing dd"
17135         kill %+ || true # reads might have finished
17136         echo "wait until dd is finished"
17137         wait
17138         log "removing the temporary file"
17139         rm -rf $DIR/$tfile || error "tmp file removal failed"
17140 }
17141 run_test 169 "parallel read and truncate should not deadlock"
17142
17143 test_170() {
17144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17145
17146         $LCTL clear     # bug 18514
17147         $LCTL debug_daemon start $TMP/${tfile}_log_good
17148         touch $DIR/$tfile
17149         $LCTL debug_daemon stop
17150         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17151                 error "sed failed to read log_good"
17152
17153         $LCTL debug_daemon start $TMP/${tfile}_log_good
17154         rm -rf $DIR/$tfile
17155         $LCTL debug_daemon stop
17156
17157         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17158                error "lctl df log_bad failed"
17159
17160         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17161         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17162
17163         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17164         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17165
17166         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17167                 error "bad_line good_line1 good_line2 are empty"
17168
17169         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17170         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17171         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17172
17173         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17174         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17175         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17176
17177         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17178                 error "bad_line_new good_line_new are empty"
17179
17180         local expected_good=$((good_line1 + good_line2*2))
17181
17182         rm -f $TMP/${tfile}*
17183         # LU-231, short malformed line may not be counted into bad lines
17184         if [ $bad_line -ne $bad_line_new ] &&
17185                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17186                 error "expected $bad_line bad lines, but got $bad_line_new"
17187                 return 1
17188         fi
17189
17190         if [ $expected_good -ne $good_line_new ]; then
17191                 error "expected $expected_good good lines, but got $good_line_new"
17192                 return 2
17193         fi
17194         true
17195 }
17196 run_test 170 "test lctl df to handle corrupted log ====================="
17197
17198 test_171() { # bug20592
17199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17200
17201         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17202         $LCTL set_param fail_loc=0x50e
17203         $LCTL set_param fail_val=3000
17204         multiop_bg_pause $DIR/$tfile O_s || true
17205         local MULTIPID=$!
17206         kill -USR1 $MULTIPID
17207         # cause log dump
17208         sleep 3
17209         wait $MULTIPID
17210         if dmesg | grep "recursive fault"; then
17211                 error "caught a recursive fault"
17212         fi
17213         $LCTL set_param fail_loc=0
17214         true
17215 }
17216 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17217
17218 # it would be good to share it with obdfilter-survey/iokit-libecho code
17219 setup_obdecho_osc () {
17220         local rc=0
17221         local ost_nid=$1
17222         local obdfilter_name=$2
17223         echo "Creating new osc for $obdfilter_name on $ost_nid"
17224         # make sure we can find loopback nid
17225         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17226
17227         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17228                            ${obdfilter_name}_osc_UUID || rc=2; }
17229         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17230                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17231         return $rc
17232 }
17233
17234 cleanup_obdecho_osc () {
17235         local obdfilter_name=$1
17236         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17237         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17238         return 0
17239 }
17240
17241 obdecho_test() {
17242         local OBD=$1
17243         local node=$2
17244         local pages=${3:-64}
17245         local rc=0
17246         local id
17247
17248         local count=10
17249         local obd_size=$(get_obd_size $node $OBD)
17250         local page_size=$(get_page_size $node)
17251         if [[ -n "$obd_size" ]]; then
17252                 local new_count=$((obd_size / (pages * page_size / 1024)))
17253                 [[ $new_count -ge $count ]] || count=$new_count
17254         fi
17255
17256         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17257         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17258                            rc=2; }
17259         if [ $rc -eq 0 ]; then
17260             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17261             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17262         fi
17263         echo "New object id is $id"
17264         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17265                            rc=4; }
17266         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17267                            "test_brw $count w v $pages $id" || rc=4; }
17268         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17269                            rc=4; }
17270         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17271                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17272         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17273                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17274         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17275         return $rc
17276 }
17277
17278 test_180a() {
17279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17280
17281         if ! [ -d /sys/fs/lustre/echo_client ] &&
17282            ! module_loaded obdecho; then
17283                 load_module obdecho/obdecho &&
17284                         stack_trap "rmmod obdecho" EXIT ||
17285                         error "unable to load obdecho on client"
17286         fi
17287
17288         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17289         local host=$($LCTL get_param -n osc.$osc.import |
17290                      awk '/current_connection:/ { print $2 }' )
17291         local target=$($LCTL get_param -n osc.$osc.import |
17292                        awk '/target:/ { print $2 }' )
17293         target=${target%_UUID}
17294
17295         if [ -n "$target" ]; then
17296                 setup_obdecho_osc $host $target &&
17297                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17298                         { error "obdecho setup failed with $?"; return; }
17299
17300                 obdecho_test ${target}_osc client ||
17301                         error "obdecho_test failed on ${target}_osc"
17302         else
17303                 $LCTL get_param osc.$osc.import
17304                 error "there is no osc.$osc.import target"
17305         fi
17306 }
17307 run_test 180a "test obdecho on osc"
17308
17309 test_180b() {
17310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17311         remote_ost_nodsh && skip "remote OST with nodsh"
17312
17313         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17314                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17315                 error "failed to load module obdecho"
17316
17317         local target=$(do_facet ost1 $LCTL dl |
17318                        awk '/obdfilter/ { print $4; exit; }')
17319
17320         if [ -n "$target" ]; then
17321                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17322         else
17323                 do_facet ost1 $LCTL dl
17324                 error "there is no obdfilter target on ost1"
17325         fi
17326 }
17327 run_test 180b "test obdecho directly on obdfilter"
17328
17329 test_180c() { # LU-2598
17330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17331         remote_ost_nodsh && skip "remote OST with nodsh"
17332         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17333                 skip "Need MDS version at least 2.4.0"
17334
17335         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17336                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17337                 error "failed to load module obdecho"
17338
17339         local target=$(do_facet ost1 $LCTL dl |
17340                        awk '/obdfilter/ { print $4; exit; }')
17341
17342         if [ -n "$target" ]; then
17343                 local pages=16384 # 64MB bulk I/O RPC size
17344
17345                 obdecho_test "$target" ost1 "$pages" ||
17346                         error "obdecho_test with pages=$pages failed with $?"
17347         else
17348                 do_facet ost1 $LCTL dl
17349                 error "there is no obdfilter target on ost1"
17350         fi
17351 }
17352 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17353
17354 test_181() { # bug 22177
17355         test_mkdir $DIR/$tdir
17356         # create enough files to index the directory
17357         createmany -o $DIR/$tdir/foobar 4000
17358         # print attributes for debug purpose
17359         lsattr -d .
17360         # open dir
17361         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17362         MULTIPID=$!
17363         # remove the files & current working dir
17364         unlinkmany $DIR/$tdir/foobar 4000
17365         rmdir $DIR/$tdir
17366         kill -USR1 $MULTIPID
17367         wait $MULTIPID
17368         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17369         return 0
17370 }
17371 run_test 181 "Test open-unlinked dir ========================"
17372
17373 test_182() {
17374         local fcount=1000
17375         local tcount=10
17376
17377         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17378
17379         $LCTL set_param mdc.*.rpc_stats=clear
17380
17381         for (( i = 0; i < $tcount; i++ )) ; do
17382                 mkdir $DIR/$tdir/$i
17383         done
17384
17385         for (( i = 0; i < $tcount; i++ )) ; do
17386                 createmany -o $DIR/$tdir/$i/f- $fcount &
17387         done
17388         wait
17389
17390         for (( i = 0; i < $tcount; i++ )) ; do
17391                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17392         done
17393         wait
17394
17395         $LCTL get_param mdc.*.rpc_stats
17396
17397         rm -rf $DIR/$tdir
17398 }
17399 run_test 182 "Test parallel modify metadata operations ================"
17400
17401 test_183() { # LU-2275
17402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17403         remote_mds_nodsh && skip "remote MDS with nodsh"
17404         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17405                 skip "Need MDS version at least 2.3.56"
17406
17407         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17408         echo aaa > $DIR/$tdir/$tfile
17409
17410 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17411         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17412
17413         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17414         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17415
17416         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17417
17418         # Flush negative dentry cache
17419         touch $DIR/$tdir/$tfile
17420
17421         # We are not checking for any leaked references here, they'll
17422         # become evident next time we do cleanup with module unload.
17423         rm -rf $DIR/$tdir
17424 }
17425 run_test 183 "No crash or request leak in case of strange dispositions ========"
17426
17427 # test suite 184 is for LU-2016, LU-2017
17428 test_184a() {
17429         check_swap_layouts_support
17430
17431         dir0=$DIR/$tdir/$testnum
17432         test_mkdir -p -c1 $dir0
17433         ref1=/etc/passwd
17434         ref2=/etc/group
17435         file1=$dir0/f1
17436         file2=$dir0/f2
17437         $LFS setstripe -c1 $file1
17438         cp $ref1 $file1
17439         $LFS setstripe -c2 $file2
17440         cp $ref2 $file2
17441         gen1=$($LFS getstripe -g $file1)
17442         gen2=$($LFS getstripe -g $file2)
17443
17444         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17445         gen=$($LFS getstripe -g $file1)
17446         [[ $gen1 != $gen ]] ||
17447                 "Layout generation on $file1 does not change"
17448         gen=$($LFS getstripe -g $file2)
17449         [[ $gen2 != $gen ]] ||
17450                 "Layout generation on $file2 does not change"
17451
17452         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17453         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17454
17455         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17456 }
17457 run_test 184a "Basic layout swap"
17458
17459 test_184b() {
17460         check_swap_layouts_support
17461
17462         dir0=$DIR/$tdir/$testnum
17463         mkdir -p $dir0 || error "creating dir $dir0"
17464         file1=$dir0/f1
17465         file2=$dir0/f2
17466         file3=$dir0/f3
17467         dir1=$dir0/d1
17468         dir2=$dir0/d2
17469         mkdir $dir1 $dir2
17470         $LFS setstripe -c1 $file1
17471         $LFS setstripe -c2 $file2
17472         $LFS setstripe -c1 $file3
17473         chown $RUNAS_ID $file3
17474         gen1=$($LFS getstripe -g $file1)
17475         gen2=$($LFS getstripe -g $file2)
17476
17477         $LFS swap_layouts $dir1 $dir2 &&
17478                 error "swap of directories layouts should fail"
17479         $LFS swap_layouts $dir1 $file1 &&
17480                 error "swap of directory and file layouts should fail"
17481         $RUNAS $LFS swap_layouts $file1 $file2 &&
17482                 error "swap of file we cannot write should fail"
17483         $LFS swap_layouts $file1 $file3 &&
17484                 error "swap of file with different owner should fail"
17485         /bin/true # to clear error code
17486 }
17487 run_test 184b "Forbidden layout swap (will generate errors)"
17488
17489 test_184c() {
17490         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17491         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17492         check_swap_layouts_support
17493         check_swap_layout_no_dom $DIR
17494
17495         local dir0=$DIR/$tdir/$testnum
17496         mkdir -p $dir0 || error "creating dir $dir0"
17497
17498         local ref1=$dir0/ref1
17499         local ref2=$dir0/ref2
17500         local file1=$dir0/file1
17501         local file2=$dir0/file2
17502         # create a file large enough for the concurrent test
17503         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17504         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17505         echo "ref file size: ref1($(stat -c %s $ref1))," \
17506              "ref2($(stat -c %s $ref2))"
17507
17508         cp $ref2 $file2
17509         dd if=$ref1 of=$file1 bs=16k &
17510         local DD_PID=$!
17511
17512         # Make sure dd starts to copy file, but wait at most 5 seconds
17513         local loops=0
17514         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17515
17516         $LFS swap_layouts $file1 $file2
17517         local rc=$?
17518         wait $DD_PID
17519         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17520         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17521
17522         # how many bytes copied before swapping layout
17523         local copied=$(stat -c %s $file2)
17524         local remaining=$(stat -c %s $ref1)
17525         remaining=$((remaining - copied))
17526         echo "Copied $copied bytes before swapping layout..."
17527
17528         cmp -n $copied $file1 $ref2 | grep differ &&
17529                 error "Content mismatch [0, $copied) of ref2 and file1"
17530         cmp -n $copied $file2 $ref1 ||
17531                 error "Content mismatch [0, $copied) of ref1 and file2"
17532         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17533                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17534
17535         # clean up
17536         rm -f $ref1 $ref2 $file1 $file2
17537 }
17538 run_test 184c "Concurrent write and layout swap"
17539
17540 test_184d() {
17541         check_swap_layouts_support
17542         check_swap_layout_no_dom $DIR
17543         [ -z "$(which getfattr 2>/dev/null)" ] &&
17544                 skip_env "no getfattr command"
17545
17546         local file1=$DIR/$tdir/$tfile-1
17547         local file2=$DIR/$tdir/$tfile-2
17548         local file3=$DIR/$tdir/$tfile-3
17549         local lovea1
17550         local lovea2
17551
17552         mkdir -p $DIR/$tdir
17553         touch $file1 || error "create $file1 failed"
17554         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17555                 error "create $file2 failed"
17556         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17557                 error "create $file3 failed"
17558         lovea1=$(get_layout_param $file1)
17559
17560         $LFS swap_layouts $file2 $file3 ||
17561                 error "swap $file2 $file3 layouts failed"
17562         $LFS swap_layouts $file1 $file2 ||
17563                 error "swap $file1 $file2 layouts failed"
17564
17565         lovea2=$(get_layout_param $file2)
17566         echo "$lovea1"
17567         echo "$lovea2"
17568         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17569
17570         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17571         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17572 }
17573 run_test 184d "allow stripeless layouts swap"
17574
17575 test_184e() {
17576         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17577                 skip "Need MDS version at least 2.6.94"
17578         check_swap_layouts_support
17579         check_swap_layout_no_dom $DIR
17580         [ -z "$(which getfattr 2>/dev/null)" ] &&
17581                 skip_env "no getfattr command"
17582
17583         local file1=$DIR/$tdir/$tfile-1
17584         local file2=$DIR/$tdir/$tfile-2
17585         local file3=$DIR/$tdir/$tfile-3
17586         local lovea
17587
17588         mkdir -p $DIR/$tdir
17589         touch $file1 || error "create $file1 failed"
17590         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17591                 error "create $file2 failed"
17592         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17593                 error "create $file3 failed"
17594
17595         $LFS swap_layouts $file1 $file2 ||
17596                 error "swap $file1 $file2 layouts failed"
17597
17598         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17599         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17600
17601         echo 123 > $file1 || error "Should be able to write into $file1"
17602
17603         $LFS swap_layouts $file1 $file3 ||
17604                 error "swap $file1 $file3 layouts failed"
17605
17606         echo 123 > $file1 || error "Should be able to write into $file1"
17607
17608         rm -rf $file1 $file2 $file3
17609 }
17610 run_test 184e "Recreate layout after stripeless layout swaps"
17611
17612 test_184f() {
17613         # Create a file with name longer than sizeof(struct stat) ==
17614         # 144 to see if we can get chars from the file name to appear
17615         # in the returned striping. Note that 'f' == 0x66.
17616         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17617
17618         mkdir -p $DIR/$tdir
17619         mcreate $DIR/$tdir/$file
17620         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17621                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17622         fi
17623 }
17624 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17625
17626 test_185() { # LU-2441
17627         # LU-3553 - no volatile file support in old servers
17628         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17629                 skip "Need MDS version at least 2.3.60"
17630
17631         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17632         touch $DIR/$tdir/spoo
17633         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17634         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17635                 error "cannot create/write a volatile file"
17636         [ "$FILESET" == "" ] &&
17637         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17638                 error "FID is still valid after close"
17639
17640         multiop_bg_pause $DIR/$tdir vVw4096_c
17641         local multi_pid=$!
17642
17643         local OLD_IFS=$IFS
17644         IFS=":"
17645         local fidv=($fid)
17646         IFS=$OLD_IFS
17647         # assume that the next FID for this client is sequential, since stdout
17648         # is unfortunately eaten by multiop_bg_pause
17649         local n=$((${fidv[1]} + 1))
17650         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17651         if [ "$FILESET" == "" ]; then
17652                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17653                         error "FID is missing before close"
17654         fi
17655         kill -USR1 $multi_pid
17656         # 1 second delay, so if mtime change we will see it
17657         sleep 1
17658         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17659         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17660 }
17661 run_test 185 "Volatile file support"
17662
17663 function create_check_volatile() {
17664         local idx=$1
17665         local tgt
17666
17667         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17668         local PID=$!
17669         sleep 1
17670         local FID=$(cat /tmp/${tfile}.fid)
17671         [ "$FID" == "" ] && error "can't get FID for volatile"
17672         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17673         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17674         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17675         kill -USR1 $PID
17676         wait
17677         sleep 1
17678         cancel_lru_locks mdc # flush opencache
17679         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17680         return 0
17681 }
17682
17683 test_185a(){
17684         # LU-12516 - volatile creation via .lustre
17685         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17686                 skip "Need MDS version at least 2.3.55"
17687
17688         create_check_volatile 0
17689         [ $MDSCOUNT -lt 2 ] && return 0
17690
17691         # DNE case
17692         create_check_volatile 1
17693
17694         return 0
17695 }
17696 run_test 185a "Volatile file creation in .lustre/fid/"
17697
17698 test_187a() {
17699         remote_mds_nodsh && skip "remote MDS with nodsh"
17700         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17701                 skip "Need MDS version at least 2.3.0"
17702
17703         local dir0=$DIR/$tdir/$testnum
17704         mkdir -p $dir0 || error "creating dir $dir0"
17705
17706         local file=$dir0/file1
17707         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17708         local dv1=$($LFS data_version $file)
17709         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17710         local dv2=$($LFS data_version $file)
17711         [[ $dv1 != $dv2 ]] ||
17712                 error "data version did not change on write $dv1 == $dv2"
17713
17714         # clean up
17715         rm -f $file1
17716 }
17717 run_test 187a "Test data version change"
17718
17719 test_187b() {
17720         remote_mds_nodsh && skip "remote MDS with nodsh"
17721         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17722                 skip "Need MDS version at least 2.3.0"
17723
17724         local dir0=$DIR/$tdir/$testnum
17725         mkdir -p $dir0 || error "creating dir $dir0"
17726
17727         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17728         [[ ${DV[0]} != ${DV[1]} ]] ||
17729                 error "data version did not change on write"\
17730                       " ${DV[0]} == ${DV[1]}"
17731
17732         # clean up
17733         rm -f $file1
17734 }
17735 run_test 187b "Test data version change on volatile file"
17736
17737 test_200() {
17738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17739         remote_mgs_nodsh && skip "remote MGS with nodsh"
17740         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17741
17742         local POOL=${POOL:-cea1}
17743         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17744         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17745         # Pool OST targets
17746         local first_ost=0
17747         local last_ost=$(($OSTCOUNT - 1))
17748         local ost_step=2
17749         local ost_list=$(seq $first_ost $ost_step $last_ost)
17750         local ost_range="$first_ost $last_ost $ost_step"
17751         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17752         local file_dir=$POOL_ROOT/file_tst
17753         local subdir=$test_path/subdir
17754         local rc=0
17755
17756         while : ; do
17757                 # former test_200a test_200b
17758                 pool_add $POOL                          || { rc=$? ; break; }
17759                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17760                 # former test_200c test_200d
17761                 mkdir -p $test_path
17762                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17763                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17764                 mkdir -p $subdir
17765                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17766                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17767                                                         || { rc=$? ; break; }
17768                 # former test_200e test_200f
17769                 local files=$((OSTCOUNT*3))
17770                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17771                                                         || { rc=$? ; break; }
17772                 pool_create_files $POOL $file_dir $files "$ost_list" \
17773                                                         || { rc=$? ; break; }
17774                 # former test_200g test_200h
17775                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17776                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17777
17778                 # former test_201a test_201b test_201c
17779                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17780
17781                 local f=$test_path/$tfile
17782                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17783                 pool_remove $POOL $f                    || { rc=$? ; break; }
17784                 break
17785         done
17786
17787         destroy_test_pools
17788
17789         return $rc
17790 }
17791 run_test 200 "OST pools"
17792
17793 # usage: default_attr <count | size | offset>
17794 default_attr() {
17795         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17796 }
17797
17798 # usage: check_default_stripe_attr
17799 check_default_stripe_attr() {
17800         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17801         case $1 in
17802         --stripe-count|-c)
17803                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17804         --stripe-size|-S)
17805                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17806         --stripe-index|-i)
17807                 EXPECTED=-1;;
17808         *)
17809                 error "unknown getstripe attr '$1'"
17810         esac
17811
17812         [ $ACTUAL == $EXPECTED ] ||
17813                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17814 }
17815
17816 test_204a() {
17817         test_mkdir $DIR/$tdir
17818         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17819
17820         check_default_stripe_attr --stripe-count
17821         check_default_stripe_attr --stripe-size
17822         check_default_stripe_attr --stripe-index
17823 }
17824 run_test 204a "Print default stripe attributes"
17825
17826 test_204b() {
17827         test_mkdir $DIR/$tdir
17828         $LFS setstripe --stripe-count 1 $DIR/$tdir
17829
17830         check_default_stripe_attr --stripe-size
17831         check_default_stripe_attr --stripe-index
17832 }
17833 run_test 204b "Print default stripe size and offset"
17834
17835 test_204c() {
17836         test_mkdir $DIR/$tdir
17837         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17838
17839         check_default_stripe_attr --stripe-count
17840         check_default_stripe_attr --stripe-index
17841 }
17842 run_test 204c "Print default stripe count and offset"
17843
17844 test_204d() {
17845         test_mkdir $DIR/$tdir
17846         $LFS setstripe --stripe-index 0 $DIR/$tdir
17847
17848         check_default_stripe_attr --stripe-count
17849         check_default_stripe_attr --stripe-size
17850 }
17851 run_test 204d "Print default stripe count and size"
17852
17853 test_204e() {
17854         test_mkdir $DIR/$tdir
17855         $LFS setstripe -d $DIR/$tdir
17856
17857         check_default_stripe_attr --stripe-count --raw
17858         check_default_stripe_attr --stripe-size --raw
17859         check_default_stripe_attr --stripe-index --raw
17860 }
17861 run_test 204e "Print raw stripe attributes"
17862
17863 test_204f() {
17864         test_mkdir $DIR/$tdir
17865         $LFS setstripe --stripe-count 1 $DIR/$tdir
17866
17867         check_default_stripe_attr --stripe-size --raw
17868         check_default_stripe_attr --stripe-index --raw
17869 }
17870 run_test 204f "Print raw stripe size and offset"
17871
17872 test_204g() {
17873         test_mkdir $DIR/$tdir
17874         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17875
17876         check_default_stripe_attr --stripe-count --raw
17877         check_default_stripe_attr --stripe-index --raw
17878 }
17879 run_test 204g "Print raw stripe count and offset"
17880
17881 test_204h() {
17882         test_mkdir $DIR/$tdir
17883         $LFS setstripe --stripe-index 0 $DIR/$tdir
17884
17885         check_default_stripe_attr --stripe-count --raw
17886         check_default_stripe_attr --stripe-size --raw
17887 }
17888 run_test 204h "Print raw stripe count and size"
17889
17890 # Figure out which job scheduler is being used, if any,
17891 # or use a fake one
17892 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17893         JOBENV=SLURM_JOB_ID
17894 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17895         JOBENV=LSB_JOBID
17896 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17897         JOBENV=PBS_JOBID
17898 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17899         JOBENV=LOADL_STEP_ID
17900 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17901         JOBENV=JOB_ID
17902 else
17903         $LCTL list_param jobid_name > /dev/null 2>&1
17904         if [ $? -eq 0 ]; then
17905                 JOBENV=nodelocal
17906         else
17907                 JOBENV=FAKE_JOBID
17908         fi
17909 fi
17910 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17911
17912 verify_jobstats() {
17913         local cmd=($1)
17914         shift
17915         local facets="$@"
17916
17917 # we don't really need to clear the stats for this test to work, since each
17918 # command has a unique jobid, but it makes debugging easier if needed.
17919 #       for facet in $facets; do
17920 #               local dev=$(convert_facet2label $facet)
17921 #               # clear old jobstats
17922 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17923 #       done
17924
17925         # use a new JobID for each test, or we might see an old one
17926         [ "$JOBENV" = "FAKE_JOBID" ] &&
17927                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17928
17929         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17930
17931         [ "$JOBENV" = "nodelocal" ] && {
17932                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17933                 $LCTL set_param jobid_name=$FAKE_JOBID
17934                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17935         }
17936
17937         log "Test: ${cmd[*]}"
17938         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17939
17940         if [ $JOBENV = "FAKE_JOBID" ]; then
17941                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17942         else
17943                 ${cmd[*]}
17944         fi
17945
17946         # all files are created on OST0000
17947         for facet in $facets; do
17948                 local stats="*.$(convert_facet2label $facet).job_stats"
17949
17950                 # strip out libtool wrappers for in-tree executables
17951                 if [ $(do_facet $facet lctl get_param $stats |
17952                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17953                         do_facet $facet lctl get_param $stats
17954                         error "No jobstats for $JOBVAL found on $facet::$stats"
17955                 fi
17956         done
17957 }
17958
17959 jobstats_set() {
17960         local new_jobenv=$1
17961
17962         set_persistent_param_and_check client "jobid_var" \
17963                 "$FSNAME.sys.jobid_var" $new_jobenv
17964 }
17965
17966 test_205a() { # Job stats
17967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17968         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17969                 skip "Need MDS version with at least 2.7.1"
17970         remote_mgs_nodsh && skip "remote MGS with nodsh"
17971         remote_mds_nodsh && skip "remote MDS with nodsh"
17972         remote_ost_nodsh && skip "remote OST with nodsh"
17973         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17974                 skip "Server doesn't support jobstats"
17975         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17976
17977         local old_jobenv=$($LCTL get_param -n jobid_var)
17978         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17979
17980         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17981                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17982         else
17983                 stack_trap "do_facet mgs $PERM_CMD \
17984                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17985         fi
17986         changelog_register
17987
17988         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17989                                 mdt.*.job_cleanup_interval | head -n 1)
17990         local new_interval=5
17991         do_facet $SINGLEMDS \
17992                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17993         stack_trap "do_facet $SINGLEMDS \
17994                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17995         local start=$SECONDS
17996
17997         local cmd
17998         # mkdir
17999         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18000         verify_jobstats "$cmd" "$SINGLEMDS"
18001         # rmdir
18002         cmd="rmdir $DIR/$tdir"
18003         verify_jobstats "$cmd" "$SINGLEMDS"
18004         # mkdir on secondary MDT
18005         if [ $MDSCOUNT -gt 1 ]; then
18006                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18007                 verify_jobstats "$cmd" "mds2"
18008         fi
18009         # mknod
18010         cmd="mknod $DIR/$tfile c 1 3"
18011         verify_jobstats "$cmd" "$SINGLEMDS"
18012         # unlink
18013         cmd="rm -f $DIR/$tfile"
18014         verify_jobstats "$cmd" "$SINGLEMDS"
18015         # create all files on OST0000 so verify_jobstats can find OST stats
18016         # open & close
18017         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18018         verify_jobstats "$cmd" "$SINGLEMDS"
18019         # setattr
18020         cmd="touch $DIR/$tfile"
18021         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18022         # write
18023         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18024         verify_jobstats "$cmd" "ost1"
18025         # read
18026         cancel_lru_locks osc
18027         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18028         verify_jobstats "$cmd" "ost1"
18029         # truncate
18030         cmd="$TRUNCATE $DIR/$tfile 0"
18031         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18032         # rename
18033         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18034         verify_jobstats "$cmd" "$SINGLEMDS"
18035         # jobstats expiry - sleep until old stats should be expired
18036         local left=$((new_interval + 5 - (SECONDS - start)))
18037         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18038                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18039                         "0" $left
18040         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18041         verify_jobstats "$cmd" "$SINGLEMDS"
18042         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18043             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18044
18045         # Ensure that jobid are present in changelog (if supported by MDS)
18046         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18047                 changelog_dump | tail -10
18048                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18049                 [ $jobids -eq 9 ] ||
18050                         error "Wrong changelog jobid count $jobids != 9"
18051
18052                 # LU-5862
18053                 JOBENV="disable"
18054                 jobstats_set $JOBENV
18055                 touch $DIR/$tfile
18056                 changelog_dump | grep $tfile
18057                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18058                 [ $jobids -eq 0 ] ||
18059                         error "Unexpected jobids when jobid_var=$JOBENV"
18060         fi
18061
18062         # test '%j' access to environment variable - if supported
18063         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18064                 JOBENV="JOBCOMPLEX"
18065                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18066
18067                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18068         fi
18069
18070         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18071                 JOBENV="JOBCOMPLEX"
18072                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18073
18074                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18075         fi
18076
18077         # test '%j' access to per-session jobid - if supported
18078         if lctl list_param jobid_this_session > /dev/null 2>&1
18079         then
18080                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18081                 lctl set_param jobid_this_session=$USER
18082
18083                 JOBENV="JOBCOMPLEX"
18084                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18085
18086                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18087         fi
18088 }
18089 run_test 205a "Verify job stats"
18090
18091 # LU-13117, LU-13597
18092 test_205b() {
18093         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18094                 skip "Need MDS version at least 2.13.54.91"
18095
18096         job_stats="mdt.*.job_stats"
18097         $LCTL set_param $job_stats=clear
18098         # Setting jobid_var to USER might not be supported
18099         $LCTL set_param jobid_var=USER || true
18100         $LCTL set_param jobid_name="%e.%u"
18101         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18102         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18103                 grep "job_id:.*foolish" &&
18104                         error "Unexpected jobid found"
18105         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18106                 grep "open:.*min.*max.*sum" ||
18107                         error "wrong job_stats format found"
18108 }
18109 run_test 205b "Verify job stats jobid and output format"
18110
18111 # LU-13733
18112 test_205c() {
18113         $LCTL set_param llite.*.stats=0
18114         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18115         $LCTL get_param llite.*.stats
18116         $LCTL get_param llite.*.stats | grep \
18117                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18118                         error "wrong client stats format found"
18119 }
18120 run_test 205c "Verify client stats format"
18121
18122 # LU-1480, LU-1773 and LU-1657
18123 test_206() {
18124         mkdir -p $DIR/$tdir
18125         $LFS setstripe -c -1 $DIR/$tdir
18126 #define OBD_FAIL_LOV_INIT 0x1403
18127         $LCTL set_param fail_loc=0xa0001403
18128         $LCTL set_param fail_val=1
18129         touch $DIR/$tdir/$tfile || true
18130 }
18131 run_test 206 "fail lov_init_raid0() doesn't lbug"
18132
18133 test_207a() {
18134         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18135         local fsz=`stat -c %s $DIR/$tfile`
18136         cancel_lru_locks mdc
18137
18138         # do not return layout in getattr intent
18139 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18140         $LCTL set_param fail_loc=0x170
18141         local sz=`stat -c %s $DIR/$tfile`
18142
18143         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18144
18145         rm -rf $DIR/$tfile
18146 }
18147 run_test 207a "can refresh layout at glimpse"
18148
18149 test_207b() {
18150         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18151         local cksum=`md5sum $DIR/$tfile`
18152         local fsz=`stat -c %s $DIR/$tfile`
18153         cancel_lru_locks mdc
18154         cancel_lru_locks osc
18155
18156         # do not return layout in getattr intent
18157 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18158         $LCTL set_param fail_loc=0x171
18159
18160         # it will refresh layout after the file is opened but before read issues
18161         echo checksum is "$cksum"
18162         echo "$cksum" |md5sum -c --quiet || error "file differs"
18163
18164         rm -rf $DIR/$tfile
18165 }
18166 run_test 207b "can refresh layout at open"
18167
18168 test_208() {
18169         # FIXME: in this test suite, only RD lease is used. This is okay
18170         # for now as only exclusive open is supported. After generic lease
18171         # is done, this test suite should be revised. - Jinshan
18172
18173         remote_mds_nodsh && skip "remote MDS with nodsh"
18174         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18175                 skip "Need MDS version at least 2.4.52"
18176
18177         echo "==== test 1: verify get lease work"
18178         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18179
18180         echo "==== test 2: verify lease can be broken by upcoming open"
18181         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18182         local PID=$!
18183         sleep 1
18184
18185         $MULTIOP $DIR/$tfile oO_RDWR:c
18186         kill -USR1 $PID && wait $PID || error "break lease error"
18187
18188         echo "==== test 3: verify lease can't be granted if an open already exists"
18189         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18190         local PID=$!
18191         sleep 1
18192
18193         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18194         kill -USR1 $PID && wait $PID || error "open file error"
18195
18196         echo "==== test 4: lease can sustain over recovery"
18197         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18198         PID=$!
18199         sleep 1
18200
18201         fail mds1
18202
18203         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18204
18205         echo "==== test 5: lease broken can't be regained by replay"
18206         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18207         PID=$!
18208         sleep 1
18209
18210         # open file to break lease and then recovery
18211         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18212         fail mds1
18213
18214         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18215
18216         rm -f $DIR/$tfile
18217 }
18218 run_test 208 "Exclusive open"
18219
18220 test_209() {
18221         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18222                 skip_env "must have disp_stripe"
18223
18224         touch $DIR/$tfile
18225         sync; sleep 5; sync;
18226
18227         echo 3 > /proc/sys/vm/drop_caches
18228         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18229                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18230         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18231
18232         # open/close 500 times
18233         for i in $(seq 500); do
18234                 cat $DIR/$tfile
18235         done
18236
18237         echo 3 > /proc/sys/vm/drop_caches
18238         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18239                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18240         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18241
18242         echo "before: $req_before, after: $req_after"
18243         [ $((req_after - req_before)) -ge 300 ] &&
18244                 error "open/close requests are not freed"
18245         return 0
18246 }
18247 run_test 209 "read-only open/close requests should be freed promptly"
18248
18249 test_210() {
18250         local pid
18251
18252         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18253         pid=$!
18254         sleep 1
18255
18256         $LFS getstripe $DIR/$tfile
18257         kill -USR1 $pid
18258         wait $pid || error "multiop failed"
18259
18260         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18261         pid=$!
18262         sleep 1
18263
18264         $LFS getstripe $DIR/$tfile
18265         kill -USR1 $pid
18266         wait $pid || error "multiop failed"
18267 }
18268 run_test 210 "lfs getstripe does not break leases"
18269
18270 test_212() {
18271         size=`date +%s`
18272         size=$((size % 8192 + 1))
18273         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18274         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18275         rm -f $DIR/f212 $DIR/f212.xyz
18276 }
18277 run_test 212 "Sendfile test ============================================"
18278
18279 test_213() {
18280         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18281         cancel_lru_locks osc
18282         lctl set_param fail_loc=0x8000040f
18283         # generate a read lock
18284         cat $DIR/$tfile > /dev/null
18285         # write to the file, it will try to cancel the above read lock.
18286         cat /etc/hosts >> $DIR/$tfile
18287 }
18288 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18289
18290 test_214() { # for bug 20133
18291         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18292         for (( i=0; i < 340; i++ )) ; do
18293                 touch $DIR/$tdir/d214c/a$i
18294         done
18295
18296         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18297         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18298         ls $DIR/d214c || error "ls $DIR/d214c failed"
18299         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18300         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18301 }
18302 run_test 214 "hash-indexed directory test - bug 20133"
18303
18304 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18305 create_lnet_proc_files() {
18306         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18307 }
18308
18309 # counterpart of create_lnet_proc_files
18310 remove_lnet_proc_files() {
18311         rm -f $TMP/lnet_$1.sys
18312 }
18313
18314 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18315 # 3rd arg as regexp for body
18316 check_lnet_proc_stats() {
18317         local l=$(cat "$TMP/lnet_$1" |wc -l)
18318         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18319
18320         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18321 }
18322
18323 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18324 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18325 # optional and can be regexp for 2nd line (lnet.routes case)
18326 check_lnet_proc_entry() {
18327         local blp=2          # blp stands for 'position of 1st line of body'
18328         [ -z "$5" ] || blp=3 # lnet.routes case
18329
18330         local l=$(cat "$TMP/lnet_$1" |wc -l)
18331         # subtracting one from $blp because the body can be empty
18332         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18333
18334         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18335                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18336
18337         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18338                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18339
18340         # bail out if any unexpected line happened
18341         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18342         [ "$?" != 0 ] || error "$2 misformatted"
18343 }
18344
18345 test_215() { # for bugs 18102, 21079, 21517
18346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18347
18348         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18349         local P='[1-9][0-9]*'           # positive numeric
18350         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18351         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18352         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18353         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18354
18355         local L1 # regexp for 1st line
18356         local L2 # regexp for 2nd line (optional)
18357         local BR # regexp for the rest (body)
18358
18359         # lnet.stats should look as 11 space-separated non-negative numerics
18360         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18361         create_lnet_proc_files "stats"
18362         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18363         remove_lnet_proc_files "stats"
18364
18365         # lnet.routes should look like this:
18366         # Routing disabled/enabled
18367         # net hops priority state router
18368         # where net is a string like tcp0, hops > 0, priority >= 0,
18369         # state is up/down,
18370         # router is a string like 192.168.1.1@tcp2
18371         L1="^Routing (disabled|enabled)$"
18372         L2="^net +hops +priority +state +router$"
18373         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18374         create_lnet_proc_files "routes"
18375         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18376         remove_lnet_proc_files "routes"
18377
18378         # lnet.routers should look like this:
18379         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18380         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18381         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18382         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18383         L1="^ref +rtr_ref +alive +router$"
18384         BR="^$P +$P +(up|down) +$NID$"
18385         create_lnet_proc_files "routers"
18386         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18387         remove_lnet_proc_files "routers"
18388
18389         # lnet.peers should look like this:
18390         # nid refs state last max rtr min tx min queue
18391         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18392         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18393         # numeric (0 or >0 or <0), queue >= 0.
18394         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18395         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18396         create_lnet_proc_files "peers"
18397         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18398         remove_lnet_proc_files "peers"
18399
18400         # lnet.buffers  should look like this:
18401         # pages count credits min
18402         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18403         L1="^pages +count +credits +min$"
18404         BR="^ +$N +$N +$I +$I$"
18405         create_lnet_proc_files "buffers"
18406         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18407         remove_lnet_proc_files "buffers"
18408
18409         # lnet.nis should look like this:
18410         # nid status alive refs peer rtr max tx min
18411         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18412         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18413         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18414         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18415         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18416         create_lnet_proc_files "nis"
18417         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18418         remove_lnet_proc_files "nis"
18419
18420         # can we successfully write to lnet.stats?
18421         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18422 }
18423 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18424
18425 test_216() { # bug 20317
18426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18427         remote_ost_nodsh && skip "remote OST with nodsh"
18428
18429         local node
18430         local facets=$(get_facets OST)
18431         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18432
18433         save_lustre_params client "osc.*.contention_seconds" > $p
18434         save_lustre_params $facets \
18435                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18436         save_lustre_params $facets \
18437                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18438         save_lustre_params $facets \
18439                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18440         clear_stats osc.*.osc_stats
18441
18442         # agressive lockless i/o settings
18443         do_nodes $(comma_list $(osts_nodes)) \
18444                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18445                         ldlm.namespaces.filter-*.contended_locks=0 \
18446                         ldlm.namespaces.filter-*.contention_seconds=60"
18447         lctl set_param -n osc.*.contention_seconds=60
18448
18449         $DIRECTIO write $DIR/$tfile 0 10 4096
18450         $CHECKSTAT -s 40960 $DIR/$tfile
18451
18452         # disable lockless i/o
18453         do_nodes $(comma_list $(osts_nodes)) \
18454                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18455                         ldlm.namespaces.filter-*.contended_locks=32 \
18456                         ldlm.namespaces.filter-*.contention_seconds=0"
18457         lctl set_param -n osc.*.contention_seconds=0
18458         clear_stats osc.*.osc_stats
18459
18460         dd if=/dev/zero of=$DIR/$tfile count=0
18461         $CHECKSTAT -s 0 $DIR/$tfile
18462
18463         restore_lustre_params <$p
18464         rm -f $p
18465         rm $DIR/$tfile
18466 }
18467 run_test 216 "check lockless direct write updates file size and kms correctly"
18468
18469 test_217() { # bug 22430
18470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18471
18472         local node
18473         local nid
18474
18475         for node in $(nodes_list); do
18476                 nid=$(host_nids_address $node $NETTYPE)
18477                 if [[ $nid = *-* ]] ; then
18478                         echo "lctl ping $(h2nettype $nid)"
18479                         lctl ping $(h2nettype $nid)
18480                 else
18481                         echo "skipping $node (no hyphen detected)"
18482                 fi
18483         done
18484 }
18485 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18486
18487 test_218() {
18488        # do directio so as not to populate the page cache
18489        log "creating a 10 Mb file"
18490        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18491        log "starting reads"
18492        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18493        log "truncating the file"
18494        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18495        log "killing dd"
18496        kill %+ || true # reads might have finished
18497        echo "wait until dd is finished"
18498        wait
18499        log "removing the temporary file"
18500        rm -rf $DIR/$tfile || error "tmp file removal failed"
18501 }
18502 run_test 218 "parallel read and truncate should not deadlock"
18503
18504 test_219() {
18505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18506
18507         # write one partial page
18508         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18509         # set no grant so vvp_io_commit_write will do sync write
18510         $LCTL set_param fail_loc=0x411
18511         # write a full page at the end of file
18512         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18513
18514         $LCTL set_param fail_loc=0
18515         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18516         $LCTL set_param fail_loc=0x411
18517         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18518
18519         # LU-4201
18520         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18521         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18522 }
18523 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18524
18525 test_220() { #LU-325
18526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18527         remote_ost_nodsh && skip "remote OST with nodsh"
18528         remote_mds_nodsh && skip "remote MDS with nodsh"
18529         remote_mgs_nodsh && skip "remote MGS with nodsh"
18530
18531         local OSTIDX=0
18532
18533         # create on MDT0000 so the last_id and next_id are correct
18534         mkdir_on_mdt0 $DIR/$tdir
18535         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18536         OST=${OST%_UUID}
18537
18538         # on the mdt's osc
18539         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18540         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18541                         osp.$mdtosc_proc1.prealloc_last_id)
18542         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18543                         osp.$mdtosc_proc1.prealloc_next_id)
18544
18545         $LFS df -i
18546
18547         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18548         #define OBD_FAIL_OST_ENOINO              0x229
18549         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18550         create_pool $FSNAME.$TESTNAME || return 1
18551         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18552
18553         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18554
18555         MDSOBJS=$((last_id - next_id))
18556         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18557
18558         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18559         echo "OST still has $count kbytes free"
18560
18561         echo "create $MDSOBJS files @next_id..."
18562         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18563
18564         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18565                         osp.$mdtosc_proc1.prealloc_last_id)
18566         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18567                         osp.$mdtosc_proc1.prealloc_next_id)
18568
18569         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18570         $LFS df -i
18571
18572         echo "cleanup..."
18573
18574         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18575         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18576
18577         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18578                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18579         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18580                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18581         echo "unlink $MDSOBJS files @$next_id..."
18582         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18583 }
18584 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18585
18586 test_221() {
18587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18588
18589         dd if=`which date` of=$MOUNT/date oflag=sync
18590         chmod +x $MOUNT/date
18591
18592         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18593         $LCTL set_param fail_loc=0x80001401
18594
18595         $MOUNT/date > /dev/null
18596         rm -f $MOUNT/date
18597 }
18598 run_test 221 "make sure fault and truncate race to not cause OOM"
18599
18600 test_222a () {
18601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18602
18603         rm -rf $DIR/$tdir
18604         test_mkdir $DIR/$tdir
18605         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18606         createmany -o $DIR/$tdir/$tfile 10
18607         cancel_lru_locks mdc
18608         cancel_lru_locks osc
18609         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18610         $LCTL set_param fail_loc=0x31a
18611         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18612         $LCTL set_param fail_loc=0
18613         rm -r $DIR/$tdir
18614 }
18615 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18616
18617 test_222b () {
18618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18619
18620         rm -rf $DIR/$tdir
18621         test_mkdir $DIR/$tdir
18622         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18623         createmany -o $DIR/$tdir/$tfile 10
18624         cancel_lru_locks mdc
18625         cancel_lru_locks osc
18626         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18627         $LCTL set_param fail_loc=0x31a
18628         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18629         $LCTL set_param fail_loc=0
18630 }
18631 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18632
18633 test_223 () {
18634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18635
18636         rm -rf $DIR/$tdir
18637         test_mkdir $DIR/$tdir
18638         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18639         createmany -o $DIR/$tdir/$tfile 10
18640         cancel_lru_locks mdc
18641         cancel_lru_locks osc
18642         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18643         $LCTL set_param fail_loc=0x31b
18644         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18645         $LCTL set_param fail_loc=0
18646         rm -r $DIR/$tdir
18647 }
18648 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18649
18650 test_224a() { # LU-1039, MRP-303
18651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18652
18653         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18654         $LCTL set_param fail_loc=0x508
18655         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18656         $LCTL set_param fail_loc=0
18657         df $DIR
18658 }
18659 run_test 224a "Don't panic on bulk IO failure"
18660
18661 test_224b() { # LU-1039, MRP-303
18662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18663
18664         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18665         cancel_lru_locks osc
18666         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18667         $LCTL set_param fail_loc=0x515
18668         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18669         $LCTL set_param fail_loc=0
18670         df $DIR
18671 }
18672 run_test 224b "Don't panic on bulk IO failure"
18673
18674 test_224c() { # LU-6441
18675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18676         remote_mds_nodsh && skip "remote MDS with nodsh"
18677
18678         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18679         save_writethrough $p
18680         set_cache writethrough on
18681
18682         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18683         local at_max=$($LCTL get_param -n at_max)
18684         local timeout=$($LCTL get_param -n timeout)
18685         local test_at="at_max"
18686         local param_at="$FSNAME.sys.at_max"
18687         local test_timeout="timeout"
18688         local param_timeout="$FSNAME.sys.timeout"
18689
18690         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18691
18692         set_persistent_param_and_check client "$test_at" "$param_at" 0
18693         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18694
18695         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18696         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18697         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18698         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18699         sync
18700         do_facet ost1 "$LCTL set_param fail_loc=0"
18701
18702         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18703         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18704                 $timeout
18705
18706         $LCTL set_param -n $pages_per_rpc
18707         restore_lustre_params < $p
18708         rm -f $p
18709 }
18710 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18711
18712 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18713 test_225a () {
18714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18715         if [ -z ${MDSSURVEY} ]; then
18716                 skip_env "mds-survey not found"
18717         fi
18718         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18719                 skip "Need MDS version at least 2.2.51"
18720
18721         local mds=$(facet_host $SINGLEMDS)
18722         local target=$(do_nodes $mds 'lctl dl' |
18723                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18724
18725         local cmd1="file_count=1000 thrhi=4"
18726         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18727         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18728         local cmd="$cmd1 $cmd2 $cmd3"
18729
18730         rm -f ${TMP}/mds_survey*
18731         echo + $cmd
18732         eval $cmd || error "mds-survey with zero-stripe failed"
18733         cat ${TMP}/mds_survey*
18734         rm -f ${TMP}/mds_survey*
18735 }
18736 run_test 225a "Metadata survey sanity with zero-stripe"
18737
18738 test_225b () {
18739         if [ -z ${MDSSURVEY} ]; then
18740                 skip_env "mds-survey not found"
18741         fi
18742         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18743                 skip "Need MDS version at least 2.2.51"
18744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18745         remote_mds_nodsh && skip "remote MDS with nodsh"
18746         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18747                 skip_env "Need to mount OST to test"
18748         fi
18749
18750         local mds=$(facet_host $SINGLEMDS)
18751         local target=$(do_nodes $mds 'lctl dl' |
18752                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18753
18754         local cmd1="file_count=1000 thrhi=4"
18755         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18756         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18757         local cmd="$cmd1 $cmd2 $cmd3"
18758
18759         rm -f ${TMP}/mds_survey*
18760         echo + $cmd
18761         eval $cmd || error "mds-survey with stripe_count failed"
18762         cat ${TMP}/mds_survey*
18763         rm -f ${TMP}/mds_survey*
18764 }
18765 run_test 225b "Metadata survey sanity with stripe_count = 1"
18766
18767 mcreate_path2fid () {
18768         local mode=$1
18769         local major=$2
18770         local minor=$3
18771         local name=$4
18772         local desc=$5
18773         local path=$DIR/$tdir/$name
18774         local fid
18775         local rc
18776         local fid_path
18777
18778         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18779                 error "cannot create $desc"
18780
18781         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18782         rc=$?
18783         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18784
18785         fid_path=$($LFS fid2path $MOUNT $fid)
18786         rc=$?
18787         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18788
18789         [ "$path" == "$fid_path" ] ||
18790                 error "fid2path returned $fid_path, expected $path"
18791
18792         echo "pass with $path and $fid"
18793 }
18794
18795 test_226a () {
18796         rm -rf $DIR/$tdir
18797         mkdir -p $DIR/$tdir
18798
18799         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18800         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18801         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18802         mcreate_path2fid 0040666 0 0 dir "directory"
18803         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18804         mcreate_path2fid 0100666 0 0 file "regular file"
18805         mcreate_path2fid 0120666 0 0 link "symbolic link"
18806         mcreate_path2fid 0140666 0 0 sock "socket"
18807 }
18808 run_test 226a "call path2fid and fid2path on files of all type"
18809
18810 test_226b () {
18811         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18812
18813         local MDTIDX=1
18814
18815         rm -rf $DIR/$tdir
18816         mkdir -p $DIR/$tdir
18817         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18818                 error "create remote directory failed"
18819         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18820         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18821                                 "character special file (null)"
18822         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18823                                 "character special file (no device)"
18824         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18825         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18826                                 "block special file (loop)"
18827         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18828         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18829         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18830 }
18831 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18832
18833 test_226c () {
18834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18835         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18836                 skip "Need MDS version at least 2.13.55"
18837
18838         local submnt=/mnt/submnt
18839         local srcfile=/etc/passwd
18840         local dstfile=$submnt/passwd
18841         local path
18842         local fid
18843
18844         rm -rf $DIR/$tdir
18845         rm -rf $submnt
18846         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18847                 error "create remote directory failed"
18848         mkdir -p $submnt || error "create $submnt failed"
18849         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18850                 error "mount $submnt failed"
18851         stack_trap "umount $submnt" EXIT
18852
18853         cp $srcfile $dstfile
18854         fid=$($LFS path2fid $dstfile)
18855         path=$($LFS fid2path $submnt "$fid")
18856         [ "$path" = "$dstfile" ] ||
18857                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18858 }
18859 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18860
18861 # LU-1299 Executing or running ldd on a truncated executable does not
18862 # cause an out-of-memory condition.
18863 test_227() {
18864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18865         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18866
18867         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18868         chmod +x $MOUNT/date
18869
18870         $MOUNT/date > /dev/null
18871         ldd $MOUNT/date > /dev/null
18872         rm -f $MOUNT/date
18873 }
18874 run_test 227 "running truncated executable does not cause OOM"
18875
18876 # LU-1512 try to reuse idle OI blocks
18877 test_228a() {
18878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18879         remote_mds_nodsh && skip "remote MDS with nodsh"
18880         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18881
18882         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18883         local myDIR=$DIR/$tdir
18884
18885         mkdir -p $myDIR
18886         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18887         $LCTL set_param fail_loc=0x80001002
18888         createmany -o $myDIR/t- 10000
18889         $LCTL set_param fail_loc=0
18890         # The guard is current the largest FID holder
18891         touch $myDIR/guard
18892         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18893                     tr -d '[')
18894         local IDX=$(($SEQ % 64))
18895
18896         do_facet $SINGLEMDS sync
18897         # Make sure journal flushed.
18898         sleep 6
18899         local blk1=$(do_facet $SINGLEMDS \
18900                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18901                      grep Blockcount | awk '{print $4}')
18902
18903         # Remove old files, some OI blocks will become idle.
18904         unlinkmany $myDIR/t- 10000
18905         # Create new files, idle OI blocks should be reused.
18906         createmany -o $myDIR/t- 2000
18907         do_facet $SINGLEMDS sync
18908         # Make sure journal flushed.
18909         sleep 6
18910         local blk2=$(do_facet $SINGLEMDS \
18911                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18912                      grep Blockcount | awk '{print $4}')
18913
18914         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18915 }
18916 run_test 228a "try to reuse idle OI blocks"
18917
18918 test_228b() {
18919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18920         remote_mds_nodsh && skip "remote MDS with nodsh"
18921         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18922
18923         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18924         local myDIR=$DIR/$tdir
18925
18926         mkdir -p $myDIR
18927         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18928         $LCTL set_param fail_loc=0x80001002
18929         createmany -o $myDIR/t- 10000
18930         $LCTL set_param fail_loc=0
18931         # The guard is current the largest FID holder
18932         touch $myDIR/guard
18933         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18934                     tr -d '[')
18935         local IDX=$(($SEQ % 64))
18936
18937         do_facet $SINGLEMDS sync
18938         # Make sure journal flushed.
18939         sleep 6
18940         local blk1=$(do_facet $SINGLEMDS \
18941                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18942                      grep Blockcount | awk '{print $4}')
18943
18944         # Remove old files, some OI blocks will become idle.
18945         unlinkmany $myDIR/t- 10000
18946
18947         # stop the MDT
18948         stop $SINGLEMDS || error "Fail to stop MDT."
18949         # remount the MDT
18950         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18951
18952         df $MOUNT || error "Fail to df."
18953         # Create new files, idle OI blocks should be reused.
18954         createmany -o $myDIR/t- 2000
18955         do_facet $SINGLEMDS sync
18956         # Make sure journal flushed.
18957         sleep 6
18958         local blk2=$(do_facet $SINGLEMDS \
18959                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18960                      grep Blockcount | awk '{print $4}')
18961
18962         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18963 }
18964 run_test 228b "idle OI blocks can be reused after MDT restart"
18965
18966 #LU-1881
18967 test_228c() {
18968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18969         remote_mds_nodsh && skip "remote MDS with nodsh"
18970         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18971
18972         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18973         local myDIR=$DIR/$tdir
18974
18975         mkdir -p $myDIR
18976         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18977         $LCTL set_param fail_loc=0x80001002
18978         # 20000 files can guarantee there are index nodes in the OI file
18979         createmany -o $myDIR/t- 20000
18980         $LCTL set_param fail_loc=0
18981         # The guard is current the largest FID holder
18982         touch $myDIR/guard
18983         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18984                     tr -d '[')
18985         local IDX=$(($SEQ % 64))
18986
18987         do_facet $SINGLEMDS sync
18988         # Make sure journal flushed.
18989         sleep 6
18990         local blk1=$(do_facet $SINGLEMDS \
18991                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18992                      grep Blockcount | awk '{print $4}')
18993
18994         # Remove old files, some OI blocks will become idle.
18995         unlinkmany $myDIR/t- 20000
18996         rm -f $myDIR/guard
18997         # The OI file should become empty now
18998
18999         # Create new files, idle OI blocks should be reused.
19000         createmany -o $myDIR/t- 2000
19001         do_facet $SINGLEMDS sync
19002         # Make sure journal flushed.
19003         sleep 6
19004         local blk2=$(do_facet $SINGLEMDS \
19005                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19006                      grep Blockcount | awk '{print $4}')
19007
19008         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19009 }
19010 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19011
19012 test_229() { # LU-2482, LU-3448
19013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19014         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19015         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19016                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19017
19018         rm -f $DIR/$tfile
19019
19020         # Create a file with a released layout and stripe count 2.
19021         $MULTIOP $DIR/$tfile H2c ||
19022                 error "failed to create file with released layout"
19023
19024         $LFS getstripe -v $DIR/$tfile
19025
19026         local pattern=$($LFS getstripe -L $DIR/$tfile)
19027         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19028
19029         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19030                 error "getstripe"
19031         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19032         stat $DIR/$tfile || error "failed to stat released file"
19033
19034         chown $RUNAS_ID $DIR/$tfile ||
19035                 error "chown $RUNAS_ID $DIR/$tfile failed"
19036
19037         chgrp $RUNAS_ID $DIR/$tfile ||
19038                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19039
19040         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19041         rm $DIR/$tfile || error "failed to remove released file"
19042 }
19043 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19044
19045 test_230a() {
19046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19048         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19049                 skip "Need MDS version at least 2.11.52"
19050
19051         local MDTIDX=1
19052
19053         test_mkdir $DIR/$tdir
19054         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19055         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19056         [ $mdt_idx -ne 0 ] &&
19057                 error "create local directory on wrong MDT $mdt_idx"
19058
19059         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19060                         error "create remote directory failed"
19061         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19062         [ $mdt_idx -ne $MDTIDX ] &&
19063                 error "create remote directory on wrong MDT $mdt_idx"
19064
19065         createmany -o $DIR/$tdir/test_230/t- 10 ||
19066                 error "create files on remote directory failed"
19067         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19068         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19069         rm -r $DIR/$tdir || error "unlink remote directory failed"
19070 }
19071 run_test 230a "Create remote directory and files under the remote directory"
19072
19073 test_230b() {
19074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19075         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19076         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19077                 skip "Need MDS version at least 2.11.52"
19078
19079         local MDTIDX=1
19080         local mdt_index
19081         local i
19082         local file
19083         local pid
19084         local stripe_count
19085         local migrate_dir=$DIR/$tdir/migrate_dir
19086         local other_dir=$DIR/$tdir/other_dir
19087
19088         test_mkdir $DIR/$tdir
19089         test_mkdir -i0 -c1 $migrate_dir
19090         test_mkdir -i0 -c1 $other_dir
19091         for ((i=0; i<10; i++)); do
19092                 mkdir -p $migrate_dir/dir_${i}
19093                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19094                         error "create files under remote dir failed $i"
19095         done
19096
19097         cp /etc/passwd $migrate_dir/$tfile
19098         cp /etc/passwd $other_dir/$tfile
19099         chattr +SAD $migrate_dir
19100         chattr +SAD $migrate_dir/$tfile
19101
19102         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19103         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19104         local old_dir_mode=$(stat -c%f $migrate_dir)
19105         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19106
19107         mkdir -p $migrate_dir/dir_default_stripe2
19108         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19109         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19110
19111         mkdir -p $other_dir
19112         ln $migrate_dir/$tfile $other_dir/luna
19113         ln $migrate_dir/$tfile $migrate_dir/sofia
19114         ln $other_dir/$tfile $migrate_dir/david
19115         ln -s $migrate_dir/$tfile $other_dir/zachary
19116         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19117         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19118
19119         local len
19120         local lnktgt
19121
19122         # inline symlink
19123         for len in 58 59 60; do
19124                 lnktgt=$(str_repeat 'l' $len)
19125                 touch $migrate_dir/$lnktgt
19126                 ln -s $lnktgt $migrate_dir/${len}char_ln
19127         done
19128
19129         # PATH_MAX
19130         for len in 4094 4095; do
19131                 lnktgt=$(str_repeat 'l' $len)
19132                 ln -s $lnktgt $migrate_dir/${len}char_ln
19133         done
19134
19135         # NAME_MAX
19136         for len in 254 255; do
19137                 touch $migrate_dir/$(str_repeat 'l' $len)
19138         done
19139
19140         $LFS migrate -m $MDTIDX $migrate_dir ||
19141                 error "fails on migrating remote dir to MDT1"
19142
19143         echo "migratate to MDT1, then checking.."
19144         for ((i = 0; i < 10; i++)); do
19145                 for file in $(find $migrate_dir/dir_${i}); do
19146                         mdt_index=$($LFS getstripe -m $file)
19147                         # broken symlink getstripe will fail
19148                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19149                                 error "$file is not on MDT${MDTIDX}"
19150                 done
19151         done
19152
19153         # the multiple link file should still in MDT0
19154         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19155         [ $mdt_index == 0 ] ||
19156                 error "$file is not on MDT${MDTIDX}"
19157
19158         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19159         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19160                 error " expect $old_dir_flag get $new_dir_flag"
19161
19162         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19163         [ "$old_file_flag" = "$new_file_flag" ] ||
19164                 error " expect $old_file_flag get $new_file_flag"
19165
19166         local new_dir_mode=$(stat -c%f $migrate_dir)
19167         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19168                 error "expect mode $old_dir_mode get $new_dir_mode"
19169
19170         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19171         [ "$old_file_mode" = "$new_file_mode" ] ||
19172                 error "expect mode $old_file_mode get $new_file_mode"
19173
19174         diff /etc/passwd $migrate_dir/$tfile ||
19175                 error "$tfile different after migration"
19176
19177         diff /etc/passwd $other_dir/luna ||
19178                 error "luna different after migration"
19179
19180         diff /etc/passwd $migrate_dir/sofia ||
19181                 error "sofia different after migration"
19182
19183         diff /etc/passwd $migrate_dir/david ||
19184                 error "david different after migration"
19185
19186         diff /etc/passwd $other_dir/zachary ||
19187                 error "zachary different after migration"
19188
19189         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19190                 error "${tfile}_ln different after migration"
19191
19192         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19193                 error "${tfile}_ln_other different after migration"
19194
19195         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19196         [ $stripe_count = 2 ] ||
19197                 error "dir strpe_count $d != 2 after migration."
19198
19199         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19200         [ $stripe_count = 2 ] ||
19201                 error "file strpe_count $d != 2 after migration."
19202
19203         #migrate back to MDT0
19204         MDTIDX=0
19205
19206         $LFS migrate -m $MDTIDX $migrate_dir ||
19207                 error "fails on migrating remote dir to MDT0"
19208
19209         echo "migrate back to MDT0, checking.."
19210         for file in $(find $migrate_dir); do
19211                 mdt_index=$($LFS getstripe -m $file)
19212                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19213                         error "$file is not on MDT${MDTIDX}"
19214         done
19215
19216         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19217         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19218                 error " expect $old_dir_flag get $new_dir_flag"
19219
19220         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19221         [ "$old_file_flag" = "$new_file_flag" ] ||
19222                 error " expect $old_file_flag get $new_file_flag"
19223
19224         local new_dir_mode=$(stat -c%f $migrate_dir)
19225         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19226                 error "expect mode $old_dir_mode get $new_dir_mode"
19227
19228         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19229         [ "$old_file_mode" = "$new_file_mode" ] ||
19230                 error "expect mode $old_file_mode get $new_file_mode"
19231
19232         diff /etc/passwd ${migrate_dir}/$tfile ||
19233                 error "$tfile different after migration"
19234
19235         diff /etc/passwd ${other_dir}/luna ||
19236                 error "luna different after migration"
19237
19238         diff /etc/passwd ${migrate_dir}/sofia ||
19239                 error "sofia different after migration"
19240
19241         diff /etc/passwd ${other_dir}/zachary ||
19242                 error "zachary different after migration"
19243
19244         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19245                 error "${tfile}_ln different after migration"
19246
19247         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19248                 error "${tfile}_ln_other different after migration"
19249
19250         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19251         [ $stripe_count = 2 ] ||
19252                 error "dir strpe_count $d != 2 after migration."
19253
19254         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19255         [ $stripe_count = 2 ] ||
19256                 error "file strpe_count $d != 2 after migration."
19257
19258         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19259 }
19260 run_test 230b "migrate directory"
19261
19262 test_230c() {
19263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19265         remote_mds_nodsh && skip "remote MDS with nodsh"
19266         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19267                 skip "Need MDS version at least 2.11.52"
19268
19269         local MDTIDX=1
19270         local total=3
19271         local mdt_index
19272         local file
19273         local migrate_dir=$DIR/$tdir/migrate_dir
19274
19275         #If migrating directory fails in the middle, all entries of
19276         #the directory is still accessiable.
19277         test_mkdir $DIR/$tdir
19278         test_mkdir -i0 -c1 $migrate_dir
19279         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19280         stat $migrate_dir
19281         createmany -o $migrate_dir/f $total ||
19282                 error "create files under ${migrate_dir} failed"
19283
19284         # fail after migrating top dir, and this will fail only once, so the
19285         # first sub file migration will fail (currently f3), others succeed.
19286         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19287         do_facet mds1 lctl set_param fail_loc=0x1801
19288         local t=$(ls $migrate_dir | wc -l)
19289         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19290                 error "migrate should fail"
19291         local u=$(ls $migrate_dir | wc -l)
19292         [ "$u" == "$t" ] || error "$u != $t during migration"
19293
19294         # add new dir/file should succeed
19295         mkdir $migrate_dir/dir ||
19296                 error "mkdir failed under migrating directory"
19297         touch $migrate_dir/file ||
19298                 error "create file failed under migrating directory"
19299
19300         # add file with existing name should fail
19301         for file in $migrate_dir/f*; do
19302                 stat $file > /dev/null || error "stat $file failed"
19303                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19304                         error "open(O_CREAT|O_EXCL) $file should fail"
19305                 $MULTIOP $file m && error "create $file should fail"
19306                 touch $DIR/$tdir/remote_dir/$tfile ||
19307                         error "touch $tfile failed"
19308                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19309                         error "link $file should fail"
19310                 mdt_index=$($LFS getstripe -m $file)
19311                 if [ $mdt_index == 0 ]; then
19312                         # file failed to migrate is not allowed to rename to
19313                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19314                                 error "rename to $file should fail"
19315                 else
19316                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19317                                 error "rename to $file failed"
19318                 fi
19319                 echo hello >> $file || error "write $file failed"
19320         done
19321
19322         # resume migration with different options should fail
19323         $LFS migrate -m 0 $migrate_dir &&
19324                 error "migrate -m 0 $migrate_dir should fail"
19325
19326         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19327                 error "migrate -c 2 $migrate_dir should fail"
19328
19329         # resume migration should succeed
19330         $LFS migrate -m $MDTIDX $migrate_dir ||
19331                 error "migrate $migrate_dir failed"
19332
19333         echo "Finish migration, then checking.."
19334         for file in $(find $migrate_dir); do
19335                 mdt_index=$($LFS getstripe -m $file)
19336                 [ $mdt_index == $MDTIDX ] ||
19337                         error "$file is not on MDT${MDTIDX}"
19338         done
19339
19340         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19341 }
19342 run_test 230c "check directory accessiblity if migration failed"
19343
19344 test_230d() {
19345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19347         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19348                 skip "Need MDS version at least 2.11.52"
19349         # LU-11235
19350         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19351
19352         local migrate_dir=$DIR/$tdir/migrate_dir
19353         local old_index
19354         local new_index
19355         local old_count
19356         local new_count
19357         local new_hash
19358         local mdt_index
19359         local i
19360         local j
19361
19362         old_index=$((RANDOM % MDSCOUNT))
19363         old_count=$((MDSCOUNT - old_index))
19364         new_index=$((RANDOM % MDSCOUNT))
19365         new_count=$((MDSCOUNT - new_index))
19366         new_hash=1 # for all_char
19367
19368         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19369         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19370
19371         test_mkdir $DIR/$tdir
19372         test_mkdir -i $old_index -c $old_count $migrate_dir
19373
19374         for ((i=0; i<100; i++)); do
19375                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19376                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19377                         error "create files under remote dir failed $i"
19378         done
19379
19380         echo -n "Migrate from MDT$old_index "
19381         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19382         echo -n "to MDT$new_index"
19383         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19384         echo
19385
19386         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19387         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19388                 error "migrate remote dir error"
19389
19390         echo "Finish migration, then checking.."
19391         for file in $(find $migrate_dir); do
19392                 mdt_index=$($LFS getstripe -m $file)
19393                 if [ $mdt_index -lt $new_index ] ||
19394                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19395                         error "$file is on MDT$mdt_index"
19396                 fi
19397         done
19398
19399         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19400 }
19401 run_test 230d "check migrate big directory"
19402
19403 test_230e() {
19404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19406         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19407                 skip "Need MDS version at least 2.11.52"
19408
19409         local i
19410         local j
19411         local a_fid
19412         local b_fid
19413
19414         mkdir_on_mdt0 $DIR/$tdir
19415         mkdir $DIR/$tdir/migrate_dir
19416         mkdir $DIR/$tdir/other_dir
19417         touch $DIR/$tdir/migrate_dir/a
19418         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19419         ls $DIR/$tdir/other_dir
19420
19421         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19422                 error "migrate dir fails"
19423
19424         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19425         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19426
19427         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19428         [ $mdt_index == 0 ] || error "a is not on MDT0"
19429
19430         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19431                 error "migrate dir fails"
19432
19433         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19434         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19435
19436         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19437         [ $mdt_index == 1 ] || error "a is not on MDT1"
19438
19439         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19440         [ $mdt_index == 1 ] || error "b is not on MDT1"
19441
19442         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19443         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19444
19445         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19446
19447         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19448 }
19449 run_test 230e "migrate mulitple local link files"
19450
19451 test_230f() {
19452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19454         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19455                 skip "Need MDS version at least 2.11.52"
19456
19457         local a_fid
19458         local ln_fid
19459
19460         mkdir -p $DIR/$tdir
19461         mkdir $DIR/$tdir/migrate_dir
19462         $LFS mkdir -i1 $DIR/$tdir/other_dir
19463         touch $DIR/$tdir/migrate_dir/a
19464         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19465         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19466         ls $DIR/$tdir/other_dir
19467
19468         # a should be migrated to MDT1, since no other links on MDT0
19469         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19470                 error "#1 migrate dir fails"
19471         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19472         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19473         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19474         [ $mdt_index == 1 ] || error "a is not on MDT1"
19475
19476         # a should stay on MDT1, because it is a mulitple link file
19477         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19478                 error "#2 migrate dir fails"
19479         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19480         [ $mdt_index == 1 ] || error "a is not on MDT1"
19481
19482         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19483                 error "#3 migrate dir fails"
19484
19485         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19486         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19487         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19488
19489         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19490         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19491
19492         # a should be migrated to MDT0, since no other links on MDT1
19493         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19494                 error "#4 migrate dir fails"
19495         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19496         [ $mdt_index == 0 ] || error "a is not on MDT0"
19497
19498         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19499 }
19500 run_test 230f "migrate mulitple remote link files"
19501
19502 test_230g() {
19503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19505         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19506                 skip "Need MDS version at least 2.11.52"
19507
19508         mkdir -p $DIR/$tdir/migrate_dir
19509
19510         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19511                 error "migrating dir to non-exist MDT succeeds"
19512         true
19513 }
19514 run_test 230g "migrate dir to non-exist MDT"
19515
19516 test_230h() {
19517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19519         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19520                 skip "Need MDS version at least 2.11.52"
19521
19522         local mdt_index
19523
19524         mkdir -p $DIR/$tdir/migrate_dir
19525
19526         $LFS migrate -m1 $DIR &&
19527                 error "migrating mountpoint1 should fail"
19528
19529         $LFS migrate -m1 $DIR/$tdir/.. &&
19530                 error "migrating mountpoint2 should fail"
19531
19532         # same as mv
19533         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19534                 error "migrating $tdir/migrate_dir/.. should fail"
19535
19536         true
19537 }
19538 run_test 230h "migrate .. and root"
19539
19540 test_230i() {
19541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19542         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19543         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19544                 skip "Need MDS version at least 2.11.52"
19545
19546         mkdir -p $DIR/$tdir/migrate_dir
19547
19548         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19549                 error "migration fails with a tailing slash"
19550
19551         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19552                 error "migration fails with two tailing slashes"
19553 }
19554 run_test 230i "lfs migrate -m tolerates trailing slashes"
19555
19556 test_230j() {
19557         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19558         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19559                 skip "Need MDS version at least 2.11.52"
19560
19561         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19562         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19563                 error "create $tfile failed"
19564         cat /etc/passwd > $DIR/$tdir/$tfile
19565
19566         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19567
19568         cmp /etc/passwd $DIR/$tdir/$tfile ||
19569                 error "DoM file mismatch after migration"
19570 }
19571 run_test 230j "DoM file data not changed after dir migration"
19572
19573 test_230k() {
19574         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19575         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19576                 skip "Need MDS version at least 2.11.56"
19577
19578         local total=20
19579         local files_on_starting_mdt=0
19580
19581         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19582         $LFS getdirstripe $DIR/$tdir
19583         for i in $(seq $total); do
19584                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19585                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19586                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19587         done
19588
19589         echo "$files_on_starting_mdt files on MDT0"
19590
19591         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19592         $LFS getdirstripe $DIR/$tdir
19593
19594         files_on_starting_mdt=0
19595         for i in $(seq $total); do
19596                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19597                         error "file $tfile.$i mismatch after migration"
19598                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19599                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19600         done
19601
19602         echo "$files_on_starting_mdt files on MDT1 after migration"
19603         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19604
19605         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19606         $LFS getdirstripe $DIR/$tdir
19607
19608         files_on_starting_mdt=0
19609         for i in $(seq $total); do
19610                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19611                         error "file $tfile.$i mismatch after 2nd migration"
19612                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19613                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19614         done
19615
19616         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19617         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19618
19619         true
19620 }
19621 run_test 230k "file data not changed after dir migration"
19622
19623 test_230l() {
19624         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19625         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19626                 skip "Need MDS version at least 2.11.56"
19627
19628         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19629         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19630                 error "create files under remote dir failed $i"
19631         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19632 }
19633 run_test 230l "readdir between MDTs won't crash"
19634
19635 test_230m() {
19636         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19637         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19638                 skip "Need MDS version at least 2.11.56"
19639
19640         local MDTIDX=1
19641         local mig_dir=$DIR/$tdir/migrate_dir
19642         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19643         local shortstr="b"
19644         local val
19645
19646         echo "Creating files and dirs with xattrs"
19647         test_mkdir $DIR/$tdir
19648         test_mkdir -i0 -c1 $mig_dir
19649         mkdir $mig_dir/dir
19650         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19651                 error "cannot set xattr attr1 on dir"
19652         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19653                 error "cannot set xattr attr2 on dir"
19654         touch $mig_dir/dir/f0
19655         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19656                 error "cannot set xattr attr1 on file"
19657         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19658                 error "cannot set xattr attr2 on file"
19659         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19660         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19661         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19662         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19663         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19664         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19665         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19666         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19667         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19668
19669         echo "Migrating to MDT1"
19670         $LFS migrate -m $MDTIDX $mig_dir ||
19671                 error "fails on migrating dir to MDT1"
19672
19673         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19674         echo "Checking xattrs"
19675         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19676         [ "$val" = $longstr ] ||
19677                 error "expecting xattr1 $longstr on dir, found $val"
19678         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19679         [ "$val" = $shortstr ] ||
19680                 error "expecting xattr2 $shortstr on dir, found $val"
19681         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19682         [ "$val" = $longstr ] ||
19683                 error "expecting xattr1 $longstr on file, found $val"
19684         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19685         [ "$val" = $shortstr ] ||
19686                 error "expecting xattr2 $shortstr on file, found $val"
19687 }
19688 run_test 230m "xattrs not changed after dir migration"
19689
19690 test_230n() {
19691         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19692         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19693                 skip "Need MDS version at least 2.13.53"
19694
19695         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19696         cat /etc/hosts > $DIR/$tdir/$tfile
19697         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19698         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19699
19700         cmp /etc/hosts $DIR/$tdir/$tfile ||
19701                 error "File data mismatch after migration"
19702 }
19703 run_test 230n "Dir migration with mirrored file"
19704
19705 test_230o() {
19706         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19707         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19708                 skip "Need MDS version at least 2.13.52"
19709
19710         local mdts=$(comma_list $(mdts_nodes))
19711         local timeout=100
19712         local restripe_status
19713         local delta
19714         local i
19715
19716         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19717
19718         # in case "crush" hash type is not set
19719         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19720
19721         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19722                            mdt.*MDT0000.enable_dir_restripe)
19723         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19724         stack_trap "do_nodes $mdts $LCTL set_param \
19725                     mdt.*.enable_dir_restripe=$restripe_status"
19726
19727         mkdir $DIR/$tdir
19728         createmany -m $DIR/$tdir/f 100 ||
19729                 error "create files under remote dir failed $i"
19730         createmany -d $DIR/$tdir/d 100 ||
19731                 error "create dirs under remote dir failed $i"
19732
19733         for i in $(seq 2 $MDSCOUNT); do
19734                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19735                 $LFS setdirstripe -c $i $DIR/$tdir ||
19736                         error "split -c $i $tdir failed"
19737                 wait_update $HOSTNAME \
19738                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19739                         error "dir split not finished"
19740                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19741                         awk '/migrate/ {sum += $2} END { print sum }')
19742                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19743                 # delta is around total_files/stripe_count
19744                 (( $delta < 200 / (i - 1) + 4 )) ||
19745                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19746         done
19747 }
19748 run_test 230o "dir split"
19749
19750 test_230p() {
19751         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19752         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19753                 skip "Need MDS version at least 2.13.52"
19754
19755         local mdts=$(comma_list $(mdts_nodes))
19756         local timeout=100
19757         local restripe_status
19758         local delta
19759         local c
19760
19761         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19762
19763         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19764
19765         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19766                            mdt.*MDT0000.enable_dir_restripe)
19767         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19768         stack_trap "do_nodes $mdts $LCTL set_param \
19769                     mdt.*.enable_dir_restripe=$restripe_status"
19770
19771         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19772         createmany -m $DIR/$tdir/f 100 ||
19773                 error "create files under remote dir failed"
19774         createmany -d $DIR/$tdir/d 100 ||
19775                 error "create dirs under remote dir failed"
19776
19777         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19778                 local mdt_hash="crush"
19779
19780                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19781                 $LFS setdirstripe -c $c $DIR/$tdir ||
19782                         error "split -c $c $tdir failed"
19783                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19784                         mdt_hash="$mdt_hash,fixed"
19785                 elif [ $c -eq 1 ]; then
19786                         mdt_hash="none"
19787                 fi
19788                 wait_update $HOSTNAME \
19789                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19790                         error "dir merge not finished"
19791                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19792                         awk '/migrate/ {sum += $2} END { print sum }')
19793                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19794                 # delta is around total_files/stripe_count
19795                 (( delta < 200 / c + 4 )) ||
19796                         error "$delta files migrated >= $((200 / c + 4))"
19797         done
19798 }
19799 run_test 230p "dir merge"
19800
19801 test_230q() {
19802         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19803         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19804                 skip "Need MDS version at least 2.13.52"
19805
19806         local mdts=$(comma_list $(mdts_nodes))
19807         local saved_threshold=$(do_facet mds1 \
19808                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19809         local saved_delta=$(do_facet mds1 \
19810                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19811         local threshold=100
19812         local delta=2
19813         local total=0
19814         local stripe_count=0
19815         local stripe_index
19816         local nr_files
19817         local create
19818
19819         # test with fewer files on ZFS
19820         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19821
19822         stack_trap "do_nodes $mdts $LCTL set_param \
19823                     mdt.*.dir_split_count=$saved_threshold"
19824         stack_trap "do_nodes $mdts $LCTL set_param \
19825                     mdt.*.dir_split_delta=$saved_delta"
19826         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19827         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19828         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19829         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19830         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19831         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19832
19833         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19834         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19835
19836         create=$((threshold * 3 / 2))
19837         while [ $stripe_count -lt $MDSCOUNT ]; do
19838                 createmany -m $DIR/$tdir/f $total $create ||
19839                         error "create sub files failed"
19840                 stat $DIR/$tdir > /dev/null
19841                 total=$((total + create))
19842                 stripe_count=$((stripe_count + delta))
19843                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19844
19845                 wait_update $HOSTNAME \
19846                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19847                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19848
19849                 wait_update $HOSTNAME \
19850                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19851                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19852
19853                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19854                 echo "$nr_files/$total files on MDT$stripe_index after split"
19855                 # allow 10% margin of imbalance with crush hash
19856                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19857                         error "$nr_files files on MDT$stripe_index after split"
19858
19859                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19860                 [ $nr_files -eq $total ] ||
19861                         error "total sub files $nr_files != $total"
19862         done
19863
19864         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19865
19866         echo "fixed layout directory won't auto split"
19867         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19868         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19869                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19870         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19871                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19872 }
19873 run_test 230q "dir auto split"
19874
19875 test_230r() {
19876         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19877         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19878         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19879                 skip "Need MDS version at least 2.13.54"
19880
19881         # maximum amount of local locks:
19882         # parent striped dir - 2 locks
19883         # new stripe in parent to migrate to - 1 lock
19884         # source and target - 2 locks
19885         # Total 5 locks for regular file
19886         mkdir -p $DIR/$tdir
19887         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19888         touch $DIR/$tdir/dir1/eee
19889
19890         # create 4 hardlink for 4 more locks
19891         # Total: 9 locks > RS_MAX_LOCKS (8)
19892         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19893         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19894         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19895         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19896         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19897         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19898         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19899         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19900
19901         cancel_lru_locks mdc
19902
19903         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19904                 error "migrate dir fails"
19905
19906         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19907 }
19908 run_test 230r "migrate with too many local locks"
19909
19910 test_230s() {
19911         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19912                 skip "Need MDS version at least 2.13.57"
19913
19914         local mdts=$(comma_list $(mdts_nodes))
19915         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19916                                 mdt.*MDT0000.enable_dir_restripe)
19917
19918         stack_trap "do_nodes $mdts $LCTL set_param \
19919                     mdt.*.enable_dir_restripe=$restripe_status"
19920
19921         local st
19922         for st in 0 1; do
19923                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19924                 test_mkdir $DIR/$tdir
19925                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19926                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19927                 rmdir $DIR/$tdir
19928         done
19929 }
19930 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19931
19932 test_230t()
19933 {
19934         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19935         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19936                 skip "Need MDS version at least 2.14.50"
19937
19938         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19939         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19940         $LFS project -p 1 -s $DIR/$tdir ||
19941                 error "set $tdir project id failed"
19942         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19943                 error "set subdir project id failed"
19944         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19945 }
19946 run_test 230t "migrate directory with project ID set"
19947
19948 test_231a()
19949 {
19950         # For simplicity this test assumes that max_pages_per_rpc
19951         # is the same across all OSCs
19952         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19953         local bulk_size=$((max_pages * PAGE_SIZE))
19954         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19955                                        head -n 1)
19956
19957         mkdir -p $DIR/$tdir
19958         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19959                 error "failed to set stripe with -S ${brw_size}M option"
19960
19961         # clear the OSC stats
19962         $LCTL set_param osc.*.stats=0 &>/dev/null
19963         stop_writeback
19964
19965         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19966         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19967                 oflag=direct &>/dev/null || error "dd failed"
19968
19969         sync; sleep 1; sync # just to be safe
19970         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19971         if [ x$nrpcs != "x1" ]; then
19972                 $LCTL get_param osc.*.stats
19973                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19974         fi
19975
19976         start_writeback
19977         # Drop the OSC cache, otherwise we will read from it
19978         cancel_lru_locks osc
19979
19980         # clear the OSC stats
19981         $LCTL set_param osc.*.stats=0 &>/dev/null
19982
19983         # Client reads $bulk_size.
19984         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19985                 iflag=direct &>/dev/null || error "dd failed"
19986
19987         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19988         if [ x$nrpcs != "x1" ]; then
19989                 $LCTL get_param osc.*.stats
19990                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19991         fi
19992 }
19993 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19994
19995 test_231b() {
19996         mkdir -p $DIR/$tdir
19997         local i
19998         for i in {0..1023}; do
19999                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20000                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20001                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20002         done
20003         sync
20004 }
20005 run_test 231b "must not assert on fully utilized OST request buffer"
20006
20007 test_232a() {
20008         mkdir -p $DIR/$tdir
20009         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20010
20011         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20012         do_facet ost1 $LCTL set_param fail_loc=0x31c
20013
20014         # ignore dd failure
20015         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20016
20017         do_facet ost1 $LCTL set_param fail_loc=0
20018         umount_client $MOUNT || error "umount failed"
20019         mount_client $MOUNT || error "mount failed"
20020         stop ost1 || error "cannot stop ost1"
20021         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20022 }
20023 run_test 232a "failed lock should not block umount"
20024
20025 test_232b() {
20026         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20027                 skip "Need MDS version at least 2.10.58"
20028
20029         mkdir -p $DIR/$tdir
20030         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20031         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20032         sync
20033         cancel_lru_locks osc
20034
20035         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20036         do_facet ost1 $LCTL set_param fail_loc=0x31c
20037
20038         # ignore failure
20039         $LFS data_version $DIR/$tdir/$tfile || true
20040
20041         do_facet ost1 $LCTL set_param fail_loc=0
20042         umount_client $MOUNT || error "umount failed"
20043         mount_client $MOUNT || error "mount failed"
20044         stop ost1 || error "cannot stop ost1"
20045         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20046 }
20047 run_test 232b "failed data version lock should not block umount"
20048
20049 test_233a() {
20050         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20051                 skip "Need MDS version at least 2.3.64"
20052         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20053
20054         local fid=$($LFS path2fid $MOUNT)
20055
20056         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20057                 error "cannot access $MOUNT using its FID '$fid'"
20058 }
20059 run_test 233a "checking that OBF of the FS root succeeds"
20060
20061 test_233b() {
20062         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20063                 skip "Need MDS version at least 2.5.90"
20064         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20065
20066         local fid=$($LFS path2fid $MOUNT/.lustre)
20067
20068         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20069                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20070
20071         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20072         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20073                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20074 }
20075 run_test 233b "checking that OBF of the FS .lustre succeeds"
20076
20077 test_234() {
20078         local p="$TMP/sanityN-$TESTNAME.parameters"
20079         save_lustre_params client "llite.*.xattr_cache" > $p
20080         lctl set_param llite.*.xattr_cache 1 ||
20081                 skip_env "xattr cache is not supported"
20082
20083         mkdir -p $DIR/$tdir || error "mkdir failed"
20084         touch $DIR/$tdir/$tfile || error "touch failed"
20085         # OBD_FAIL_LLITE_XATTR_ENOMEM
20086         $LCTL set_param fail_loc=0x1405
20087         getfattr -n user.attr $DIR/$tdir/$tfile &&
20088                 error "getfattr should have failed with ENOMEM"
20089         $LCTL set_param fail_loc=0x0
20090         rm -rf $DIR/$tdir
20091
20092         restore_lustre_params < $p
20093         rm -f $p
20094 }
20095 run_test 234 "xattr cache should not crash on ENOMEM"
20096
20097 test_235() {
20098         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20099                 skip "Need MDS version at least 2.4.52"
20100
20101         flock_deadlock $DIR/$tfile
20102         local RC=$?
20103         case $RC in
20104                 0)
20105                 ;;
20106                 124) error "process hangs on a deadlock"
20107                 ;;
20108                 *) error "error executing flock_deadlock $DIR/$tfile"
20109                 ;;
20110         esac
20111 }
20112 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20113
20114 #LU-2935
20115 test_236() {
20116         check_swap_layouts_support
20117
20118         local ref1=/etc/passwd
20119         local ref2=/etc/group
20120         local file1=$DIR/$tdir/f1
20121         local file2=$DIR/$tdir/f2
20122
20123         test_mkdir -c1 $DIR/$tdir
20124         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20125         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20126         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20127         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20128         local fd=$(free_fd)
20129         local cmd="exec $fd<>$file2"
20130         eval $cmd
20131         rm $file2
20132         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20133                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20134         cmd="exec $fd>&-"
20135         eval $cmd
20136         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20137
20138         #cleanup
20139         rm -rf $DIR/$tdir
20140 }
20141 run_test 236 "Layout swap on open unlinked file"
20142
20143 # LU-4659 linkea consistency
20144 test_238() {
20145         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20146                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20147                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20148                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20149
20150         touch $DIR/$tfile
20151         ln $DIR/$tfile $DIR/$tfile.lnk
20152         touch $DIR/$tfile.new
20153         mv $DIR/$tfile.new $DIR/$tfile
20154         local fid1=$($LFS path2fid $DIR/$tfile)
20155         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20156         local path1=$($LFS fid2path $FSNAME "$fid1")
20157         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20158         local path2=$($LFS fid2path $FSNAME "$fid2")
20159         [ $tfile.lnk == $path2 ] ||
20160                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20161         rm -f $DIR/$tfile*
20162 }
20163 run_test 238 "Verify linkea consistency"
20164
20165 test_239A() { # was test_239
20166         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20167                 skip "Need MDS version at least 2.5.60"
20168
20169         local list=$(comma_list $(mdts_nodes))
20170
20171         mkdir -p $DIR/$tdir
20172         createmany -o $DIR/$tdir/f- 5000
20173         unlinkmany $DIR/$tdir/f- 5000
20174         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20175                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20176         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20177                         osp.*MDT*.sync_in_flight" | calc_sum)
20178         [ "$changes" -eq 0 ] || error "$changes not synced"
20179 }
20180 run_test 239A "osp_sync test"
20181
20182 test_239a() { #LU-5297
20183         remote_mds_nodsh && skip "remote MDS with nodsh"
20184
20185         touch $DIR/$tfile
20186         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20187         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20188         chgrp $RUNAS_GID $DIR/$tfile
20189         wait_delete_completed
20190 }
20191 run_test 239a "process invalid osp sync record correctly"
20192
20193 test_239b() { #LU-5297
20194         remote_mds_nodsh && skip "remote MDS with nodsh"
20195
20196         touch $DIR/$tfile1
20197         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20198         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20199         chgrp $RUNAS_GID $DIR/$tfile1
20200         wait_delete_completed
20201         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20202         touch $DIR/$tfile2
20203         chgrp $RUNAS_GID $DIR/$tfile2
20204         wait_delete_completed
20205 }
20206 run_test 239b "process osp sync record with ENOMEM error correctly"
20207
20208 test_240() {
20209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20210         remote_mds_nodsh && skip "remote MDS with nodsh"
20211
20212         mkdir -p $DIR/$tdir
20213
20214         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20215                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20216         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20217                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20218
20219         umount_client $MOUNT || error "umount failed"
20220         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20221         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20222         mount_client $MOUNT || error "failed to mount client"
20223
20224         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20225         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20226 }
20227 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20228
20229 test_241_bio() {
20230         local count=$1
20231         local bsize=$2
20232
20233         for LOOP in $(seq $count); do
20234                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20235                 cancel_lru_locks $OSC || true
20236         done
20237 }
20238
20239 test_241_dio() {
20240         local count=$1
20241         local bsize=$2
20242
20243         for LOOP in $(seq $1); do
20244                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20245                         2>/dev/null
20246         done
20247 }
20248
20249 test_241a() { # was test_241
20250         local bsize=$PAGE_SIZE
20251
20252         (( bsize < 40960 )) && bsize=40960
20253         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20254         ls -la $DIR/$tfile
20255         cancel_lru_locks $OSC
20256         test_241_bio 1000 $bsize &
20257         PID=$!
20258         test_241_dio 1000 $bsize
20259         wait $PID
20260 }
20261 run_test 241a "bio vs dio"
20262
20263 test_241b() {
20264         local bsize=$PAGE_SIZE
20265
20266         (( bsize < 40960 )) && bsize=40960
20267         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20268         ls -la $DIR/$tfile
20269         test_241_dio 1000 $bsize &
20270         PID=$!
20271         test_241_dio 1000 $bsize
20272         wait $PID
20273 }
20274 run_test 241b "dio vs dio"
20275
20276 test_242() {
20277         remote_mds_nodsh && skip "remote MDS with nodsh"
20278
20279         mkdir_on_mdt0 $DIR/$tdir
20280         touch $DIR/$tdir/$tfile
20281
20282         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20283         do_facet mds1 lctl set_param fail_loc=0x105
20284         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20285
20286         do_facet mds1 lctl set_param fail_loc=0
20287         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20288 }
20289 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20290
20291 test_243()
20292 {
20293         test_mkdir $DIR/$tdir
20294         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20295 }
20296 run_test 243 "various group lock tests"
20297
20298 test_244a()
20299 {
20300         test_mkdir $DIR/$tdir
20301         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20302         sendfile_grouplock $DIR/$tdir/$tfile || \
20303                 error "sendfile+grouplock failed"
20304         rm -rf $DIR/$tdir
20305 }
20306 run_test 244a "sendfile with group lock tests"
20307
20308 test_244b()
20309 {
20310         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20311
20312         local threads=50
20313         local size=$((1024*1024))
20314
20315         test_mkdir $DIR/$tdir
20316         for i in $(seq 1 $threads); do
20317                 local file=$DIR/$tdir/file_$((i / 10))
20318                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20319                 local pids[$i]=$!
20320         done
20321         for i in $(seq 1 $threads); do
20322                 wait ${pids[$i]}
20323         done
20324 }
20325 run_test 244b "multi-threaded write with group lock"
20326
20327 test_245() {
20328         local flagname="multi_mod_rpcs"
20329         local connect_data_name="max_mod_rpcs"
20330         local out
20331
20332         # check if multiple modify RPCs flag is set
20333         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20334                 grep "connect_flags:")
20335         echo "$out"
20336
20337         echo "$out" | grep -qw $flagname
20338         if [ $? -ne 0 ]; then
20339                 echo "connect flag $flagname is not set"
20340                 return
20341         fi
20342
20343         # check if multiple modify RPCs data is set
20344         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20345         echo "$out"
20346
20347         echo "$out" | grep -qw $connect_data_name ||
20348                 error "import should have connect data $connect_data_name"
20349 }
20350 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20351
20352 cleanup_247() {
20353         local submount=$1
20354
20355         trap 0
20356         umount_client $submount
20357         rmdir $submount
20358 }
20359
20360 test_247a() {
20361         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20362                 grep -q subtree ||
20363                 skip_env "Fileset feature is not supported"
20364
20365         local submount=${MOUNT}_$tdir
20366
20367         mkdir $MOUNT/$tdir
20368         mkdir -p $submount || error "mkdir $submount failed"
20369         FILESET="$FILESET/$tdir" mount_client $submount ||
20370                 error "mount $submount failed"
20371         trap "cleanup_247 $submount" EXIT
20372         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20373         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20374                 error "read $MOUNT/$tdir/$tfile failed"
20375         cleanup_247 $submount
20376 }
20377 run_test 247a "mount subdir as fileset"
20378
20379 test_247b() {
20380         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20381                 skip_env "Fileset feature is not supported"
20382
20383         local submount=${MOUNT}_$tdir
20384
20385         rm -rf $MOUNT/$tdir
20386         mkdir -p $submount || error "mkdir $submount failed"
20387         SKIP_FILESET=1
20388         FILESET="$FILESET/$tdir" mount_client $submount &&
20389                 error "mount $submount should fail"
20390         rmdir $submount
20391 }
20392 run_test 247b "mount subdir that dose not exist"
20393
20394 test_247c() {
20395         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20396                 skip_env "Fileset feature is not supported"
20397
20398         local submount=${MOUNT}_$tdir
20399
20400         mkdir -p $MOUNT/$tdir/dir1
20401         mkdir -p $submount || error "mkdir $submount failed"
20402         trap "cleanup_247 $submount" EXIT
20403         FILESET="$FILESET/$tdir" mount_client $submount ||
20404                 error "mount $submount failed"
20405         local fid=$($LFS path2fid $MOUNT/)
20406         $LFS fid2path $submount $fid && error "fid2path should fail"
20407         cleanup_247 $submount
20408 }
20409 run_test 247c "running fid2path outside subdirectory root"
20410
20411 test_247d() {
20412         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20413                 skip "Fileset feature is not supported"
20414
20415         local submount=${MOUNT}_$tdir
20416
20417         mkdir -p $MOUNT/$tdir/dir1
20418         mkdir -p $submount || error "mkdir $submount failed"
20419         FILESET="$FILESET/$tdir" mount_client $submount ||
20420                 error "mount $submount failed"
20421         trap "cleanup_247 $submount" EXIT
20422
20423         local td=$submount/dir1
20424         local fid=$($LFS path2fid $td)
20425         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20426
20427         # check that we get the same pathname back
20428         local rootpath
20429         local found
20430         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20431                 echo "$rootpath $fid"
20432                 found=$($LFS fid2path $rootpath "$fid")
20433                 [ -n "found" ] || error "fid2path should succeed"
20434                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20435         done
20436         # check wrong root path format
20437         rootpath=$submount"_wrong"
20438         found=$($LFS fid2path $rootpath "$fid")
20439         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20440
20441         cleanup_247 $submount
20442 }
20443 run_test 247d "running fid2path inside subdirectory root"
20444
20445 # LU-8037
20446 test_247e() {
20447         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20448                 grep -q subtree ||
20449                 skip "Fileset feature is not supported"
20450
20451         local submount=${MOUNT}_$tdir
20452
20453         mkdir $MOUNT/$tdir
20454         mkdir -p $submount || error "mkdir $submount failed"
20455         FILESET="$FILESET/.." mount_client $submount &&
20456                 error "mount $submount should fail"
20457         rmdir $submount
20458 }
20459 run_test 247e "mount .. as fileset"
20460
20461 test_247f() {
20462         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20463         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20464                 skip "Need at least version 2.13.52"
20465         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20466                 skip "Need at least version 2.14.50"
20467         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20468                 grep -q subtree ||
20469                 skip "Fileset feature is not supported"
20470
20471         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20472         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20473                 error "mkdir remote failed"
20474         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20475                 error "mkdir remote/subdir failed"
20476         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20477                 error "mkdir striped failed"
20478         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20479
20480         local submount=${MOUNT}_$tdir
20481
20482         mkdir -p $submount || error "mkdir $submount failed"
20483         stack_trap "rmdir $submount"
20484
20485         local dir
20486         local stat
20487         local fileset=$FILESET
20488         local mdts=$(comma_list $(mdts_nodes))
20489
20490         stat=$(do_facet mds1 $LCTL get_param -n \
20491                 mdt.*MDT0000.enable_remote_subdir_mount)
20492         stack_trap "do_nodes $mdts $LCTL set_param \
20493                 mdt.*.enable_remote_subdir_mount=$stat"
20494
20495         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20496         stack_trap "umount_client $submount"
20497         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20498                 error "mount remote dir $dir should fail"
20499
20500         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20501                 $tdir/striped/. ; do
20502                 FILESET="$fileset/$dir" mount_client $submount ||
20503                         error "mount $dir failed"
20504                 umount_client $submount
20505         done
20506
20507         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20508         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20509                 error "mount $tdir/remote failed"
20510 }
20511 run_test 247f "mount striped or remote directory as fileset"
20512
20513 test_247g() {
20514         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20515         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20516                 skip "Need at least version 2.14.50"
20517
20518         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20519                 error "mkdir $tdir failed"
20520         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20521
20522         local submount=${MOUNT}_$tdir
20523
20524         mkdir -p $submount || error "mkdir $submount failed"
20525         stack_trap "rmdir $submount"
20526
20527         FILESET="$fileset/$tdir" mount_client $submount ||
20528                 error "mount $dir failed"
20529         stack_trap "umount $submount"
20530
20531         local mdts=$(comma_list $(mdts_nodes))
20532
20533         local nrpcs
20534
20535         stat $submount > /dev/null
20536         cancel_lru_locks $MDC
20537         stat $submount > /dev/null
20538         stat $submount/$tfile > /dev/null
20539         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20540         stat $submount/$tfile > /dev/null
20541         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20542                 awk '/getattr/ {sum += $2} END {print sum}')
20543
20544         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20545 }
20546 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20547
20548 test_248a() {
20549         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20550         [ -z "$fast_read_sav" ] && skip "no fast read support"
20551
20552         # create a large file for fast read verification
20553         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20554
20555         # make sure the file is created correctly
20556         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20557                 { rm -f $DIR/$tfile; skip "file creation error"; }
20558
20559         echo "Test 1: verify that fast read is 4 times faster on cache read"
20560
20561         # small read with fast read enabled
20562         $LCTL set_param -n llite.*.fast_read=1
20563         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20564                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20565                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20566         # small read with fast read disabled
20567         $LCTL set_param -n llite.*.fast_read=0
20568         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20569                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20570                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20571
20572         # verify that fast read is 4 times faster for cache read
20573         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20574                 error_not_in_vm "fast read was not 4 times faster: " \
20575                            "$t_fast vs $t_slow"
20576
20577         echo "Test 2: verify the performance between big and small read"
20578         $LCTL set_param -n llite.*.fast_read=1
20579
20580         # 1k non-cache read
20581         cancel_lru_locks osc
20582         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20583                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20584                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20585
20586         # 1M non-cache read
20587         cancel_lru_locks osc
20588         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20589                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20590                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20591
20592         # verify that big IO is not 4 times faster than small IO
20593         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20594                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20595
20596         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20597         rm -f $DIR/$tfile
20598 }
20599 run_test 248a "fast read verification"
20600
20601 test_248b() {
20602         # Default short_io_bytes=16384, try both smaller and larger sizes.
20603         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20604         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20605         echo "bs=53248 count=113 normal buffered write"
20606         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20607                 error "dd of initial data file failed"
20608         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20609
20610         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20611         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20612                 error "dd with sync normal writes failed"
20613         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20614
20615         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20616         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20617                 error "dd with sync small writes failed"
20618         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20619
20620         cancel_lru_locks osc
20621
20622         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20623         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20624         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20625         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20626                 iflag=direct || error "dd with O_DIRECT small read failed"
20627         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20628         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20629                 error "compare $TMP/$tfile.1 failed"
20630
20631         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20632         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20633
20634         # just to see what the maximum tunable value is, and test parsing
20635         echo "test invalid parameter 2MB"
20636         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20637                 error "too-large short_io_bytes allowed"
20638         echo "test maximum parameter 512KB"
20639         # if we can set a larger short_io_bytes, run test regardless of version
20640         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20641                 # older clients may not allow setting it this large, that's OK
20642                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20643                         skip "Need at least client version 2.13.50"
20644                 error "medium short_io_bytes failed"
20645         fi
20646         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20647         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20648
20649         echo "test large parameter 64KB"
20650         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20651         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20652
20653         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20654         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20655                 error "dd with sync large writes failed"
20656         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20657
20658         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20659         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20660         num=$((113 * 4096 / PAGE_SIZE))
20661         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20662         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20663                 error "dd with O_DIRECT large writes failed"
20664         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20665                 error "compare $DIR/$tfile.3 failed"
20666
20667         cancel_lru_locks osc
20668
20669         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20670         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20671                 error "dd with O_DIRECT large read failed"
20672         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20673                 error "compare $TMP/$tfile.2 failed"
20674
20675         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20676         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20677                 error "dd with O_DIRECT large read failed"
20678         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20679                 error "compare $TMP/$tfile.3 failed"
20680 }
20681 run_test 248b "test short_io read and write for both small and large sizes"
20682
20683 test_249() { # LU-7890
20684         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20685                 skip "Need at least version 2.8.54"
20686
20687         rm -f $DIR/$tfile
20688         $LFS setstripe -c 1 $DIR/$tfile
20689         # Offset 2T == 4k * 512M
20690         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20691                 error "dd to 2T offset failed"
20692 }
20693 run_test 249 "Write above 2T file size"
20694
20695 test_250() {
20696         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20697          && skip "no 16TB file size limit on ZFS"
20698
20699         $LFS setstripe -c 1 $DIR/$tfile
20700         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20701         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20702         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20703         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20704                 conv=notrunc,fsync && error "append succeeded"
20705         return 0
20706 }
20707 run_test 250 "Write above 16T limit"
20708
20709 test_251() {
20710         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20711
20712         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20713         #Skip once - writing the first stripe will succeed
20714         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20715         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20716                 error "short write happened"
20717
20718         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20719         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20720                 error "short read happened"
20721
20722         rm -f $DIR/$tfile
20723 }
20724 run_test 251 "Handling short read and write correctly"
20725
20726 test_252() {
20727         remote_mds_nodsh && skip "remote MDS with nodsh"
20728         remote_ost_nodsh && skip "remote OST with nodsh"
20729         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20730                 skip_env "ldiskfs only test"
20731         fi
20732
20733         local tgt
20734         local dev
20735         local out
20736         local uuid
20737         local num
20738         local gen
20739
20740         # check lr_reader on OST0000
20741         tgt=ost1
20742         dev=$(facet_device $tgt)
20743         out=$(do_facet $tgt $LR_READER $dev)
20744         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20745         echo "$out"
20746         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20747         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20748                 error "Invalid uuid returned by $LR_READER on target $tgt"
20749         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20750
20751         # check lr_reader -c on MDT0000
20752         tgt=mds1
20753         dev=$(facet_device $tgt)
20754         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20755                 skip "$LR_READER does not support additional options"
20756         fi
20757         out=$(do_facet $tgt $LR_READER -c $dev)
20758         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20759         echo "$out"
20760         num=$(echo "$out" | grep -c "mdtlov")
20761         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20762                 error "Invalid number of mdtlov clients returned by $LR_READER"
20763         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20764
20765         # check lr_reader -cr on MDT0000
20766         out=$(do_facet $tgt $LR_READER -cr $dev)
20767         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20768         echo "$out"
20769         echo "$out" | grep -q "^reply_data:$" ||
20770                 error "$LR_READER should have returned 'reply_data' section"
20771         num=$(echo "$out" | grep -c "client_generation")
20772         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20773 }
20774 run_test 252 "check lr_reader tool"
20775
20776 test_253() {
20777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20778         remote_mds_nodsh && skip "remote MDS with nodsh"
20779         remote_mgs_nodsh && skip "remote MGS with nodsh"
20780
20781         local ostidx=0
20782         local rc=0
20783         local ost_name=$(ostname_from_index $ostidx)
20784
20785         # on the mdt's osc
20786         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20787         do_facet $SINGLEMDS $LCTL get_param -n \
20788                 osp.$mdtosc_proc1.reserved_mb_high ||
20789                 skip  "remote MDS does not support reserved_mb_high"
20790
20791         rm -rf $DIR/$tdir
20792         wait_mds_ost_sync
20793         wait_delete_completed
20794         mkdir $DIR/$tdir
20795
20796         pool_add $TESTNAME || error "Pool creation failed"
20797         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20798
20799         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20800                 error "Setstripe failed"
20801
20802         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20803
20804         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20805                     grep "watermarks")
20806         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20807
20808         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20809                         osp.$mdtosc_proc1.prealloc_status)
20810         echo "prealloc_status $oa_status"
20811
20812         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20813                 error "File creation should fail"
20814
20815         #object allocation was stopped, but we still able to append files
20816         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20817                 oflag=append || error "Append failed"
20818
20819         rm -f $DIR/$tdir/$tfile.0
20820
20821         # For this test, we want to delete the files we created to go out of
20822         # space but leave the watermark, so we remain nearly out of space
20823         ost_watermarks_enospc_delete_files $tfile $ostidx
20824
20825         wait_delete_completed
20826
20827         sleep_maxage
20828
20829         for i in $(seq 10 12); do
20830                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20831                         2>/dev/null || error "File creation failed after rm"
20832         done
20833
20834         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20835                         osp.$mdtosc_proc1.prealloc_status)
20836         echo "prealloc_status $oa_status"
20837
20838         if (( oa_status != 0 )); then
20839                 error "Object allocation still disable after rm"
20840         fi
20841 }
20842 run_test 253 "Check object allocation limit"
20843
20844 test_254() {
20845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20846         remote_mds_nodsh && skip "remote MDS with nodsh"
20847         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20848                 skip "MDS does not support changelog_size"
20849
20850         local cl_user
20851         local MDT0=$(facet_svc $SINGLEMDS)
20852
20853         changelog_register || error "changelog_register failed"
20854
20855         changelog_clear 0 || error "changelog_clear failed"
20856
20857         local size1=$(do_facet $SINGLEMDS \
20858                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20859         echo "Changelog size $size1"
20860
20861         rm -rf $DIR/$tdir
20862         $LFS mkdir -i 0 $DIR/$tdir
20863         # change something
20864         mkdir -p $DIR/$tdir/pics/2008/zachy
20865         touch $DIR/$tdir/pics/2008/zachy/timestamp
20866         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20867         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20868         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20869         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20870         rm $DIR/$tdir/pics/desktop.jpg
20871
20872         local size2=$(do_facet $SINGLEMDS \
20873                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20874         echo "Changelog size after work $size2"
20875
20876         (( $size2 > $size1 )) ||
20877                 error "new Changelog size=$size2 less than old size=$size1"
20878 }
20879 run_test 254 "Check changelog size"
20880
20881 ladvise_no_type()
20882 {
20883         local type=$1
20884         local file=$2
20885
20886         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20887                 awk -F: '{print $2}' | grep $type > /dev/null
20888         if [ $? -ne 0 ]; then
20889                 return 0
20890         fi
20891         return 1
20892 }
20893
20894 ladvise_no_ioctl()
20895 {
20896         local file=$1
20897
20898         lfs ladvise -a willread $file > /dev/null 2>&1
20899         if [ $? -eq 0 ]; then
20900                 return 1
20901         fi
20902
20903         lfs ladvise -a willread $file 2>&1 |
20904                 grep "Inappropriate ioctl for device" > /dev/null
20905         if [ $? -eq 0 ]; then
20906                 return 0
20907         fi
20908         return 1
20909 }
20910
20911 percent() {
20912         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20913 }
20914
20915 # run a random read IO workload
20916 # usage: random_read_iops <filename> <filesize> <iosize>
20917 random_read_iops() {
20918         local file=$1
20919         local fsize=$2
20920         local iosize=${3:-4096}
20921
20922         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20923                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20924 }
20925
20926 drop_file_oss_cache() {
20927         local file="$1"
20928         local nodes="$2"
20929
20930         $LFS ladvise -a dontneed $file 2>/dev/null ||
20931                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20932 }
20933
20934 ladvise_willread_performance()
20935 {
20936         local repeat=10
20937         local average_origin=0
20938         local average_cache=0
20939         local average_ladvise=0
20940
20941         for ((i = 1; i <= $repeat; i++)); do
20942                 echo "Iter $i/$repeat: reading without willread hint"
20943                 cancel_lru_locks osc
20944                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20945                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20946                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20947                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20948
20949                 cancel_lru_locks osc
20950                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20951                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20952                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20953
20954                 cancel_lru_locks osc
20955                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20956                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20957                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20958                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20959                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20960         done
20961         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20962         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20963         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20964
20965         speedup_cache=$(percent $average_cache $average_origin)
20966         speedup_ladvise=$(percent $average_ladvise $average_origin)
20967
20968         echo "Average uncached read: $average_origin"
20969         echo "Average speedup with OSS cached read: " \
20970                 "$average_cache = +$speedup_cache%"
20971         echo "Average speedup with ladvise willread: " \
20972                 "$average_ladvise = +$speedup_ladvise%"
20973
20974         local lowest_speedup=20
20975         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20976                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20977                         "got $average_cache%. Skipping ladvise willread check."
20978                 return 0
20979         fi
20980
20981         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20982         # it is still good to run until then to exercise 'ladvise willread'
20983         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20984                 [ "$ost1_FSTYPE" = "zfs" ] &&
20985                 echo "osd-zfs does not support dontneed or drop_caches" &&
20986                 return 0
20987
20988         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20989         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20990                 error_not_in_vm "Speedup with willread is less than " \
20991                         "$lowest_speedup%, got $average_ladvise%"
20992 }
20993
20994 test_255a() {
20995         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20996                 skip "lustre < 2.8.54 does not support ladvise "
20997         remote_ost_nodsh && skip "remote OST with nodsh"
20998
20999         stack_trap "rm -f $DIR/$tfile"
21000         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21001
21002         ladvise_no_type willread $DIR/$tfile &&
21003                 skip "willread ladvise is not supported"
21004
21005         ladvise_no_ioctl $DIR/$tfile &&
21006                 skip "ladvise ioctl is not supported"
21007
21008         local size_mb=100
21009         local size=$((size_mb * 1048576))
21010         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21011                 error "dd to $DIR/$tfile failed"
21012
21013         lfs ladvise -a willread $DIR/$tfile ||
21014                 error "Ladvise failed with no range argument"
21015
21016         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21017                 error "Ladvise failed with no -l or -e argument"
21018
21019         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21020                 error "Ladvise failed with only -e argument"
21021
21022         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21023                 error "Ladvise failed with only -l argument"
21024
21025         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21026                 error "End offset should not be smaller than start offset"
21027
21028         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21029                 error "End offset should not be equal to start offset"
21030
21031         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21032                 error "Ladvise failed with overflowing -s argument"
21033
21034         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21035                 error "Ladvise failed with overflowing -e argument"
21036
21037         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21038                 error "Ladvise failed with overflowing -l argument"
21039
21040         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21041                 error "Ladvise succeeded with conflicting -l and -e arguments"
21042
21043         echo "Synchronous ladvise should wait"
21044         local delay=4
21045 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21046         do_nodes $(comma_list $(osts_nodes)) \
21047                 $LCTL set_param fail_val=$delay fail_loc=0x237
21048
21049         local start_ts=$SECONDS
21050         lfs ladvise -a willread $DIR/$tfile ||
21051                 error "Ladvise failed with no range argument"
21052         local end_ts=$SECONDS
21053         local inteval_ts=$((end_ts - start_ts))
21054
21055         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21056                 error "Synchronous advice didn't wait reply"
21057         fi
21058
21059         echo "Asynchronous ladvise shouldn't wait"
21060         local start_ts=$SECONDS
21061         lfs ladvise -a willread -b $DIR/$tfile ||
21062                 error "Ladvise failed with no range argument"
21063         local end_ts=$SECONDS
21064         local inteval_ts=$((end_ts - start_ts))
21065
21066         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21067                 error "Asynchronous advice blocked"
21068         fi
21069
21070         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21071         ladvise_willread_performance
21072 }
21073 run_test 255a "check 'lfs ladvise -a willread'"
21074
21075 facet_meminfo() {
21076         local facet=$1
21077         local info=$2
21078
21079         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21080 }
21081
21082 test_255b() {
21083         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21084                 skip "lustre < 2.8.54 does not support ladvise "
21085         remote_ost_nodsh && skip "remote OST with nodsh"
21086
21087         stack_trap "rm -f $DIR/$tfile"
21088         lfs setstripe -c 1 -i 0 $DIR/$tfile
21089
21090         ladvise_no_type dontneed $DIR/$tfile &&
21091                 skip "dontneed ladvise is not supported"
21092
21093         ladvise_no_ioctl $DIR/$tfile &&
21094                 skip "ladvise ioctl is not supported"
21095
21096         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21097                 [ "$ost1_FSTYPE" = "zfs" ] &&
21098                 skip "zfs-osd does not support 'ladvise dontneed'"
21099
21100         local size_mb=100
21101         local size=$((size_mb * 1048576))
21102         # In order to prevent disturbance of other processes, only check 3/4
21103         # of the memory usage
21104         local kibibytes=$((size_mb * 1024 * 3 / 4))
21105
21106         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21107                 error "dd to $DIR/$tfile failed"
21108
21109         #force write to complete before dropping OST cache & checking memory
21110         sync
21111
21112         local total=$(facet_meminfo ost1 MemTotal)
21113         echo "Total memory: $total KiB"
21114
21115         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21116         local before_read=$(facet_meminfo ost1 Cached)
21117         echo "Cache used before read: $before_read KiB"
21118
21119         lfs ladvise -a willread $DIR/$tfile ||
21120                 error "Ladvise willread failed"
21121         local after_read=$(facet_meminfo ost1 Cached)
21122         echo "Cache used after read: $after_read KiB"
21123
21124         lfs ladvise -a dontneed $DIR/$tfile ||
21125                 error "Ladvise dontneed again failed"
21126         local no_read=$(facet_meminfo ost1 Cached)
21127         echo "Cache used after dontneed ladvise: $no_read KiB"
21128
21129         if [ $total -lt $((before_read + kibibytes)) ]; then
21130                 echo "Memory is too small, abort checking"
21131                 return 0
21132         fi
21133
21134         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21135                 error "Ladvise willread should use more memory" \
21136                         "than $kibibytes KiB"
21137         fi
21138
21139         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21140                 error "Ladvise dontneed should release more memory" \
21141                         "than $kibibytes KiB"
21142         fi
21143 }
21144 run_test 255b "check 'lfs ladvise -a dontneed'"
21145
21146 test_255c() {
21147         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21148                 skip "lustre < 2.10.50 does not support lockahead"
21149
21150         local ost1_imp=$(get_osc_import_name client ost1)
21151         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21152                          cut -d'.' -f2)
21153         local count
21154         local new_count
21155         local difference
21156         local i
21157         local rc
21158
21159         test_mkdir -p $DIR/$tdir
21160         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21161
21162         #test 10 returns only success/failure
21163         i=10
21164         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21165         rc=$?
21166         if [ $rc -eq 255 ]; then
21167                 error "Ladvise test${i} failed, ${rc}"
21168         fi
21169
21170         #test 11 counts lock enqueue requests, all others count new locks
21171         i=11
21172         count=$(do_facet ost1 \
21173                 $LCTL get_param -n ost.OSS.ost.stats)
21174         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21175
21176         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21177         rc=$?
21178         if [ $rc -eq 255 ]; then
21179                 error "Ladvise test${i} failed, ${rc}"
21180         fi
21181
21182         new_count=$(do_facet ost1 \
21183                 $LCTL get_param -n ost.OSS.ost.stats)
21184         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21185                    awk '{ print $2 }')
21186
21187         difference="$((new_count - count))"
21188         if [ $difference -ne $rc ]; then
21189                 error "Ladvise test${i}, bad enqueue count, returned " \
21190                       "${rc}, actual ${difference}"
21191         fi
21192
21193         for i in $(seq 12 21); do
21194                 # If we do not do this, we run the risk of having too many
21195                 # locks and starting lock cancellation while we are checking
21196                 # lock counts.
21197                 cancel_lru_locks osc
21198
21199                 count=$($LCTL get_param -n \
21200                        ldlm.namespaces.$imp_name.lock_unused_count)
21201
21202                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21203                 rc=$?
21204                 if [ $rc -eq 255 ]; then
21205                         error "Ladvise test ${i} failed, ${rc}"
21206                 fi
21207
21208                 new_count=$($LCTL get_param -n \
21209                        ldlm.namespaces.$imp_name.lock_unused_count)
21210                 difference="$((new_count - count))"
21211
21212                 # Test 15 output is divided by 100 to map down to valid return
21213                 if [ $i -eq 15 ]; then
21214                         rc="$((rc * 100))"
21215                 fi
21216
21217                 if [ $difference -ne $rc ]; then
21218                         error "Ladvise test ${i}, bad lock count, returned " \
21219                               "${rc}, actual ${difference}"
21220                 fi
21221         done
21222
21223         #test 22 returns only success/failure
21224         i=22
21225         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21226         rc=$?
21227         if [ $rc -eq 255 ]; then
21228                 error "Ladvise test${i} failed, ${rc}"
21229         fi
21230 }
21231 run_test 255c "suite of ladvise lockahead tests"
21232
21233 test_256() {
21234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21235         remote_mds_nodsh && skip "remote MDS with nodsh"
21236         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21237         changelog_users $SINGLEMDS | grep "^cl" &&
21238                 skip "active changelog user"
21239
21240         local cl_user
21241         local cat_sl
21242         local mdt_dev
21243
21244         mdt_dev=$(mdsdevname 1)
21245         echo $mdt_dev
21246
21247         changelog_register || error "changelog_register failed"
21248
21249         rm -rf $DIR/$tdir
21250         mkdir_on_mdt0 $DIR/$tdir
21251
21252         changelog_clear 0 || error "changelog_clear failed"
21253
21254         # change something
21255         touch $DIR/$tdir/{1..10}
21256
21257         # stop the MDT
21258         stop $SINGLEMDS || error "Fail to stop MDT"
21259
21260         # remount the MDT
21261
21262         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21263
21264         #after mount new plainllog is used
21265         touch $DIR/$tdir/{11..19}
21266         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21267         stack_trap "rm -f $tmpfile"
21268         cat_sl=$(do_facet $SINGLEMDS "sync; \
21269                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21270                  llog_reader $tmpfile | grep -c type=1064553b")
21271         do_facet $SINGLEMDS llog_reader $tmpfile
21272
21273         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21274
21275         changelog_clear 0 || error "changelog_clear failed"
21276
21277         cat_sl=$(do_facet $SINGLEMDS "sync; \
21278                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21279                  llog_reader $tmpfile | grep -c type=1064553b")
21280
21281         if (( cat_sl == 2 )); then
21282                 error "Empty plain llog was not deleted from changelog catalog"
21283         elif (( cat_sl != 1 )); then
21284                 error "Active plain llog shouldn't be deleted from catalog"
21285         fi
21286 }
21287 run_test 256 "Check llog delete for empty and not full state"
21288
21289 test_257() {
21290         remote_mds_nodsh && skip "remote MDS with nodsh"
21291         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21292                 skip "Need MDS version at least 2.8.55"
21293
21294         test_mkdir $DIR/$tdir
21295
21296         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21297                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21298         stat $DIR/$tdir
21299
21300 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21301         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21302         local facet=mds$((mdtidx + 1))
21303         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21304         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21305
21306         stop $facet || error "stop MDS failed"
21307         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21308                 error "start MDS fail"
21309         wait_recovery_complete $facet
21310 }
21311 run_test 257 "xattr locks are not lost"
21312
21313 # Verify we take the i_mutex when security requires it
21314 test_258a() {
21315 #define OBD_FAIL_IMUTEX_SEC 0x141c
21316         $LCTL set_param fail_loc=0x141c
21317         touch $DIR/$tfile
21318         chmod u+s $DIR/$tfile
21319         chmod a+rwx $DIR/$tfile
21320         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21321         RC=$?
21322         if [ $RC -ne 0 ]; then
21323                 error "error, failed to take i_mutex, rc=$?"
21324         fi
21325         rm -f $DIR/$tfile
21326 }
21327 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21328
21329 # Verify we do NOT take the i_mutex in the normal case
21330 test_258b() {
21331 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21332         $LCTL set_param fail_loc=0x141d
21333         touch $DIR/$tfile
21334         chmod a+rwx $DIR
21335         chmod a+rw $DIR/$tfile
21336         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21337         RC=$?
21338         if [ $RC -ne 0 ]; then
21339                 error "error, took i_mutex unnecessarily, rc=$?"
21340         fi
21341         rm -f $DIR/$tfile
21342
21343 }
21344 run_test 258b "verify i_mutex security behavior"
21345
21346 test_259() {
21347         local file=$DIR/$tfile
21348         local before
21349         local after
21350
21351         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21352
21353         stack_trap "rm -f $file" EXIT
21354
21355         wait_delete_completed
21356         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21357         echo "before: $before"
21358
21359         $LFS setstripe -i 0 -c 1 $file
21360         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21361         sync_all_data
21362         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21363         echo "after write: $after"
21364
21365 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21366         do_facet ost1 $LCTL set_param fail_loc=0x2301
21367         $TRUNCATE $file 0
21368         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21369         echo "after truncate: $after"
21370
21371         stop ost1
21372         do_facet ost1 $LCTL set_param fail_loc=0
21373         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21374         sleep 2
21375         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21376         echo "after restart: $after"
21377         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21378                 error "missing truncate?"
21379
21380         return 0
21381 }
21382 run_test 259 "crash at delayed truncate"
21383
21384 test_260() {
21385 #define OBD_FAIL_MDC_CLOSE               0x806
21386         $LCTL set_param fail_loc=0x80000806
21387         touch $DIR/$tfile
21388
21389 }
21390 run_test 260 "Check mdc_close fail"
21391
21392 ### Data-on-MDT sanity tests ###
21393 test_270a() {
21394         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21395                 skip "Need MDS version at least 2.10.55 for DoM"
21396
21397         # create DoM file
21398         local dom=$DIR/$tdir/dom_file
21399         local tmp=$DIR/$tdir/tmp_file
21400
21401         mkdir_on_mdt0 $DIR/$tdir
21402
21403         # basic checks for DoM component creation
21404         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21405                 error "Can set MDT layout to non-first entry"
21406
21407         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21408                 error "Can define multiple entries as MDT layout"
21409
21410         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21411
21412         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21413         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21414         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21415
21416         local mdtidx=$($LFS getstripe -m $dom)
21417         local mdtname=MDT$(printf %04x $mdtidx)
21418         local facet=mds$((mdtidx + 1))
21419         local space_check=1
21420
21421         # Skip free space checks with ZFS
21422         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21423
21424         # write
21425         sync
21426         local size_tmp=$((65536 * 3))
21427         local mdtfree1=$(do_facet $facet \
21428                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21429
21430         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21431         # check also direct IO along write
21432         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21433         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21434         sync
21435         cmp $tmp $dom || error "file data is different"
21436         [ $(stat -c%s $dom) == $size_tmp ] ||
21437                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21438         if [ $space_check == 1 ]; then
21439                 local mdtfree2=$(do_facet $facet \
21440                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21441
21442                 # increase in usage from by $size_tmp
21443                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21444                         error "MDT free space wrong after write: " \
21445                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21446         fi
21447
21448         # truncate
21449         local size_dom=10000
21450
21451         $TRUNCATE $dom $size_dom
21452         [ $(stat -c%s $dom) == $size_dom ] ||
21453                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21454         if [ $space_check == 1 ]; then
21455                 mdtfree1=$(do_facet $facet \
21456                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21457                 # decrease in usage from $size_tmp to new $size_dom
21458                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21459                   $(((size_tmp - size_dom) / 1024)) ] ||
21460                         error "MDT free space is wrong after truncate: " \
21461                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21462         fi
21463
21464         # append
21465         cat $tmp >> $dom
21466         sync
21467         size_dom=$((size_dom + size_tmp))
21468         [ $(stat -c%s $dom) == $size_dom ] ||
21469                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21470         if [ $space_check == 1 ]; then
21471                 mdtfree2=$(do_facet $facet \
21472                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21473                 # increase in usage by $size_tmp from previous
21474                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21475                         error "MDT free space is wrong after append: " \
21476                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21477         fi
21478
21479         # delete
21480         rm $dom
21481         if [ $space_check == 1 ]; then
21482                 mdtfree1=$(do_facet $facet \
21483                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21484                 # decrease in usage by $size_dom from previous
21485                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21486                         error "MDT free space is wrong after removal: " \
21487                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21488         fi
21489
21490         # combined striping
21491         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21492                 error "Can't create DoM + OST striping"
21493
21494         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21495         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21496         # check also direct IO along write
21497         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21498         sync
21499         cmp $tmp $dom || error "file data is different"
21500         [ $(stat -c%s $dom) == $size_tmp ] ||
21501                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21502         rm $dom $tmp
21503
21504         return 0
21505 }
21506 run_test 270a "DoM: basic functionality tests"
21507
21508 test_270b() {
21509         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21510                 skip "Need MDS version at least 2.10.55"
21511
21512         local dom=$DIR/$tdir/dom_file
21513         local max_size=1048576
21514
21515         mkdir -p $DIR/$tdir
21516         $LFS setstripe -E $max_size -L mdt $dom
21517
21518         # truncate over the limit
21519         $TRUNCATE $dom $(($max_size + 1)) &&
21520                 error "successful truncate over the maximum size"
21521         # write over the limit
21522         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21523                 error "successful write over the maximum size"
21524         # append over the limit
21525         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21526         echo "12345" >> $dom && error "successful append over the maximum size"
21527         rm $dom
21528
21529         return 0
21530 }
21531 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21532
21533 test_270c() {
21534         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21535                 skip "Need MDS version at least 2.10.55"
21536
21537         mkdir -p $DIR/$tdir
21538         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21539
21540         # check files inherit DoM EA
21541         touch $DIR/$tdir/first
21542         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21543                 error "bad pattern"
21544         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21545                 error "bad stripe count"
21546         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21547                 error "bad stripe size"
21548
21549         # check directory inherits DoM EA and uses it as default
21550         mkdir $DIR/$tdir/subdir
21551         touch $DIR/$tdir/subdir/second
21552         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21553                 error "bad pattern in sub-directory"
21554         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21555                 error "bad stripe count in sub-directory"
21556         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21557                 error "bad stripe size in sub-directory"
21558         return 0
21559 }
21560 run_test 270c "DoM: DoM EA inheritance tests"
21561
21562 test_270d() {
21563         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21564                 skip "Need MDS version at least 2.10.55"
21565
21566         mkdir -p $DIR/$tdir
21567         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21568
21569         # inherit default DoM striping
21570         mkdir $DIR/$tdir/subdir
21571         touch $DIR/$tdir/subdir/f1
21572
21573         # change default directory striping
21574         $LFS setstripe -c 1 $DIR/$tdir/subdir
21575         touch $DIR/$tdir/subdir/f2
21576         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21577                 error "wrong default striping in file 2"
21578         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21579                 error "bad pattern in file 2"
21580         return 0
21581 }
21582 run_test 270d "DoM: change striping from DoM to RAID0"
21583
21584 test_270e() {
21585         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21586                 skip "Need MDS version at least 2.10.55"
21587
21588         mkdir -p $DIR/$tdir/dom
21589         mkdir -p $DIR/$tdir/norm
21590         DOMFILES=20
21591         NORMFILES=10
21592         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21593         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21594
21595         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21596         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21597
21598         # find DoM files by layout
21599         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21600         [ $NUM -eq  $DOMFILES ] ||
21601                 error "lfs find -L: found $NUM, expected $DOMFILES"
21602         echo "Test 1: lfs find 20 DOM files by layout: OK"
21603
21604         # there should be 1 dir with default DOM striping
21605         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21606         [ $NUM -eq  1 ] ||
21607                 error "lfs find -L: found $NUM, expected 1 dir"
21608         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21609
21610         # find DoM files by stripe size
21611         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21612         [ $NUM -eq  $DOMFILES ] ||
21613                 error "lfs find -S: found $NUM, expected $DOMFILES"
21614         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21615
21616         # find files by stripe offset except DoM files
21617         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21618         [ $NUM -eq  $NORMFILES ] ||
21619                 error "lfs find -i: found $NUM, expected $NORMFILES"
21620         echo "Test 5: lfs find no DOM files by stripe index: OK"
21621         return 0
21622 }
21623 run_test 270e "DoM: lfs find with DoM files test"
21624
21625 test_270f() {
21626         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21627                 skip "Need MDS version at least 2.10.55"
21628
21629         local mdtname=${FSNAME}-MDT0000-mdtlov
21630         local dom=$DIR/$tdir/dom_file
21631         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21632                                                 lod.$mdtname.dom_stripesize)
21633         local dom_limit=131072
21634
21635         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21636         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21637                                                 lod.$mdtname.dom_stripesize)
21638         [ ${dom_limit} -eq ${dom_current} ] ||
21639                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21640
21641         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21642         $LFS setstripe -d $DIR/$tdir
21643         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21644                 error "Can't set directory default striping"
21645
21646         # exceed maximum stripe size
21647         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21648                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21649         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21650                 error "Able to create DoM component size more than LOD limit"
21651
21652         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21653         dom_current=$(do_facet mds1 $LCTL get_param -n \
21654                                                 lod.$mdtname.dom_stripesize)
21655         [ 0 -eq ${dom_current} ] ||
21656                 error "Can't set zero DoM stripe limit"
21657         rm $dom
21658
21659         # attempt to create DoM file on server with disabled DoM should
21660         # remove DoM entry from layout and be succeed
21661         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21662                 error "Can't create DoM file (DoM is disabled)"
21663         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21664                 error "File has DoM component while DoM is disabled"
21665         rm $dom
21666
21667         # attempt to create DoM file with only DoM stripe should return error
21668         $LFS setstripe -E $dom_limit -L mdt $dom &&
21669                 error "Able to create DoM-only file while DoM is disabled"
21670
21671         # too low values to be aligned with smallest stripe size 64K
21672         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21673         dom_current=$(do_facet mds1 $LCTL get_param -n \
21674                                                 lod.$mdtname.dom_stripesize)
21675         [ 30000 -eq ${dom_current} ] &&
21676                 error "Can set too small DoM stripe limit"
21677
21678         # 64K is a minimal stripe size in Lustre, expect limit of that size
21679         [ 65536 -eq ${dom_current} ] ||
21680                 error "Limit is not set to 64K but ${dom_current}"
21681
21682         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21683         dom_current=$(do_facet mds1 $LCTL get_param -n \
21684                                                 lod.$mdtname.dom_stripesize)
21685         echo $dom_current
21686         [ 2147483648 -eq ${dom_current} ] &&
21687                 error "Can set too large DoM stripe limit"
21688
21689         do_facet mds1 $LCTL set_param -n \
21690                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21691         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21692                 error "Can't create DoM component size after limit change"
21693         do_facet mds1 $LCTL set_param -n \
21694                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21695         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21696                 error "Can't create DoM file after limit decrease"
21697         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21698                 error "Can create big DoM component after limit decrease"
21699         touch ${dom}_def ||
21700                 error "Can't create file with old default layout"
21701
21702         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21703         return 0
21704 }
21705 run_test 270f "DoM: maximum DoM stripe size checks"
21706
21707 test_270g() {
21708         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21709                 skip "Need MDS version at least 2.13.52"
21710         local dom=$DIR/$tdir/$tfile
21711
21712         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21713         local lodname=${FSNAME}-MDT0000-mdtlov
21714
21715         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21716         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21717         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21718         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21719
21720         local dom_limit=1024
21721         local dom_threshold="50%"
21722
21723         $LFS setstripe -d $DIR/$tdir
21724         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21725                 error "Can't set directory default striping"
21726
21727         do_facet mds1 $LCTL set_param -n \
21728                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21729         # set 0 threshold and create DOM file to change tunable stripesize
21730         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21731         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21732                 error "Failed to create $dom file"
21733         # now tunable dom_cur_stripesize should reach maximum
21734         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21735                                         lod.${lodname}.dom_stripesize_cur_kb)
21736         [[ $dom_current == $dom_limit ]] ||
21737                 error "Current DOM stripesize is not maximum"
21738         rm $dom
21739
21740         # set threshold for further tests
21741         do_facet mds1 $LCTL set_param -n \
21742                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21743         echo "DOM threshold is $dom_threshold free space"
21744         local dom_def
21745         local dom_set
21746         # Spoof bfree to exceed threshold
21747         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21748         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21749         for spfree in 40 20 0 15 30 55; do
21750                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21751                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21752                         error "Failed to create $dom file"
21753                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21754                                         lod.${lodname}.dom_stripesize_cur_kb)
21755                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21756                 [[ $dom_def != $dom_current ]] ||
21757                         error "Default stripe size was not changed"
21758                 if [[ $spfree > 0 ]] ; then
21759                         dom_set=$($LFS getstripe -S $dom)
21760                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21761                                 error "DOM component size is still old"
21762                 else
21763                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21764                                 error "DoM component is set with no free space"
21765                 fi
21766                 rm $dom
21767                 dom_current=$dom_def
21768         done
21769 }
21770 run_test 270g "DoM: default DoM stripe size depends on free space"
21771
21772 test_270h() {
21773         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21774                 skip "Need MDS version at least 2.13.53"
21775
21776         local mdtname=${FSNAME}-MDT0000-mdtlov
21777         local dom=$DIR/$tdir/$tfile
21778         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21779
21780         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21781         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21782
21783         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21784         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21785                 error "can't create OST file"
21786         # mirrored file with DOM entry in the second mirror
21787         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21788                 error "can't create mirror with DoM component"
21789
21790         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21791
21792         # DOM component in the middle and has other enries in the same mirror,
21793         # should succeed but lost DoM component
21794         $LFS setstripe --copy=${dom}_1 $dom ||
21795                 error "Can't create file from OST|DOM mirror layout"
21796         # check new file has no DoM layout after all
21797         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21798                 error "File has DoM component while DoM is disabled"
21799 }
21800 run_test 270h "DoM: DoM stripe removal when disabled on server"
21801
21802 test_271a() {
21803         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21804                 skip "Need MDS version at least 2.10.55"
21805
21806         local dom=$DIR/$tdir/dom
21807
21808         mkdir -p $DIR/$tdir
21809
21810         $LFS setstripe -E 1024K -L mdt $dom
21811
21812         lctl set_param -n mdc.*.stats=clear
21813         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21814         cat $dom > /dev/null
21815         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21816         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21817         ls $dom
21818         rm -f $dom
21819 }
21820 run_test 271a "DoM: data is cached for read after write"
21821
21822 test_271b() {
21823         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21824                 skip "Need MDS version at least 2.10.55"
21825
21826         local dom=$DIR/$tdir/dom
21827
21828         mkdir -p $DIR/$tdir
21829
21830         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21831
21832         lctl set_param -n mdc.*.stats=clear
21833         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21834         cancel_lru_locks mdc
21835         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21836         # second stat to check size is cached on client
21837         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21838         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21839         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21840         rm -f $dom
21841 }
21842 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21843
21844 test_271ba() {
21845         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21846                 skip "Need MDS version at least 2.10.55"
21847
21848         local dom=$DIR/$tdir/dom
21849
21850         mkdir -p $DIR/$tdir
21851
21852         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21853
21854         lctl set_param -n mdc.*.stats=clear
21855         lctl set_param -n osc.*.stats=clear
21856         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21857         cancel_lru_locks mdc
21858         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21859         # second stat to check size is cached on client
21860         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21861         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21862         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21863         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21864         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21865         rm -f $dom
21866 }
21867 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21868
21869
21870 get_mdc_stats() {
21871         local mdtidx=$1
21872         local param=$2
21873         local mdt=MDT$(printf %04x $mdtidx)
21874
21875         if [ -z $param ]; then
21876                 lctl get_param -n mdc.*$mdt*.stats
21877         else
21878                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21879         fi
21880 }
21881
21882 test_271c() {
21883         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21884                 skip "Need MDS version at least 2.10.55"
21885
21886         local dom=$DIR/$tdir/dom
21887
21888         mkdir -p $DIR/$tdir
21889
21890         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21891
21892         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21893         local facet=mds$((mdtidx + 1))
21894
21895         cancel_lru_locks mdc
21896         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21897         createmany -o $dom 1000
21898         lctl set_param -n mdc.*.stats=clear
21899         smalliomany -w $dom 1000 200
21900         get_mdc_stats $mdtidx
21901         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21902         # Each file has 1 open, 1 IO enqueues, total 2000
21903         # but now we have also +1 getxattr for security.capability, total 3000
21904         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21905         unlinkmany $dom 1000
21906
21907         cancel_lru_locks mdc
21908         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21909         createmany -o $dom 1000
21910         lctl set_param -n mdc.*.stats=clear
21911         smalliomany -w $dom 1000 200
21912         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21913         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21914         # for OPEN and IO lock.
21915         [ $((enq - enq_2)) -ge 1000 ] ||
21916                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21917         unlinkmany $dom 1000
21918         return 0
21919 }
21920 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21921
21922 cleanup_271def_tests() {
21923         trap 0
21924         rm -f $1
21925 }
21926
21927 test_271d() {
21928         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21929                 skip "Need MDS version at least 2.10.57"
21930
21931         local dom=$DIR/$tdir/dom
21932         local tmp=$TMP/$tfile
21933         trap "cleanup_271def_tests $tmp" EXIT
21934
21935         mkdir -p $DIR/$tdir
21936
21937         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21938
21939         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21940
21941         cancel_lru_locks mdc
21942         dd if=/dev/urandom of=$tmp bs=1000 count=1
21943         dd if=$tmp of=$dom bs=1000 count=1
21944         cancel_lru_locks mdc
21945
21946         cat /etc/hosts >> $tmp
21947         lctl set_param -n mdc.*.stats=clear
21948
21949         # append data to the same file it should update local page
21950         echo "Append to the same page"
21951         cat /etc/hosts >> $dom
21952         local num=$(get_mdc_stats $mdtidx ost_read)
21953         local ra=$(get_mdc_stats $mdtidx req_active)
21954         local rw=$(get_mdc_stats $mdtidx req_waittime)
21955
21956         [ -z $num ] || error "$num READ RPC occured"
21957         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21958         echo "... DONE"
21959
21960         # compare content
21961         cmp $tmp $dom || error "file miscompare"
21962
21963         cancel_lru_locks mdc
21964         lctl set_param -n mdc.*.stats=clear
21965
21966         echo "Open and read file"
21967         cat $dom > /dev/null
21968         local num=$(get_mdc_stats $mdtidx ost_read)
21969         local ra=$(get_mdc_stats $mdtidx req_active)
21970         local rw=$(get_mdc_stats $mdtidx req_waittime)
21971
21972         [ -z $num ] || error "$num READ RPC occured"
21973         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21974         echo "... DONE"
21975
21976         # compare content
21977         cmp $tmp $dom || error "file miscompare"
21978
21979         return 0
21980 }
21981 run_test 271d "DoM: read on open (1K file in reply buffer)"
21982
21983 test_271f() {
21984         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21985                 skip "Need MDS version at least 2.10.57"
21986
21987         local dom=$DIR/$tdir/dom
21988         local tmp=$TMP/$tfile
21989         trap "cleanup_271def_tests $tmp" EXIT
21990
21991         mkdir -p $DIR/$tdir
21992
21993         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21994
21995         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21996
21997         cancel_lru_locks mdc
21998         dd if=/dev/urandom of=$tmp bs=265000 count=1
21999         dd if=$tmp of=$dom bs=265000 count=1
22000         cancel_lru_locks mdc
22001         cat /etc/hosts >> $tmp
22002         lctl set_param -n mdc.*.stats=clear
22003
22004         echo "Append to the same page"
22005         cat /etc/hosts >> $dom
22006         local num=$(get_mdc_stats $mdtidx ost_read)
22007         local ra=$(get_mdc_stats $mdtidx req_active)
22008         local rw=$(get_mdc_stats $mdtidx req_waittime)
22009
22010         [ -z $num ] || error "$num READ RPC occured"
22011         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22012         echo "... DONE"
22013
22014         # compare content
22015         cmp $tmp $dom || error "file miscompare"
22016
22017         cancel_lru_locks mdc
22018         lctl set_param -n mdc.*.stats=clear
22019
22020         echo "Open and read file"
22021         cat $dom > /dev/null
22022         local num=$(get_mdc_stats $mdtidx ost_read)
22023         local ra=$(get_mdc_stats $mdtidx req_active)
22024         local rw=$(get_mdc_stats $mdtidx req_waittime)
22025
22026         [ -z $num ] && num=0
22027         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22028         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22029         echo "... DONE"
22030
22031         # compare content
22032         cmp $tmp $dom || error "file miscompare"
22033
22034         return 0
22035 }
22036 run_test 271f "DoM: read on open (200K file and read tail)"
22037
22038 test_271g() {
22039         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22040                 skip "Skipping due to old client or server version"
22041
22042         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22043         # to get layout
22044         $CHECKSTAT -t file $DIR1/$tfile
22045
22046         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22047         MULTIOP_PID=$!
22048         sleep 1
22049         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22050         $LCTL set_param fail_loc=0x80000314
22051         rm $DIR1/$tfile || error "Unlink fails"
22052         RC=$?
22053         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22054         [ $RC -eq 0 ] || error "Failed write to stale object"
22055 }
22056 run_test 271g "Discard DoM data vs client flush race"
22057
22058 test_272a() {
22059         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22060                 skip "Need MDS version at least 2.11.50"
22061
22062         local dom=$DIR/$tdir/dom
22063         mkdir -p $DIR/$tdir
22064
22065         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22066         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22067                 error "failed to write data into $dom"
22068         local old_md5=$(md5sum $dom)
22069
22070         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22071                 error "failed to migrate to the same DoM component"
22072
22073         local new_md5=$(md5sum $dom)
22074
22075         [ "$old_md5" == "$new_md5" ] ||
22076                 error "md5sum differ: $old_md5, $new_md5"
22077
22078         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22079                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22080 }
22081 run_test 272a "DoM migration: new layout with the same DOM component"
22082
22083 test_272b() {
22084         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22085                 skip "Need MDS version at least 2.11.50"
22086
22087         local dom=$DIR/$tdir/dom
22088         mkdir -p $DIR/$tdir
22089         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22090
22091         local mdtidx=$($LFS getstripe -m $dom)
22092         local mdtname=MDT$(printf %04x $mdtidx)
22093         local facet=mds$((mdtidx + 1))
22094
22095         local mdtfree1=$(do_facet $facet \
22096                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22097         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22098                 error "failed to write data into $dom"
22099         local old_md5=$(md5sum $dom)
22100         cancel_lru_locks mdc
22101         local mdtfree1=$(do_facet $facet \
22102                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22103
22104         $LFS migrate -c2 $dom ||
22105                 error "failed to migrate to the new composite layout"
22106         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22107                 error "MDT stripe was not removed"
22108
22109         cancel_lru_locks mdc
22110         local new_md5=$(md5sum $dom)
22111         [ "$old_md5" == "$new_md5" ] ||
22112                 error "$old_md5 != $new_md5"
22113
22114         # Skip free space checks with ZFS
22115         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22116                 local mdtfree2=$(do_facet $facet \
22117                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22118                 [ $mdtfree2 -gt $mdtfree1 ] ||
22119                         error "MDT space is not freed after migration"
22120         fi
22121         return 0
22122 }
22123 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22124
22125 test_272c() {
22126         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22127                 skip "Need MDS version at least 2.11.50"
22128
22129         local dom=$DIR/$tdir/$tfile
22130         mkdir -p $DIR/$tdir
22131         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22132
22133         local mdtidx=$($LFS getstripe -m $dom)
22134         local mdtname=MDT$(printf %04x $mdtidx)
22135         local facet=mds$((mdtidx + 1))
22136
22137         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22138                 error "failed to write data into $dom"
22139         local old_md5=$(md5sum $dom)
22140         cancel_lru_locks mdc
22141         local mdtfree1=$(do_facet $facet \
22142                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22143
22144         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22145                 error "failed to migrate to the new composite layout"
22146         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22147                 error "MDT stripe was not removed"
22148
22149         cancel_lru_locks mdc
22150         local new_md5=$(md5sum $dom)
22151         [ "$old_md5" == "$new_md5" ] ||
22152                 error "$old_md5 != $new_md5"
22153
22154         # Skip free space checks with ZFS
22155         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22156                 local mdtfree2=$(do_facet $facet \
22157                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22158                 [ $mdtfree2 -gt $mdtfree1 ] ||
22159                         error "MDS space is not freed after migration"
22160         fi
22161         return 0
22162 }
22163 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22164
22165 test_272d() {
22166         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22167                 skip "Need MDS version at least 2.12.55"
22168
22169         local dom=$DIR/$tdir/$tfile
22170         mkdir -p $DIR/$tdir
22171         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22172
22173         local mdtidx=$($LFS getstripe -m $dom)
22174         local mdtname=MDT$(printf %04x $mdtidx)
22175         local facet=mds$((mdtidx + 1))
22176
22177         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22178                 error "failed to write data into $dom"
22179         local old_md5=$(md5sum $dom)
22180         cancel_lru_locks mdc
22181         local mdtfree1=$(do_facet $facet \
22182                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22183
22184         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22185                 error "failed mirroring to the new composite layout"
22186         $LFS mirror resync $dom ||
22187                 error "failed mirror resync"
22188         $LFS mirror split --mirror-id 1 -d $dom ||
22189                 error "failed mirror split"
22190
22191         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22192                 error "MDT stripe was not removed"
22193
22194         cancel_lru_locks mdc
22195         local new_md5=$(md5sum $dom)
22196         [ "$old_md5" == "$new_md5" ] ||
22197                 error "$old_md5 != $new_md5"
22198
22199         # Skip free space checks with ZFS
22200         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22201                 local mdtfree2=$(do_facet $facet \
22202                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22203                 [ $mdtfree2 -gt $mdtfree1 ] ||
22204                         error "MDS space is not freed after DOM mirror deletion"
22205         fi
22206         return 0
22207 }
22208 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22209
22210 test_272e() {
22211         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22212                 skip "Need MDS version at least 2.12.55"
22213
22214         local dom=$DIR/$tdir/$tfile
22215         mkdir -p $DIR/$tdir
22216         $LFS setstripe -c 2 $dom
22217
22218         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22219                 error "failed to write data into $dom"
22220         local old_md5=$(md5sum $dom)
22221         cancel_lru_locks mdc
22222
22223         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22224                 error "failed mirroring to the DOM layout"
22225         $LFS mirror resync $dom ||
22226                 error "failed mirror resync"
22227         $LFS mirror split --mirror-id 1 -d $dom ||
22228                 error "failed mirror split"
22229
22230         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22231                 error "MDT stripe was not removed"
22232
22233         cancel_lru_locks mdc
22234         local new_md5=$(md5sum $dom)
22235         [ "$old_md5" == "$new_md5" ] ||
22236                 error "$old_md5 != $new_md5"
22237
22238         return 0
22239 }
22240 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22241
22242 test_272f() {
22243         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22244                 skip "Need MDS version at least 2.12.55"
22245
22246         local dom=$DIR/$tdir/$tfile
22247         mkdir -p $DIR/$tdir
22248         $LFS setstripe -c 2 $dom
22249
22250         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22251                 error "failed to write data into $dom"
22252         local old_md5=$(md5sum $dom)
22253         cancel_lru_locks mdc
22254
22255         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22256                 error "failed migrating to the DOM file"
22257
22258         cancel_lru_locks mdc
22259         local new_md5=$(md5sum $dom)
22260         [ "$old_md5" != "$new_md5" ] &&
22261                 error "$old_md5 != $new_md5"
22262
22263         return 0
22264 }
22265 run_test 272f "DoM migration: OST-striped file to DOM file"
22266
22267 test_273a() {
22268         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22269                 skip "Need MDS version at least 2.11.50"
22270
22271         # Layout swap cannot be done if either file has DOM component,
22272         # this will never be supported, migration should be used instead
22273
22274         local dom=$DIR/$tdir/$tfile
22275         mkdir -p $DIR/$tdir
22276
22277         $LFS setstripe -c2 ${dom}_plain
22278         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22279         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22280                 error "can swap layout with DoM component"
22281         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22282                 error "can swap layout with DoM component"
22283
22284         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22285         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22286                 error "can swap layout with DoM component"
22287         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22288                 error "can swap layout with DoM component"
22289         return 0
22290 }
22291 run_test 273a "DoM: layout swapping should fail with DOM"
22292
22293 test_273b() {
22294         mkdir -p $DIR/$tdir
22295         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22296
22297 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22298         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22299
22300         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22301 }
22302 run_test 273b "DoM: race writeback and object destroy"
22303
22304 test_275() {
22305         remote_ost_nodsh && skip "remote OST with nodsh"
22306         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22307                 skip "Need OST version >= 2.10.57"
22308
22309         local file=$DIR/$tfile
22310         local oss
22311
22312         oss=$(comma_list $(osts_nodes))
22313
22314         dd if=/dev/urandom of=$file bs=1M count=2 ||
22315                 error "failed to create a file"
22316         cancel_lru_locks osc
22317
22318         #lock 1
22319         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22320                 error "failed to read a file"
22321
22322 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22323         $LCTL set_param fail_loc=0x8000031f
22324
22325         cancel_lru_locks osc &
22326         sleep 1
22327
22328 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22329         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22330         #IO takes another lock, but matches the PENDING one
22331         #and places it to the IO RPC
22332         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22333                 error "failed to read a file with PENDING lock"
22334 }
22335 run_test 275 "Read on a canceled duplicate lock"
22336
22337 test_276() {
22338         remote_ost_nodsh && skip "remote OST with nodsh"
22339         local pid
22340
22341         do_facet ost1 "(while true; do \
22342                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22343                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22344         pid=$!
22345
22346         for LOOP in $(seq 20); do
22347                 stop ost1
22348                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22349         done
22350         kill -9 $pid
22351         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22352                 rm $TMP/sanity_276_pid"
22353 }
22354 run_test 276 "Race between mount and obd_statfs"
22355
22356 test_277() {
22357         $LCTL set_param ldlm.namespaces.*.lru_size=0
22358         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22359         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22360                         grep ^used_mb | awk '{print $2}')
22361         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22362         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22363                 oflag=direct conv=notrunc
22364         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22365                         grep ^used_mb | awk '{print $2}')
22366         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22367 }
22368 run_test 277 "Direct IO shall drop page cache"
22369
22370 test_278() {
22371         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22372         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22373         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22374                 skip "needs the same host for mdt1 mdt2" && return
22375
22376         local pid1
22377         local pid2
22378
22379 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22380         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22381         stop mds2 &
22382         pid2=$!
22383
22384         stop mds1
22385
22386         echo "Starting MDTs"
22387         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22388         wait $pid2
22389 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22390 #will return NULL
22391         do_facet mds2 $LCTL set_param fail_loc=0
22392
22393         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22394         wait_recovery_complete mds2
22395 }
22396 run_test 278 "Race starting MDS between MDTs stop/start"
22397
22398 test_280() {
22399         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22400                 skip "Need MGS version at least 2.13.52"
22401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22402         combined_mgs_mds || skip "needs combined MGS/MDT"
22403
22404         umount_client $MOUNT
22405 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22406         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22407
22408         mount_client $MOUNT &
22409         sleep 1
22410         stop mgs || error "stop mgs failed"
22411         #for a race mgs would crash
22412         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22413         # make sure we unmount client before remounting
22414         wait
22415         umount_client $MOUNT
22416         mount_client $MOUNT || error "mount client failed"
22417 }
22418 run_test 280 "Race between MGS umount and client llog processing"
22419
22420 cleanup_test_300() {
22421         trap 0
22422         umask $SAVE_UMASK
22423 }
22424 test_striped_dir() {
22425         local mdt_index=$1
22426         local stripe_count
22427         local stripe_index
22428
22429         mkdir -p $DIR/$tdir
22430
22431         SAVE_UMASK=$(umask)
22432         trap cleanup_test_300 RETURN EXIT
22433
22434         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22435                                                 $DIR/$tdir/striped_dir ||
22436                 error "set striped dir error"
22437
22438         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22439         [ "$mode" = "755" ] || error "expect 755 got $mode"
22440
22441         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22442                 error "getdirstripe failed"
22443         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22444         if [ "$stripe_count" != "2" ]; then
22445                 error "1:stripe_count is $stripe_count, expect 2"
22446         fi
22447         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22448         if [ "$stripe_count" != "2" ]; then
22449                 error "2:stripe_count is $stripe_count, expect 2"
22450         fi
22451
22452         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22453         if [ "$stripe_index" != "$mdt_index" ]; then
22454                 error "stripe_index is $stripe_index, expect $mdt_index"
22455         fi
22456
22457         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22458                 error "nlink error after create striped dir"
22459
22460         mkdir $DIR/$tdir/striped_dir/a
22461         mkdir $DIR/$tdir/striped_dir/b
22462
22463         stat $DIR/$tdir/striped_dir/a ||
22464                 error "create dir under striped dir failed"
22465         stat $DIR/$tdir/striped_dir/b ||
22466                 error "create dir under striped dir failed"
22467
22468         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22469                 error "nlink error after mkdir"
22470
22471         rmdir $DIR/$tdir/striped_dir/a
22472         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22473                 error "nlink error after rmdir"
22474
22475         rmdir $DIR/$tdir/striped_dir/b
22476         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22477                 error "nlink error after rmdir"
22478
22479         chattr +i $DIR/$tdir/striped_dir
22480         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22481                 error "immutable flags not working under striped dir!"
22482         chattr -i $DIR/$tdir/striped_dir
22483
22484         rmdir $DIR/$tdir/striped_dir ||
22485                 error "rmdir striped dir error"
22486
22487         cleanup_test_300
22488
22489         true
22490 }
22491
22492 test_300a() {
22493         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22494                 skip "skipped for lustre < 2.7.0"
22495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22497
22498         test_striped_dir 0 || error "failed on striped dir on MDT0"
22499         test_striped_dir 1 || error "failed on striped dir on MDT0"
22500 }
22501 run_test 300a "basic striped dir sanity test"
22502
22503 test_300b() {
22504         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22505                 skip "skipped for lustre < 2.7.0"
22506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22508
22509         local i
22510         local mtime1
22511         local mtime2
22512         local mtime3
22513
22514         test_mkdir $DIR/$tdir || error "mkdir fail"
22515         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22516                 error "set striped dir error"
22517         for i in {0..9}; do
22518                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22519                 sleep 1
22520                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22521                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22522                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22523                 sleep 1
22524                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22525                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22526                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22527         done
22528         true
22529 }
22530 run_test 300b "check ctime/mtime for striped dir"
22531
22532 test_300c() {
22533         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22534                 skip "skipped for lustre < 2.7.0"
22535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22536         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22537
22538         local file_count
22539
22540         mkdir_on_mdt0 $DIR/$tdir
22541         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22542                 error "set striped dir error"
22543
22544         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22545                 error "chown striped dir failed"
22546
22547         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22548                 error "create 5k files failed"
22549
22550         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22551
22552         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22553
22554         rm -rf $DIR/$tdir
22555 }
22556 run_test 300c "chown && check ls under striped directory"
22557
22558 test_300d() {
22559         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22560                 skip "skipped for lustre < 2.7.0"
22561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22563
22564         local stripe_count
22565         local file
22566
22567         mkdir -p $DIR/$tdir
22568         $LFS setstripe -c 2 $DIR/$tdir
22569
22570         #local striped directory
22571         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22572                 error "set striped dir error"
22573         #look at the directories for debug purposes
22574         ls -l $DIR/$tdir
22575         $LFS getdirstripe $DIR/$tdir
22576         ls -l $DIR/$tdir/striped_dir
22577         $LFS getdirstripe $DIR/$tdir/striped_dir
22578         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22579                 error "create 10 files failed"
22580
22581         #remote striped directory
22582         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22583                 error "set striped dir error"
22584         #look at the directories for debug purposes
22585         ls -l $DIR/$tdir
22586         $LFS getdirstripe $DIR/$tdir
22587         ls -l $DIR/$tdir/remote_striped_dir
22588         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22589         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22590                 error "create 10 files failed"
22591
22592         for file in $(find $DIR/$tdir); do
22593                 stripe_count=$($LFS getstripe -c $file)
22594                 [ $stripe_count -eq 2 ] ||
22595                         error "wrong stripe $stripe_count for $file"
22596         done
22597
22598         rm -rf $DIR/$tdir
22599 }
22600 run_test 300d "check default stripe under striped directory"
22601
22602 test_300e() {
22603         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22604                 skip "Need MDS version at least 2.7.55"
22605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22607
22608         local stripe_count
22609         local file
22610
22611         mkdir -p $DIR/$tdir
22612
22613         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22614                 error "set striped dir error"
22615
22616         touch $DIR/$tdir/striped_dir/a
22617         touch $DIR/$tdir/striped_dir/b
22618         touch $DIR/$tdir/striped_dir/c
22619
22620         mkdir $DIR/$tdir/striped_dir/dir_a
22621         mkdir $DIR/$tdir/striped_dir/dir_b
22622         mkdir $DIR/$tdir/striped_dir/dir_c
22623
22624         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22625                 error "set striped adir under striped dir error"
22626
22627         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22628                 error "set striped bdir under striped dir error"
22629
22630         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22631                 error "set striped cdir under striped dir error"
22632
22633         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22634                 error "rename dir under striped dir fails"
22635
22636         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22637                 error "rename dir under different stripes fails"
22638
22639         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22640                 error "rename file under striped dir should succeed"
22641
22642         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22643                 error "rename dir under striped dir should succeed"
22644
22645         rm -rf $DIR/$tdir
22646 }
22647 run_test 300e "check rename under striped directory"
22648
22649 test_300f() {
22650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22651         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22652         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22653                 skip "Need MDS version at least 2.7.55"
22654
22655         local stripe_count
22656         local file
22657
22658         rm -rf $DIR/$tdir
22659         mkdir -p $DIR/$tdir
22660
22661         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22662                 error "set striped dir error"
22663
22664         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22665                 error "set striped dir error"
22666
22667         touch $DIR/$tdir/striped_dir/a
22668         mkdir $DIR/$tdir/striped_dir/dir_a
22669         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22670                 error "create striped dir under striped dir fails"
22671
22672         touch $DIR/$tdir/striped_dir1/b
22673         mkdir $DIR/$tdir/striped_dir1/dir_b
22674         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22675                 error "create striped dir under striped dir fails"
22676
22677         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22678                 error "rename dir under different striped dir should fail"
22679
22680         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22681                 error "rename striped dir under diff striped dir should fail"
22682
22683         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22684                 error "rename file under diff striped dirs fails"
22685
22686         rm -rf $DIR/$tdir
22687 }
22688 run_test 300f "check rename cross striped directory"
22689
22690 test_300_check_default_striped_dir()
22691 {
22692         local dirname=$1
22693         local default_count=$2
22694         local default_index=$3
22695         local stripe_count
22696         local stripe_index
22697         local dir_stripe_index
22698         local dir
22699
22700         echo "checking $dirname $default_count $default_index"
22701         $LFS setdirstripe -D -c $default_count -i $default_index \
22702                                 -H all_char $DIR/$tdir/$dirname ||
22703                 error "set default stripe on striped dir error"
22704         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22705         [ $stripe_count -eq $default_count ] ||
22706                 error "expect $default_count get $stripe_count for $dirname"
22707
22708         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22709         [ $stripe_index -eq $default_index ] ||
22710                 error "expect $default_index get $stripe_index for $dirname"
22711
22712         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22713                                                 error "create dirs failed"
22714
22715         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22716         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22717         for dir in $(find $DIR/$tdir/$dirname/*); do
22718                 stripe_count=$($LFS getdirstripe -c $dir)
22719                 (( $stripe_count == $default_count )) ||
22720                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22721                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22722                 error "stripe count $default_count != $stripe_count for $dir"
22723
22724                 stripe_index=$($LFS getdirstripe -i $dir)
22725                 [ $default_index -eq -1 ] ||
22726                         [ $stripe_index -eq $default_index ] ||
22727                         error "$stripe_index != $default_index for $dir"
22728
22729                 #check default stripe
22730                 stripe_count=$($LFS getdirstripe -D -c $dir)
22731                 [ $stripe_count -eq $default_count ] ||
22732                 error "default count $default_count != $stripe_count for $dir"
22733
22734                 stripe_index=$($LFS getdirstripe -D -i $dir)
22735                 [ $stripe_index -eq $default_index ] ||
22736                 error "default index $default_index != $stripe_index for $dir"
22737         done
22738         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22739 }
22740
22741 test_300g() {
22742         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22743         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22744                 skip "Need MDS version at least 2.7.55"
22745
22746         local dir
22747         local stripe_count
22748         local stripe_index
22749
22750         mkdir_on_mdt0 $DIR/$tdir
22751         mkdir $DIR/$tdir/normal_dir
22752
22753         #Checking when client cache stripe index
22754         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22755         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22756                 error "create striped_dir failed"
22757
22758         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22759                 error "create dir0 fails"
22760         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22761         [ $stripe_index -eq 0 ] ||
22762                 error "dir0 expect index 0 got $stripe_index"
22763
22764         mkdir $DIR/$tdir/striped_dir/dir1 ||
22765                 error "create dir1 fails"
22766         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22767         [ $stripe_index -eq 1 ] ||
22768                 error "dir1 expect index 1 got $stripe_index"
22769
22770         #check default stripe count/stripe index
22771         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22772         test_300_check_default_striped_dir normal_dir 1 0
22773         test_300_check_default_striped_dir normal_dir -1 1
22774         test_300_check_default_striped_dir normal_dir 2 -1
22775
22776         #delete default stripe information
22777         echo "delete default stripeEA"
22778         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22779                 error "set default stripe on striped dir error"
22780
22781         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22782         for dir in $(find $DIR/$tdir/normal_dir/*); do
22783                 stripe_count=$($LFS getdirstripe -c $dir)
22784                 [ $stripe_count -eq 0 ] ||
22785                         error "expect 1 get $stripe_count for $dir"
22786         done
22787 }
22788 run_test 300g "check default striped directory for normal directory"
22789
22790 test_300h() {
22791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22792         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22793                 skip "Need MDS version at least 2.7.55"
22794
22795         local dir
22796         local stripe_count
22797
22798         mkdir $DIR/$tdir
22799         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22800                 error "set striped dir error"
22801
22802         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22803         test_300_check_default_striped_dir striped_dir 1 0
22804         test_300_check_default_striped_dir striped_dir -1 1
22805         test_300_check_default_striped_dir striped_dir 2 -1
22806
22807         #delete default stripe information
22808         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22809                 error "set default stripe on striped dir error"
22810
22811         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22812         for dir in $(find $DIR/$tdir/striped_dir/*); do
22813                 stripe_count=$($LFS getdirstripe -c $dir)
22814                 [ $stripe_count -eq 0 ] ||
22815                         error "expect 1 get $stripe_count for $dir"
22816         done
22817 }
22818 run_test 300h "check default striped directory for striped directory"
22819
22820 test_300i() {
22821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22822         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22823         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22824                 skip "Need MDS version at least 2.7.55"
22825
22826         local stripe_count
22827         local file
22828
22829         mkdir $DIR/$tdir
22830
22831         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22832                 error "set striped dir error"
22833
22834         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22835                 error "create files under striped dir failed"
22836
22837         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22838                 error "set striped hashdir error"
22839
22840         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22841                 error "create dir0 under hash dir failed"
22842         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22843                 error "create dir1 under hash dir failed"
22844         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22845                 error "create dir2 under hash dir failed"
22846
22847         # unfortunately, we need to umount to clear dir layout cache for now
22848         # once we fully implement dir layout, we can drop this
22849         umount_client $MOUNT || error "umount failed"
22850         mount_client $MOUNT || error "mount failed"
22851
22852         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22853         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22854         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22855
22856         #set the stripe to be unknown hash type
22857         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22858         $LCTL set_param fail_loc=0x1901
22859         for ((i = 0; i < 10; i++)); do
22860                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22861                         error "stat f-$i failed"
22862                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22863         done
22864
22865         touch $DIR/$tdir/striped_dir/f0 &&
22866                 error "create under striped dir with unknown hash should fail"
22867
22868         $LCTL set_param fail_loc=0
22869
22870         umount_client $MOUNT || error "umount failed"
22871         mount_client $MOUNT || error "mount failed"
22872
22873         return 0
22874 }
22875 run_test 300i "client handle unknown hash type striped directory"
22876
22877 test_300j() {
22878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22880         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22881                 skip "Need MDS version at least 2.7.55"
22882
22883         local stripe_count
22884         local file
22885
22886         mkdir $DIR/$tdir
22887
22888         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22889         $LCTL set_param fail_loc=0x1702
22890         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22891                 error "set striped dir error"
22892
22893         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22894                 error "create files under striped dir failed"
22895
22896         $LCTL set_param fail_loc=0
22897
22898         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22899
22900         return 0
22901 }
22902 run_test 300j "test large update record"
22903
22904 test_300k() {
22905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22907         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22908                 skip "Need MDS version at least 2.7.55"
22909
22910         # this test needs a huge transaction
22911         local kb
22912         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22913              osd*.$FSNAME-MDT0000.kbytestotal")
22914         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22915
22916         local stripe_count
22917         local file
22918
22919         mkdir $DIR/$tdir
22920
22921         #define OBD_FAIL_LARGE_STRIPE   0x1703
22922         $LCTL set_param fail_loc=0x1703
22923         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22924                 error "set striped dir error"
22925         $LCTL set_param fail_loc=0
22926
22927         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22928                 error "getstripeddir fails"
22929         rm -rf $DIR/$tdir/striped_dir ||
22930                 error "unlink striped dir fails"
22931
22932         return 0
22933 }
22934 run_test 300k "test large striped directory"
22935
22936 test_300l() {
22937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22939         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22940                 skip "Need MDS version at least 2.7.55"
22941
22942         local stripe_index
22943
22944         test_mkdir -p $DIR/$tdir/striped_dir
22945         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22946                         error "chown $RUNAS_ID failed"
22947         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22948                 error "set default striped dir failed"
22949
22950         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22951         $LCTL set_param fail_loc=0x80000158
22952         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22953
22954         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22955         [ $stripe_index -eq 1 ] ||
22956                 error "expect 1 get $stripe_index for $dir"
22957 }
22958 run_test 300l "non-root user to create dir under striped dir with stale layout"
22959
22960 test_300m() {
22961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22962         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22963         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22964                 skip "Need MDS version at least 2.7.55"
22965
22966         mkdir -p $DIR/$tdir/striped_dir
22967         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22968                 error "set default stripes dir error"
22969
22970         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22971
22972         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22973         [ $stripe_count -eq 0 ] ||
22974                         error "expect 0 get $stripe_count for a"
22975
22976         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22977                 error "set default stripes dir error"
22978
22979         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22980
22981         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22982         [ $stripe_count -eq 0 ] ||
22983                         error "expect 0 get $stripe_count for b"
22984
22985         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22986                 error "set default stripes dir error"
22987
22988         mkdir $DIR/$tdir/striped_dir/c &&
22989                 error "default stripe_index is invalid, mkdir c should fails"
22990
22991         rm -rf $DIR/$tdir || error "rmdir fails"
22992 }
22993 run_test 300m "setstriped directory on single MDT FS"
22994
22995 cleanup_300n() {
22996         local list=$(comma_list $(mdts_nodes))
22997
22998         trap 0
22999         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23000 }
23001
23002 test_300n() {
23003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23004         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23005         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23006                 skip "Need MDS version at least 2.7.55"
23007         remote_mds_nodsh && skip "remote MDS with nodsh"
23008
23009         local stripe_index
23010         local list=$(comma_list $(mdts_nodes))
23011
23012         trap cleanup_300n RETURN EXIT
23013         mkdir -p $DIR/$tdir
23014         chmod 777 $DIR/$tdir
23015         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23016                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23017                 error "create striped dir succeeds with gid=0"
23018
23019         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23020         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23021                 error "create striped dir fails with gid=-1"
23022
23023         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23024         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23025                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23026                 error "set default striped dir succeeds with gid=0"
23027
23028
23029         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23030         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23031                 error "set default striped dir fails with gid=-1"
23032
23033
23034         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23035         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23036                                         error "create test_dir fails"
23037         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23038                                         error "create test_dir1 fails"
23039         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23040                                         error "create test_dir2 fails"
23041         cleanup_300n
23042 }
23043 run_test 300n "non-root user to create dir under striped dir with default EA"
23044
23045 test_300o() {
23046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23047         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23048         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23049                 skip "Need MDS version at least 2.7.55"
23050
23051         local numfree1
23052         local numfree2
23053
23054         mkdir -p $DIR/$tdir
23055
23056         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23057         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23058         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23059                 skip "not enough free inodes $numfree1 $numfree2"
23060         fi
23061
23062         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23063         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23064         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23065                 skip "not enough free space $numfree1 $numfree2"
23066         fi
23067
23068         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23069                 error "setdirstripe fails"
23070
23071         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23072                 error "create dirs fails"
23073
23074         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23075         ls $DIR/$tdir/striped_dir > /dev/null ||
23076                 error "ls striped dir fails"
23077         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23078                 error "unlink big striped dir fails"
23079 }
23080 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23081
23082 test_300p() {
23083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23084         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23085         remote_mds_nodsh && skip "remote MDS with nodsh"
23086
23087         mkdir_on_mdt0 $DIR/$tdir
23088
23089         #define OBD_FAIL_OUT_ENOSPC     0x1704
23090         do_facet mds2 lctl set_param fail_loc=0x80001704
23091         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23092                  && error "create striped directory should fail"
23093
23094         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23095
23096         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23097         true
23098 }
23099 run_test 300p "create striped directory without space"
23100
23101 test_300q() {
23102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23103         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23104
23105         local fd=$(free_fd)
23106         local cmd="exec $fd<$tdir"
23107         cd $DIR
23108         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23109         eval $cmd
23110         cmd="exec $fd<&-"
23111         trap "eval $cmd" EXIT
23112         cd $tdir || error "cd $tdir fails"
23113         rmdir  ../$tdir || error "rmdir $tdir fails"
23114         mkdir local_dir && error "create dir succeeds"
23115         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23116         eval $cmd
23117         return 0
23118 }
23119 run_test 300q "create remote directory under orphan directory"
23120
23121 test_300r() {
23122         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23123                 skip "Need MDS version at least 2.7.55" && return
23124         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23125
23126         mkdir $DIR/$tdir
23127
23128         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23129                 error "set striped dir error"
23130
23131         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23132                 error "getstripeddir fails"
23133
23134         local stripe_count
23135         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23136                       awk '/lmv_stripe_count:/ { print $2 }')
23137
23138         [ $MDSCOUNT -ne $stripe_count ] &&
23139                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23140
23141         rm -rf $DIR/$tdir/striped_dir ||
23142                 error "unlink striped dir fails"
23143 }
23144 run_test 300r "test -1 striped directory"
23145
23146 test_300s_helper() {
23147         local count=$1
23148
23149         local stripe_dir=$DIR/$tdir/striped_dir.$count
23150
23151         $LFS mkdir -c $count $stripe_dir ||
23152                 error "lfs mkdir -c error"
23153
23154         $LFS getdirstripe $stripe_dir ||
23155                 error "lfs getdirstripe fails"
23156
23157         local stripe_count
23158         stripe_count=$($LFS getdirstripe $stripe_dir |
23159                       awk '/lmv_stripe_count:/ { print $2 }')
23160
23161         [ $count -ne $stripe_count ] &&
23162                 error_noexit "bad stripe count $stripe_count expected $count"
23163
23164         local dupe_stripes
23165         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23166                 awk '/0x/ {count[$1] += 1}; END {
23167                         for (idx in count) {
23168                                 if (count[idx]>1) {
23169                                         print "index " idx " count " count[idx]
23170                                 }
23171                         }
23172                 }')
23173
23174         if [[ -n "$dupe_stripes" ]] ; then
23175                 lfs getdirstripe $stripe_dir
23176                 error_noexit "Dupe MDT above: $dupe_stripes "
23177         fi
23178
23179         rm -rf $stripe_dir ||
23180                 error_noexit "unlink $stripe_dir fails"
23181 }
23182
23183 test_300s() {
23184         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23185                 skip "Need MDS version at least 2.7.55" && return
23186         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23187
23188         mkdir $DIR/$tdir
23189         for count in $(seq 2 $MDSCOUNT); do
23190                 test_300s_helper $count
23191         done
23192 }
23193 run_test 300s "test lfs mkdir -c without -i"
23194
23195
23196 prepare_remote_file() {
23197         mkdir $DIR/$tdir/src_dir ||
23198                 error "create remote source failed"
23199
23200         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23201                  error "cp to remote source failed"
23202         touch $DIR/$tdir/src_dir/a
23203
23204         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23205                 error "create remote target dir failed"
23206
23207         touch $DIR/$tdir/tgt_dir/b
23208
23209         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23210                 error "rename dir cross MDT failed!"
23211
23212         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23213                 error "src_child still exists after rename"
23214
23215         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23216                 error "missing file(a) after rename"
23217
23218         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23219                 error "diff after rename"
23220 }
23221
23222 test_310a() {
23223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23225
23226         local remote_file=$DIR/$tdir/tgt_dir/b
23227
23228         mkdir -p $DIR/$tdir
23229
23230         prepare_remote_file || error "prepare remote file failed"
23231
23232         #open-unlink file
23233         $OPENUNLINK $remote_file $remote_file ||
23234                 error "openunlink $remote_file failed"
23235         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23236 }
23237 run_test 310a "open unlink remote file"
23238
23239 test_310b() {
23240         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23242
23243         local remote_file=$DIR/$tdir/tgt_dir/b
23244
23245         mkdir -p $DIR/$tdir
23246
23247         prepare_remote_file || error "prepare remote file failed"
23248
23249         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23250         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23251         $CHECKSTAT -t file $remote_file || error "check file failed"
23252 }
23253 run_test 310b "unlink remote file with multiple links while open"
23254
23255 test_310c() {
23256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23257         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23258
23259         local remote_file=$DIR/$tdir/tgt_dir/b
23260
23261         mkdir -p $DIR/$tdir
23262
23263         prepare_remote_file || error "prepare remote file failed"
23264
23265         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23266         multiop_bg_pause $remote_file O_uc ||
23267                         error "mulitop failed for remote file"
23268         MULTIPID=$!
23269         $MULTIOP $DIR/$tfile Ouc
23270         kill -USR1 $MULTIPID
23271         wait $MULTIPID
23272 }
23273 run_test 310c "open-unlink remote file with multiple links"
23274
23275 #LU-4825
23276 test_311() {
23277         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23278         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23279         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23280                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23281         remote_mds_nodsh && skip "remote MDS with nodsh"
23282
23283         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23284         local mdts=$(comma_list $(mdts_nodes))
23285
23286         mkdir -p $DIR/$tdir
23287         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23288         createmany -o $DIR/$tdir/$tfile. 1000
23289
23290         # statfs data is not real time, let's just calculate it
23291         old_iused=$((old_iused + 1000))
23292
23293         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23294                         osp.*OST0000*MDT0000.create_count")
23295         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23296                                 osp.*OST0000*MDT0000.max_create_count")
23297         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23298
23299         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23300         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23301         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23302
23303         unlinkmany $DIR/$tdir/$tfile. 1000
23304
23305         do_nodes $mdts "$LCTL set_param -n \
23306                         osp.*OST0000*.max_create_count=$max_count"
23307         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23308                 do_nodes $mdts "$LCTL set_param -n \
23309                                 osp.*OST0000*.create_count=$count"
23310         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23311                         grep "=0" && error "create_count is zero"
23312
23313         local new_iused
23314         for i in $(seq 120); do
23315                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23316                 # system may be too busy to destroy all objs in time, use
23317                 # a somewhat small value to not fail autotest
23318                 [ $((old_iused - new_iused)) -gt 400 ] && break
23319                 sleep 1
23320         done
23321
23322         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23323         [ $((old_iused - new_iused)) -gt 400 ] ||
23324                 error "objs not destroyed after unlink"
23325 }
23326 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23327
23328 zfs_oid_to_objid()
23329 {
23330         local ost=$1
23331         local objid=$2
23332
23333         local vdevdir=$(dirname $(facet_vdevice $ost))
23334         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23335         local zfs_zapid=$(do_facet $ost $cmd |
23336                           grep -w "/O/0/d$((objid%32))" -C 5 |
23337                           awk '/Object/{getline; print $1}')
23338         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23339                           awk "/$objid = /"'{printf $3}')
23340
23341         echo $zfs_objid
23342 }
23343
23344 zfs_object_blksz() {
23345         local ost=$1
23346         local objid=$2
23347
23348         local vdevdir=$(dirname $(facet_vdevice $ost))
23349         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23350         local blksz=$(do_facet $ost $cmd $objid |
23351                       awk '/dblk/{getline; printf $4}')
23352
23353         case "${blksz: -1}" in
23354                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23355                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23356                 *) ;;
23357         esac
23358
23359         echo $blksz
23360 }
23361
23362 test_312() { # LU-4856
23363         remote_ost_nodsh && skip "remote OST with nodsh"
23364         [ "$ost1_FSTYPE" = "zfs" ] ||
23365                 skip_env "the test only applies to zfs"
23366
23367         local max_blksz=$(do_facet ost1 \
23368                           $ZFS get -p recordsize $(facet_device ost1) |
23369                           awk '!/VALUE/{print $3}')
23370
23371         # to make life a little bit easier
23372         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23373         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23374
23375         local tf=$DIR/$tdir/$tfile
23376         touch $tf
23377         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23378
23379         # Get ZFS object id
23380         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23381         # block size change by sequential overwrite
23382         local bs
23383
23384         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23385                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23386
23387                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23388                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23389         done
23390         rm -f $tf
23391
23392         # block size change by sequential append write
23393         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23394         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23395         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23396         local count
23397
23398         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23399                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23400                         oflag=sync conv=notrunc
23401
23402                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23403                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23404                         error "blksz error, actual $blksz, " \
23405                                 "expected: 2 * $count * $PAGE_SIZE"
23406         done
23407         rm -f $tf
23408
23409         # random write
23410         touch $tf
23411         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23412         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23413
23414         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23415         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23416         [ $blksz -eq $PAGE_SIZE ] ||
23417                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23418
23419         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23420         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23421         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23422
23423         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23424         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23425         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23426 }
23427 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23428
23429 test_313() {
23430         remote_ost_nodsh && skip "remote OST with nodsh"
23431
23432         local file=$DIR/$tfile
23433
23434         rm -f $file
23435         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23436
23437         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23438         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23439         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23440                 error "write should failed"
23441         do_facet ost1 "$LCTL set_param fail_loc=0"
23442         rm -f $file
23443 }
23444 run_test 313 "io should fail after last_rcvd update fail"
23445
23446 test_314() {
23447         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23448
23449         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23450         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23451         rm -f $DIR/$tfile
23452         wait_delete_completed
23453         do_facet ost1 "$LCTL set_param fail_loc=0"
23454 }
23455 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23456
23457 test_315() { # LU-618
23458         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23459
23460         local file=$DIR/$tfile
23461         rm -f $file
23462
23463         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23464                 error "multiop file write failed"
23465         $MULTIOP $file oO_RDONLY:r4063232_c &
23466         PID=$!
23467
23468         sleep 2
23469
23470         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23471         kill -USR1 $PID
23472
23473         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23474         rm -f $file
23475 }
23476 run_test 315 "read should be accounted"
23477
23478 test_316() {
23479         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23480         large_xattr_enabled || skip_env "ea_inode feature disabled"
23481
23482         rm -rf $DIR/$tdir/d
23483         mkdir -p $DIR/$tdir/d
23484         chown nobody $DIR/$tdir/d
23485         touch $DIR/$tdir/d/file
23486
23487         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23488 }
23489 run_test 316 "lfs mv"
23490
23491 test_317() {
23492         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23493                 skip "Need MDS version at least 2.11.53"
23494         if [ "$ost1_FSTYPE" == "zfs" ]; then
23495                 skip "LU-10370: no implementation for ZFS"
23496         fi
23497
23498         local trunc_sz
23499         local grant_blk_size
23500
23501         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23502                         awk '/grant_block_size:/ { print $2; exit; }')
23503         #
23504         # Create File of size 5M. Truncate it to below size's and verify
23505         # blocks count.
23506         #
23507         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23508                 error "Create file $DIR/$tfile failed"
23509         stack_trap "rm -f $DIR/$tfile" EXIT
23510
23511         for trunc_sz in 2097152 4097 4000 509 0; do
23512                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23513                         error "truncate $tfile to $trunc_sz failed"
23514                 local sz=$(stat --format=%s $DIR/$tfile)
23515                 local blk=$(stat --format=%b $DIR/$tfile)
23516                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23517                                      grant_blk_size) * 8))
23518
23519                 if [[ $blk -ne $trunc_blk ]]; then
23520                         $(which stat) $DIR/$tfile
23521                         error "Expected Block $trunc_blk got $blk for $tfile"
23522                 fi
23523
23524                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23525                         error "Expected Size $trunc_sz got $sz for $tfile"
23526         done
23527
23528         #
23529         # sparse file test
23530         # Create file with a hole and write actual two blocks. Block count
23531         # must be 16.
23532         #
23533         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23534                 conv=fsync || error "Create file : $DIR/$tfile"
23535
23536         # Calculate the final truncate size.
23537         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23538
23539         #
23540         # truncate to size $trunc_sz bytes. Strip the last block
23541         # The block count must drop to 8
23542         #
23543         $TRUNCATE $DIR/$tfile $trunc_sz ||
23544                 error "truncate $tfile to $trunc_sz failed"
23545
23546         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23547         sz=$(stat --format=%s $DIR/$tfile)
23548         blk=$(stat --format=%b $DIR/$tfile)
23549
23550         if [[ $blk -ne $trunc_bsz ]]; then
23551                 $(which stat) $DIR/$tfile
23552                 error "Expected Block $trunc_bsz got $blk for $tfile"
23553         fi
23554
23555         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23556                 error "Expected Size $trunc_sz got $sz for $tfile"
23557 }
23558 run_test 317 "Verify blocks get correctly update after truncate"
23559
23560 test_318() {
23561         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23562         local old_max_active=$($LCTL get_param -n \
23563                             ${llite_name}.max_read_ahead_async_active \
23564                             2>/dev/null)
23565
23566         $LCTL set_param llite.*.max_read_ahead_async_active=256
23567         local max_active=$($LCTL get_param -n \
23568                            ${llite_name}.max_read_ahead_async_active \
23569                            2>/dev/null)
23570         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23571
23572         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23573                 error "set max_read_ahead_async_active should succeed"
23574
23575         $LCTL set_param llite.*.max_read_ahead_async_active=512
23576         max_active=$($LCTL get_param -n \
23577                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23578         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23579
23580         # restore @max_active
23581         [ $old_max_active -ne 0 ] && $LCTL set_param \
23582                 llite.*.max_read_ahead_async_active=$old_max_active
23583
23584         local old_threshold=$($LCTL get_param -n \
23585                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23586         local max_per_file_mb=$($LCTL get_param -n \
23587                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23588
23589         local invalid=$(($max_per_file_mb + 1))
23590         $LCTL set_param \
23591                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23592                         && error "set $invalid should fail"
23593
23594         local valid=$(($invalid - 1))
23595         $LCTL set_param \
23596                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23597                         error "set $valid should succeed"
23598         local threshold=$($LCTL get_param -n \
23599                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23600         [ $threshold -eq $valid ] || error \
23601                 "expect threshold $valid got $threshold"
23602         $LCTL set_param \
23603                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23604 }
23605 run_test 318 "Verify async readahead tunables"
23606
23607 test_319() {
23608         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23609
23610         local before=$(date +%s)
23611         local evict
23612         local mdir=$DIR/$tdir
23613         local file=$mdir/xxx
23614
23615         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23616         touch $file
23617
23618 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23619         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23620         $LFS mv -m1 $file &
23621
23622         sleep 1
23623         dd if=$file of=/dev/null
23624         wait
23625         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23626           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23627
23628         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23629 }
23630 run_test 319 "lost lease lock on migrate error"
23631
23632 test_398a() { # LU-4198
23633         local ost1_imp=$(get_osc_import_name client ost1)
23634         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23635                          cut -d'.' -f2)
23636
23637         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23638         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23639
23640         # request a new lock on client
23641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23642
23643         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23644         local lock_count=$($LCTL get_param -n \
23645                            ldlm.namespaces.$imp_name.lru_size)
23646         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23647
23648         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23649
23650         # no lock cached, should use lockless IO and not enqueue new lock
23651         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23652         lock_count=$($LCTL get_param -n \
23653                      ldlm.namespaces.$imp_name.lru_size)
23654         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23655 }
23656 run_test 398a "direct IO should cancel lock otherwise lockless"
23657
23658 test_398b() { # LU-4198
23659         which fio || skip_env "no fio installed"
23660         $LFS setstripe -c -1 $DIR/$tfile
23661
23662         local size=12
23663         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23664
23665         local njobs=4
23666         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23667         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23668                 --numjobs=$njobs --fallocate=none \
23669                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23670                 --filename=$DIR/$tfile &
23671         bg_pid=$!
23672
23673         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23674         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23675                 --numjobs=$njobs --fallocate=none \
23676                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23677                 --filename=$DIR/$tfile || true
23678         wait $bg_pid
23679
23680         rm -f $DIR/$tfile
23681 }
23682 run_test 398b "DIO and buffer IO race"
23683
23684 test_398c() { # LU-4198
23685         local ost1_imp=$(get_osc_import_name client ost1)
23686         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23687                          cut -d'.' -f2)
23688
23689         which fio || skip_env "no fio installed"
23690
23691         saved_debug=$($LCTL get_param -n debug)
23692         $LCTL set_param debug=0
23693
23694         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23695         ((size /= 1024)) # by megabytes
23696         ((size /= 2)) # write half of the OST at most
23697         [ $size -gt 40 ] && size=40 #reduce test time anyway
23698
23699         $LFS setstripe -c 1 $DIR/$tfile
23700
23701         # it seems like ldiskfs reserves more space than necessary if the
23702         # writing blocks are not mapped, so it extends the file firstly
23703         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23704         cancel_lru_locks osc
23705
23706         # clear and verify rpc_stats later
23707         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23708
23709         local njobs=4
23710         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23711         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23712                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23713                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23714                 --filename=$DIR/$tfile
23715         [ $? -eq 0 ] || error "fio write error"
23716
23717         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23718                 error "Locks were requested while doing AIO"
23719
23720         # get the percentage of 1-page I/O
23721         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23722                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23723                 awk '{print $7}')
23724         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23725
23726         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23727         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23728                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23729                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23730                 --filename=$DIR/$tfile
23731         [ $? -eq 0 ] || error "fio mixed read write error"
23732
23733         echo "AIO with large block size ${size}M"
23734         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23735                 --numjobs=1 --fallocate=none --ioengine=libaio \
23736                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23737                 --filename=$DIR/$tfile
23738         [ $? -eq 0 ] || error "fio large block size failed"
23739
23740         rm -f $DIR/$tfile
23741         $LCTL set_param debug="$saved_debug"
23742 }
23743 run_test 398c "run fio to test AIO"
23744
23745 test_398d() { #  LU-13846
23746         which aiocp || skip_env "no aiocp installed"
23747         local aio_file=$DIR/$tfile.aio
23748
23749         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23750
23751         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23752         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23753         stack_trap "rm -f $DIR/$tfile $aio_file"
23754
23755         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23756
23757         # make sure we don't crash and fail properly
23758         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23759                 error "aio not aligned with PAGE SIZE should fail"
23760
23761         rm -f $DIR/$tfile $aio_file
23762 }
23763 run_test 398d "run aiocp to verify block size > stripe size"
23764
23765 test_398e() {
23766         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23767         touch $DIR/$tfile.new
23768         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23769 }
23770 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23771
23772 test_398f() { #  LU-14687
23773         which aiocp || skip_env "no aiocp installed"
23774         local aio_file=$DIR/$tfile.aio
23775
23776         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23777
23778         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23779         stack_trap "rm -f $DIR/$tfile $aio_file"
23780
23781         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23782         $LCTL set_param fail_loc=0x1418
23783         # make sure we don't crash and fail properly
23784         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23785                 error "aio with page allocation failure succeeded"
23786         $LCTL set_param fail_loc=0
23787         diff $DIR/$tfile $aio_file
23788         [[ $? != 0 ]] || error "no diff after failed aiocp"
23789 }
23790 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23791
23792 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23793 # stripe and i/o size must be > stripe size
23794 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23795 # single RPC in flight.  This test shows async DIO submission is working by
23796 # showing multiple RPCs in flight.
23797 test_398g() { #  LU-13798
23798         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23799
23800         # We need to do some i/o first to acquire enough grant to put our RPCs
23801         # in flight; otherwise a new connection may not have enough grant
23802         # available
23803         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23804                 error "parallel dio failed"
23805         stack_trap "rm -f $DIR/$tfile"
23806
23807         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23808         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23809         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23810         stack_trap "$LCTL set_param -n $pages_per_rpc"
23811
23812         # Recreate file so it's empty
23813         rm -f $DIR/$tfile
23814         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23815         #Pause rpc completion to guarantee we see multiple rpcs in flight
23816         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23817         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23818         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23819
23820         # Clear rpc stats
23821         $LCTL set_param osc.*.rpc_stats=c
23822
23823         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23824                 error "parallel dio failed"
23825         stack_trap "rm -f $DIR/$tfile"
23826
23827         $LCTL get_param osc.*-OST0000-*.rpc_stats
23828         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23829                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23830                 grep "8:" | awk '{print $8}')
23831         # We look at the "8 rpcs in flight" field, and verify A) it is present
23832         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23833         # as expected for an 8M DIO to a file with 1M stripes.
23834         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23835
23836         # Verify turning off parallel dio works as expected
23837         # Clear rpc stats
23838         $LCTL set_param osc.*.rpc_stats=c
23839         $LCTL set_param llite.*.parallel_dio=0
23840         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23841
23842         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23843                 error "dio with parallel dio disabled failed"
23844
23845         # Ideally, we would see only one RPC in flight here, but there is an
23846         # unavoidable race between i/o completion and RPC in flight counting,
23847         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23848         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23849         # So instead we just verify it's always < 8.
23850         $LCTL get_param osc.*-OST0000-*.rpc_stats
23851         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23852                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23853                 grep '^$' -B1 | grep . | awk '{print $1}')
23854         [ $ret != "8:" ] ||
23855                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23856 }
23857 run_test 398g "verify parallel dio async RPC submission"
23858
23859 test_398h() { #  LU-13798
23860         local dio_file=$DIR/$tfile.dio
23861
23862         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23863
23864         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23865         stack_trap "rm -f $DIR/$tfile $dio_file"
23866
23867         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23868                 error "parallel dio failed"
23869         diff $DIR/$tfile $dio_file
23870         [[ $? == 0 ]] || error "file diff after aiocp"
23871 }
23872 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23873
23874 test_398i() { #  LU-13798
23875         local dio_file=$DIR/$tfile.dio
23876
23877         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23878
23879         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23880         stack_trap "rm -f $DIR/$tfile $dio_file"
23881
23882         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23883         $LCTL set_param fail_loc=0x1418
23884         # make sure we don't crash and fail properly
23885         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23886                 error "parallel dio page allocation failure succeeded"
23887         diff $DIR/$tfile $dio_file
23888         [[ $? != 0 ]] || error "no diff after failed aiocp"
23889 }
23890 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23891
23892 test_398j() { #  LU-13798
23893         # Stripe size > RPC size but less than i/o size tests split across
23894         # stripes and RPCs for individual i/o op
23895         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23896
23897         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23898         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23899         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23900         stack_trap "$LCTL set_param -n $pages_per_rpc"
23901
23902         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23903                 error "parallel dio write failed"
23904         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23905
23906         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23907                 error "parallel dio read failed"
23908         diff $DIR/$tfile $DIR/$tfile.2
23909         [[ $? == 0 ]] || error "file diff after parallel dio read"
23910 }
23911 run_test 398j "test parallel dio where stripe size > rpc_size"
23912
23913 test_398k() { #  LU-13798
23914         wait_delete_completed
23915         wait_mds_ost_sync
23916
23917         # 4 stripe file; we will cause out of space on OST0
23918         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23919
23920         # Fill OST0 (if it's not too large)
23921         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23922                    head -n1)
23923         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23924                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23925         fi
23926         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23927         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23928                 error "dd should fill OST0"
23929         stack_trap "rm -f $DIR/$tfile.1"
23930
23931         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23932         err=$?
23933
23934         ls -la $DIR/$tfile
23935         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23936                 error "file is not 0 bytes in size"
23937
23938         # dd above should not succeed, but don't error until here so we can
23939         # get debug info above
23940         [[ $err != 0 ]] ||
23941                 error "parallel dio write with enospc succeeded"
23942         stack_trap "rm -f $DIR/$tfile"
23943 }
23944 run_test 398k "test enospc on first stripe"
23945
23946 test_398l() { #  LU-13798
23947         wait_delete_completed
23948         wait_mds_ost_sync
23949
23950         # 4 stripe file; we will cause out of space on OST0
23951         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23952         # happens on the second i/o chunk we issue
23953         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23954
23955         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23956         stack_trap "rm -f $DIR/$tfile"
23957
23958         # Fill OST0 (if it's not too large)
23959         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23960                    head -n1)
23961         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23962                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23963         fi
23964         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23965         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23966                 error "dd should fill OST0"
23967         stack_trap "rm -f $DIR/$tfile.1"
23968
23969         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23970         err=$?
23971         stack_trap "rm -f $DIR/$tfile.2"
23972
23973         # Check that short write completed as expected
23974         ls -la $DIR/$tfile.2
23975         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23976                 error "file is not 1M in size"
23977
23978         # dd above should not succeed, but don't error until here so we can
23979         # get debug info above
23980         [[ $err != 0 ]] ||
23981                 error "parallel dio write with enospc succeeded"
23982
23983         # Truncate source file to same length as output file and diff them
23984         $TRUNCATE $DIR/$tfile 1048576
23985         diff $DIR/$tfile $DIR/$tfile.2
23986         [[ $? == 0 ]] || error "data incorrect after short write"
23987 }
23988 run_test 398l "test enospc on intermediate stripe/RPC"
23989
23990 test_398m() { #  LU-13798
23991         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23992
23993         # Set up failure on OST0, the first stripe:
23994         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23995         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23996         # So this fail_val specifies OST0
23997         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23998         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23999
24000         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24001                 error "parallel dio write with failure on first stripe succeeded"
24002         stack_trap "rm -f $DIR/$tfile"
24003         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24004
24005         # Place data in file for read
24006         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24007                 error "parallel dio write failed"
24008
24009         # Fail read on OST0, first stripe
24010         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24011         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24012         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24013                 error "parallel dio read with error on first stripe succeeded"
24014         rm -f $DIR/$tfile.2
24015         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24016
24017         # Switch to testing on OST1, second stripe
24018         # Clear file contents, maintain striping
24019         echo > $DIR/$tfile
24020         # Set up failure on OST1, second stripe:
24021         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24022         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24023
24024         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24025                 error "parallel dio write with failure on first stripe succeeded"
24026         stack_trap "rm -f $DIR/$tfile"
24027         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24028
24029         # Place data in file for read
24030         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24031                 error "parallel dio write failed"
24032
24033         # Fail read on OST1, second stripe
24034         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24035         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24036         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24037                 error "parallel dio read with error on first stripe succeeded"
24038         rm -f $DIR/$tfile.2
24039         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24040 }
24041 run_test 398m "test RPC failures with parallel dio"
24042
24043 # Parallel submission of DIO should not cause problems for append, but it's
24044 # important to verify.
24045 test_398n() { #  LU-13798
24046         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24047
24048         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24049                 error "dd to create source file failed"
24050         stack_trap "rm -f $DIR/$tfile"
24051
24052         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24053                 error "parallel dio write with failure on second stripe succeeded"
24054         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24055         diff $DIR/$tfile $DIR/$tfile.1
24056         [[ $? == 0 ]] || error "data incorrect after append"
24057
24058 }
24059 run_test 398n "test append with parallel DIO"
24060
24061 test_fake_rw() {
24062         local read_write=$1
24063         if [ "$read_write" = "write" ]; then
24064                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24065         elif [ "$read_write" = "read" ]; then
24066                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24067         else
24068                 error "argument error"
24069         fi
24070
24071         # turn off debug for performance testing
24072         local saved_debug=$($LCTL get_param -n debug)
24073         $LCTL set_param debug=0
24074
24075         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24076
24077         # get ost1 size - $FSNAME-OST0000
24078         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24079         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24080         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24081
24082         if [ "$read_write" = "read" ]; then
24083                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24084         fi
24085
24086         local start_time=$(date +%s.%N)
24087         $dd_cmd bs=1M count=$blocks oflag=sync ||
24088                 error "real dd $read_write error"
24089         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24090
24091         if [ "$read_write" = "write" ]; then
24092                 rm -f $DIR/$tfile
24093         fi
24094
24095         # define OBD_FAIL_OST_FAKE_RW           0x238
24096         do_facet ost1 $LCTL set_param fail_loc=0x238
24097
24098         local start_time=$(date +%s.%N)
24099         $dd_cmd bs=1M count=$blocks oflag=sync ||
24100                 error "fake dd $read_write error"
24101         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24102
24103         if [ "$read_write" = "write" ]; then
24104                 # verify file size
24105                 cancel_lru_locks osc
24106                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24107                         error "$tfile size not $blocks MB"
24108         fi
24109         do_facet ost1 $LCTL set_param fail_loc=0
24110
24111         echo "fake $read_write $duration_fake vs. normal $read_write" \
24112                 "$duration in seconds"
24113         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24114                 error_not_in_vm "fake write is slower"
24115
24116         $LCTL set_param -n debug="$saved_debug"
24117         rm -f $DIR/$tfile
24118 }
24119 test_399a() { # LU-7655 for OST fake write
24120         remote_ost_nodsh && skip "remote OST with nodsh"
24121
24122         test_fake_rw write
24123 }
24124 run_test 399a "fake write should not be slower than normal write"
24125
24126 test_399b() { # LU-8726 for OST fake read
24127         remote_ost_nodsh && skip "remote OST with nodsh"
24128         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24129                 skip_env "ldiskfs only test"
24130         fi
24131
24132         test_fake_rw read
24133 }
24134 run_test 399b "fake read should not be slower than normal read"
24135
24136 test_400a() { # LU-1606, was conf-sanity test_74
24137         if ! which $CC > /dev/null 2>&1; then
24138                 skip_env "$CC is not installed"
24139         fi
24140
24141         local extra_flags=''
24142         local out=$TMP/$tfile
24143         local prefix=/usr/include/lustre
24144         local prog
24145
24146         # Oleg removes c files in his test rig so test if any c files exist
24147         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24148                 skip_env "Needed c test files are missing"
24149
24150         if ! [[ -d $prefix ]]; then
24151                 # Assume we're running in tree and fixup the include path.
24152                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24153                 extra_flags+=" -L$LUSTRE/utils/.lib"
24154         fi
24155
24156         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24157                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24158                         error "client api broken"
24159         done
24160         rm -f $out
24161 }
24162 run_test 400a "Lustre client api program can compile and link"
24163
24164 test_400b() { # LU-1606, LU-5011
24165         local header
24166         local out=$TMP/$tfile
24167         local prefix=/usr/include/linux/lustre
24168
24169         # We use a hard coded prefix so that this test will not fail
24170         # when run in tree. There are headers in lustre/include/lustre/
24171         # that are not packaged (like lustre_idl.h) and have more
24172         # complicated include dependencies (like config.h and lnet/types.h).
24173         # Since this test about correct packaging we just skip them when
24174         # they don't exist (see below) rather than try to fixup cppflags.
24175
24176         if ! which $CC > /dev/null 2>&1; then
24177                 skip_env "$CC is not installed"
24178         fi
24179
24180         for header in $prefix/*.h; do
24181                 if ! [[ -f "$header" ]]; then
24182                         continue
24183                 fi
24184
24185                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24186                         continue # lustre_ioctl.h is internal header
24187                 fi
24188
24189                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24190                         error "cannot compile '$header'"
24191         done
24192         rm -f $out
24193 }
24194 run_test 400b "packaged headers can be compiled"
24195
24196 test_401a() { #LU-7437
24197         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24198         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24199
24200         #count the number of parameters by "list_param -R"
24201         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24202         #count the number of parameters by listing proc files
24203         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24204         echo "proc_dirs='$proc_dirs'"
24205         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24206         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24207                       sort -u | wc -l)
24208
24209         [ $params -eq $procs ] ||
24210                 error "found $params parameters vs. $procs proc files"
24211
24212         # test the list_param -D option only returns directories
24213         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24214         #count the number of parameters by listing proc directories
24215         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24216                 sort -u | wc -l)
24217
24218         [ $params -eq $procs ] ||
24219                 error "found $params parameters vs. $procs proc files"
24220 }
24221 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24222
24223 test_401b() {
24224         # jobid_var may not allow arbitrary values, so use jobid_name
24225         # if available
24226         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24227                 local testname=jobid_name tmp='testing%p'
24228         else
24229                 local testname=jobid_var tmp=testing
24230         fi
24231
24232         local save=$($LCTL get_param -n $testname)
24233
24234         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24235                 error "no error returned when setting bad parameters"
24236
24237         local jobid_new=$($LCTL get_param -n foe $testname baz)
24238         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24239
24240         $LCTL set_param -n fog=bam $testname=$save bat=fog
24241         local jobid_old=$($LCTL get_param -n foe $testname bag)
24242         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24243 }
24244 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24245
24246 test_401c() {
24247         # jobid_var may not allow arbitrary values, so use jobid_name
24248         # if available
24249         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24250                 local testname=jobid_name
24251         else
24252                 local testname=jobid_var
24253         fi
24254
24255         local jobid_var_old=$($LCTL get_param -n $testname)
24256         local jobid_var_new
24257
24258         $LCTL set_param $testname= &&
24259                 error "no error returned for 'set_param a='"
24260
24261         jobid_var_new=$($LCTL get_param -n $testname)
24262         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24263                 error "$testname was changed by setting without value"
24264
24265         $LCTL set_param $testname &&
24266                 error "no error returned for 'set_param a'"
24267
24268         jobid_var_new=$($LCTL get_param -n $testname)
24269         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24270                 error "$testname was changed by setting without value"
24271 }
24272 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24273
24274 test_401d() {
24275         # jobid_var may not allow arbitrary values, so use jobid_name
24276         # if available
24277         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24278                 local testname=jobid_name new_value='foo=bar%p'
24279         else
24280                 local testname=jobid_var new_valuie=foo=bar
24281         fi
24282
24283         local jobid_var_old=$($LCTL get_param -n $testname)
24284         local jobid_var_new
24285
24286         $LCTL set_param $testname=$new_value ||
24287                 error "'set_param a=b' did not accept a value containing '='"
24288
24289         jobid_var_new=$($LCTL get_param -n $testname)
24290         [[ "$jobid_var_new" == "$new_value" ]] ||
24291                 error "'set_param a=b' failed on a value containing '='"
24292
24293         # Reset the $testname to test the other format
24294         $LCTL set_param $testname=$jobid_var_old
24295         jobid_var_new=$($LCTL get_param -n $testname)
24296         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24297                 error "failed to reset $testname"
24298
24299         $LCTL set_param $testname $new_value ||
24300                 error "'set_param a b' did not accept a value containing '='"
24301
24302         jobid_var_new=$($LCTL get_param -n $testname)
24303         [[ "$jobid_var_new" == "$new_value" ]] ||
24304                 error "'set_param a b' failed on a value containing '='"
24305
24306         $LCTL set_param $testname $jobid_var_old
24307         jobid_var_new=$($LCTL get_param -n $testname)
24308         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24309                 error "failed to reset $testname"
24310 }
24311 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24312
24313 test_401e() { # LU-14779
24314         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24315                 error "lctl list_param MGC* failed"
24316         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24317         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24318                 error "lctl get_param lru_size failed"
24319 }
24320 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24321
24322 test_402() {
24323         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24324         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24325                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24326         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24327                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24328                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24329         remote_mds_nodsh && skip "remote MDS with nodsh"
24330
24331         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24332 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24333         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24334         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24335                 echo "Touch failed - OK"
24336 }
24337 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24338
24339 test_403() {
24340         local file1=$DIR/$tfile.1
24341         local file2=$DIR/$tfile.2
24342         local tfile=$TMP/$tfile
24343
24344         rm -f $file1 $file2 $tfile
24345
24346         touch $file1
24347         ln $file1 $file2
24348
24349         # 30 sec OBD_TIMEOUT in ll_getattr()
24350         # right before populating st_nlink
24351         $LCTL set_param fail_loc=0x80001409
24352         stat -c %h $file1 > $tfile &
24353
24354         # create an alias, drop all locks and reclaim the dentry
24355         < $file2
24356         cancel_lru_locks mdc
24357         cancel_lru_locks osc
24358         sysctl -w vm.drop_caches=2
24359
24360         wait
24361
24362         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24363
24364         rm -f $tfile $file1 $file2
24365 }
24366 run_test 403 "i_nlink should not drop to zero due to aliasing"
24367
24368 test_404() { # LU-6601
24369         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24370                 skip "Need server version newer than 2.8.52"
24371         remote_mds_nodsh && skip "remote MDS with nodsh"
24372
24373         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24374                 awk '/osp .*-osc-MDT/ { print $4}')
24375
24376         local osp
24377         for osp in $mosps; do
24378                 echo "Deactivate: " $osp
24379                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24380                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24381                         awk -vp=$osp '$4 == p { print $2 }')
24382                 [ $stat = IN ] || {
24383                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24384                         error "deactivate error"
24385                 }
24386                 echo "Activate: " $osp
24387                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24388                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24389                         awk -vp=$osp '$4 == p { print $2 }')
24390                 [ $stat = UP ] || {
24391                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24392                         error "activate error"
24393                 }
24394         done
24395 }
24396 run_test 404 "validate manual {de}activated works properly for OSPs"
24397
24398 test_405() {
24399         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24400         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24401                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24402                         skip "Layout swap lock is not supported"
24403
24404         check_swap_layouts_support
24405         check_swap_layout_no_dom $DIR
24406
24407         test_mkdir $DIR/$tdir
24408         swap_lock_test -d $DIR/$tdir ||
24409                 error "One layout swap locked test failed"
24410 }
24411 run_test 405 "Various layout swap lock tests"
24412
24413 test_406() {
24414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24415         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24416         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24418         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24419                 skip "Need MDS version at least 2.8.50"
24420
24421         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24422         local test_pool=$TESTNAME
24423
24424         pool_add $test_pool || error "pool_add failed"
24425         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24426                 error "pool_add_targets failed"
24427
24428         save_layout_restore_at_exit $MOUNT
24429
24430         # parent set default stripe count only, child will stripe from both
24431         # parent and fs default
24432         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24433                 error "setstripe $MOUNT failed"
24434         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24435         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24436         for i in $(seq 10); do
24437                 local f=$DIR/$tdir/$tfile.$i
24438                 touch $f || error "touch failed"
24439                 local count=$($LFS getstripe -c $f)
24440                 [ $count -eq $OSTCOUNT ] ||
24441                         error "$f stripe count $count != $OSTCOUNT"
24442                 local offset=$($LFS getstripe -i $f)
24443                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24444                 local size=$($LFS getstripe -S $f)
24445                 [ $size -eq $((def_stripe_size * 2)) ] ||
24446                         error "$f stripe size $size != $((def_stripe_size * 2))"
24447                 local pool=$($LFS getstripe -p $f)
24448                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24449         done
24450
24451         # change fs default striping, delete parent default striping, now child
24452         # will stripe from new fs default striping only
24453         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24454                 error "change $MOUNT default stripe failed"
24455         $LFS setstripe -c 0 $DIR/$tdir ||
24456                 error "delete $tdir default stripe failed"
24457         for i in $(seq 11 20); do
24458                 local f=$DIR/$tdir/$tfile.$i
24459                 touch $f || error "touch $f failed"
24460                 local count=$($LFS getstripe -c $f)
24461                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24462                 local offset=$($LFS getstripe -i $f)
24463                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24464                 local size=$($LFS getstripe -S $f)
24465                 [ $size -eq $def_stripe_size ] ||
24466                         error "$f stripe size $size != $def_stripe_size"
24467                 local pool=$($LFS getstripe -p $f)
24468                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24469         done
24470
24471         unlinkmany $DIR/$tdir/$tfile. 1 20
24472
24473         local f=$DIR/$tdir/$tfile
24474         pool_remove_all_targets $test_pool $f
24475         pool_remove $test_pool $f
24476 }
24477 run_test 406 "DNE support fs default striping"
24478
24479 test_407() {
24480         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24481         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24482                 skip "Need MDS version at least 2.8.55"
24483         remote_mds_nodsh && skip "remote MDS with nodsh"
24484
24485         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24486                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24487         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24488                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24489         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24490
24491         #define OBD_FAIL_DT_TXN_STOP    0x2019
24492         for idx in $(seq $MDSCOUNT); do
24493                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24494         done
24495         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24496         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24497                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24498         true
24499 }
24500 run_test 407 "transaction fail should cause operation fail"
24501
24502 test_408() {
24503         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24504
24505         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24506         lctl set_param fail_loc=0x8000040a
24507         # let ll_prepare_partial_page() fail
24508         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24509
24510         rm -f $DIR/$tfile
24511
24512         # create at least 100 unused inodes so that
24513         # shrink_icache_memory(0) should not return 0
24514         touch $DIR/$tfile-{0..100}
24515         rm -f $DIR/$tfile-{0..100}
24516         sync
24517
24518         echo 2 > /proc/sys/vm/drop_caches
24519 }
24520 run_test 408 "drop_caches should not hang due to page leaks"
24521
24522 test_409()
24523 {
24524         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24525
24526         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24527         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24528         touch $DIR/$tdir/guard || error "(2) Fail to create"
24529
24530         local PREFIX=$(str_repeat 'A' 128)
24531         echo "Create 1K hard links start at $(date)"
24532         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24533                 error "(3) Fail to hard link"
24534
24535         echo "Links count should be right although linkEA overflow"
24536         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24537         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24538         [ $linkcount -eq 1001 ] ||
24539                 error "(5) Unexpected hard links count: $linkcount"
24540
24541         echo "List all links start at $(date)"
24542         ls -l $DIR/$tdir/foo > /dev/null ||
24543                 error "(6) Fail to list $DIR/$tdir/foo"
24544
24545         echo "Unlink hard links start at $(date)"
24546         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24547                 error "(7) Fail to unlink"
24548         echo "Unlink hard links finished at $(date)"
24549 }
24550 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24551
24552 test_410()
24553 {
24554         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24555                 skip "Need client version at least 2.9.59"
24556         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24557                 skip "Need MODULES build"
24558
24559         # Create a file, and stat it from the kernel
24560         local testfile=$DIR/$tfile
24561         touch $testfile
24562
24563         local run_id=$RANDOM
24564         local my_ino=$(stat --format "%i" $testfile)
24565
24566         # Try to insert the module. This will always fail as the
24567         # module is designed to not be inserted.
24568         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24569             &> /dev/null
24570
24571         # Anything but success is a test failure
24572         dmesg | grep -q \
24573             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24574             error "no inode match"
24575 }
24576 run_test 410 "Test inode number returned from kernel thread"
24577
24578 cleanup_test411_cgroup() {
24579         trap 0
24580         rmdir "$1"
24581 }
24582
24583 test_411() {
24584         local cg_basedir=/sys/fs/cgroup/memory
24585         # LU-9966
24586         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24587                 skip "no setup for cgroup"
24588
24589         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24590                 error "test file creation failed"
24591         cancel_lru_locks osc
24592
24593         # Create a very small memory cgroup to force a slab allocation error
24594         local cgdir=$cg_basedir/osc_slab_alloc
24595         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24596         trap "cleanup_test411_cgroup $cgdir" EXIT
24597         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24598         echo 1M > $cgdir/memory.limit_in_bytes
24599
24600         # Should not LBUG, just be killed by oom-killer
24601         # dd will return 0 even allocation failure in some environment.
24602         # So don't check return value
24603         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24604         cleanup_test411_cgroup $cgdir
24605
24606         return 0
24607 }
24608 run_test 411 "Slab allocation error with cgroup does not LBUG"
24609
24610 test_412() {
24611         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24612         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24613                 skip "Need server version at least 2.10.55"
24614         fi
24615
24616         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24617                 error "mkdir failed"
24618         $LFS getdirstripe $DIR/$tdir
24619         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24620         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24621                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24622         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24623         [ $stripe_count -eq 2 ] ||
24624                 error "expect 2 get $stripe_count"
24625 }
24626 run_test 412 "mkdir on specific MDTs"
24627
24628 generate_uneven_mdts() {
24629         local threshold=$1
24630         local ffree
24631         local bavail
24632         local max
24633         local min
24634         local max_index
24635         local min_index
24636         local tmp
24637         local i
24638
24639         echo
24640         echo "Check for uneven MDTs: "
24641
24642         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24643         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24644         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24645
24646         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24647         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24648         max_index=0
24649         min_index=0
24650         for ((i = 1; i < ${#ffree[@]}; i++)); do
24651                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24652                 if [ $tmp -gt $max ]; then
24653                         max=$tmp
24654                         max_index=$i
24655                 fi
24656                 if [ $tmp -lt $min ]; then
24657                         min=$tmp
24658                         min_index=$i
24659                 fi
24660         done
24661
24662         # Check if we need to generate uneven MDTs
24663         local diff=$(((max - min) * 100 / min))
24664         local testdir=$DIR/$tdir-fillmdt
24665
24666         mkdir -p $testdir
24667
24668         i=0
24669         while (( diff < threshold )); do
24670                 # generate uneven MDTs, create till $threshold% diff
24671                 echo -n "weight diff=$diff% must be > $threshold% ..."
24672                 echo "Fill MDT$min_index with 100 files: loop $i"
24673                 testdir=$DIR/$tdir-fillmdt/$i
24674                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24675                         error "mkdir $testdir failed"
24676                 $LFS setstripe -E 1M -L mdt $testdir ||
24677                         error "setstripe $testdir failed"
24678                 for F in f.{0..99}; do
24679                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24680                                 /dev/null 2>&1 || error "dd $F failed"
24681                 done
24682
24683                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24684                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24685                 max=$(((${ffree[max_index]} >> 8) * \
24686                         (${bavail[max_index]} * bsize >> 16)))
24687                 min=$(((${ffree[min_index]} >> 8) * \
24688                         (${bavail[min_index]} * bsize >> 16)))
24689                 diff=$(((max - min) * 100 / min))
24690                 i=$((i + 1))
24691         done
24692
24693         echo "MDT filesfree available: ${ffree[@]}"
24694         echo "MDT blocks available: ${bavail[@]}"
24695         echo "weight diff=$diff%"
24696 }
24697
24698 test_qos_mkdir() {
24699         local mkdir_cmd=$1
24700         local stripe_count=$2
24701         local mdts=$(comma_list $(mdts_nodes))
24702
24703         local testdir
24704         local lmv_qos_prio_free
24705         local lmv_qos_threshold_rr
24706         local lmv_qos_maxage
24707         local lod_qos_prio_free
24708         local lod_qos_threshold_rr
24709         local lod_qos_maxage
24710         local count
24711         local i
24712
24713         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24714         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24715         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24716                 head -n1)
24717         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24718         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24719         stack_trap "$LCTL set_param \
24720                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24721         stack_trap "$LCTL set_param \
24722                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24723         stack_trap "$LCTL set_param \
24724                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24725
24726         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24727                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24728         lod_qos_prio_free=${lod_qos_prio_free%%%}
24729         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24730                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24731         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24732         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24733                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24734         stack_trap "do_nodes $mdts $LCTL set_param \
24735                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24736         stack_trap "do_nodes $mdts $LCTL set_param \
24737                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24738         stack_trap "do_nodes $mdts $LCTL set_param \
24739                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24740
24741         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24742         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24743
24744         testdir=$DIR/$tdir-s$stripe_count/rr
24745
24746         local stripe_index=$($LFS getstripe -m $testdir)
24747         local test_mkdir_rr=true
24748
24749         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24750         getfattr -d -m dmv -e hex $testdir | grep dmv
24751         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24752                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24753                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24754                         test_mkdir_rr=false
24755         fi
24756
24757         echo
24758         $test_mkdir_rr &&
24759                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24760                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24761
24762         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24763         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24764                 eval $mkdir_cmd $testdir/subdir$i ||
24765                         error "$mkdir_cmd subdir$i failed"
24766         done
24767
24768         for (( i = 0; i < $MDSCOUNT; i++ )); do
24769                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24770                 echo "$count directories created on MDT$i"
24771                 if $test_mkdir_rr; then
24772                         (( $count == 100 )) ||
24773                                 error "subdirs are not evenly distributed"
24774                 elif (( $i == $stripe_index )); then
24775                         (( $count == 100 * MDSCOUNT )) ||
24776                                 error "$count subdirs created on MDT$i"
24777                 else
24778                         (( $count == 0 )) ||
24779                                 error "$count subdirs created on MDT$i"
24780                 fi
24781
24782                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24783                         count=$($LFS getdirstripe $testdir/* |
24784                                 grep -c -P "^\s+$i\t")
24785                         echo "$count stripes created on MDT$i"
24786                         # deviation should < 5% of average
24787                         (( $count >= 95 * stripe_count &&
24788                            $count <= 105 * stripe_count)) ||
24789                                 error "stripes are not evenly distributed"
24790                 fi
24791         done
24792
24793         echo
24794         echo "Check for uneven MDTs: "
24795
24796         local ffree
24797         local bavail
24798         local max
24799         local min
24800         local max_index
24801         local min_index
24802         local tmp
24803
24804         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24805         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24806         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24807
24808         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24809         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24810         max_index=0
24811         min_index=0
24812         for ((i = 1; i < ${#ffree[@]}; i++)); do
24813                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24814                 if [ $tmp -gt $max ]; then
24815                         max=$tmp
24816                         max_index=$i
24817                 fi
24818                 if [ $tmp -lt $min ]; then
24819                         min=$tmp
24820                         min_index=$i
24821                 fi
24822         done
24823
24824         (( ${ffree[min_index]} > 0 )) ||
24825                 skip "no free files in MDT$min_index"
24826         (( ${ffree[min_index]} < 100000000 )) ||
24827                 skip "too many free files in MDT$min_index"
24828
24829         echo "MDT filesfree available: ${ffree[@]}"
24830         echo "MDT blocks available: ${bavail[@]}"
24831         echo "weight diff=$(((max - min) * 100 / min))%"
24832         echo
24833         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24834
24835         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24836         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24837         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24838         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24839         # decrease statfs age, so that it can be updated in time
24840         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24841         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24842
24843         sleep 1
24844
24845         testdir=$DIR/$tdir-s$stripe_count/qos
24846         local num=200
24847
24848         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24849         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24850                 eval $mkdir_cmd $testdir/subdir$i ||
24851                         error "$mkdir_cmd subdir$i failed"
24852         done
24853
24854         for (( i = 0; i < $MDSCOUNT; i++ )); do
24855                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24856                 echo "$count directories created on MDT$i"
24857
24858                 if [ $stripe_count -gt 1 ]; then
24859                         count=$($LFS getdirstripe $testdir/* |
24860                                 grep -c -P "^\s+$i\t")
24861                         echo "$count stripes created on MDT$i"
24862                 fi
24863         done
24864
24865         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24866         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24867
24868         # D-value should > 10% of averge
24869         (( max - min >= num / 10 )) ||
24870                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24871
24872         # 5% for stripes
24873         if (( stripe_count > 1 )); then
24874                 max=$($LFS getdirstripe $testdir/* |
24875                       grep -c -P "^\s+$max_index\t")
24876                 min=$($LFS getdirstripe $testdir/* |
24877                         grep -c -P "^\s+$min_index\t")
24878                 (( max - min >= num * stripe_count / 20 )) ||
24879                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24880         fi
24881 }
24882
24883 most_full_mdt() {
24884         local ffree
24885         local bavail
24886         local bsize
24887         local min
24888         local min_index
24889         local tmp
24890
24891         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24892         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24893         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24894
24895         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24896         min_index=0
24897         for ((i = 1; i < ${#ffree[@]}; i++)); do
24898                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24899                 (( tmp < min )) && min=$tmp && min_index=$i
24900         done
24901
24902         echo -n $min_index
24903 }
24904
24905 test_413a() {
24906         [ $MDSCOUNT -lt 2 ] &&
24907                 skip "We need at least 2 MDTs for this test"
24908
24909         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24910                 skip "Need server version at least 2.12.52"
24911
24912         local stripe_count
24913
24914         generate_uneven_mdts 100
24915         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24916                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24917                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24918                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
24919                         error "mkdir failed"
24920                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
24921         done
24922 }
24923 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24924
24925 test_413b() {
24926         [ $MDSCOUNT -lt 2 ] &&
24927                 skip "We need at least 2 MDTs for this test"
24928
24929         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24930                 skip "Need server version at least 2.12.52"
24931
24932         local testdir
24933         local stripe_count
24934
24935         generate_uneven_mdts 100
24936         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24937                 testdir=$DIR/$tdir-s$stripe_count
24938                 mkdir $testdir || error "mkdir $testdir failed"
24939                 mkdir $testdir/rr || error "mkdir rr failed"
24940                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
24941                         error "mkdir qos failed"
24942                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24943                         $testdir/rr || error "setdirstripe rr failed"
24944                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24945                         error "setdirstripe failed"
24946                 test_qos_mkdir "mkdir" $stripe_count
24947         done
24948 }
24949 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24950
24951 test_413c() {
24952         (( $MDSCOUNT >= 2 )) ||
24953                 skip "We need at least 2 MDTs for this test"
24954
24955         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
24956                 skip "Need server version at least 2.14.51"
24957
24958         local testdir
24959         local inherit
24960         local inherit_rr
24961
24962         testdir=$DIR/${tdir}-s1
24963         mkdir $testdir || error "mkdir $testdir failed"
24964         mkdir $testdir/rr || error "mkdir rr failed"
24965         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
24966         # default max_inherit is -1, default max_inherit_rr is 0
24967         $LFS setdirstripe -D -c 1 $testdir/rr ||
24968                 error "setdirstripe rr failed"
24969         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24970                 error "setdirstripe qos failed"
24971         test_qos_mkdir "mkdir" 1
24972
24973         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24974         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24975         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24976         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24977         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
24978
24979         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24980         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24981         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24982         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24983         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
24984         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24985         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
24986                 error "level2 shouldn't have default LMV" || true
24987 }
24988 run_test 413c "mkdir with default LMV max inherit rr"
24989
24990 test_413d() {
24991         (( MDSCOUNT >= 2 )) ||
24992                 skip "We need at least 2 MDTs for this test"
24993
24994         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
24995                 skip "Need server version at least 2.14.51"
24996
24997         local lmv_qos_threshold_rr
24998
24999         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25000                 head -n1)
25001         stack_trap "$LCTL set_param \
25002                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25003
25004         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25005         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25006         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25007                 error "$tdir shouldn't have default LMV"
25008         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25009                 error "mkdir sub failed"
25010
25011         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25012
25013         (( count == 100 )) || error "$count subdirs on MDT0"
25014 }
25015 run_test 413d "inherit ROOT default LMV"
25016
25017 test_413z() {
25018         local pids=""
25019         local subdir
25020         local pid
25021
25022         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25023                 unlinkmany $subdir/f. 100 &
25024                 pids="$pids $!"
25025         done
25026
25027         for pid in $pids; do
25028                 wait $pid
25029         done
25030 }
25031 run_test 413z "413 test cleanup"
25032
25033 test_414() {
25034 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25035         $LCTL set_param fail_loc=0x80000521
25036         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25037         rm -f $DIR/$tfile
25038 }
25039 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25040
25041 test_415() {
25042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25043         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25044                 skip "Need server version at least 2.11.52"
25045
25046         # LU-11102
25047         local total
25048         local setattr_pid
25049         local start_time
25050         local end_time
25051         local duration
25052
25053         total=500
25054         # this test may be slow on ZFS
25055         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25056
25057         # though this test is designed for striped directory, let's test normal
25058         # directory too since lock is always saved as CoS lock.
25059         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25060         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25061
25062         (
25063                 while true; do
25064                         touch $DIR/$tdir
25065                 done
25066         ) &
25067         setattr_pid=$!
25068
25069         start_time=$(date +%s)
25070         for i in $(seq $total); do
25071                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25072                         > /dev/null
25073         done
25074         end_time=$(date +%s)
25075         duration=$((end_time - start_time))
25076
25077         kill -9 $setattr_pid
25078
25079         echo "rename $total files took $duration sec"
25080         [ $duration -lt 100 ] || error "rename took $duration sec"
25081 }
25082 run_test 415 "lock revoke is not missing"
25083
25084 test_416() {
25085         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25086                 skip "Need server version at least 2.11.55"
25087
25088         # define OBD_FAIL_OSD_TXN_START    0x19a
25089         do_facet mds1 lctl set_param fail_loc=0x19a
25090
25091         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25092
25093         true
25094 }
25095 run_test 416 "transaction start failure won't cause system hung"
25096
25097 cleanup_417() {
25098         trap 0
25099         do_nodes $(comma_list $(mdts_nodes)) \
25100                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25101         do_nodes $(comma_list $(mdts_nodes)) \
25102                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25103         do_nodes $(comma_list $(mdts_nodes)) \
25104                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25105 }
25106
25107 test_417() {
25108         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25109         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25110                 skip "Need MDS version at least 2.11.56"
25111
25112         trap cleanup_417 RETURN EXIT
25113
25114         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25115         do_nodes $(comma_list $(mdts_nodes)) \
25116                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25117         $LFS migrate -m 0 $DIR/$tdir.1 &&
25118                 error "migrate dir $tdir.1 should fail"
25119
25120         do_nodes $(comma_list $(mdts_nodes)) \
25121                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25122         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25123                 error "create remote dir $tdir.2 should fail"
25124
25125         do_nodes $(comma_list $(mdts_nodes)) \
25126                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25127         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25128                 error "create striped dir $tdir.3 should fail"
25129         true
25130 }
25131 run_test 417 "disable remote dir, striped dir and dir migration"
25132
25133 # Checks that the outputs of df [-i] and lfs df [-i] match
25134 #
25135 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25136 check_lfs_df() {
25137         local dir=$2
25138         local inodes
25139         local df_out
25140         local lfs_df_out
25141         local count
25142         local passed=false
25143
25144         # blocks or inodes
25145         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25146
25147         for count in {1..100}; do
25148                 do_rpc_nodes "$CLIENTS" cancel_lru_locks
25149                 sync; sleep 0.2
25150
25151                 # read the lines of interest
25152                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25153                         error "df $inodes $dir | tail -n +2 failed"
25154                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25155                         error "lfs df $inodes $dir | grep summary: failed"
25156
25157                 # skip first substrings of each output as they are different
25158                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25159                 # compare the two outputs
25160                 passed=true
25161                 for i in {1..5}; do
25162                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25163                 done
25164                 $passed && break
25165         done
25166
25167         if ! $passed; then
25168                 df -P $inodes $dir
25169                 echo
25170                 lfs df $inodes $dir
25171                 error "df and lfs df $1 output mismatch: "      \
25172                       "df ${inodes}: ${df_out[*]}, "            \
25173                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25174         fi
25175 }
25176
25177 test_418() {
25178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25179
25180         local dir=$DIR/$tdir
25181         local numfiles=$((RANDOM % 4096 + 2))
25182         local numblocks=$((RANDOM % 256 + 1))
25183
25184         wait_delete_completed
25185         test_mkdir $dir
25186
25187         # check block output
25188         check_lfs_df blocks $dir
25189         # check inode output
25190         check_lfs_df inodes $dir
25191
25192         # create a single file and retest
25193         echo "Creating a single file and testing"
25194         createmany -o $dir/$tfile- 1 &>/dev/null ||
25195                 error "creating 1 file in $dir failed"
25196         check_lfs_df blocks $dir
25197         check_lfs_df inodes $dir
25198
25199         # create a random number of files
25200         echo "Creating $((numfiles - 1)) files and testing"
25201         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25202                 error "creating $((numfiles - 1)) files in $dir failed"
25203
25204         # write a random number of blocks to the first test file
25205         echo "Writing $numblocks 4K blocks and testing"
25206         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25207                 count=$numblocks &>/dev/null ||
25208                 error "dd to $dir/${tfile}-0 failed"
25209
25210         # retest
25211         check_lfs_df blocks $dir
25212         check_lfs_df inodes $dir
25213
25214         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25215                 error "unlinking $numfiles files in $dir failed"
25216 }
25217 run_test 418 "df and lfs df outputs match"
25218
25219 test_419()
25220 {
25221         local dir=$DIR/$tdir
25222
25223         mkdir -p $dir
25224         touch $dir/file
25225
25226         cancel_lru_locks mdc
25227
25228         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25229         $LCTL set_param fail_loc=0x1410
25230         cat $dir/file
25231         $LCTL set_param fail_loc=0
25232         rm -rf $dir
25233 }
25234 run_test 419 "Verify open file by name doesn't crash kernel"
25235
25236 test_420()
25237 {
25238         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25239                 skip "Need MDS version at least 2.12.53"
25240
25241         local SAVE_UMASK=$(umask)
25242         local dir=$DIR/$tdir
25243         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25244
25245         mkdir -p $dir
25246         umask 0000
25247         mkdir -m03777 $dir/testdir
25248         ls -dn $dir/testdir
25249         # Need to remove trailing '.' when SELinux is enabled
25250         local dirperms=$(ls -dn $dir/testdir |
25251                          awk '{ sub(/\.$/, "", $1); print $1}')
25252         [ $dirperms == "drwxrwsrwt" ] ||
25253                 error "incorrect perms on $dir/testdir"
25254
25255         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25256                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25257         ls -n $dir/testdir/testfile
25258         local fileperms=$(ls -n $dir/testdir/testfile |
25259                           awk '{ sub(/\.$/, "", $1); print $1}')
25260         [ $fileperms == "-rwxr-xr-x" ] ||
25261                 error "incorrect perms on $dir/testdir/testfile"
25262
25263         umask $SAVE_UMASK
25264 }
25265 run_test 420 "clear SGID bit on non-directories for non-members"
25266
25267 test_421a() {
25268         local cnt
25269         local fid1
25270         local fid2
25271
25272         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25273                 skip "Need MDS version at least 2.12.54"
25274
25275         test_mkdir $DIR/$tdir
25276         createmany -o $DIR/$tdir/f 3
25277         cnt=$(ls -1 $DIR/$tdir | wc -l)
25278         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25279
25280         fid1=$(lfs path2fid $DIR/$tdir/f1)
25281         fid2=$(lfs path2fid $DIR/$tdir/f2)
25282         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25283
25284         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25285         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25286
25287         cnt=$(ls -1 $DIR/$tdir | wc -l)
25288         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25289
25290         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25291         createmany -o $DIR/$tdir/f 3
25292         cnt=$(ls -1 $DIR/$tdir | wc -l)
25293         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25294
25295         fid1=$(lfs path2fid $DIR/$tdir/f1)
25296         fid2=$(lfs path2fid $DIR/$tdir/f2)
25297         echo "remove using fsname $FSNAME"
25298         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25299
25300         cnt=$(ls -1 $DIR/$tdir | wc -l)
25301         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25302 }
25303 run_test 421a "simple rm by fid"
25304
25305 test_421b() {
25306         local cnt
25307         local FID1
25308         local FID2
25309
25310         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25311                 skip "Need MDS version at least 2.12.54"
25312
25313         test_mkdir $DIR/$tdir
25314         createmany -o $DIR/$tdir/f 3
25315         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25316         MULTIPID=$!
25317
25318         FID1=$(lfs path2fid $DIR/$tdir/f1)
25319         FID2=$(lfs path2fid $DIR/$tdir/f2)
25320         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25321
25322         kill -USR1 $MULTIPID
25323         wait
25324
25325         cnt=$(ls $DIR/$tdir | wc -l)
25326         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25327 }
25328 run_test 421b "rm by fid on open file"
25329
25330 test_421c() {
25331         local cnt
25332         local FIDS
25333
25334         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25335                 skip "Need MDS version at least 2.12.54"
25336
25337         test_mkdir $DIR/$tdir
25338         createmany -o $DIR/$tdir/f 3
25339         touch $DIR/$tdir/$tfile
25340         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25341         cnt=$(ls -1 $DIR/$tdir | wc -l)
25342         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25343
25344         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25345         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25346
25347         cnt=$(ls $DIR/$tdir | wc -l)
25348         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25349 }
25350 run_test 421c "rm by fid against hardlinked files"
25351
25352 test_421d() {
25353         local cnt
25354         local FIDS
25355
25356         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25357                 skip "Need MDS version at least 2.12.54"
25358
25359         test_mkdir $DIR/$tdir
25360         createmany -o $DIR/$tdir/f 4097
25361         cnt=$(ls -1 $DIR/$tdir | wc -l)
25362         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25363
25364         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25365         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25366
25367         cnt=$(ls $DIR/$tdir | wc -l)
25368         rm -rf $DIR/$tdir
25369         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25370 }
25371 run_test 421d "rmfid en masse"
25372
25373 test_421e() {
25374         local cnt
25375         local FID
25376
25377         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25378         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25379                 skip "Need MDS version at least 2.12.54"
25380
25381         mkdir -p $DIR/$tdir
25382         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25383         createmany -o $DIR/$tdir/striped_dir/f 512
25384         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25385         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25386
25387         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25388                 sed "s/[/][^:]*://g")
25389         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25390
25391         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25392         rm -rf $DIR/$tdir
25393         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25394 }
25395 run_test 421e "rmfid in DNE"
25396
25397 test_421f() {
25398         local cnt
25399         local FID
25400
25401         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25402                 skip "Need MDS version at least 2.12.54"
25403
25404         test_mkdir $DIR/$tdir
25405         touch $DIR/$tdir/f
25406         cnt=$(ls -1 $DIR/$tdir | wc -l)
25407         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25408
25409         FID=$(lfs path2fid $DIR/$tdir/f)
25410         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25411         # rmfid should fail
25412         cnt=$(ls -1 $DIR/$tdir | wc -l)
25413         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25414
25415         chmod a+rw $DIR/$tdir
25416         ls -la $DIR/$tdir
25417         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25418         # rmfid should fail
25419         cnt=$(ls -1 $DIR/$tdir | wc -l)
25420         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25421
25422         rm -f $DIR/$tdir/f
25423         $RUNAS touch $DIR/$tdir/f
25424         FID=$(lfs path2fid $DIR/$tdir/f)
25425         echo "rmfid as root"
25426         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25427         cnt=$(ls -1 $DIR/$tdir | wc -l)
25428         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25429
25430         rm -f $DIR/$tdir/f
25431         $RUNAS touch $DIR/$tdir/f
25432         cnt=$(ls -1 $DIR/$tdir | wc -l)
25433         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25434         FID=$(lfs path2fid $DIR/$tdir/f)
25435         # rmfid w/o user_fid2path mount option should fail
25436         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25437         cnt=$(ls -1 $DIR/$tdir | wc -l)
25438         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25439
25440         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25441         stack_trap "rmdir $tmpdir"
25442         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25443                 error "failed to mount client'"
25444         stack_trap "umount_client $tmpdir"
25445
25446         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25447         # rmfid should succeed
25448         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25449         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25450
25451         # rmfid shouldn't allow to remove files due to dir's permission
25452         chmod a+rwx $tmpdir/$tdir
25453         touch $tmpdir/$tdir/f
25454         ls -la $tmpdir/$tdir
25455         FID=$(lfs path2fid $tmpdir/$tdir/f)
25456         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25457         return 0
25458 }
25459 run_test 421f "rmfid checks permissions"
25460
25461 test_421g() {
25462         local cnt
25463         local FIDS
25464
25465         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25466         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25467                 skip "Need MDS version at least 2.12.54"
25468
25469         mkdir -p $DIR/$tdir
25470         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25471         createmany -o $DIR/$tdir/striped_dir/f 512
25472         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25473         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25474
25475         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25476                 sed "s/[/][^:]*://g")
25477
25478         rm -f $DIR/$tdir/striped_dir/f1*
25479         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25480         removed=$((512 - cnt))
25481
25482         # few files have been just removed, so we expect
25483         # rmfid to fail on their fids
25484         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25485         [ $removed != $errors ] && error "$errors != $removed"
25486
25487         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25488         rm -rf $DIR/$tdir
25489         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25490 }
25491 run_test 421g "rmfid to return errors properly"
25492
25493 test_422() {
25494         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25495         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25496         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25497         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25498         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25499
25500         local amc=$(at_max_get client)
25501         local amo=$(at_max_get mds1)
25502         local timeout=`lctl get_param -n timeout`
25503
25504         at_max_set 0 client
25505         at_max_set 0 mds1
25506
25507 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25508         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25509                         fail_val=$(((2*timeout + 10)*1000))
25510         touch $DIR/$tdir/d3/file &
25511         sleep 2
25512 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25513         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25514                         fail_val=$((2*timeout + 5))
25515         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25516         local pid=$!
25517         sleep 1
25518         kill -9 $pid
25519         sleep $((2 * timeout))
25520         echo kill $pid
25521         kill -9 $pid
25522         lctl mark touch
25523         touch $DIR/$tdir/d2/file3
25524         touch $DIR/$tdir/d2/file4
25525         touch $DIR/$tdir/d2/file5
25526
25527         wait
25528         at_max_set $amc client
25529         at_max_set $amo mds1
25530
25531         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25532         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25533                 error "Watchdog is always throttled"
25534 }
25535 run_test 422 "kill a process with RPC in progress"
25536
25537 stat_test() {
25538     df -h $MOUNT &
25539     df -h $MOUNT &
25540     df -h $MOUNT &
25541     df -h $MOUNT &
25542     df -h $MOUNT &
25543     df -h $MOUNT &
25544 }
25545
25546 test_423() {
25547     local _stats
25548     # ensure statfs cache is expired
25549     sleep 2;
25550
25551     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25552     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25553
25554     return 0
25555 }
25556 run_test 423 "statfs should return a right data"
25557
25558 test_424() {
25559 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25560         $LCTL set_param fail_loc=0x80000522
25561         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25562         rm -f $DIR/$tfile
25563 }
25564 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25565
25566 test_425() {
25567         test_mkdir -c -1 $DIR/$tdir
25568         $LFS setstripe -c -1 $DIR/$tdir
25569
25570         lru_resize_disable "" 100
25571         stack_trap "lru_resize_enable" EXIT
25572
25573         sleep 5
25574
25575         for i in $(seq $((MDSCOUNT * 125))); do
25576                 local t=$DIR/$tdir/$tfile_$i
25577
25578                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25579                         error_noexit "Create file $t"
25580         done
25581         stack_trap "rm -rf $DIR/$tdir" EXIT
25582
25583         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25584                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25585                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25586
25587                 [ $lock_count -le $lru_size ] ||
25588                         error "osc lock count $lock_count > lru size $lru_size"
25589         done
25590
25591         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25592                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25593                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25594
25595                 [ $lock_count -le $lru_size ] ||
25596                         error "mdc lock count $lock_count > lru size $lru_size"
25597         done
25598 }
25599 run_test 425 "lock count should not exceed lru size"
25600
25601 test_426() {
25602         splice-test -r $DIR/$tfile
25603         splice-test -rd $DIR/$tfile
25604         splice-test $DIR/$tfile
25605         splice-test -d $DIR/$tfile
25606 }
25607 run_test 426 "splice test on Lustre"
25608
25609 test_427() {
25610         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25611         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25612                 skip "Need MDS version at least 2.12.4"
25613         local log
25614
25615         mkdir $DIR/$tdir
25616         mkdir $DIR/$tdir/1
25617         mkdir $DIR/$tdir/2
25618         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25619         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25620
25621         $LFS getdirstripe $DIR/$tdir/1/dir
25622
25623         #first setfattr for creating updatelog
25624         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25625
25626 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25627         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25628         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25629         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25630
25631         sleep 2
25632         fail mds2
25633         wait_recovery_complete mds2 $((2*TIMEOUT))
25634
25635         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25636         echo $log | grep "get update log failed" &&
25637                 error "update log corruption is detected" || true
25638 }
25639 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25640
25641 test_428() {
25642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25643         local cache_limit=$CACHE_MAX
25644
25645         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25646         $LCTL set_param -n llite.*.max_cached_mb=64
25647
25648         mkdir $DIR/$tdir
25649         $LFS setstripe -c 1 $DIR/$tdir
25650         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25651         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25652         #test write
25653         for f in $(seq 4); do
25654                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25655         done
25656         wait
25657
25658         cancel_lru_locks osc
25659         # Test read
25660         for f in $(seq 4); do
25661                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25662         done
25663         wait
25664 }
25665 run_test 428 "large block size IO should not hang"
25666
25667 test_429() { # LU-7915 / LU-10948
25668         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25669         local testfile=$DIR/$tfile
25670         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25671         local new_flag=1
25672         local first_rpc
25673         local second_rpc
25674         local third_rpc
25675
25676         $LCTL get_param $ll_opencache_threshold_count ||
25677                 skip "client does not have opencache parameter"
25678
25679         set_opencache $new_flag
25680         stack_trap "restore_opencache"
25681         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25682                 error "enable opencache failed"
25683         touch $testfile
25684         # drop MDC DLM locks
25685         cancel_lru_locks mdc
25686         # clear MDC RPC stats counters
25687         $LCTL set_param $mdc_rpcstats=clear
25688
25689         # According to the current implementation, we need to run 3 times
25690         # open & close file to verify if opencache is enabled correctly.
25691         # 1st, RPCs are sent for lookup/open and open handle is released on
25692         #      close finally.
25693         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25694         #      so open handle won't be released thereafter.
25695         # 3rd, No RPC is sent out.
25696         $MULTIOP $testfile oc || error "multiop failed"
25697         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25698         echo "1st: $first_rpc RPCs in flight"
25699
25700         $MULTIOP $testfile oc || error "multiop failed"
25701         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25702         echo "2nd: $second_rpc RPCs in flight"
25703
25704         $MULTIOP $testfile oc || error "multiop failed"
25705         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25706         echo "3rd: $third_rpc RPCs in flight"
25707
25708         #verify no MDC RPC is sent
25709         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25710 }
25711 run_test 429 "verify if opencache flag on client side does work"
25712
25713 lseek_test_430() {
25714         local offset
25715         local file=$1
25716
25717         # data at [200K, 400K)
25718         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25719                 error "256K->512K dd fails"
25720         # data at [2M, 3M)
25721         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25722                 error "2M->3M dd fails"
25723         # data at [4M, 5M)
25724         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25725                 error "4M->5M dd fails"
25726         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25727         # start at first component hole #1
25728         printf "Seeking hole from 1000 ... "
25729         offset=$(lseek_test -l 1000 $file)
25730         echo $offset
25731         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25732         printf "Seeking data from 1000 ... "
25733         offset=$(lseek_test -d 1000 $file)
25734         echo $offset
25735         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25736
25737         # start at first component data block
25738         printf "Seeking hole from 300000 ... "
25739         offset=$(lseek_test -l 300000 $file)
25740         echo $offset
25741         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25742         printf "Seeking data from 300000 ... "
25743         offset=$(lseek_test -d 300000 $file)
25744         echo $offset
25745         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25746
25747         # start at the first component but beyond end of object size
25748         printf "Seeking hole from 1000000 ... "
25749         offset=$(lseek_test -l 1000000 $file)
25750         echo $offset
25751         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25752         printf "Seeking data from 1000000 ... "
25753         offset=$(lseek_test -d 1000000 $file)
25754         echo $offset
25755         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25756
25757         # start at second component stripe 2 (empty file)
25758         printf "Seeking hole from 1500000 ... "
25759         offset=$(lseek_test -l 1500000 $file)
25760         echo $offset
25761         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25762         printf "Seeking data from 1500000 ... "
25763         offset=$(lseek_test -d 1500000 $file)
25764         echo $offset
25765         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25766
25767         # start at second component stripe 1 (all data)
25768         printf "Seeking hole from 3000000 ... "
25769         offset=$(lseek_test -l 3000000 $file)
25770         echo $offset
25771         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25772         printf "Seeking data from 3000000 ... "
25773         offset=$(lseek_test -d 3000000 $file)
25774         echo $offset
25775         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25776
25777         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25778                 error "2nd dd fails"
25779         echo "Add data block at 640K...1280K"
25780
25781         # start at before new data block, in hole
25782         printf "Seeking hole from 600000 ... "
25783         offset=$(lseek_test -l 600000 $file)
25784         echo $offset
25785         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25786         printf "Seeking data from 600000 ... "
25787         offset=$(lseek_test -d 600000 $file)
25788         echo $offset
25789         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25790
25791         # start at the first component new data block
25792         printf "Seeking hole from 1000000 ... "
25793         offset=$(lseek_test -l 1000000 $file)
25794         echo $offset
25795         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25796         printf "Seeking data from 1000000 ... "
25797         offset=$(lseek_test -d 1000000 $file)
25798         echo $offset
25799         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25800
25801         # start at second component stripe 2, new data
25802         printf "Seeking hole from 1200000 ... "
25803         offset=$(lseek_test -l 1200000 $file)
25804         echo $offset
25805         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25806         printf "Seeking data from 1200000 ... "
25807         offset=$(lseek_test -d 1200000 $file)
25808         echo $offset
25809         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25810
25811         # start beyond file end
25812         printf "Using offset > filesize ... "
25813         lseek_test -l 4000000 $file && error "lseek should fail"
25814         printf "Using offset > filesize ... "
25815         lseek_test -d 4000000 $file && error "lseek should fail"
25816
25817         printf "Done\n\n"
25818 }
25819
25820 test_430a() {
25821         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25822                 skip "MDT does not support SEEK_HOLE"
25823
25824         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25825                 skip "OST does not support SEEK_HOLE"
25826
25827         local file=$DIR/$tdir/$tfile
25828
25829         mkdir -p $DIR/$tdir
25830
25831         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25832         # OST stripe #1 will have continuous data at [1M, 3M)
25833         # OST stripe #2 is empty
25834         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25835         lseek_test_430 $file
25836         rm $file
25837         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25838         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25839         lseek_test_430 $file
25840         rm $file
25841         $LFS setstripe -c2 -S 512K $file
25842         echo "Two stripes, stripe size 512K"
25843         lseek_test_430 $file
25844         rm $file
25845         # FLR with stale mirror
25846         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25847                        -N -c2 -S 1M $file
25848         echo "Mirrored file:"
25849         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25850         echo "Plain 2 stripes 1M"
25851         lseek_test_430 $file
25852         rm $file
25853 }
25854 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25855
25856 test_430b() {
25857         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25858                 skip "OST does not support SEEK_HOLE"
25859
25860         local offset
25861         local file=$DIR/$tdir/$tfile
25862
25863         mkdir -p $DIR/$tdir
25864         # Empty layout lseek should fail
25865         $MCREATE $file
25866         # seek from 0
25867         printf "Seeking hole from 0 ... "
25868         lseek_test -l 0 $file && error "lseek should fail"
25869         printf "Seeking data from 0 ... "
25870         lseek_test -d 0 $file && error "lseek should fail"
25871         rm $file
25872
25873         # 1M-hole file
25874         $LFS setstripe -E 1M -c2 -E eof $file
25875         $TRUNCATE $file 1048576
25876         printf "Seeking hole from 1000000 ... "
25877         offset=$(lseek_test -l 1000000 $file)
25878         echo $offset
25879         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25880         printf "Seeking data from 1000000 ... "
25881         lseek_test -d 1000000 $file && error "lseek should fail"
25882         rm $file
25883
25884         # full component followed by non-inited one
25885         $LFS setstripe -E 1M -c2 -E eof $file
25886         dd if=/dev/urandom of=$file bs=1M count=1
25887         printf "Seeking hole from 1000000 ... "
25888         offset=$(lseek_test -l 1000000 $file)
25889         echo $offset
25890         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25891         printf "Seeking hole from 1048576 ... "
25892         lseek_test -l 1048576 $file && error "lseek should fail"
25893         # init second component and truncate back
25894         echo "123" >> $file
25895         $TRUNCATE $file 1048576
25896         printf "Seeking hole from 1000000 ... "
25897         offset=$(lseek_test -l 1000000 $file)
25898         echo $offset
25899         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25900         printf "Seeking hole from 1048576 ... "
25901         lseek_test -l 1048576 $file && error "lseek should fail"
25902         # boundary checks for big values
25903         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25904         offset=$(lseek_test -d 0 $file.10g)
25905         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25906         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25907         offset=$(lseek_test -d 0 $file.100g)
25908         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25909         return 0
25910 }
25911 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25912
25913 test_430c() {
25914         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25915                 skip "OST does not support SEEK_HOLE"
25916
25917         local file=$DIR/$tdir/$tfile
25918         local start
25919
25920         mkdir -p $DIR/$tdir
25921         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25922
25923         # cp version 8.33+ prefers lseek over fiemap
25924         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25925                 start=$SECONDS
25926                 time cp $file /dev/null
25927                 (( SECONDS - start < 5 )) ||
25928                         error "cp: too long runtime $((SECONDS - start))"
25929
25930         fi
25931         # tar version 1.29+ supports SEEK_HOLE/DATA
25932         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25933                 start=$SECONDS
25934                 time tar cS $file - | cat > /dev/null
25935                 (( SECONDS - start < 5 )) ||
25936                         error "tar: too long runtime $((SECONDS - start))"
25937         fi
25938 }
25939 run_test 430c "lseek: external tools check"
25940
25941 test_431() { # LU-14187
25942         local file=$DIR/$tdir/$tfile
25943
25944         mkdir -p $DIR/$tdir
25945         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25946         dd if=/dev/urandom of=$file bs=4k count=1
25947         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25948         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25949         #define OBD_FAIL_OST_RESTART_IO 0x251
25950         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25951         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25952         cp $file $file.0
25953         cancel_lru_locks
25954         sync_all_data
25955         echo 3 > /proc/sys/vm/drop_caches
25956         diff  $file $file.0 || error "data diff"
25957 }
25958 run_test 431 "Restart transaction for IO"
25959
25960 cleanup_test_432() {
25961         do_facet mgs $LCTL nodemap_activate 0
25962         wait_nm_sync active
25963 }
25964
25965 test_432() {
25966         local tmpdir=$TMP/dir432
25967
25968         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
25969                 skip "Need MDS version at least 2.14.52"
25970
25971         stack_trap cleanup_test_432 EXIT
25972         mkdir $DIR/$tdir
25973         mkdir $tmpdir
25974
25975         do_facet mgs $LCTL nodemap_activate 1
25976         wait_nm_sync active
25977         do_facet mgs $LCTL nodemap_modify --name default \
25978                 --property admin --value 1
25979         do_facet mgs $LCTL nodemap_modify --name default \
25980                 --property trusted --value 1
25981         cancel_lru_locks mdc
25982         wait_nm_sync default admin_nodemap
25983         wait_nm_sync default trusted_nodemap
25984
25985         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
25986                grep -ci "Operation not permitted") -ne 0 ]; then
25987                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
25988         fi
25989 }
25990 run_test 432 "mv dir from outside Lustre"
25991
25992 prep_801() {
25993         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25994         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25995                 skip "Need server version at least 2.9.55"
25996
25997         start_full_debug_logging
25998 }
25999
26000 post_801() {
26001         stop_full_debug_logging
26002 }
26003
26004 barrier_stat() {
26005         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26006                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26007                            awk '/The barrier for/ { print $7 }')
26008                 echo $st
26009         else
26010                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26011                 echo \'$st\'
26012         fi
26013 }
26014
26015 barrier_expired() {
26016         local expired
26017
26018         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26019                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26020                           awk '/will be expired/ { print $7 }')
26021         else
26022                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26023         fi
26024
26025         echo $expired
26026 }
26027
26028 test_801a() {
26029         prep_801
26030
26031         echo "Start barrier_freeze at: $(date)"
26032         #define OBD_FAIL_BARRIER_DELAY          0x2202
26033         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26034         # Do not reduce barrier time - See LU-11873
26035         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26036
26037         sleep 2
26038         local b_status=$(barrier_stat)
26039         echo "Got barrier status at: $(date)"
26040         [ "$b_status" = "'freezing_p1'" ] ||
26041                 error "(1) unexpected barrier status $b_status"
26042
26043         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26044         wait
26045         b_status=$(barrier_stat)
26046         [ "$b_status" = "'frozen'" ] ||
26047                 error "(2) unexpected barrier status $b_status"
26048
26049         local expired=$(barrier_expired)
26050         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26051         sleep $((expired + 3))
26052
26053         b_status=$(barrier_stat)
26054         [ "$b_status" = "'expired'" ] ||
26055                 error "(3) unexpected barrier status $b_status"
26056
26057         # Do not reduce barrier time - See LU-11873
26058         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26059                 error "(4) fail to freeze barrier"
26060
26061         b_status=$(barrier_stat)
26062         [ "$b_status" = "'frozen'" ] ||
26063                 error "(5) unexpected barrier status $b_status"
26064
26065         echo "Start barrier_thaw at: $(date)"
26066         #define OBD_FAIL_BARRIER_DELAY          0x2202
26067         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26068         do_facet mgs $LCTL barrier_thaw $FSNAME &
26069
26070         sleep 2
26071         b_status=$(barrier_stat)
26072         echo "Got barrier status at: $(date)"
26073         [ "$b_status" = "'thawing'" ] ||
26074                 error "(6) unexpected barrier status $b_status"
26075
26076         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26077         wait
26078         b_status=$(barrier_stat)
26079         [ "$b_status" = "'thawed'" ] ||
26080                 error "(7) unexpected barrier status $b_status"
26081
26082         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26083         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26084         do_facet mgs $LCTL barrier_freeze $FSNAME
26085
26086         b_status=$(barrier_stat)
26087         [ "$b_status" = "'failed'" ] ||
26088                 error "(8) unexpected barrier status $b_status"
26089
26090         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26091         do_facet mgs $LCTL barrier_thaw $FSNAME
26092
26093         post_801
26094 }
26095 run_test 801a "write barrier user interfaces and stat machine"
26096
26097 test_801b() {
26098         prep_801
26099
26100         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26101         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26102         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26103         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26104         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26105
26106         cancel_lru_locks mdc
26107
26108         # 180 seconds should be long enough
26109         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26110
26111         local b_status=$(barrier_stat)
26112         [ "$b_status" = "'frozen'" ] ||
26113                 error "(6) unexpected barrier status $b_status"
26114
26115         mkdir $DIR/$tdir/d0/d10 &
26116         mkdir_pid=$!
26117
26118         touch $DIR/$tdir/d1/f13 &
26119         touch_pid=$!
26120
26121         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26122         ln_pid=$!
26123
26124         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26125         mv_pid=$!
26126
26127         rm -f $DIR/$tdir/d4/f12 &
26128         rm_pid=$!
26129
26130         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26131
26132         # To guarantee taht the 'stat' is not blocked
26133         b_status=$(barrier_stat)
26134         [ "$b_status" = "'frozen'" ] ||
26135                 error "(8) unexpected barrier status $b_status"
26136
26137         # let above commands to run at background
26138         sleep 5
26139
26140         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26141         ps -p $touch_pid || error "(10) touch should be blocked"
26142         ps -p $ln_pid || error "(11) link should be blocked"
26143         ps -p $mv_pid || error "(12) rename should be blocked"
26144         ps -p $rm_pid || error "(13) unlink should be blocked"
26145
26146         b_status=$(barrier_stat)
26147         [ "$b_status" = "'frozen'" ] ||
26148                 error "(14) unexpected barrier status $b_status"
26149
26150         do_facet mgs $LCTL barrier_thaw $FSNAME
26151         b_status=$(barrier_stat)
26152         [ "$b_status" = "'thawed'" ] ||
26153                 error "(15) unexpected barrier status $b_status"
26154
26155         wait $mkdir_pid || error "(16) mkdir should succeed"
26156         wait $touch_pid || error "(17) touch should succeed"
26157         wait $ln_pid || error "(18) link should succeed"
26158         wait $mv_pid || error "(19) rename should succeed"
26159         wait $rm_pid || error "(20) unlink should succeed"
26160
26161         post_801
26162 }
26163 run_test 801b "modification will be blocked by write barrier"
26164
26165 test_801c() {
26166         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26167
26168         prep_801
26169
26170         stop mds2 || error "(1) Fail to stop mds2"
26171
26172         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26173
26174         local b_status=$(barrier_stat)
26175         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26176                 do_facet mgs $LCTL barrier_thaw $FSNAME
26177                 error "(2) unexpected barrier status $b_status"
26178         }
26179
26180         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26181                 error "(3) Fail to rescan barrier bitmap"
26182
26183         # Do not reduce barrier time - See LU-11873
26184         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26185
26186         b_status=$(barrier_stat)
26187         [ "$b_status" = "'frozen'" ] ||
26188                 error "(4) unexpected barrier status $b_status"
26189
26190         do_facet mgs $LCTL barrier_thaw $FSNAME
26191         b_status=$(barrier_stat)
26192         [ "$b_status" = "'thawed'" ] ||
26193                 error "(5) unexpected barrier status $b_status"
26194
26195         local devname=$(mdsdevname 2)
26196
26197         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26198
26199         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26200                 error "(7) Fail to rescan barrier bitmap"
26201
26202         post_801
26203 }
26204 run_test 801c "rescan barrier bitmap"
26205
26206 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26207 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26208 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26209 saved_MOUNT_OPTS=$MOUNT_OPTS
26210
26211 cleanup_802a() {
26212         trap 0
26213
26214         stopall
26215         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26216         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26217         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26218         MOUNT_OPTS=$saved_MOUNT_OPTS
26219         setupall
26220 }
26221
26222 test_802a() {
26223         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26224         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26225         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26226                 skip "Need server version at least 2.9.55"
26227
26228         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26229
26230         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26231
26232         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26233                 error "(2) Fail to copy"
26234
26235         trap cleanup_802a EXIT
26236
26237         # sync by force before remount as readonly
26238         sync; sync_all_data; sleep 3; sync_all_data
26239
26240         stopall
26241
26242         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26243         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26244         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26245
26246         echo "Mount the server as read only"
26247         setupall server_only || error "(3) Fail to start servers"
26248
26249         echo "Mount client without ro should fail"
26250         mount_client $MOUNT &&
26251                 error "(4) Mount client without 'ro' should fail"
26252
26253         echo "Mount client with ro should succeed"
26254         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26255         mount_client $MOUNT ||
26256                 error "(5) Mount client with 'ro' should succeed"
26257
26258         echo "Modify should be refused"
26259         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26260
26261         echo "Read should be allowed"
26262         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26263                 error "(7) Read should succeed under ro mode"
26264
26265         cleanup_802a
26266 }
26267 run_test 802a "simulate readonly device"
26268
26269 test_802b() {
26270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26271         remote_mds_nodsh && skip "remote MDS with nodsh"
26272
26273         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26274                 skip "readonly option not available"
26275
26276         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26277
26278         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26279                 error "(2) Fail to copy"
26280
26281         # write back all cached data before setting MDT to readonly
26282         cancel_lru_locks
26283         sync_all_data
26284
26285         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26286         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26287
26288         echo "Modify should be refused"
26289         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26290
26291         echo "Read should be allowed"
26292         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26293                 error "(7) Read should succeed under ro mode"
26294
26295         # disable readonly
26296         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26297 }
26298 run_test 802b "be able to set MDTs to readonly"
26299
26300 test_803a() {
26301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26302         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26303                 skip "MDS needs to be newer than 2.10.54"
26304
26305         mkdir_on_mdt0 $DIR/$tdir
26306         # Create some objects on all MDTs to trigger related logs objects
26307         for idx in $(seq $MDSCOUNT); do
26308                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26309                         $DIR/$tdir/dir${idx} ||
26310                         error "Fail to create $DIR/$tdir/dir${idx}"
26311         done
26312
26313         sync; sleep 3
26314         wait_delete_completed # ensure old test cleanups are finished
26315         echo "before create:"
26316         $LFS df -i $MOUNT
26317         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26318
26319         for i in {1..10}; do
26320                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26321                         error "Fail to create $DIR/$tdir/foo$i"
26322         done
26323
26324         sync; sleep 3
26325         echo "after create:"
26326         $LFS df -i $MOUNT
26327         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26328
26329         # allow for an llog to be cleaned up during the test
26330         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26331                 error "before ($before_used) + 10 > after ($after_used)"
26332
26333         for i in {1..10}; do
26334                 rm -rf $DIR/$tdir/foo$i ||
26335                         error "Fail to remove $DIR/$tdir/foo$i"
26336         done
26337
26338         sleep 3 # avoid MDT return cached statfs
26339         wait_delete_completed
26340         echo "after unlink:"
26341         $LFS df -i $MOUNT
26342         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26343
26344         # allow for an llog to be created during the test
26345         [ $after_used -le $((before_used + 1)) ] ||
26346                 error "after ($after_used) > before ($before_used) + 1"
26347 }
26348 run_test 803a "verify agent object for remote object"
26349
26350 test_803b() {
26351         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26352         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26353                 skip "MDS needs to be newer than 2.13.56"
26354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26355
26356         for i in $(seq 0 $((MDSCOUNT - 1))); do
26357                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26358         done
26359
26360         local before=0
26361         local after=0
26362
26363         local tmp
26364
26365         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26366         for i in $(seq 0 $((MDSCOUNT - 1))); do
26367                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26368                         awk '/getattr/ { print $2 }')
26369                 before=$((before + tmp))
26370         done
26371         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26372         for i in $(seq 0 $((MDSCOUNT - 1))); do
26373                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26374                         awk '/getattr/ { print $2 }')
26375                 after=$((after + tmp))
26376         done
26377
26378         [ $before -eq $after ] || error "getattr count $before != $after"
26379 }
26380 run_test 803b "remote object can getattr from cache"
26381
26382 test_804() {
26383         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26384         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26385                 skip "MDS needs to be newer than 2.10.54"
26386         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26387
26388         mkdir -p $DIR/$tdir
26389         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26390                 error "Fail to create $DIR/$tdir/dir0"
26391
26392         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26393         local dev=$(mdsdevname 2)
26394
26395         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26396                 grep ${fid} || error "NOT found agent entry for dir0"
26397
26398         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26399                 error "Fail to create $DIR/$tdir/dir1"
26400
26401         touch $DIR/$tdir/dir1/foo0 ||
26402                 error "Fail to create $DIR/$tdir/dir1/foo0"
26403         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26404         local rc=0
26405
26406         for idx in $(seq $MDSCOUNT); do
26407                 dev=$(mdsdevname $idx)
26408                 do_facet mds${idx} \
26409                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26410                         grep ${fid} && rc=$idx
26411         done
26412
26413         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26414                 error "Fail to rename foo0 to foo1"
26415         if [ $rc -eq 0 ]; then
26416                 for idx in $(seq $MDSCOUNT); do
26417                         dev=$(mdsdevname $idx)
26418                         do_facet mds${idx} \
26419                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26420                         grep ${fid} && rc=$idx
26421                 done
26422         fi
26423
26424         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26425                 error "Fail to rename foo1 to foo2"
26426         if [ $rc -eq 0 ]; then
26427                 for idx in $(seq $MDSCOUNT); do
26428                         dev=$(mdsdevname $idx)
26429                         do_facet mds${idx} \
26430                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26431                         grep ${fid} && rc=$idx
26432                 done
26433         fi
26434
26435         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26436
26437         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26438                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26439         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26440                 error "Fail to rename foo2 to foo0"
26441         unlink $DIR/$tdir/dir1/foo0 ||
26442                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26443         rm -rf $DIR/$tdir/dir0 ||
26444                 error "Fail to rm $DIR/$tdir/dir0"
26445
26446         for idx in $(seq $MDSCOUNT); do
26447                 dev=$(mdsdevname $idx)
26448                 rc=0
26449
26450                 stop mds${idx}
26451                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26452                         rc=$?
26453                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26454                         error "mount mds$idx failed"
26455                 df $MOUNT > /dev/null 2>&1
26456
26457                 # e2fsck should not return error
26458                 [ $rc -eq 0 ] ||
26459                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26460         done
26461 }
26462 run_test 804 "verify agent entry for remote entry"
26463
26464 cleanup_805() {
26465         do_facet $SINGLEMDS zfs set quota=$old $fsset
26466         unlinkmany $DIR/$tdir/f- 1000000
26467         trap 0
26468 }
26469
26470 test_805() {
26471         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26472         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26473         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26474                 skip "netfree not implemented before 0.7"
26475         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26476                 skip "Need MDS version at least 2.10.57"
26477
26478         local fsset
26479         local freekb
26480         local usedkb
26481         local old
26482         local quota
26483         local pref="osd-zfs.$FSNAME-MDT0000."
26484
26485         # limit available space on MDS dataset to meet nospace issue
26486         # quickly. then ZFS 0.7.2 can use reserved space if asked
26487         # properly (using netfree flag in osd_declare_destroy()
26488         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26489         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26490                 gawk '{print $3}')
26491         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26492         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26493         let "usedkb=usedkb-freekb"
26494         let "freekb=freekb/2"
26495         if let "freekb > 5000"; then
26496                 let "freekb=5000"
26497         fi
26498         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26499         trap cleanup_805 EXIT
26500         mkdir_on_mdt0 $DIR/$tdir
26501         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26502                 error "Can't set PFL layout"
26503         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26504         rm -rf $DIR/$tdir || error "not able to remove"
26505         do_facet $SINGLEMDS zfs set quota=$old $fsset
26506         trap 0
26507 }
26508 run_test 805 "ZFS can remove from full fs"
26509
26510 # Size-on-MDS test
26511 check_lsom_data()
26512 {
26513         local file=$1
26514         local expect=$(stat -c %s $file)
26515
26516         check_lsom_size $1 $expect
26517
26518         local blocks=$($LFS getsom -b $file)
26519         expect=$(stat -c %b $file)
26520         [[ $blocks == $expect ]] ||
26521                 error "$file expected blocks: $expect, got: $blocks"
26522 }
26523
26524 check_lsom_size()
26525 {
26526         local size
26527         local expect=$2
26528
26529         cancel_lru_locks mdc
26530
26531         size=$($LFS getsom -s $1)
26532         [[ $size == $expect ]] ||
26533                 error "$file expected size: $expect, got: $size"
26534 }
26535
26536 test_806() {
26537         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26538                 skip "Need MDS version at least 2.11.52"
26539
26540         local bs=1048576
26541
26542         touch $DIR/$tfile || error "touch $tfile failed"
26543
26544         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26545         save_lustre_params client "llite.*.xattr_cache" > $save
26546         lctl set_param llite.*.xattr_cache=0
26547         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26548
26549         # single-threaded write
26550         echo "Test SOM for single-threaded write"
26551         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26552                 error "write $tfile failed"
26553         check_lsom_size $DIR/$tfile $bs
26554
26555         local num=32
26556         local size=$(($num * $bs))
26557         local offset=0
26558         local i
26559
26560         echo "Test SOM for single client multi-threaded($num) write"
26561         $TRUNCATE $DIR/$tfile 0
26562         for ((i = 0; i < $num; i++)); do
26563                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26564                 local pids[$i]=$!
26565                 offset=$((offset + $bs))
26566         done
26567         for (( i=0; i < $num; i++ )); do
26568                 wait ${pids[$i]}
26569         done
26570         check_lsom_size $DIR/$tfile $size
26571
26572         $TRUNCATE $DIR/$tfile 0
26573         for ((i = 0; i < $num; i++)); do
26574                 offset=$((offset - $bs))
26575                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26576                 local pids[$i]=$!
26577         done
26578         for (( i=0; i < $num; i++ )); do
26579                 wait ${pids[$i]}
26580         done
26581         check_lsom_size $DIR/$tfile $size
26582
26583         # multi-client writes
26584         num=$(get_node_count ${CLIENTS//,/ })
26585         size=$(($num * $bs))
26586         offset=0
26587         i=0
26588
26589         echo "Test SOM for multi-client ($num) writes"
26590         $TRUNCATE $DIR/$tfile 0
26591         for client in ${CLIENTS//,/ }; do
26592                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26593                 local pids[$i]=$!
26594                 i=$((i + 1))
26595                 offset=$((offset + $bs))
26596         done
26597         for (( i=0; i < $num; i++ )); do
26598                 wait ${pids[$i]}
26599         done
26600         check_lsom_size $DIR/$tfile $offset
26601
26602         i=0
26603         $TRUNCATE $DIR/$tfile 0
26604         for client in ${CLIENTS//,/ }; do
26605                 offset=$((offset - $bs))
26606                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26607                 local pids[$i]=$!
26608                 i=$((i + 1))
26609         done
26610         for (( i=0; i < $num; i++ )); do
26611                 wait ${pids[$i]}
26612         done
26613         check_lsom_size $DIR/$tfile $size
26614
26615         # verify truncate
26616         echo "Test SOM for truncate"
26617         $TRUNCATE $DIR/$tfile 1048576
26618         check_lsom_size $DIR/$tfile 1048576
26619         $TRUNCATE $DIR/$tfile 1234
26620         check_lsom_size $DIR/$tfile 1234
26621
26622         # verify SOM blocks count
26623         echo "Verify SOM block count"
26624         $TRUNCATE $DIR/$tfile 0
26625         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26626                 error "failed to write file $tfile"
26627         check_lsom_data $DIR/$tfile
26628 }
26629 run_test 806 "Verify Lazy Size on MDS"
26630
26631 test_807() {
26632         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26633         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26634                 skip "Need MDS version at least 2.11.52"
26635
26636         # Registration step
26637         changelog_register || error "changelog_register failed"
26638         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26639         changelog_users $SINGLEMDS | grep -q $cl_user ||
26640                 error "User $cl_user not found in changelog_users"
26641
26642         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26643         save_lustre_params client "llite.*.xattr_cache" > $save
26644         lctl set_param llite.*.xattr_cache=0
26645         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26646
26647         rm -rf $DIR/$tdir || error "rm $tdir failed"
26648         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26649         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26650         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26651         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26652                 error "truncate $tdir/trunc failed"
26653
26654         local bs=1048576
26655         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26656                 error "write $tfile failed"
26657
26658         # multi-client wirtes
26659         local num=$(get_node_count ${CLIENTS//,/ })
26660         local offset=0
26661         local i=0
26662
26663         echo "Test SOM for multi-client ($num) writes"
26664         touch $DIR/$tfile || error "touch $tfile failed"
26665         $TRUNCATE $DIR/$tfile 0
26666         for client in ${CLIENTS//,/ }; do
26667                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26668                 local pids[$i]=$!
26669                 i=$((i + 1))
26670                 offset=$((offset + $bs))
26671         done
26672         for (( i=0; i < $num; i++ )); do
26673                 wait ${pids[$i]}
26674         done
26675
26676         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26677         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26678         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26679         check_lsom_data $DIR/$tdir/trunc
26680         check_lsom_data $DIR/$tdir/single_dd
26681         check_lsom_data $DIR/$tfile
26682
26683         rm -rf $DIR/$tdir
26684         # Deregistration step
26685         changelog_deregister || error "changelog_deregister failed"
26686 }
26687 run_test 807 "verify LSOM syncing tool"
26688
26689 check_som_nologged()
26690 {
26691         local lines=$($LFS changelog $FSNAME-MDT0000 |
26692                 grep 'x=trusted.som' | wc -l)
26693         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26694 }
26695
26696 test_808() {
26697         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26698                 skip "Need MDS version at least 2.11.55"
26699
26700         # Registration step
26701         changelog_register || error "changelog_register failed"
26702
26703         touch $DIR/$tfile || error "touch $tfile failed"
26704         check_som_nologged
26705
26706         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26707                 error "write $tfile failed"
26708         check_som_nologged
26709
26710         $TRUNCATE $DIR/$tfile 1234
26711         check_som_nologged
26712
26713         $TRUNCATE $DIR/$tfile 1048576
26714         check_som_nologged
26715
26716         # Deregistration step
26717         changelog_deregister || error "changelog_deregister failed"
26718 }
26719 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26720
26721 check_som_nodata()
26722 {
26723         $LFS getsom $1
26724         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26725 }
26726
26727 test_809() {
26728         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26729                 skip "Need MDS version at least 2.11.56"
26730
26731         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26732                 error "failed to create DoM-only file $DIR/$tfile"
26733         touch $DIR/$tfile || error "touch $tfile failed"
26734         check_som_nodata $DIR/$tfile
26735
26736         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26737                 error "write $tfile failed"
26738         check_som_nodata $DIR/$tfile
26739
26740         $TRUNCATE $DIR/$tfile 1234
26741         check_som_nodata $DIR/$tfile
26742
26743         $TRUNCATE $DIR/$tfile 4097
26744         check_som_nodata $DIR/$file
26745 }
26746 run_test 809 "Verify no SOM xattr store for DoM-only files"
26747
26748 test_810() {
26749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26750         $GSS && skip_env "could not run with gss"
26751         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26752                 skip "OST < 2.12.58 doesn't align checksum"
26753
26754         set_checksums 1
26755         stack_trap "set_checksums $ORIG_CSUM" EXIT
26756         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26757
26758         local csum
26759         local before
26760         local after
26761         for csum in $CKSUM_TYPES; do
26762                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26763                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26764                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26765                         eval set -- $i
26766                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26767                         before=$(md5sum $DIR/$tfile)
26768                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26769                         after=$(md5sum $DIR/$tfile)
26770                         [ "$before" == "$after" ] ||
26771                                 error "$csum: $before != $after bs=$1 seek=$2"
26772                 done
26773         done
26774 }
26775 run_test 810 "partial page writes on ZFS (LU-11663)"
26776
26777 test_812a() {
26778         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26779                 skip "OST < 2.12.51 doesn't support this fail_loc"
26780
26781         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26782         # ensure ost1 is connected
26783         stat $DIR/$tfile >/dev/null || error "can't stat"
26784         wait_osc_import_state client ost1 FULL
26785         # no locks, no reqs to let the connection idle
26786         cancel_lru_locks osc
26787
26788         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26789 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26790         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26791         wait_osc_import_state client ost1 CONNECTING
26792         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26793
26794         stat $DIR/$tfile >/dev/null || error "can't stat file"
26795 }
26796 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26797
26798 test_812b() { # LU-12378
26799         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26800                 skip "OST < 2.12.51 doesn't support this fail_loc"
26801
26802         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26803         # ensure ost1 is connected
26804         stat $DIR/$tfile >/dev/null || error "can't stat"
26805         wait_osc_import_state client ost1 FULL
26806         # no locks, no reqs to let the connection idle
26807         cancel_lru_locks osc
26808
26809         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26810 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26811         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26812         wait_osc_import_state client ost1 CONNECTING
26813         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26814
26815         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26816         wait_osc_import_state client ost1 IDLE
26817 }
26818 run_test 812b "do not drop no resend request for idle connect"
26819
26820 test_812c() {
26821         local old
26822
26823         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26824
26825         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26826         $LFS getstripe $DIR/$tfile
26827         $LCTL set_param osc.*.idle_timeout=10
26828         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26829         # ensure ost1 is connected
26830         stat $DIR/$tfile >/dev/null || error "can't stat"
26831         wait_osc_import_state client ost1 FULL
26832         # no locks, no reqs to let the connection idle
26833         cancel_lru_locks osc
26834
26835 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26836         $LCTL set_param fail_loc=0x80000533
26837         sleep 15
26838         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26839 }
26840 run_test 812c "idle import vs lock enqueue race"
26841
26842 test_813() {
26843         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26844         [ -z "$file_heat_sav" ] && skip "no file heat support"
26845
26846         local readsample
26847         local writesample
26848         local readbyte
26849         local writebyte
26850         local readsample1
26851         local writesample1
26852         local readbyte1
26853         local writebyte1
26854
26855         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26856         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26857
26858         $LCTL set_param -n llite.*.file_heat=1
26859         echo "Turn on file heat"
26860         echo "Period second: $period_second, Decay percentage: $decay_pct"
26861
26862         echo "QQQQ" > $DIR/$tfile
26863         echo "QQQQ" > $DIR/$tfile
26864         echo "QQQQ" > $DIR/$tfile
26865         cat $DIR/$tfile > /dev/null
26866         cat $DIR/$tfile > /dev/null
26867         cat $DIR/$tfile > /dev/null
26868         cat $DIR/$tfile > /dev/null
26869
26870         local out=$($LFS heat_get $DIR/$tfile)
26871
26872         $LFS heat_get $DIR/$tfile
26873         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26874         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26875         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26876         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26877
26878         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26879         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26880         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26881         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26882
26883         sleep $((period_second + 3))
26884         echo "Sleep $((period_second + 3)) seconds..."
26885         # The recursion formula to calculate the heat of the file f is as
26886         # follow:
26887         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26888         # Where Hi is the heat value in the period between time points i*I and
26889         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26890         # to the weight of Ci.
26891         out=$($LFS heat_get $DIR/$tfile)
26892         $LFS heat_get $DIR/$tfile
26893         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26894         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26895         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26896         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26897
26898         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26899                 error "read sample ($readsample) is wrong"
26900         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26901                 error "write sample ($writesample) is wrong"
26902         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26903                 error "read bytes ($readbyte) is wrong"
26904         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26905                 error "write bytes ($writebyte) is wrong"
26906
26907         echo "QQQQ" > $DIR/$tfile
26908         echo "QQQQ" > $DIR/$tfile
26909         echo "QQQQ" > $DIR/$tfile
26910         cat $DIR/$tfile > /dev/null
26911         cat $DIR/$tfile > /dev/null
26912         cat $DIR/$tfile > /dev/null
26913         cat $DIR/$tfile > /dev/null
26914
26915         sleep $((period_second + 3))
26916         echo "Sleep $((period_second + 3)) seconds..."
26917
26918         out=$($LFS heat_get $DIR/$tfile)
26919         $LFS heat_get $DIR/$tfile
26920         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26921         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26922         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26923         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26924
26925         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26926                 4 * $decay_pct) / 100") -eq 1 ] ||
26927                 error "read sample ($readsample1) is wrong"
26928         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26929                 3 * $decay_pct) / 100") -eq 1 ] ||
26930                 error "write sample ($writesample1) is wrong"
26931         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26932                 20 * $decay_pct) / 100") -eq 1 ] ||
26933                 error "read bytes ($readbyte1) is wrong"
26934         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26935                 15 * $decay_pct) / 100") -eq 1 ] ||
26936                 error "write bytes ($writebyte1) is wrong"
26937
26938         echo "Turn off file heat for the file $DIR/$tfile"
26939         $LFS heat_set -o $DIR/$tfile
26940
26941         echo "QQQQ" > $DIR/$tfile
26942         echo "QQQQ" > $DIR/$tfile
26943         echo "QQQQ" > $DIR/$tfile
26944         cat $DIR/$tfile > /dev/null
26945         cat $DIR/$tfile > /dev/null
26946         cat $DIR/$tfile > /dev/null
26947         cat $DIR/$tfile > /dev/null
26948
26949         out=$($LFS heat_get $DIR/$tfile)
26950         $LFS heat_get $DIR/$tfile
26951         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26952         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26953         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26954         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26955
26956         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26957         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26958         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26959         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26960
26961         echo "Trun on file heat for the file $DIR/$tfile"
26962         $LFS heat_set -O $DIR/$tfile
26963
26964         echo "QQQQ" > $DIR/$tfile
26965         echo "QQQQ" > $DIR/$tfile
26966         echo "QQQQ" > $DIR/$tfile
26967         cat $DIR/$tfile > /dev/null
26968         cat $DIR/$tfile > /dev/null
26969         cat $DIR/$tfile > /dev/null
26970         cat $DIR/$tfile > /dev/null
26971
26972         out=$($LFS heat_get $DIR/$tfile)
26973         $LFS heat_get $DIR/$tfile
26974         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26975         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26976         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26977         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26978
26979         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26980         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26981         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26982         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26983
26984         $LFS heat_set -c $DIR/$tfile
26985         $LCTL set_param -n llite.*.file_heat=0
26986         echo "Turn off file heat support for the Lustre filesystem"
26987
26988         echo "QQQQ" > $DIR/$tfile
26989         echo "QQQQ" > $DIR/$tfile
26990         echo "QQQQ" > $DIR/$tfile
26991         cat $DIR/$tfile > /dev/null
26992         cat $DIR/$tfile > /dev/null
26993         cat $DIR/$tfile > /dev/null
26994         cat $DIR/$tfile > /dev/null
26995
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         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27004         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27005         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27006         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27007
27008         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27009         rm -f $DIR/$tfile
27010 }
27011 run_test 813 "File heat verfication"
27012
27013 test_814()
27014 {
27015         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27016         echo -n y >> $DIR/$tfile
27017         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27018         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27019 }
27020 run_test 814 "sparse cp works as expected (LU-12361)"
27021
27022 test_815()
27023 {
27024         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27025         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27026 }
27027 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27028
27029 test_816() {
27030         local ost1_imp=$(get_osc_import_name client ost1)
27031         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27032                          cut -d'.' -f2)
27033
27034         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27035         # ensure ost1 is connected
27036
27037         stat $DIR/$tfile >/dev/null || error "can't stat"
27038         wait_osc_import_state client ost1 FULL
27039         # no locks, no reqs to let the connection idle
27040         cancel_lru_locks osc
27041         lru_resize_disable osc
27042         local before
27043         local now
27044         before=$($LCTL get_param -n \
27045                  ldlm.namespaces.$imp_name.lru_size)
27046
27047         wait_osc_import_state client ost1 IDLE
27048         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27049         now=$($LCTL get_param -n \
27050               ldlm.namespaces.$imp_name.lru_size)
27051         [ $before == $now ] || error "lru_size changed $before != $now"
27052 }
27053 run_test 816 "do not reset lru_resize on idle reconnect"
27054
27055 cleanup_817() {
27056         umount $tmpdir
27057         exportfs -u localhost:$DIR/nfsexp
27058         rm -rf $DIR/nfsexp
27059 }
27060
27061 test_817() {
27062         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27063
27064         mkdir -p $DIR/nfsexp
27065         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27066                 error "failed to export nfs"
27067
27068         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27069         stack_trap cleanup_817 EXIT
27070
27071         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27072                 error "failed to mount nfs to $tmpdir"
27073
27074         cp /bin/true $tmpdir
27075         $DIR/nfsexp/true || error "failed to execute 'true' command"
27076 }
27077 run_test 817 "nfsd won't cache write lock for exec file"
27078
27079 test_818() {
27080         mkdir $DIR/$tdir
27081         $LFS setstripe -c1 -i0 $DIR/$tfile
27082         $LFS setstripe -c1 -i1 $DIR/$tfile
27083         stop $SINGLEMDS
27084         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27085         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27086         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27087                 error "start $SINGLEMDS failed"
27088         rm -rf $DIR/$tdir
27089 }
27090 run_test 818 "unlink with failed llog"
27091
27092 test_819a() {
27093         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27094         cancel_lru_locks osc
27095         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27096         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27097         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27098         rm -f $TDIR/$tfile
27099 }
27100 run_test 819a "too big niobuf in read"
27101
27102 test_819b() {
27103         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27104         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27105         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27106         cancel_lru_locks osc
27107         sleep 1
27108         rm -f $TDIR/$tfile
27109 }
27110 run_test 819b "too big niobuf in write"
27111
27112
27113 function test_820_start_ost() {
27114         sleep 5
27115
27116         for num in $(seq $OSTCOUNT); do
27117                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27118         done
27119 }
27120
27121 test_820() {
27122         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27123
27124         mkdir $DIR/$tdir
27125         umount_client $MOUNT || error "umount failed"
27126         for num in $(seq $OSTCOUNT); do
27127                 stop ost$num
27128         done
27129
27130         # mount client with no active OSTs
27131         # so that the client can't initialize max LOV EA size
27132         # from OSC notifications
27133         mount_client $MOUNT || error "mount failed"
27134         # delay OST starting to keep this 0 max EA size for a while
27135         test_820_start_ost &
27136
27137         # create a directory on MDS2
27138         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27139                 error "Failed to create directory"
27140         # open intent should update default EA size
27141         # see mdc_update_max_ea_from_body()
27142         # notice this is the very first RPC to MDS2
27143         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27144         ret=$?
27145         echo $out
27146         # With SSK, this situation can lead to -EPERM being returned.
27147         # In that case, simply retry.
27148         if [ $ret -ne 0 ] && $SHARED_KEY; then
27149                 if echo "$out" | grep -q "not permitted"; then
27150                         cp /etc/services $DIR/$tdir/mds2
27151                         ret=$?
27152                 fi
27153         fi
27154         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27155 }
27156 run_test 820 "update max EA from open intent"
27157
27158 test_822() {
27159         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27160
27161         save_lustre_params mds1 \
27162                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27163         do_facet $SINGLEMDS "$LCTL set_param -n \
27164                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27165         do_facet $SINGLEMDS "$LCTL set_param -n \
27166                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27167
27168         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27169         local maxage=$(do_facet mds1 $LCTL get_param -n \
27170                        osp.$FSNAME-OST0000*MDT0000.maxage)
27171         sleep $((maxage + 1))
27172
27173         #define OBD_FAIL_NET_ERROR_RPC          0x532
27174         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27175
27176         stack_trap "restore_lustre_params < $p; rm $p"
27177
27178         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27179                       osp.$FSNAME-OST0000*MDT0000.create_count")
27180         for i in $(seq 1 $count); do
27181                 touch $DIR/$tfile.${i} || error "touch failed"
27182         done
27183 }
27184 run_test 822 "test precreate failure"
27185
27186 #
27187 # tests that do cleanup/setup should be run at the end
27188 #
27189
27190 test_900() {
27191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27192         local ls
27193
27194         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27195         $LCTL set_param fail_loc=0x903
27196
27197         cancel_lru_locks MGC
27198
27199         FAIL_ON_ERROR=true cleanup
27200         FAIL_ON_ERROR=true setup
27201 }
27202 run_test 900 "umount should not race with any mgc requeue thread"
27203
27204 # LUS-6253/LU-11185
27205 test_901() {
27206         local oldc
27207         local newc
27208         local olds
27209         local news
27210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27211
27212         # some get_param have a bug to handle dot in param name
27213         cancel_lru_locks MGC
27214         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27215         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27216         umount_client $MOUNT || error "umount failed"
27217         mount_client $MOUNT || error "mount failed"
27218         cancel_lru_locks MGC
27219         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27220         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27221
27222         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27223         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27224
27225         return 0
27226 }
27227 run_test 901 "don't leak a mgc lock on client umount"
27228
27229 # LU-13377
27230 test_902() {
27231         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27232                 skip "client does not have LU-13377 fix"
27233         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27234         $LCTL set_param fail_loc=0x1415
27235         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27236         cancel_lru_locks osc
27237         rm -f $DIR/$tfile
27238 }
27239 run_test 902 "test short write doesn't hang lustre"
27240
27241 # LU-14711
27242 test_903() {
27243         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27244         echo "blah" > $DIR/${tfile}-2
27245         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27246         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27247         $LCTL set_param fail_loc=0x417 fail_val=20
27248
27249         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27250         sleep 1 # To start the destroy
27251         wait_destroy_complete 150 || error "Destroy taking too long"
27252         cat $DIR/$tfile > /dev/null || error "Evicted"
27253 }
27254 run_test 903 "Test long page discard does not cause evictions"
27255
27256 complete $SECONDS
27257 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27258 check_and_cleanup_lustre
27259 if [ "$I_MOUNTED" != "yes" ]; then
27260         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27261 fi
27262 exit_status