Whamcloud - gitweb
57fc1f7b1cc47944d2173ccf13867322cb51dfde
[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
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_160q() {
16447         local mdt="$(facet_svc $SINGLEMDS)"
16448         local clu
16449
16450         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16451         remote_mds_nodsh && skip "remote MDS with nodsh"
16452         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16453                 skip "Need MDS version at least 2.14.54"
16454
16455         # set server mask to minimal value like server init does
16456         changelog_chmask "MARK"
16457         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16458                 error "changelog_register failed"
16459         # check effective mask again, should be treated as DEFMASK now
16460         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16461                                 mdd.$mdt.changelog_current_mask -n)
16462         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16463                 error "changelog_deregister failed"
16464         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16465 }
16466 run_test 160q "changelog effective mask is DEFMASK if not set"
16467
16468 test_161a() {
16469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16470
16471         test_mkdir -c1 $DIR/$tdir
16472         cp /etc/hosts $DIR/$tdir/$tfile
16473         test_mkdir -c1 $DIR/$tdir/foo1
16474         test_mkdir -c1 $DIR/$tdir/foo2
16475         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16476         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16477         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16478         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16479         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16480         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16481                 $LFS fid2path $DIR $FID
16482                 error "bad link ea"
16483         fi
16484         # middle
16485         rm $DIR/$tdir/foo2/zachary
16486         # last
16487         rm $DIR/$tdir/foo2/thor
16488         # first
16489         rm $DIR/$tdir/$tfile
16490         # rename
16491         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16492         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16493                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16494         rm $DIR/$tdir/foo2/maggie
16495
16496         # overflow the EA
16497         local longname=$tfile.avg_len_is_thirty_two_
16498         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16499                 error_noexit 'failed to unlink many hardlinks'" EXIT
16500         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16501                 error "failed to hardlink many files"
16502         links=$($LFS fid2path $DIR $FID | wc -l)
16503         echo -n "${links}/1000 links in link EA"
16504         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16505 }
16506 run_test 161a "link ea sanity"
16507
16508 test_161b() {
16509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16510         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16511
16512         local MDTIDX=1
16513         local remote_dir=$DIR/$tdir/remote_dir
16514
16515         mkdir -p $DIR/$tdir
16516         $LFS mkdir -i $MDTIDX $remote_dir ||
16517                 error "create remote directory failed"
16518
16519         cp /etc/hosts $remote_dir/$tfile
16520         mkdir -p $remote_dir/foo1
16521         mkdir -p $remote_dir/foo2
16522         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16523         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16524         ln $remote_dir/$tfile $remote_dir/foo1/luna
16525         ln $remote_dir/$tfile $remote_dir/foo2/thor
16526
16527         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16528                      tr -d ']')
16529         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16530                 $LFS fid2path $DIR $FID
16531                 error "bad link ea"
16532         fi
16533         # middle
16534         rm $remote_dir/foo2/zachary
16535         # last
16536         rm $remote_dir/foo2/thor
16537         # first
16538         rm $remote_dir/$tfile
16539         # rename
16540         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16541         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16542         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16543                 $LFS fid2path $DIR $FID
16544                 error "bad link rename"
16545         fi
16546         rm $remote_dir/foo2/maggie
16547
16548         # overflow the EA
16549         local longname=filename_avg_len_is_thirty_two_
16550         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16551                 error "failed to hardlink many files"
16552         links=$($LFS fid2path $DIR $FID | wc -l)
16553         echo -n "${links}/1000 links in link EA"
16554         [[ ${links} -gt 60 ]] ||
16555                 error "expected at least 60 links in link EA"
16556         unlinkmany $remote_dir/foo2/$longname 1000 ||
16557         error "failed to unlink many hardlinks"
16558 }
16559 run_test 161b "link ea sanity under remote directory"
16560
16561 test_161c() {
16562         remote_mds_nodsh && skip "remote MDS with nodsh"
16563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16564         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16565                 skip "Need MDS version at least 2.1.5"
16566
16567         # define CLF_RENAME_LAST 0x0001
16568         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16569         changelog_register || error "changelog_register failed"
16570
16571         rm -rf $DIR/$tdir
16572         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16573         touch $DIR/$tdir/foo_161c
16574         touch $DIR/$tdir/bar_161c
16575         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16576         changelog_dump | grep RENME | tail -n 5
16577         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16578         changelog_clear 0 || error "changelog_clear failed"
16579         if [ x$flags != "x0x1" ]; then
16580                 error "flag $flags is not 0x1"
16581         fi
16582
16583         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16584         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16585         touch $DIR/$tdir/foo_161c
16586         touch $DIR/$tdir/bar_161c
16587         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16588         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16589         changelog_dump | grep RENME | tail -n 5
16590         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16591         changelog_clear 0 || error "changelog_clear failed"
16592         if [ x$flags != "x0x0" ]; then
16593                 error "flag $flags is not 0x0"
16594         fi
16595         echo "rename overwrite a target having nlink > 1," \
16596                 "changelog record has flags of $flags"
16597
16598         # rename doesn't overwrite a target (changelog flag 0x0)
16599         touch $DIR/$tdir/foo_161c
16600         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16601         changelog_dump | grep RENME | tail -n 5
16602         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16603         changelog_clear 0 || error "changelog_clear failed"
16604         if [ x$flags != "x0x0" ]; then
16605                 error "flag $flags is not 0x0"
16606         fi
16607         echo "rename doesn't overwrite a target," \
16608                 "changelog record has flags of $flags"
16609
16610         # define CLF_UNLINK_LAST 0x0001
16611         # unlink a file having nlink = 1 (changelog flag 0x1)
16612         rm -f $DIR/$tdir/foo2_161c
16613         changelog_dump | grep UNLNK | tail -n 5
16614         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16615         changelog_clear 0 || error "changelog_clear failed"
16616         if [ x$flags != "x0x1" ]; then
16617                 error "flag $flags is not 0x1"
16618         fi
16619         echo "unlink a file having nlink = 1," \
16620                 "changelog record has flags of $flags"
16621
16622         # unlink a file having nlink > 1 (changelog flag 0x0)
16623         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16624         rm -f $DIR/$tdir/foobar_161c
16625         changelog_dump | grep UNLNK | tail -n 5
16626         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16627         changelog_clear 0 || error "changelog_clear failed"
16628         if [ x$flags != "x0x0" ]; then
16629                 error "flag $flags is not 0x0"
16630         fi
16631         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16632 }
16633 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16634
16635 test_161d() {
16636         remote_mds_nodsh && skip "remote MDS with nodsh"
16637         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16638
16639         local pid
16640         local fid
16641
16642         changelog_register || error "changelog_register failed"
16643
16644         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16645         # interfer with $MOUNT/.lustre/fid/ access
16646         mkdir $DIR/$tdir
16647         [[ $? -eq 0 ]] || error "mkdir failed"
16648
16649         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16650         $LCTL set_param fail_loc=0x8000140c
16651         # 5s pause
16652         $LCTL set_param fail_val=5
16653
16654         # create file
16655         echo foofoo > $DIR/$tdir/$tfile &
16656         pid=$!
16657
16658         # wait for create to be delayed
16659         sleep 2
16660
16661         ps -p $pid
16662         [[ $? -eq 0 ]] || error "create should be blocked"
16663
16664         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16665         stack_trap "rm -f $tempfile"
16666         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16667         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16668         # some delay may occur during ChangeLog publishing and file read just
16669         # above, that could allow file write to happen finally
16670         [[ -s $tempfile ]] && echo "file should be empty"
16671
16672         $LCTL set_param fail_loc=0
16673
16674         wait $pid
16675         [[ $? -eq 0 ]] || error "create failed"
16676 }
16677 run_test 161d "create with concurrent .lustre/fid access"
16678
16679 check_path() {
16680         local expected="$1"
16681         shift
16682         local fid="$2"
16683
16684         local path
16685         path=$($LFS fid2path "$@")
16686         local rc=$?
16687
16688         if [ $rc -ne 0 ]; then
16689                 error "path looked up of '$expected' failed: rc=$rc"
16690         elif [ "$path" != "$expected" ]; then
16691                 error "path looked up '$path' instead of '$expected'"
16692         else
16693                 echo "FID '$fid' resolves to path '$path' as expected"
16694         fi
16695 }
16696
16697 test_162a() { # was test_162
16698         test_mkdir -p -c1 $DIR/$tdir/d2
16699         touch $DIR/$tdir/d2/$tfile
16700         touch $DIR/$tdir/d2/x1
16701         touch $DIR/$tdir/d2/x2
16702         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16703         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16704         # regular file
16705         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16706         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16707
16708         # softlink
16709         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16710         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16711         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16712
16713         # softlink to wrong file
16714         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16715         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16716         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16717
16718         # hardlink
16719         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16720         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16721         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16722         # fid2path dir/fsname should both work
16723         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16724         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16725
16726         # hardlink count: check that there are 2 links
16727         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16728         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16729
16730         # hardlink indexing: remove the first link
16731         rm $DIR/$tdir/d2/p/q/r/hlink
16732         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16733 }
16734 run_test 162a "path lookup sanity"
16735
16736 test_162b() {
16737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16738         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16739
16740         mkdir $DIR/$tdir
16741         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16742                                 error "create striped dir failed"
16743
16744         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16745                                         tail -n 1 | awk '{print $2}')
16746         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16747
16748         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16749         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16750
16751         # regular file
16752         for ((i=0;i<5;i++)); do
16753                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16754                         error "get fid for f$i failed"
16755                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16756
16757                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16758                         error "get fid for d$i failed"
16759                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16760         done
16761
16762         return 0
16763 }
16764 run_test 162b "striped directory path lookup sanity"
16765
16766 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16767 test_162c() {
16768         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16769                 skip "Need MDS version at least 2.7.51"
16770
16771         local lpath=$tdir.local
16772         local rpath=$tdir.remote
16773
16774         test_mkdir $DIR/$lpath
16775         test_mkdir $DIR/$rpath
16776
16777         for ((i = 0; i <= 101; i++)); do
16778                 lpath="$lpath/$i"
16779                 mkdir $DIR/$lpath
16780                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16781                         error "get fid for local directory $DIR/$lpath failed"
16782                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16783
16784                 rpath="$rpath/$i"
16785                 test_mkdir $DIR/$rpath
16786                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16787                         error "get fid for remote directory $DIR/$rpath failed"
16788                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16789         done
16790
16791         return 0
16792 }
16793 run_test 162c "fid2path works with paths 100 or more directories deep"
16794
16795 oalr_event_count() {
16796         local event="${1}"
16797         local trace="${2}"
16798
16799         awk -v name="${FSNAME}-OST0000" \
16800             -v event="${event}" \
16801             '$1 == "TRACE" && $2 == event && $3 == name' \
16802             "${trace}" |
16803         wc -l
16804 }
16805
16806 oalr_expect_event_count() {
16807         local event="${1}"
16808         local trace="${2}"
16809         local expect="${3}"
16810         local count
16811
16812         count=$(oalr_event_count "${event}" "${trace}")
16813         if ((count == expect)); then
16814                 return 0
16815         fi
16816
16817         error_noexit "${event} event count was '${count}', expected ${expect}"
16818         cat "${trace}" >&2
16819         exit 1
16820 }
16821
16822 cleanup_165() {
16823         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16824         stop ost1
16825         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16826 }
16827
16828 setup_165() {
16829         sync # Flush previous IOs so we can count log entries.
16830         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16831         stack_trap cleanup_165 EXIT
16832 }
16833
16834 test_165a() {
16835         local trace="/tmp/${tfile}.trace"
16836         local rc
16837         local count
16838
16839         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16840                 skip "OFD access log unsupported"
16841
16842         setup_165
16843         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16844         sleep 5
16845
16846         do_facet ost1 ofd_access_log_reader --list
16847         stop ost1
16848
16849         do_facet ost1 killall -TERM ofd_access_log_reader
16850         wait
16851         rc=$?
16852
16853         if ((rc != 0)); then
16854                 error "ofd_access_log_reader exited with rc = '${rc}'"
16855         fi
16856
16857         # Parse trace file for discovery events:
16858         oalr_expect_event_count alr_log_add "${trace}" 1
16859         oalr_expect_event_count alr_log_eof "${trace}" 1
16860         oalr_expect_event_count alr_log_free "${trace}" 1
16861 }
16862 run_test 165a "ofd access log discovery"
16863
16864 test_165b() {
16865         local trace="/tmp/${tfile}.trace"
16866         local file="${DIR}/${tfile}"
16867         local pfid1
16868         local pfid2
16869         local -a entry
16870         local rc
16871         local count
16872         local size
16873         local flags
16874
16875         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16876                 skip "OFD access log unsupported"
16877
16878         setup_165
16879         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16880         sleep 5
16881
16882         do_facet ost1 ofd_access_log_reader --list
16883
16884         lfs setstripe -c 1 -i 0 "${file}"
16885         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16886                 error "cannot create '${file}'"
16887
16888         sleep 5
16889         do_facet ost1 killall -TERM ofd_access_log_reader
16890         wait
16891         rc=$?
16892
16893         if ((rc != 0)); then
16894                 error "ofd_access_log_reader exited with rc = '${rc}'"
16895         fi
16896
16897         oalr_expect_event_count alr_log_entry "${trace}" 1
16898
16899         pfid1=$($LFS path2fid "${file}")
16900
16901         # 1     2             3   4    5     6   7    8    9     10
16902         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16903         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16904
16905         echo "entry = '${entry[*]}'" >&2
16906
16907         pfid2=${entry[4]}
16908         if [[ "${pfid1}" != "${pfid2}" ]]; then
16909                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16910         fi
16911
16912         size=${entry[8]}
16913         if ((size != 1048576)); then
16914                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16915         fi
16916
16917         flags=${entry[10]}
16918         if [[ "${flags}" != "w" ]]; then
16919                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16920         fi
16921
16922         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16923         sleep 5
16924
16925         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16926                 error "cannot read '${file}'"
16927         sleep 5
16928
16929         do_facet ost1 killall -TERM ofd_access_log_reader
16930         wait
16931         rc=$?
16932
16933         if ((rc != 0)); then
16934                 error "ofd_access_log_reader exited with rc = '${rc}'"
16935         fi
16936
16937         oalr_expect_event_count alr_log_entry "${trace}" 1
16938
16939         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16940         echo "entry = '${entry[*]}'" >&2
16941
16942         pfid2=${entry[4]}
16943         if [[ "${pfid1}" != "${pfid2}" ]]; then
16944                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16945         fi
16946
16947         size=${entry[8]}
16948         if ((size != 524288)); then
16949                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16950         fi
16951
16952         flags=${entry[10]}
16953         if [[ "${flags}" != "r" ]]; then
16954                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16955         fi
16956 }
16957 run_test 165b "ofd access log entries are produced and consumed"
16958
16959 test_165c() {
16960         local trace="/tmp/${tfile}.trace"
16961         local file="${DIR}/${tdir}/${tfile}"
16962
16963         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16964                 skip "OFD access log unsupported"
16965
16966         test_mkdir "${DIR}/${tdir}"
16967
16968         setup_165
16969         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16970         sleep 5
16971
16972         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16973
16974         # 4096 / 64 = 64. Create twice as many entries.
16975         for ((i = 0; i < 128; i++)); do
16976                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16977                         error "cannot create file"
16978         done
16979
16980         sync
16981
16982         do_facet ost1 killall -TERM ofd_access_log_reader
16983         wait
16984         rc=$?
16985         if ((rc != 0)); then
16986                 error "ofd_access_log_reader exited with rc = '${rc}'"
16987         fi
16988
16989         unlinkmany  "${file}-%d" 128
16990 }
16991 run_test 165c "full ofd access logs do not block IOs"
16992
16993 oal_get_read_count() {
16994         local stats="$1"
16995
16996         # STATS lustre-OST0001 alr_read_count 1
16997
16998         do_facet ost1 cat "${stats}" |
16999         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17000              END { print count; }'
17001 }
17002
17003 oal_expect_read_count() {
17004         local stats="$1"
17005         local count
17006         local expect="$2"
17007
17008         # Ask ofd_access_log_reader to write stats.
17009         do_facet ost1 killall -USR1 ofd_access_log_reader
17010
17011         # Allow some time for things to happen.
17012         sleep 1
17013
17014         count=$(oal_get_read_count "${stats}")
17015         if ((count == expect)); then
17016                 return 0
17017         fi
17018
17019         error_noexit "bad read count, got ${count}, expected ${expect}"
17020         do_facet ost1 cat "${stats}" >&2
17021         exit 1
17022 }
17023
17024 test_165d() {
17025         local stats="/tmp/${tfile}.stats"
17026         local file="${DIR}/${tdir}/${tfile}"
17027         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17028
17029         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17030                 skip "OFD access log unsupported"
17031
17032         test_mkdir "${DIR}/${tdir}"
17033
17034         setup_165
17035         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17036         sleep 5
17037
17038         lfs setstripe -c 1 -i 0 "${file}"
17039
17040         do_facet ost1 lctl set_param "${param}=rw"
17041         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17042                 error "cannot create '${file}'"
17043         oal_expect_read_count "${stats}" 1
17044
17045         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17046                 error "cannot read '${file}'"
17047         oal_expect_read_count "${stats}" 2
17048
17049         do_facet ost1 lctl set_param "${param}=r"
17050         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17051                 error "cannot create '${file}'"
17052         oal_expect_read_count "${stats}" 2
17053
17054         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17055                 error "cannot read '${file}'"
17056         oal_expect_read_count "${stats}" 3
17057
17058         do_facet ost1 lctl set_param "${param}=w"
17059         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17060                 error "cannot create '${file}'"
17061         oal_expect_read_count "${stats}" 4
17062
17063         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17064                 error "cannot read '${file}'"
17065         oal_expect_read_count "${stats}" 4
17066
17067         do_facet ost1 lctl set_param "${param}=0"
17068         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17069                 error "cannot create '${file}'"
17070         oal_expect_read_count "${stats}" 4
17071
17072         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17073                 error "cannot read '${file}'"
17074         oal_expect_read_count "${stats}" 4
17075
17076         do_facet ost1 killall -TERM ofd_access_log_reader
17077         wait
17078         rc=$?
17079         if ((rc != 0)); then
17080                 error "ofd_access_log_reader exited with rc = '${rc}'"
17081         fi
17082 }
17083 run_test 165d "ofd_access_log mask works"
17084
17085 test_165e() {
17086         local stats="/tmp/${tfile}.stats"
17087         local file0="${DIR}/${tdir}-0/${tfile}"
17088         local file1="${DIR}/${tdir}-1/${tfile}"
17089
17090         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17091                 skip "OFD access log unsupported"
17092
17093         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17094
17095         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17096         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17097
17098         lfs setstripe -c 1 -i 0 "${file0}"
17099         lfs setstripe -c 1 -i 0 "${file1}"
17100
17101         setup_165
17102         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17103         sleep 5
17104
17105         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17106                 error "cannot create '${file0}'"
17107         sync
17108         oal_expect_read_count "${stats}" 0
17109
17110         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17111                 error "cannot create '${file1}'"
17112         sync
17113         oal_expect_read_count "${stats}" 1
17114
17115         do_facet ost1 killall -TERM ofd_access_log_reader
17116         wait
17117         rc=$?
17118         if ((rc != 0)); then
17119                 error "ofd_access_log_reader exited with rc = '${rc}'"
17120         fi
17121 }
17122 run_test 165e "ofd_access_log MDT index filter works"
17123
17124 test_165f() {
17125         local trace="/tmp/${tfile}.trace"
17126         local rc
17127         local count
17128
17129         setup_165
17130         do_facet ost1 timeout 60 ofd_access_log_reader \
17131                 --exit-on-close --debug=- --trace=- > "${trace}" &
17132         sleep 5
17133         stop ost1
17134
17135         wait
17136         rc=$?
17137
17138         if ((rc != 0)); then
17139                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17140                 cat "${trace}"
17141                 exit 1
17142         fi
17143 }
17144 run_test 165f "ofd_access_log_reader --exit-on-close works"
17145
17146 test_169() {
17147         # do directio so as not to populate the page cache
17148         log "creating a 10 Mb file"
17149         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17150                 error "multiop failed while creating a file"
17151         log "starting reads"
17152         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17153         log "truncating the file"
17154         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17155                 error "multiop failed while truncating the file"
17156         log "killing dd"
17157         kill %+ || true # reads might have finished
17158         echo "wait until dd is finished"
17159         wait
17160         log "removing the temporary file"
17161         rm -rf $DIR/$tfile || error "tmp file removal failed"
17162 }
17163 run_test 169 "parallel read and truncate should not deadlock"
17164
17165 test_170() {
17166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17167
17168         $LCTL clear     # bug 18514
17169         $LCTL debug_daemon start $TMP/${tfile}_log_good
17170         touch $DIR/$tfile
17171         $LCTL debug_daemon stop
17172         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17173                 error "sed failed to read log_good"
17174
17175         $LCTL debug_daemon start $TMP/${tfile}_log_good
17176         rm -rf $DIR/$tfile
17177         $LCTL debug_daemon stop
17178
17179         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17180                error "lctl df log_bad failed"
17181
17182         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17183         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17184
17185         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17186         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17187
17188         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17189                 error "bad_line good_line1 good_line2 are empty"
17190
17191         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17192         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17193         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17194
17195         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17196         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17197         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17198
17199         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17200                 error "bad_line_new good_line_new are empty"
17201
17202         local expected_good=$((good_line1 + good_line2*2))
17203
17204         rm -f $TMP/${tfile}*
17205         # LU-231, short malformed line may not be counted into bad lines
17206         if [ $bad_line -ne $bad_line_new ] &&
17207                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17208                 error "expected $bad_line bad lines, but got $bad_line_new"
17209                 return 1
17210         fi
17211
17212         if [ $expected_good -ne $good_line_new ]; then
17213                 error "expected $expected_good good lines, but got $good_line_new"
17214                 return 2
17215         fi
17216         true
17217 }
17218 run_test 170 "test lctl df to handle corrupted log ====================="
17219
17220 test_171() { # bug20592
17221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17222
17223         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17224         $LCTL set_param fail_loc=0x50e
17225         $LCTL set_param fail_val=3000
17226         multiop_bg_pause $DIR/$tfile O_s || true
17227         local MULTIPID=$!
17228         kill -USR1 $MULTIPID
17229         # cause log dump
17230         sleep 3
17231         wait $MULTIPID
17232         if dmesg | grep "recursive fault"; then
17233                 error "caught a recursive fault"
17234         fi
17235         $LCTL set_param fail_loc=0
17236         true
17237 }
17238 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17239
17240 # it would be good to share it with obdfilter-survey/iokit-libecho code
17241 setup_obdecho_osc () {
17242         local rc=0
17243         local ost_nid=$1
17244         local obdfilter_name=$2
17245         echo "Creating new osc for $obdfilter_name on $ost_nid"
17246         # make sure we can find loopback nid
17247         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17248
17249         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17250                            ${obdfilter_name}_osc_UUID || rc=2; }
17251         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17252                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17253         return $rc
17254 }
17255
17256 cleanup_obdecho_osc () {
17257         local obdfilter_name=$1
17258         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17259         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17260         return 0
17261 }
17262
17263 obdecho_test() {
17264         local OBD=$1
17265         local node=$2
17266         local pages=${3:-64}
17267         local rc=0
17268         local id
17269
17270         local count=10
17271         local obd_size=$(get_obd_size $node $OBD)
17272         local page_size=$(get_page_size $node)
17273         if [[ -n "$obd_size" ]]; then
17274                 local new_count=$((obd_size / (pages * page_size / 1024)))
17275                 [[ $new_count -ge $count ]] || count=$new_count
17276         fi
17277
17278         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17279         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17280                            rc=2; }
17281         if [ $rc -eq 0 ]; then
17282             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17283             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17284         fi
17285         echo "New object id is $id"
17286         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17287                            rc=4; }
17288         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17289                            "test_brw $count w v $pages $id" || rc=4; }
17290         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17291                            rc=4; }
17292         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17293                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17294         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17295                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17296         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17297         return $rc
17298 }
17299
17300 test_180a() {
17301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17302
17303         if ! [ -d /sys/fs/lustre/echo_client ] &&
17304            ! module_loaded obdecho; then
17305                 load_module obdecho/obdecho &&
17306                         stack_trap "rmmod obdecho" EXIT ||
17307                         error "unable to load obdecho on client"
17308         fi
17309
17310         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17311         local host=$($LCTL get_param -n osc.$osc.import |
17312                      awk '/current_connection:/ { print $2 }' )
17313         local target=$($LCTL get_param -n osc.$osc.import |
17314                        awk '/target:/ { print $2 }' )
17315         target=${target%_UUID}
17316
17317         if [ -n "$target" ]; then
17318                 setup_obdecho_osc $host $target &&
17319                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17320                         { error "obdecho setup failed with $?"; return; }
17321
17322                 obdecho_test ${target}_osc client ||
17323                         error "obdecho_test failed on ${target}_osc"
17324         else
17325                 $LCTL get_param osc.$osc.import
17326                 error "there is no osc.$osc.import target"
17327         fi
17328 }
17329 run_test 180a "test obdecho on osc"
17330
17331 test_180b() {
17332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17333         remote_ost_nodsh && skip "remote OST with nodsh"
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                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17344         else
17345                 do_facet ost1 $LCTL dl
17346                 error "there is no obdfilter target on ost1"
17347         fi
17348 }
17349 run_test 180b "test obdecho directly on obdfilter"
17350
17351 test_180c() { # LU-2598
17352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17353         remote_ost_nodsh && skip "remote OST with nodsh"
17354         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17355                 skip "Need MDS version at least 2.4.0"
17356
17357         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17358                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17359                 error "failed to load module obdecho"
17360
17361         local target=$(do_facet ost1 $LCTL dl |
17362                        awk '/obdfilter/ { print $4; exit; }')
17363
17364         if [ -n "$target" ]; then
17365                 local pages=16384 # 64MB bulk I/O RPC size
17366
17367                 obdecho_test "$target" ost1 "$pages" ||
17368                         error "obdecho_test with pages=$pages failed with $?"
17369         else
17370                 do_facet ost1 $LCTL dl
17371                 error "there is no obdfilter target on ost1"
17372         fi
17373 }
17374 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17375
17376 test_181() { # bug 22177
17377         test_mkdir $DIR/$tdir
17378         # create enough files to index the directory
17379         createmany -o $DIR/$tdir/foobar 4000
17380         # print attributes for debug purpose
17381         lsattr -d .
17382         # open dir
17383         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17384         MULTIPID=$!
17385         # remove the files & current working dir
17386         unlinkmany $DIR/$tdir/foobar 4000
17387         rmdir $DIR/$tdir
17388         kill -USR1 $MULTIPID
17389         wait $MULTIPID
17390         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17391         return 0
17392 }
17393 run_test 181 "Test open-unlinked dir ========================"
17394
17395 test_182() {
17396         local fcount=1000
17397         local tcount=10
17398
17399         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17400
17401         $LCTL set_param mdc.*.rpc_stats=clear
17402
17403         for (( i = 0; i < $tcount; i++ )) ; do
17404                 mkdir $DIR/$tdir/$i
17405         done
17406
17407         for (( i = 0; i < $tcount; i++ )) ; do
17408                 createmany -o $DIR/$tdir/$i/f- $fcount &
17409         done
17410         wait
17411
17412         for (( i = 0; i < $tcount; i++ )) ; do
17413                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17414         done
17415         wait
17416
17417         $LCTL get_param mdc.*.rpc_stats
17418
17419         rm -rf $DIR/$tdir
17420 }
17421 run_test 182 "Test parallel modify metadata operations ================"
17422
17423 test_183() { # LU-2275
17424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17425         remote_mds_nodsh && skip "remote MDS with nodsh"
17426         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17427                 skip "Need MDS version at least 2.3.56"
17428
17429         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17430         echo aaa > $DIR/$tdir/$tfile
17431
17432 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17433         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17434
17435         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17436         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17437
17438         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17439
17440         # Flush negative dentry cache
17441         touch $DIR/$tdir/$tfile
17442
17443         # We are not checking for any leaked references here, they'll
17444         # become evident next time we do cleanup with module unload.
17445         rm -rf $DIR/$tdir
17446 }
17447 run_test 183 "No crash or request leak in case of strange dispositions ========"
17448
17449 # test suite 184 is for LU-2016, LU-2017
17450 test_184a() {
17451         check_swap_layouts_support
17452
17453         dir0=$DIR/$tdir/$testnum
17454         test_mkdir -p -c1 $dir0
17455         ref1=/etc/passwd
17456         ref2=/etc/group
17457         file1=$dir0/f1
17458         file2=$dir0/f2
17459         $LFS setstripe -c1 $file1
17460         cp $ref1 $file1
17461         $LFS setstripe -c2 $file2
17462         cp $ref2 $file2
17463         gen1=$($LFS getstripe -g $file1)
17464         gen2=$($LFS getstripe -g $file2)
17465
17466         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17467         gen=$($LFS getstripe -g $file1)
17468         [[ $gen1 != $gen ]] ||
17469                 "Layout generation on $file1 does not change"
17470         gen=$($LFS getstripe -g $file2)
17471         [[ $gen2 != $gen ]] ||
17472                 "Layout generation on $file2 does not change"
17473
17474         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17475         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17476
17477         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17478 }
17479 run_test 184a "Basic layout swap"
17480
17481 test_184b() {
17482         check_swap_layouts_support
17483
17484         dir0=$DIR/$tdir/$testnum
17485         mkdir -p $dir0 || error "creating dir $dir0"
17486         file1=$dir0/f1
17487         file2=$dir0/f2
17488         file3=$dir0/f3
17489         dir1=$dir0/d1
17490         dir2=$dir0/d2
17491         mkdir $dir1 $dir2
17492         $LFS setstripe -c1 $file1
17493         $LFS setstripe -c2 $file2
17494         $LFS setstripe -c1 $file3
17495         chown $RUNAS_ID $file3
17496         gen1=$($LFS getstripe -g $file1)
17497         gen2=$($LFS getstripe -g $file2)
17498
17499         $LFS swap_layouts $dir1 $dir2 &&
17500                 error "swap of directories layouts should fail"
17501         $LFS swap_layouts $dir1 $file1 &&
17502                 error "swap of directory and file layouts should fail"
17503         $RUNAS $LFS swap_layouts $file1 $file2 &&
17504                 error "swap of file we cannot write should fail"
17505         $LFS swap_layouts $file1 $file3 &&
17506                 error "swap of file with different owner should fail"
17507         /bin/true # to clear error code
17508 }
17509 run_test 184b "Forbidden layout swap (will generate errors)"
17510
17511 test_184c() {
17512         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17513         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17514         check_swap_layouts_support
17515         check_swap_layout_no_dom $DIR
17516
17517         local dir0=$DIR/$tdir/$testnum
17518         mkdir -p $dir0 || error "creating dir $dir0"
17519
17520         local ref1=$dir0/ref1
17521         local ref2=$dir0/ref2
17522         local file1=$dir0/file1
17523         local file2=$dir0/file2
17524         # create a file large enough for the concurrent test
17525         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17526         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17527         echo "ref file size: ref1($(stat -c %s $ref1))," \
17528              "ref2($(stat -c %s $ref2))"
17529
17530         cp $ref2 $file2
17531         dd if=$ref1 of=$file1 bs=16k &
17532         local DD_PID=$!
17533
17534         # Make sure dd starts to copy file, but wait at most 5 seconds
17535         local loops=0
17536         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17537
17538         $LFS swap_layouts $file1 $file2
17539         local rc=$?
17540         wait $DD_PID
17541         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17542         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17543
17544         # how many bytes copied before swapping layout
17545         local copied=$(stat -c %s $file2)
17546         local remaining=$(stat -c %s $ref1)
17547         remaining=$((remaining - copied))
17548         echo "Copied $copied bytes before swapping layout..."
17549
17550         cmp -n $copied $file1 $ref2 | grep differ &&
17551                 error "Content mismatch [0, $copied) of ref2 and file1"
17552         cmp -n $copied $file2 $ref1 ||
17553                 error "Content mismatch [0, $copied) of ref1 and file2"
17554         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17555                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17556
17557         # clean up
17558         rm -f $ref1 $ref2 $file1 $file2
17559 }
17560 run_test 184c "Concurrent write and layout swap"
17561
17562 test_184d() {
17563         check_swap_layouts_support
17564         check_swap_layout_no_dom $DIR
17565         [ -z "$(which getfattr 2>/dev/null)" ] &&
17566                 skip_env "no getfattr command"
17567
17568         local file1=$DIR/$tdir/$tfile-1
17569         local file2=$DIR/$tdir/$tfile-2
17570         local file3=$DIR/$tdir/$tfile-3
17571         local lovea1
17572         local lovea2
17573
17574         mkdir -p $DIR/$tdir
17575         touch $file1 || error "create $file1 failed"
17576         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17577                 error "create $file2 failed"
17578         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17579                 error "create $file3 failed"
17580         lovea1=$(get_layout_param $file1)
17581
17582         $LFS swap_layouts $file2 $file3 ||
17583                 error "swap $file2 $file3 layouts failed"
17584         $LFS swap_layouts $file1 $file2 ||
17585                 error "swap $file1 $file2 layouts failed"
17586
17587         lovea2=$(get_layout_param $file2)
17588         echo "$lovea1"
17589         echo "$lovea2"
17590         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17591
17592         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17593         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17594 }
17595 run_test 184d "allow stripeless layouts swap"
17596
17597 test_184e() {
17598         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17599                 skip "Need MDS version at least 2.6.94"
17600         check_swap_layouts_support
17601         check_swap_layout_no_dom $DIR
17602         [ -z "$(which getfattr 2>/dev/null)" ] &&
17603                 skip_env "no getfattr command"
17604
17605         local file1=$DIR/$tdir/$tfile-1
17606         local file2=$DIR/$tdir/$tfile-2
17607         local file3=$DIR/$tdir/$tfile-3
17608         local lovea
17609
17610         mkdir -p $DIR/$tdir
17611         touch $file1 || error "create $file1 failed"
17612         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17613                 error "create $file2 failed"
17614         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17615                 error "create $file3 failed"
17616
17617         $LFS swap_layouts $file1 $file2 ||
17618                 error "swap $file1 $file2 layouts failed"
17619
17620         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17621         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17622
17623         echo 123 > $file1 || error "Should be able to write into $file1"
17624
17625         $LFS swap_layouts $file1 $file3 ||
17626                 error "swap $file1 $file3 layouts failed"
17627
17628         echo 123 > $file1 || error "Should be able to write into $file1"
17629
17630         rm -rf $file1 $file2 $file3
17631 }
17632 run_test 184e "Recreate layout after stripeless layout swaps"
17633
17634 test_184f() {
17635         # Create a file with name longer than sizeof(struct stat) ==
17636         # 144 to see if we can get chars from the file name to appear
17637         # in the returned striping. Note that 'f' == 0x66.
17638         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17639
17640         mkdir -p $DIR/$tdir
17641         mcreate $DIR/$tdir/$file
17642         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17643                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17644         fi
17645 }
17646 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17647
17648 test_185() { # LU-2441
17649         # LU-3553 - no volatile file support in old servers
17650         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17651                 skip "Need MDS version at least 2.3.60"
17652
17653         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17654         touch $DIR/$tdir/spoo
17655         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17656         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17657                 error "cannot create/write a volatile file"
17658         [ "$FILESET" == "" ] &&
17659         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17660                 error "FID is still valid after close"
17661
17662         multiop_bg_pause $DIR/$tdir vVw4096_c
17663         local multi_pid=$!
17664
17665         local OLD_IFS=$IFS
17666         IFS=":"
17667         local fidv=($fid)
17668         IFS=$OLD_IFS
17669         # assume that the next FID for this client is sequential, since stdout
17670         # is unfortunately eaten by multiop_bg_pause
17671         local n=$((${fidv[1]} + 1))
17672         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17673         if [ "$FILESET" == "" ]; then
17674                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17675                         error "FID is missing before close"
17676         fi
17677         kill -USR1 $multi_pid
17678         # 1 second delay, so if mtime change we will see it
17679         sleep 1
17680         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17681         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17682 }
17683 run_test 185 "Volatile file support"
17684
17685 function create_check_volatile() {
17686         local idx=$1
17687         local tgt
17688
17689         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17690         local PID=$!
17691         sleep 1
17692         local FID=$(cat /tmp/${tfile}.fid)
17693         [ "$FID" == "" ] && error "can't get FID for volatile"
17694         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17695         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17696         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17697         kill -USR1 $PID
17698         wait
17699         sleep 1
17700         cancel_lru_locks mdc # flush opencache
17701         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17702         return 0
17703 }
17704
17705 test_185a(){
17706         # LU-12516 - volatile creation via .lustre
17707         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17708                 skip "Need MDS version at least 2.3.55"
17709
17710         create_check_volatile 0
17711         [ $MDSCOUNT -lt 2 ] && return 0
17712
17713         # DNE case
17714         create_check_volatile 1
17715
17716         return 0
17717 }
17718 run_test 185a "Volatile file creation in .lustre/fid/"
17719
17720 test_187a() {
17721         remote_mds_nodsh && skip "remote MDS with nodsh"
17722         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17723                 skip "Need MDS version at least 2.3.0"
17724
17725         local dir0=$DIR/$tdir/$testnum
17726         mkdir -p $dir0 || error "creating dir $dir0"
17727
17728         local file=$dir0/file1
17729         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17730         local dv1=$($LFS data_version $file)
17731         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17732         local dv2=$($LFS data_version $file)
17733         [[ $dv1 != $dv2 ]] ||
17734                 error "data version did not change on write $dv1 == $dv2"
17735
17736         # clean up
17737         rm -f $file1
17738 }
17739 run_test 187a "Test data version change"
17740
17741 test_187b() {
17742         remote_mds_nodsh && skip "remote MDS with nodsh"
17743         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17744                 skip "Need MDS version at least 2.3.0"
17745
17746         local dir0=$DIR/$tdir/$testnum
17747         mkdir -p $dir0 || error "creating dir $dir0"
17748
17749         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17750         [[ ${DV[0]} != ${DV[1]} ]] ||
17751                 error "data version did not change on write"\
17752                       " ${DV[0]} == ${DV[1]}"
17753
17754         # clean up
17755         rm -f $file1
17756 }
17757 run_test 187b "Test data version change on volatile file"
17758
17759 test_200() {
17760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17761         remote_mgs_nodsh && skip "remote MGS with nodsh"
17762         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17763
17764         local POOL=${POOL:-cea1}
17765         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17766         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17767         # Pool OST targets
17768         local first_ost=0
17769         local last_ost=$(($OSTCOUNT - 1))
17770         local ost_step=2
17771         local ost_list=$(seq $first_ost $ost_step $last_ost)
17772         local ost_range="$first_ost $last_ost $ost_step"
17773         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17774         local file_dir=$POOL_ROOT/file_tst
17775         local subdir=$test_path/subdir
17776         local rc=0
17777
17778         while : ; do
17779                 # former test_200a test_200b
17780                 pool_add $POOL                          || { rc=$? ; break; }
17781                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17782                 # former test_200c test_200d
17783                 mkdir -p $test_path
17784                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17785                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17786                 mkdir -p $subdir
17787                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17788                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17789                                                         || { rc=$? ; break; }
17790                 # former test_200e test_200f
17791                 local files=$((OSTCOUNT*3))
17792                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17793                                                         || { rc=$? ; break; }
17794                 pool_create_files $POOL $file_dir $files "$ost_list" \
17795                                                         || { rc=$? ; break; }
17796                 # former test_200g test_200h
17797                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17798                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17799
17800                 # former test_201a test_201b test_201c
17801                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17802
17803                 local f=$test_path/$tfile
17804                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17805                 pool_remove $POOL $f                    || { rc=$? ; break; }
17806                 break
17807         done
17808
17809         destroy_test_pools
17810
17811         return $rc
17812 }
17813 run_test 200 "OST pools"
17814
17815 # usage: default_attr <count | size | offset>
17816 default_attr() {
17817         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17818 }
17819
17820 # usage: check_default_stripe_attr
17821 check_default_stripe_attr() {
17822         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17823         case $1 in
17824         --stripe-count|-c)
17825                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17826         --stripe-size|-S)
17827                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17828         --stripe-index|-i)
17829                 EXPECTED=-1;;
17830         *)
17831                 error "unknown getstripe attr '$1'"
17832         esac
17833
17834         [ $ACTUAL == $EXPECTED ] ||
17835                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17836 }
17837
17838 test_204a() {
17839         test_mkdir $DIR/$tdir
17840         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17841
17842         check_default_stripe_attr --stripe-count
17843         check_default_stripe_attr --stripe-size
17844         check_default_stripe_attr --stripe-index
17845 }
17846 run_test 204a "Print default stripe attributes"
17847
17848 test_204b() {
17849         test_mkdir $DIR/$tdir
17850         $LFS setstripe --stripe-count 1 $DIR/$tdir
17851
17852         check_default_stripe_attr --stripe-size
17853         check_default_stripe_attr --stripe-index
17854 }
17855 run_test 204b "Print default stripe size and offset"
17856
17857 test_204c() {
17858         test_mkdir $DIR/$tdir
17859         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17860
17861         check_default_stripe_attr --stripe-count
17862         check_default_stripe_attr --stripe-index
17863 }
17864 run_test 204c "Print default stripe count and offset"
17865
17866 test_204d() {
17867         test_mkdir $DIR/$tdir
17868         $LFS setstripe --stripe-index 0 $DIR/$tdir
17869
17870         check_default_stripe_attr --stripe-count
17871         check_default_stripe_attr --stripe-size
17872 }
17873 run_test 204d "Print default stripe count and size"
17874
17875 test_204e() {
17876         test_mkdir $DIR/$tdir
17877         $LFS setstripe -d $DIR/$tdir
17878
17879         check_default_stripe_attr --stripe-count --raw
17880         check_default_stripe_attr --stripe-size --raw
17881         check_default_stripe_attr --stripe-index --raw
17882 }
17883 run_test 204e "Print raw stripe attributes"
17884
17885 test_204f() {
17886         test_mkdir $DIR/$tdir
17887         $LFS setstripe --stripe-count 1 $DIR/$tdir
17888
17889         check_default_stripe_attr --stripe-size --raw
17890         check_default_stripe_attr --stripe-index --raw
17891 }
17892 run_test 204f "Print raw stripe size and offset"
17893
17894 test_204g() {
17895         test_mkdir $DIR/$tdir
17896         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17897
17898         check_default_stripe_attr --stripe-count --raw
17899         check_default_stripe_attr --stripe-index --raw
17900 }
17901 run_test 204g "Print raw stripe count and offset"
17902
17903 test_204h() {
17904         test_mkdir $DIR/$tdir
17905         $LFS setstripe --stripe-index 0 $DIR/$tdir
17906
17907         check_default_stripe_attr --stripe-count --raw
17908         check_default_stripe_attr --stripe-size --raw
17909 }
17910 run_test 204h "Print raw stripe count and size"
17911
17912 # Figure out which job scheduler is being used, if any,
17913 # or use a fake one
17914 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17915         JOBENV=SLURM_JOB_ID
17916 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17917         JOBENV=LSB_JOBID
17918 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17919         JOBENV=PBS_JOBID
17920 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17921         JOBENV=LOADL_STEP_ID
17922 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17923         JOBENV=JOB_ID
17924 else
17925         $LCTL list_param jobid_name > /dev/null 2>&1
17926         if [ $? -eq 0 ]; then
17927                 JOBENV=nodelocal
17928         else
17929                 JOBENV=FAKE_JOBID
17930         fi
17931 fi
17932 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17933
17934 verify_jobstats() {
17935         local cmd=($1)
17936         shift
17937         local facets="$@"
17938
17939 # we don't really need to clear the stats for this test to work, since each
17940 # command has a unique jobid, but it makes debugging easier if needed.
17941 #       for facet in $facets; do
17942 #               local dev=$(convert_facet2label $facet)
17943 #               # clear old jobstats
17944 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17945 #       done
17946
17947         # use a new JobID for each test, or we might see an old one
17948         [ "$JOBENV" = "FAKE_JOBID" ] &&
17949                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17950
17951         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17952
17953         [ "$JOBENV" = "nodelocal" ] && {
17954                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17955                 $LCTL set_param jobid_name=$FAKE_JOBID
17956                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17957         }
17958
17959         log "Test: ${cmd[*]}"
17960         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17961
17962         if [ $JOBENV = "FAKE_JOBID" ]; then
17963                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17964         else
17965                 ${cmd[*]}
17966         fi
17967
17968         # all files are created on OST0000
17969         for facet in $facets; do
17970                 local stats="*.$(convert_facet2label $facet).job_stats"
17971
17972                 # strip out libtool wrappers for in-tree executables
17973                 if [ $(do_facet $facet lctl get_param $stats |
17974                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17975                         do_facet $facet lctl get_param $stats
17976                         error "No jobstats for $JOBVAL found on $facet::$stats"
17977                 fi
17978         done
17979 }
17980
17981 jobstats_set() {
17982         local new_jobenv=$1
17983
17984         set_persistent_param_and_check client "jobid_var" \
17985                 "$FSNAME.sys.jobid_var" $new_jobenv
17986 }
17987
17988 test_205a() { # Job stats
17989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17990         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17991                 skip "Need MDS version with at least 2.7.1"
17992         remote_mgs_nodsh && skip "remote MGS with nodsh"
17993         remote_mds_nodsh && skip "remote MDS with nodsh"
17994         remote_ost_nodsh && skip "remote OST with nodsh"
17995         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17996                 skip "Server doesn't support jobstats"
17997         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17998
17999         local old_jobenv=$($LCTL get_param -n jobid_var)
18000         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18001
18002         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18003                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18004         else
18005                 stack_trap "do_facet mgs $PERM_CMD \
18006                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18007         fi
18008         changelog_register
18009
18010         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18011                                 mdt.*.job_cleanup_interval | head -n 1)
18012         local new_interval=5
18013         do_facet $SINGLEMDS \
18014                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18015         stack_trap "do_facet $SINGLEMDS \
18016                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18017         local start=$SECONDS
18018
18019         local cmd
18020         # mkdir
18021         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18022         verify_jobstats "$cmd" "$SINGLEMDS"
18023         # rmdir
18024         cmd="rmdir $DIR/$tdir"
18025         verify_jobstats "$cmd" "$SINGLEMDS"
18026         # mkdir on secondary MDT
18027         if [ $MDSCOUNT -gt 1 ]; then
18028                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18029                 verify_jobstats "$cmd" "mds2"
18030         fi
18031         # mknod
18032         cmd="mknod $DIR/$tfile c 1 3"
18033         verify_jobstats "$cmd" "$SINGLEMDS"
18034         # unlink
18035         cmd="rm -f $DIR/$tfile"
18036         verify_jobstats "$cmd" "$SINGLEMDS"
18037         # create all files on OST0000 so verify_jobstats can find OST stats
18038         # open & close
18039         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18040         verify_jobstats "$cmd" "$SINGLEMDS"
18041         # setattr
18042         cmd="touch $DIR/$tfile"
18043         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18044         # write
18045         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18046         verify_jobstats "$cmd" "ost1"
18047         # read
18048         cancel_lru_locks osc
18049         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18050         verify_jobstats "$cmd" "ost1"
18051         # truncate
18052         cmd="$TRUNCATE $DIR/$tfile 0"
18053         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18054         # rename
18055         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18056         verify_jobstats "$cmd" "$SINGLEMDS"
18057         # jobstats expiry - sleep until old stats should be expired
18058         local left=$((new_interval + 5 - (SECONDS - start)))
18059         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18060                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18061                         "0" $left
18062         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18063         verify_jobstats "$cmd" "$SINGLEMDS"
18064         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18065             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18066
18067         # Ensure that jobid are present in changelog (if supported by MDS)
18068         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18069                 changelog_dump | tail -10
18070                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18071                 [ $jobids -eq 9 ] ||
18072                         error "Wrong changelog jobid count $jobids != 9"
18073
18074                 # LU-5862
18075                 JOBENV="disable"
18076                 jobstats_set $JOBENV
18077                 touch $DIR/$tfile
18078                 changelog_dump | grep $tfile
18079                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18080                 [ $jobids -eq 0 ] ||
18081                         error "Unexpected jobids when jobid_var=$JOBENV"
18082         fi
18083
18084         # test '%j' access to environment variable - if supported
18085         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18086                 JOBENV="JOBCOMPLEX"
18087                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18088
18089                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18090         fi
18091
18092         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18093                 JOBENV="JOBCOMPLEX"
18094                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18095
18096                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18097         fi
18098
18099         # test '%j' access to per-session jobid - if supported
18100         if lctl list_param jobid_this_session > /dev/null 2>&1
18101         then
18102                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18103                 lctl set_param jobid_this_session=$USER
18104
18105                 JOBENV="JOBCOMPLEX"
18106                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18107
18108                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18109         fi
18110 }
18111 run_test 205a "Verify job stats"
18112
18113 # LU-13117, LU-13597
18114 test_205b() {
18115         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18116                 skip "Need MDS version at least 2.13.54.91"
18117
18118         job_stats="mdt.*.job_stats"
18119         $LCTL set_param $job_stats=clear
18120         # Setting jobid_var to USER might not be supported
18121         $LCTL set_param jobid_var=USER || true
18122         $LCTL set_param jobid_name="%e.%u"
18123         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18124         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18125                 grep "job_id:.*foolish" &&
18126                         error "Unexpected jobid found"
18127         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18128                 grep "open:.*min.*max.*sum" ||
18129                         error "wrong job_stats format found"
18130 }
18131 run_test 205b "Verify job stats jobid and output format"
18132
18133 # LU-13733
18134 test_205c() {
18135         $LCTL set_param llite.*.stats=0
18136         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18137         $LCTL get_param llite.*.stats
18138         $LCTL get_param llite.*.stats | grep \
18139                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18140                         error "wrong client stats format found"
18141 }
18142 run_test 205c "Verify client stats format"
18143
18144 # LU-1480, LU-1773 and LU-1657
18145 test_206() {
18146         mkdir -p $DIR/$tdir
18147         $LFS setstripe -c -1 $DIR/$tdir
18148 #define OBD_FAIL_LOV_INIT 0x1403
18149         $LCTL set_param fail_loc=0xa0001403
18150         $LCTL set_param fail_val=1
18151         touch $DIR/$tdir/$tfile || true
18152 }
18153 run_test 206 "fail lov_init_raid0() doesn't lbug"
18154
18155 test_207a() {
18156         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18157         local fsz=`stat -c %s $DIR/$tfile`
18158         cancel_lru_locks mdc
18159
18160         # do not return layout in getattr intent
18161 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18162         $LCTL set_param fail_loc=0x170
18163         local sz=`stat -c %s $DIR/$tfile`
18164
18165         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18166
18167         rm -rf $DIR/$tfile
18168 }
18169 run_test 207a "can refresh layout at glimpse"
18170
18171 test_207b() {
18172         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18173         local cksum=`md5sum $DIR/$tfile`
18174         local fsz=`stat -c %s $DIR/$tfile`
18175         cancel_lru_locks mdc
18176         cancel_lru_locks osc
18177
18178         # do not return layout in getattr intent
18179 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18180         $LCTL set_param fail_loc=0x171
18181
18182         # it will refresh layout after the file is opened but before read issues
18183         echo checksum is "$cksum"
18184         echo "$cksum" |md5sum -c --quiet || error "file differs"
18185
18186         rm -rf $DIR/$tfile
18187 }
18188 run_test 207b "can refresh layout at open"
18189
18190 test_208() {
18191         # FIXME: in this test suite, only RD lease is used. This is okay
18192         # for now as only exclusive open is supported. After generic lease
18193         # is done, this test suite should be revised. - Jinshan
18194
18195         remote_mds_nodsh && skip "remote MDS with nodsh"
18196         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18197                 skip "Need MDS version at least 2.4.52"
18198
18199         echo "==== test 1: verify get lease work"
18200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18201
18202         echo "==== test 2: verify lease can be broken by upcoming open"
18203         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18204         local PID=$!
18205         sleep 1
18206
18207         $MULTIOP $DIR/$tfile oO_RDWR:c
18208         kill -USR1 $PID && wait $PID || error "break lease error"
18209
18210         echo "==== test 3: verify lease can't be granted if an open already exists"
18211         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18212         local PID=$!
18213         sleep 1
18214
18215         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18216         kill -USR1 $PID && wait $PID || error "open file error"
18217
18218         echo "==== test 4: lease can sustain over recovery"
18219         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18220         PID=$!
18221         sleep 1
18222
18223         fail mds1
18224
18225         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18226
18227         echo "==== test 5: lease broken can't be regained by replay"
18228         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18229         PID=$!
18230         sleep 1
18231
18232         # open file to break lease and then recovery
18233         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18234         fail mds1
18235
18236         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18237
18238         rm -f $DIR/$tfile
18239 }
18240 run_test 208 "Exclusive open"
18241
18242 test_209() {
18243         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18244                 skip_env "must have disp_stripe"
18245
18246         touch $DIR/$tfile
18247         sync; sleep 5; sync;
18248
18249         echo 3 > /proc/sys/vm/drop_caches
18250         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18251                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18252         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18253
18254         # open/close 500 times
18255         for i in $(seq 500); do
18256                 cat $DIR/$tfile
18257         done
18258
18259         echo 3 > /proc/sys/vm/drop_caches
18260         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18261                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18262         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18263
18264         echo "before: $req_before, after: $req_after"
18265         [ $((req_after - req_before)) -ge 300 ] &&
18266                 error "open/close requests are not freed"
18267         return 0
18268 }
18269 run_test 209 "read-only open/close requests should be freed promptly"
18270
18271 test_210() {
18272         local pid
18273
18274         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18275         pid=$!
18276         sleep 1
18277
18278         $LFS getstripe $DIR/$tfile
18279         kill -USR1 $pid
18280         wait $pid || error "multiop failed"
18281
18282         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18283         pid=$!
18284         sleep 1
18285
18286         $LFS getstripe $DIR/$tfile
18287         kill -USR1 $pid
18288         wait $pid || error "multiop failed"
18289 }
18290 run_test 210 "lfs getstripe does not break leases"
18291
18292 test_212() {
18293         size=`date +%s`
18294         size=$((size % 8192 + 1))
18295         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18296         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18297         rm -f $DIR/f212 $DIR/f212.xyz
18298 }
18299 run_test 212 "Sendfile test ============================================"
18300
18301 test_213() {
18302         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18303         cancel_lru_locks osc
18304         lctl set_param fail_loc=0x8000040f
18305         # generate a read lock
18306         cat $DIR/$tfile > /dev/null
18307         # write to the file, it will try to cancel the above read lock.
18308         cat /etc/hosts >> $DIR/$tfile
18309 }
18310 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18311
18312 test_214() { # for bug 20133
18313         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18314         for (( i=0; i < 340; i++ )) ; do
18315                 touch $DIR/$tdir/d214c/a$i
18316         done
18317
18318         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18319         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18320         ls $DIR/d214c || error "ls $DIR/d214c failed"
18321         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18322         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18323 }
18324 run_test 214 "hash-indexed directory test - bug 20133"
18325
18326 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18327 create_lnet_proc_files() {
18328         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18329 }
18330
18331 # counterpart of create_lnet_proc_files
18332 remove_lnet_proc_files() {
18333         rm -f $TMP/lnet_$1.sys
18334 }
18335
18336 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18337 # 3rd arg as regexp for body
18338 check_lnet_proc_stats() {
18339         local l=$(cat "$TMP/lnet_$1" |wc -l)
18340         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18341
18342         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18343 }
18344
18345 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18346 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18347 # optional and can be regexp for 2nd line (lnet.routes case)
18348 check_lnet_proc_entry() {
18349         local blp=2          # blp stands for 'position of 1st line of body'
18350         [ -z "$5" ] || blp=3 # lnet.routes case
18351
18352         local l=$(cat "$TMP/lnet_$1" |wc -l)
18353         # subtracting one from $blp because the body can be empty
18354         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18355
18356         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18357                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18358
18359         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18360                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18361
18362         # bail out if any unexpected line happened
18363         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18364         [ "$?" != 0 ] || error "$2 misformatted"
18365 }
18366
18367 test_215() { # for bugs 18102, 21079, 21517
18368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18369
18370         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18371         local P='[1-9][0-9]*'           # positive numeric
18372         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18373         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18374         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18375         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18376
18377         local L1 # regexp for 1st line
18378         local L2 # regexp for 2nd line (optional)
18379         local BR # regexp for the rest (body)
18380
18381         # lnet.stats should look as 11 space-separated non-negative numerics
18382         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18383         create_lnet_proc_files "stats"
18384         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18385         remove_lnet_proc_files "stats"
18386
18387         # lnet.routes should look like this:
18388         # Routing disabled/enabled
18389         # net hops priority state router
18390         # where net is a string like tcp0, hops > 0, priority >= 0,
18391         # state is up/down,
18392         # router is a string like 192.168.1.1@tcp2
18393         L1="^Routing (disabled|enabled)$"
18394         L2="^net +hops +priority +state +router$"
18395         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18396         create_lnet_proc_files "routes"
18397         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18398         remove_lnet_proc_files "routes"
18399
18400         # lnet.routers should look like this:
18401         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18402         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18403         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18404         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18405         L1="^ref +rtr_ref +alive +router$"
18406         BR="^$P +$P +(up|down) +$NID$"
18407         create_lnet_proc_files "routers"
18408         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18409         remove_lnet_proc_files "routers"
18410
18411         # lnet.peers should look like this:
18412         # nid refs state last max rtr min tx min queue
18413         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18414         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18415         # numeric (0 or >0 or <0), queue >= 0.
18416         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18417         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18418         create_lnet_proc_files "peers"
18419         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18420         remove_lnet_proc_files "peers"
18421
18422         # lnet.buffers  should look like this:
18423         # pages count credits min
18424         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18425         L1="^pages +count +credits +min$"
18426         BR="^ +$N +$N +$I +$I$"
18427         create_lnet_proc_files "buffers"
18428         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18429         remove_lnet_proc_files "buffers"
18430
18431         # lnet.nis should look like this:
18432         # nid status alive refs peer rtr max tx min
18433         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18434         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18435         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18436         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18437         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18438         create_lnet_proc_files "nis"
18439         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18440         remove_lnet_proc_files "nis"
18441
18442         # can we successfully write to lnet.stats?
18443         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18444 }
18445 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18446
18447 test_216() { # bug 20317
18448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18449         remote_ost_nodsh && skip "remote OST with nodsh"
18450
18451         local node
18452         local facets=$(get_facets OST)
18453         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18454
18455         save_lustre_params client "osc.*.contention_seconds" > $p
18456         save_lustre_params $facets \
18457                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18458         save_lustre_params $facets \
18459                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18460         save_lustre_params $facets \
18461                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18462         clear_stats osc.*.osc_stats
18463
18464         # agressive lockless i/o settings
18465         do_nodes $(comma_list $(osts_nodes)) \
18466                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18467                         ldlm.namespaces.filter-*.contended_locks=0 \
18468                         ldlm.namespaces.filter-*.contention_seconds=60"
18469         lctl set_param -n osc.*.contention_seconds=60
18470
18471         $DIRECTIO write $DIR/$tfile 0 10 4096
18472         $CHECKSTAT -s 40960 $DIR/$tfile
18473
18474         # disable lockless i/o
18475         do_nodes $(comma_list $(osts_nodes)) \
18476                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18477                         ldlm.namespaces.filter-*.contended_locks=32 \
18478                         ldlm.namespaces.filter-*.contention_seconds=0"
18479         lctl set_param -n osc.*.contention_seconds=0
18480         clear_stats osc.*.osc_stats
18481
18482         dd if=/dev/zero of=$DIR/$tfile count=0
18483         $CHECKSTAT -s 0 $DIR/$tfile
18484
18485         restore_lustre_params <$p
18486         rm -f $p
18487         rm $DIR/$tfile
18488 }
18489 run_test 216 "check lockless direct write updates file size and kms correctly"
18490
18491 test_217() { # bug 22430
18492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18493
18494         local node
18495         local nid
18496
18497         for node in $(nodes_list); do
18498                 nid=$(host_nids_address $node $NETTYPE)
18499                 if [[ $nid = *-* ]] ; then
18500                         echo "lctl ping $(h2nettype $nid)"
18501                         lctl ping $(h2nettype $nid)
18502                 else
18503                         echo "skipping $node (no hyphen detected)"
18504                 fi
18505         done
18506 }
18507 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18508
18509 test_218() {
18510        # do directio so as not to populate the page cache
18511        log "creating a 10 Mb file"
18512        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18513        log "starting reads"
18514        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18515        log "truncating the file"
18516        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18517        log "killing dd"
18518        kill %+ || true # reads might have finished
18519        echo "wait until dd is finished"
18520        wait
18521        log "removing the temporary file"
18522        rm -rf $DIR/$tfile || error "tmp file removal failed"
18523 }
18524 run_test 218 "parallel read and truncate should not deadlock"
18525
18526 test_219() {
18527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18528
18529         # write one partial page
18530         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18531         # set no grant so vvp_io_commit_write will do sync write
18532         $LCTL set_param fail_loc=0x411
18533         # write a full page at the end of file
18534         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18535
18536         $LCTL set_param fail_loc=0
18537         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18538         $LCTL set_param fail_loc=0x411
18539         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18540
18541         # LU-4201
18542         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18543         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18544 }
18545 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18546
18547 test_220() { #LU-325
18548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18549         remote_ost_nodsh && skip "remote OST with nodsh"
18550         remote_mds_nodsh && skip "remote MDS with nodsh"
18551         remote_mgs_nodsh && skip "remote MGS with nodsh"
18552
18553         local OSTIDX=0
18554
18555         # create on MDT0000 so the last_id and next_id are correct
18556         mkdir_on_mdt0 $DIR/$tdir
18557         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18558         OST=${OST%_UUID}
18559
18560         # on the mdt's osc
18561         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18562         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18563                         osp.$mdtosc_proc1.prealloc_last_id)
18564         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18565                         osp.$mdtosc_proc1.prealloc_next_id)
18566
18567         $LFS df -i
18568
18569         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18570         #define OBD_FAIL_OST_ENOINO              0x229
18571         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18572         create_pool $FSNAME.$TESTNAME || return 1
18573         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18574
18575         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18576
18577         MDSOBJS=$((last_id - next_id))
18578         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18579
18580         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18581         echo "OST still has $count kbytes free"
18582
18583         echo "create $MDSOBJS files @next_id..."
18584         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18585
18586         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18587                         osp.$mdtosc_proc1.prealloc_last_id)
18588         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18589                         osp.$mdtosc_proc1.prealloc_next_id)
18590
18591         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18592         $LFS df -i
18593
18594         echo "cleanup..."
18595
18596         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18597         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18598
18599         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18600                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18601         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18602                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18603         echo "unlink $MDSOBJS files @$next_id..."
18604         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18605 }
18606 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18607
18608 test_221() {
18609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18610
18611         dd if=`which date` of=$MOUNT/date oflag=sync
18612         chmod +x $MOUNT/date
18613
18614         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18615         $LCTL set_param fail_loc=0x80001401
18616
18617         $MOUNT/date > /dev/null
18618         rm -f $MOUNT/date
18619 }
18620 run_test 221 "make sure fault and truncate race to not cause OOM"
18621
18622 test_222a () {
18623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18624
18625         rm -rf $DIR/$tdir
18626         test_mkdir $DIR/$tdir
18627         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18628         createmany -o $DIR/$tdir/$tfile 10
18629         cancel_lru_locks mdc
18630         cancel_lru_locks osc
18631         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18632         $LCTL set_param fail_loc=0x31a
18633         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18634         $LCTL set_param fail_loc=0
18635         rm -r $DIR/$tdir
18636 }
18637 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18638
18639 test_222b () {
18640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18641
18642         rm -rf $DIR/$tdir
18643         test_mkdir $DIR/$tdir
18644         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18645         createmany -o $DIR/$tdir/$tfile 10
18646         cancel_lru_locks mdc
18647         cancel_lru_locks osc
18648         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18649         $LCTL set_param fail_loc=0x31a
18650         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18651         $LCTL set_param fail_loc=0
18652 }
18653 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18654
18655 test_223 () {
18656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18657
18658         rm -rf $DIR/$tdir
18659         test_mkdir $DIR/$tdir
18660         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18661         createmany -o $DIR/$tdir/$tfile 10
18662         cancel_lru_locks mdc
18663         cancel_lru_locks osc
18664         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18665         $LCTL set_param fail_loc=0x31b
18666         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18667         $LCTL set_param fail_loc=0
18668         rm -r $DIR/$tdir
18669 }
18670 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18671
18672 test_224a() { # LU-1039, MRP-303
18673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18674
18675         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18676         $LCTL set_param fail_loc=0x508
18677         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18678         $LCTL set_param fail_loc=0
18679         df $DIR
18680 }
18681 run_test 224a "Don't panic on bulk IO failure"
18682
18683 test_224b() { # LU-1039, MRP-303
18684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18685
18686         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18687         cancel_lru_locks osc
18688         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18689         $LCTL set_param fail_loc=0x515
18690         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18691         $LCTL set_param fail_loc=0
18692         df $DIR
18693 }
18694 run_test 224b "Don't panic on bulk IO failure"
18695
18696 test_224c() { # LU-6441
18697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18698         remote_mds_nodsh && skip "remote MDS with nodsh"
18699
18700         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18701         save_writethrough $p
18702         set_cache writethrough on
18703
18704         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18705         local at_max=$($LCTL get_param -n at_max)
18706         local timeout=$($LCTL get_param -n timeout)
18707         local test_at="at_max"
18708         local param_at="$FSNAME.sys.at_max"
18709         local test_timeout="timeout"
18710         local param_timeout="$FSNAME.sys.timeout"
18711
18712         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18713
18714         set_persistent_param_and_check client "$test_at" "$param_at" 0
18715         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18716
18717         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18718         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18719         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18720         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18721         sync
18722         do_facet ost1 "$LCTL set_param fail_loc=0"
18723
18724         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18725         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18726                 $timeout
18727
18728         $LCTL set_param -n $pages_per_rpc
18729         restore_lustre_params < $p
18730         rm -f $p
18731 }
18732 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18733
18734 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18735 test_225a () {
18736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18737         if [ -z ${MDSSURVEY} ]; then
18738                 skip_env "mds-survey not found"
18739         fi
18740         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18741                 skip "Need MDS version at least 2.2.51"
18742
18743         local mds=$(facet_host $SINGLEMDS)
18744         local target=$(do_nodes $mds 'lctl dl' |
18745                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18746
18747         local cmd1="file_count=1000 thrhi=4"
18748         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18749         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18750         local cmd="$cmd1 $cmd2 $cmd3"
18751
18752         rm -f ${TMP}/mds_survey*
18753         echo + $cmd
18754         eval $cmd || error "mds-survey with zero-stripe failed"
18755         cat ${TMP}/mds_survey*
18756         rm -f ${TMP}/mds_survey*
18757 }
18758 run_test 225a "Metadata survey sanity with zero-stripe"
18759
18760 test_225b () {
18761         if [ -z ${MDSSURVEY} ]; then
18762                 skip_env "mds-survey not found"
18763         fi
18764         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18765                 skip "Need MDS version at least 2.2.51"
18766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18767         remote_mds_nodsh && skip "remote MDS with nodsh"
18768         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18769                 skip_env "Need to mount OST to test"
18770         fi
18771
18772         local mds=$(facet_host $SINGLEMDS)
18773         local target=$(do_nodes $mds 'lctl dl' |
18774                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18775
18776         local cmd1="file_count=1000 thrhi=4"
18777         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18778         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18779         local cmd="$cmd1 $cmd2 $cmd3"
18780
18781         rm -f ${TMP}/mds_survey*
18782         echo + $cmd
18783         eval $cmd || error "mds-survey with stripe_count failed"
18784         cat ${TMP}/mds_survey*
18785         rm -f ${TMP}/mds_survey*
18786 }
18787 run_test 225b "Metadata survey sanity with stripe_count = 1"
18788
18789 mcreate_path2fid () {
18790         local mode=$1
18791         local major=$2
18792         local minor=$3
18793         local name=$4
18794         local desc=$5
18795         local path=$DIR/$tdir/$name
18796         local fid
18797         local rc
18798         local fid_path
18799
18800         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18801                 error "cannot create $desc"
18802
18803         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18804         rc=$?
18805         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18806
18807         fid_path=$($LFS fid2path $MOUNT $fid)
18808         rc=$?
18809         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18810
18811         [ "$path" == "$fid_path" ] ||
18812                 error "fid2path returned $fid_path, expected $path"
18813
18814         echo "pass with $path and $fid"
18815 }
18816
18817 test_226a () {
18818         rm -rf $DIR/$tdir
18819         mkdir -p $DIR/$tdir
18820
18821         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18822         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18823         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18824         mcreate_path2fid 0040666 0 0 dir "directory"
18825         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18826         mcreate_path2fid 0100666 0 0 file "regular file"
18827         mcreate_path2fid 0120666 0 0 link "symbolic link"
18828         mcreate_path2fid 0140666 0 0 sock "socket"
18829 }
18830 run_test 226a "call path2fid and fid2path on files of all type"
18831
18832 test_226b () {
18833         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18834
18835         local MDTIDX=1
18836
18837         rm -rf $DIR/$tdir
18838         mkdir -p $DIR/$tdir
18839         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18840                 error "create remote directory failed"
18841         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18842         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18843                                 "character special file (null)"
18844         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18845                                 "character special file (no device)"
18846         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18847         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18848                                 "block special file (loop)"
18849         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18850         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18851         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18852 }
18853 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18854
18855 test_226c () {
18856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18857         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18858                 skip "Need MDS version at least 2.13.55"
18859
18860         local submnt=/mnt/submnt
18861         local srcfile=/etc/passwd
18862         local dstfile=$submnt/passwd
18863         local path
18864         local fid
18865
18866         rm -rf $DIR/$tdir
18867         rm -rf $submnt
18868         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18869                 error "create remote directory failed"
18870         mkdir -p $submnt || error "create $submnt failed"
18871         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18872                 error "mount $submnt failed"
18873         stack_trap "umount $submnt" EXIT
18874
18875         cp $srcfile $dstfile
18876         fid=$($LFS path2fid $dstfile)
18877         path=$($LFS fid2path $submnt "$fid")
18878         [ "$path" = "$dstfile" ] ||
18879                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18880 }
18881 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18882
18883 # LU-1299 Executing or running ldd on a truncated executable does not
18884 # cause an out-of-memory condition.
18885 test_227() {
18886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18887         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18888
18889         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18890         chmod +x $MOUNT/date
18891
18892         $MOUNT/date > /dev/null
18893         ldd $MOUNT/date > /dev/null
18894         rm -f $MOUNT/date
18895 }
18896 run_test 227 "running truncated executable does not cause OOM"
18897
18898 # LU-1512 try to reuse idle OI blocks
18899 test_228a() {
18900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18901         remote_mds_nodsh && skip "remote MDS with nodsh"
18902         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18903
18904         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18905         local myDIR=$DIR/$tdir
18906
18907         mkdir -p $myDIR
18908         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18909         $LCTL set_param fail_loc=0x80001002
18910         createmany -o $myDIR/t- 10000
18911         $LCTL set_param fail_loc=0
18912         # The guard is current the largest FID holder
18913         touch $myDIR/guard
18914         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18915                     tr -d '[')
18916         local IDX=$(($SEQ % 64))
18917
18918         do_facet $SINGLEMDS sync
18919         # Make sure journal flushed.
18920         sleep 6
18921         local blk1=$(do_facet $SINGLEMDS \
18922                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18923                      grep Blockcount | awk '{print $4}')
18924
18925         # Remove old files, some OI blocks will become idle.
18926         unlinkmany $myDIR/t- 10000
18927         # Create new files, idle OI blocks should be reused.
18928         createmany -o $myDIR/t- 2000
18929         do_facet $SINGLEMDS sync
18930         # Make sure journal flushed.
18931         sleep 6
18932         local blk2=$(do_facet $SINGLEMDS \
18933                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18934                      grep Blockcount | awk '{print $4}')
18935
18936         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18937 }
18938 run_test 228a "try to reuse idle OI blocks"
18939
18940 test_228b() {
18941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18942         remote_mds_nodsh && skip "remote MDS with nodsh"
18943         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18944
18945         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18946         local myDIR=$DIR/$tdir
18947
18948         mkdir -p $myDIR
18949         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18950         $LCTL set_param fail_loc=0x80001002
18951         createmany -o $myDIR/t- 10000
18952         $LCTL set_param fail_loc=0
18953         # The guard is current the largest FID holder
18954         touch $myDIR/guard
18955         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18956                     tr -d '[')
18957         local IDX=$(($SEQ % 64))
18958
18959         do_facet $SINGLEMDS sync
18960         # Make sure journal flushed.
18961         sleep 6
18962         local blk1=$(do_facet $SINGLEMDS \
18963                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18964                      grep Blockcount | awk '{print $4}')
18965
18966         # Remove old files, some OI blocks will become idle.
18967         unlinkmany $myDIR/t- 10000
18968
18969         # stop the MDT
18970         stop $SINGLEMDS || error "Fail to stop MDT."
18971         # remount the MDT
18972         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18973
18974         df $MOUNT || error "Fail to df."
18975         # Create new files, idle OI blocks should be reused.
18976         createmany -o $myDIR/t- 2000
18977         do_facet $SINGLEMDS sync
18978         # Make sure journal flushed.
18979         sleep 6
18980         local blk2=$(do_facet $SINGLEMDS \
18981                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18982                      grep Blockcount | awk '{print $4}')
18983
18984         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18985 }
18986 run_test 228b "idle OI blocks can be reused after MDT restart"
18987
18988 #LU-1881
18989 test_228c() {
18990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18991         remote_mds_nodsh && skip "remote MDS with nodsh"
18992         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18993
18994         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18995         local myDIR=$DIR/$tdir
18996
18997         mkdir -p $myDIR
18998         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18999         $LCTL set_param fail_loc=0x80001002
19000         # 20000 files can guarantee there are index nodes in the OI file
19001         createmany -o $myDIR/t- 20000
19002         $LCTL set_param fail_loc=0
19003         # The guard is current the largest FID holder
19004         touch $myDIR/guard
19005         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19006                     tr -d '[')
19007         local IDX=$(($SEQ % 64))
19008
19009         do_facet $SINGLEMDS sync
19010         # Make sure journal flushed.
19011         sleep 6
19012         local blk1=$(do_facet $SINGLEMDS \
19013                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19014                      grep Blockcount | awk '{print $4}')
19015
19016         # Remove old files, some OI blocks will become idle.
19017         unlinkmany $myDIR/t- 20000
19018         rm -f $myDIR/guard
19019         # The OI file should become empty now
19020
19021         # Create new files, idle OI blocks should be reused.
19022         createmany -o $myDIR/t- 2000
19023         do_facet $SINGLEMDS sync
19024         # Make sure journal flushed.
19025         sleep 6
19026         local blk2=$(do_facet $SINGLEMDS \
19027                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19028                      grep Blockcount | awk '{print $4}')
19029
19030         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19031 }
19032 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19033
19034 test_229() { # LU-2482, LU-3448
19035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19036         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19037         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19038                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19039
19040         rm -f $DIR/$tfile
19041
19042         # Create a file with a released layout and stripe count 2.
19043         $MULTIOP $DIR/$tfile H2c ||
19044                 error "failed to create file with released layout"
19045
19046         $LFS getstripe -v $DIR/$tfile
19047
19048         local pattern=$($LFS getstripe -L $DIR/$tfile)
19049         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19050
19051         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19052                 error "getstripe"
19053         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19054         stat $DIR/$tfile || error "failed to stat released file"
19055
19056         chown $RUNAS_ID $DIR/$tfile ||
19057                 error "chown $RUNAS_ID $DIR/$tfile failed"
19058
19059         chgrp $RUNAS_ID $DIR/$tfile ||
19060                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19061
19062         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19063         rm $DIR/$tfile || error "failed to remove released file"
19064 }
19065 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19066
19067 test_230a() {
19068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19070         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19071                 skip "Need MDS version at least 2.11.52"
19072
19073         local MDTIDX=1
19074
19075         test_mkdir $DIR/$tdir
19076         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19077         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19078         [ $mdt_idx -ne 0 ] &&
19079                 error "create local directory on wrong MDT $mdt_idx"
19080
19081         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19082                         error "create remote directory failed"
19083         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19084         [ $mdt_idx -ne $MDTIDX ] &&
19085                 error "create remote directory on wrong MDT $mdt_idx"
19086
19087         createmany -o $DIR/$tdir/test_230/t- 10 ||
19088                 error "create files on remote directory failed"
19089         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19090         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19091         rm -r $DIR/$tdir || error "unlink remote directory failed"
19092 }
19093 run_test 230a "Create remote directory and files under the remote directory"
19094
19095 test_230b() {
19096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19097         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19098         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19099                 skip "Need MDS version at least 2.11.52"
19100
19101         local MDTIDX=1
19102         local mdt_index
19103         local i
19104         local file
19105         local pid
19106         local stripe_count
19107         local migrate_dir=$DIR/$tdir/migrate_dir
19108         local other_dir=$DIR/$tdir/other_dir
19109
19110         test_mkdir $DIR/$tdir
19111         test_mkdir -i0 -c1 $migrate_dir
19112         test_mkdir -i0 -c1 $other_dir
19113         for ((i=0; i<10; i++)); do
19114                 mkdir -p $migrate_dir/dir_${i}
19115                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19116                         error "create files under remote dir failed $i"
19117         done
19118
19119         cp /etc/passwd $migrate_dir/$tfile
19120         cp /etc/passwd $other_dir/$tfile
19121         chattr +SAD $migrate_dir
19122         chattr +SAD $migrate_dir/$tfile
19123
19124         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19125         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19126         local old_dir_mode=$(stat -c%f $migrate_dir)
19127         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19128
19129         mkdir -p $migrate_dir/dir_default_stripe2
19130         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19131         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19132
19133         mkdir -p $other_dir
19134         ln $migrate_dir/$tfile $other_dir/luna
19135         ln $migrate_dir/$tfile $migrate_dir/sofia
19136         ln $other_dir/$tfile $migrate_dir/david
19137         ln -s $migrate_dir/$tfile $other_dir/zachary
19138         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19139         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19140
19141         local len
19142         local lnktgt
19143
19144         # inline symlink
19145         for len in 58 59 60; do
19146                 lnktgt=$(str_repeat 'l' $len)
19147                 touch $migrate_dir/$lnktgt
19148                 ln -s $lnktgt $migrate_dir/${len}char_ln
19149         done
19150
19151         # PATH_MAX
19152         for len in 4094 4095; do
19153                 lnktgt=$(str_repeat 'l' $len)
19154                 ln -s $lnktgt $migrate_dir/${len}char_ln
19155         done
19156
19157         # NAME_MAX
19158         for len in 254 255; do
19159                 touch $migrate_dir/$(str_repeat 'l' $len)
19160         done
19161
19162         $LFS migrate -m $MDTIDX $migrate_dir ||
19163                 error "fails on migrating remote dir to MDT1"
19164
19165         echo "migratate to MDT1, then checking.."
19166         for ((i = 0; i < 10; i++)); do
19167                 for file in $(find $migrate_dir/dir_${i}); do
19168                         mdt_index=$($LFS getstripe -m $file)
19169                         # broken symlink getstripe will fail
19170                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19171                                 error "$file is not on MDT${MDTIDX}"
19172                 done
19173         done
19174
19175         # the multiple link file should still in MDT0
19176         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19177         [ $mdt_index == 0 ] ||
19178                 error "$file is not on MDT${MDTIDX}"
19179
19180         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19181         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19182                 error " expect $old_dir_flag get $new_dir_flag"
19183
19184         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19185         [ "$old_file_flag" = "$new_file_flag" ] ||
19186                 error " expect $old_file_flag get $new_file_flag"
19187
19188         local new_dir_mode=$(stat -c%f $migrate_dir)
19189         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19190                 error "expect mode $old_dir_mode get $new_dir_mode"
19191
19192         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19193         [ "$old_file_mode" = "$new_file_mode" ] ||
19194                 error "expect mode $old_file_mode get $new_file_mode"
19195
19196         diff /etc/passwd $migrate_dir/$tfile ||
19197                 error "$tfile different after migration"
19198
19199         diff /etc/passwd $other_dir/luna ||
19200                 error "luna different after migration"
19201
19202         diff /etc/passwd $migrate_dir/sofia ||
19203                 error "sofia different after migration"
19204
19205         diff /etc/passwd $migrate_dir/david ||
19206                 error "david different after migration"
19207
19208         diff /etc/passwd $other_dir/zachary ||
19209                 error "zachary different after migration"
19210
19211         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19212                 error "${tfile}_ln different after migration"
19213
19214         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19215                 error "${tfile}_ln_other different after migration"
19216
19217         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19218         [ $stripe_count = 2 ] ||
19219                 error "dir strpe_count $d != 2 after migration."
19220
19221         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19222         [ $stripe_count = 2 ] ||
19223                 error "file strpe_count $d != 2 after migration."
19224
19225         #migrate back to MDT0
19226         MDTIDX=0
19227
19228         $LFS migrate -m $MDTIDX $migrate_dir ||
19229                 error "fails on migrating remote dir to MDT0"
19230
19231         echo "migrate back to MDT0, checking.."
19232         for file in $(find $migrate_dir); do
19233                 mdt_index=$($LFS getstripe -m $file)
19234                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19235                         error "$file is not on MDT${MDTIDX}"
19236         done
19237
19238         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19239         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19240                 error " expect $old_dir_flag get $new_dir_flag"
19241
19242         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19243         [ "$old_file_flag" = "$new_file_flag" ] ||
19244                 error " expect $old_file_flag get $new_file_flag"
19245
19246         local new_dir_mode=$(stat -c%f $migrate_dir)
19247         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19248                 error "expect mode $old_dir_mode get $new_dir_mode"
19249
19250         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19251         [ "$old_file_mode" = "$new_file_mode" ] ||
19252                 error "expect mode $old_file_mode get $new_file_mode"
19253
19254         diff /etc/passwd ${migrate_dir}/$tfile ||
19255                 error "$tfile different after migration"
19256
19257         diff /etc/passwd ${other_dir}/luna ||
19258                 error "luna different after migration"
19259
19260         diff /etc/passwd ${migrate_dir}/sofia ||
19261                 error "sofia different after migration"
19262
19263         diff /etc/passwd ${other_dir}/zachary ||
19264                 error "zachary different after migration"
19265
19266         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19267                 error "${tfile}_ln different after migration"
19268
19269         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19270                 error "${tfile}_ln_other different after migration"
19271
19272         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19273         [ $stripe_count = 2 ] ||
19274                 error "dir strpe_count $d != 2 after migration."
19275
19276         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19277         [ $stripe_count = 2 ] ||
19278                 error "file strpe_count $d != 2 after migration."
19279
19280         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19281 }
19282 run_test 230b "migrate directory"
19283
19284 test_230c() {
19285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19286         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19287         remote_mds_nodsh && skip "remote MDS with nodsh"
19288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19289                 skip "Need MDS version at least 2.11.52"
19290
19291         local MDTIDX=1
19292         local total=3
19293         local mdt_index
19294         local file
19295         local migrate_dir=$DIR/$tdir/migrate_dir
19296
19297         #If migrating directory fails in the middle, all entries of
19298         #the directory is still accessiable.
19299         test_mkdir $DIR/$tdir
19300         test_mkdir -i0 -c1 $migrate_dir
19301         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19302         stat $migrate_dir
19303         createmany -o $migrate_dir/f $total ||
19304                 error "create files under ${migrate_dir} failed"
19305
19306         # fail after migrating top dir, and this will fail only once, so the
19307         # first sub file migration will fail (currently f3), others succeed.
19308         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19309         do_facet mds1 lctl set_param fail_loc=0x1801
19310         local t=$(ls $migrate_dir | wc -l)
19311         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19312                 error "migrate should fail"
19313         local u=$(ls $migrate_dir | wc -l)
19314         [ "$u" == "$t" ] || error "$u != $t during migration"
19315
19316         # add new dir/file should succeed
19317         mkdir $migrate_dir/dir ||
19318                 error "mkdir failed under migrating directory"
19319         touch $migrate_dir/file ||
19320                 error "create file failed under migrating directory"
19321
19322         # add file with existing name should fail
19323         for file in $migrate_dir/f*; do
19324                 stat $file > /dev/null || error "stat $file failed"
19325                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19326                         error "open(O_CREAT|O_EXCL) $file should fail"
19327                 $MULTIOP $file m && error "create $file should fail"
19328                 touch $DIR/$tdir/remote_dir/$tfile ||
19329                         error "touch $tfile failed"
19330                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19331                         error "link $file should fail"
19332                 mdt_index=$($LFS getstripe -m $file)
19333                 if [ $mdt_index == 0 ]; then
19334                         # file failed to migrate is not allowed to rename to
19335                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19336                                 error "rename to $file should fail"
19337                 else
19338                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19339                                 error "rename to $file failed"
19340                 fi
19341                 echo hello >> $file || error "write $file failed"
19342         done
19343
19344         # resume migration with different options should fail
19345         $LFS migrate -m 0 $migrate_dir &&
19346                 error "migrate -m 0 $migrate_dir should fail"
19347
19348         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19349                 error "migrate -c 2 $migrate_dir should fail"
19350
19351         # resume migration should succeed
19352         $LFS migrate -m $MDTIDX $migrate_dir ||
19353                 error "migrate $migrate_dir failed"
19354
19355         echo "Finish migration, then checking.."
19356         for file in $(find $migrate_dir); do
19357                 mdt_index=$($LFS getstripe -m $file)
19358                 [ $mdt_index == $MDTIDX ] ||
19359                         error "$file is not on MDT${MDTIDX}"
19360         done
19361
19362         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19363 }
19364 run_test 230c "check directory accessiblity if migration failed"
19365
19366 test_230d() {
19367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19368         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19369         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19370                 skip "Need MDS version at least 2.11.52"
19371         # LU-11235
19372         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19373
19374         local migrate_dir=$DIR/$tdir/migrate_dir
19375         local old_index
19376         local new_index
19377         local old_count
19378         local new_count
19379         local new_hash
19380         local mdt_index
19381         local i
19382         local j
19383
19384         old_index=$((RANDOM % MDSCOUNT))
19385         old_count=$((MDSCOUNT - old_index))
19386         new_index=$((RANDOM % MDSCOUNT))
19387         new_count=$((MDSCOUNT - new_index))
19388         new_hash=1 # for all_char
19389
19390         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19391         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19392
19393         test_mkdir $DIR/$tdir
19394         test_mkdir -i $old_index -c $old_count $migrate_dir
19395
19396         for ((i=0; i<100; i++)); do
19397                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19398                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19399                         error "create files under remote dir failed $i"
19400         done
19401
19402         echo -n "Migrate from MDT$old_index "
19403         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19404         echo -n "to MDT$new_index"
19405         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19406         echo
19407
19408         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19409         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19410                 error "migrate remote dir error"
19411
19412         echo "Finish migration, then checking.."
19413         for file in $(find $migrate_dir); do
19414                 mdt_index=$($LFS getstripe -m $file)
19415                 if [ $mdt_index -lt $new_index ] ||
19416                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19417                         error "$file is on MDT$mdt_index"
19418                 fi
19419         done
19420
19421         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19422 }
19423 run_test 230d "check migrate big directory"
19424
19425 test_230e() {
19426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19427         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19428         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19429                 skip "Need MDS version at least 2.11.52"
19430
19431         local i
19432         local j
19433         local a_fid
19434         local b_fid
19435
19436         mkdir_on_mdt0 $DIR/$tdir
19437         mkdir $DIR/$tdir/migrate_dir
19438         mkdir $DIR/$tdir/other_dir
19439         touch $DIR/$tdir/migrate_dir/a
19440         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19441         ls $DIR/$tdir/other_dir
19442
19443         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19444                 error "migrate dir fails"
19445
19446         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19447         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19448
19449         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19450         [ $mdt_index == 0 ] || error "a is not on MDT0"
19451
19452         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19453                 error "migrate dir fails"
19454
19455         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19456         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19457
19458         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19459         [ $mdt_index == 1 ] || error "a is not on MDT1"
19460
19461         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19462         [ $mdt_index == 1 ] || error "b is not on MDT1"
19463
19464         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19465         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19466
19467         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19468
19469         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19470 }
19471 run_test 230e "migrate mulitple local link files"
19472
19473 test_230f() {
19474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19475         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19476         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19477                 skip "Need MDS version at least 2.11.52"
19478
19479         local a_fid
19480         local ln_fid
19481
19482         mkdir -p $DIR/$tdir
19483         mkdir $DIR/$tdir/migrate_dir
19484         $LFS mkdir -i1 $DIR/$tdir/other_dir
19485         touch $DIR/$tdir/migrate_dir/a
19486         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19487         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19488         ls $DIR/$tdir/other_dir
19489
19490         # a should be migrated to MDT1, since no other links on MDT0
19491         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19492                 error "#1 migrate dir fails"
19493         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19494         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19495         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19496         [ $mdt_index == 1 ] || error "a is not on MDT1"
19497
19498         # a should stay on MDT1, because it is a mulitple link file
19499         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19500                 error "#2 migrate dir fails"
19501         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19502         [ $mdt_index == 1 ] || error "a is not on MDT1"
19503
19504         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19505                 error "#3 migrate dir fails"
19506
19507         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19508         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19509         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19510
19511         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19512         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19513
19514         # a should be migrated to MDT0, since no other links on MDT1
19515         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19516                 error "#4 migrate dir fails"
19517         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19518         [ $mdt_index == 0 ] || error "a is not on MDT0"
19519
19520         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19521 }
19522 run_test 230f "migrate mulitple remote link files"
19523
19524 test_230g() {
19525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19526         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19527         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19528                 skip "Need MDS version at least 2.11.52"
19529
19530         mkdir -p $DIR/$tdir/migrate_dir
19531
19532         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19533                 error "migrating dir to non-exist MDT succeeds"
19534         true
19535 }
19536 run_test 230g "migrate dir to non-exist MDT"
19537
19538 test_230h() {
19539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19541         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19542                 skip "Need MDS version at least 2.11.52"
19543
19544         local mdt_index
19545
19546         mkdir -p $DIR/$tdir/migrate_dir
19547
19548         $LFS migrate -m1 $DIR &&
19549                 error "migrating mountpoint1 should fail"
19550
19551         $LFS migrate -m1 $DIR/$tdir/.. &&
19552                 error "migrating mountpoint2 should fail"
19553
19554         # same as mv
19555         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19556                 error "migrating $tdir/migrate_dir/.. should fail"
19557
19558         true
19559 }
19560 run_test 230h "migrate .. and root"
19561
19562 test_230i() {
19563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19564         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19565         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19566                 skip "Need MDS version at least 2.11.52"
19567
19568         mkdir -p $DIR/$tdir/migrate_dir
19569
19570         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19571                 error "migration fails with a tailing slash"
19572
19573         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19574                 error "migration fails with two tailing slashes"
19575 }
19576 run_test 230i "lfs migrate -m tolerates trailing slashes"
19577
19578 test_230j() {
19579         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19580         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19581                 skip "Need MDS version at least 2.11.52"
19582
19583         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19584         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19585                 error "create $tfile failed"
19586         cat /etc/passwd > $DIR/$tdir/$tfile
19587
19588         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19589
19590         cmp /etc/passwd $DIR/$tdir/$tfile ||
19591                 error "DoM file mismatch after migration"
19592 }
19593 run_test 230j "DoM file data not changed after dir migration"
19594
19595 test_230k() {
19596         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19597         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19598                 skip "Need MDS version at least 2.11.56"
19599
19600         local total=20
19601         local files_on_starting_mdt=0
19602
19603         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19604         $LFS getdirstripe $DIR/$tdir
19605         for i in $(seq $total); do
19606                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19607                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19608                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19609         done
19610
19611         echo "$files_on_starting_mdt files on MDT0"
19612
19613         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19614         $LFS getdirstripe $DIR/$tdir
19615
19616         files_on_starting_mdt=0
19617         for i in $(seq $total); do
19618                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19619                         error "file $tfile.$i mismatch after migration"
19620                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19621                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19622         done
19623
19624         echo "$files_on_starting_mdt files on MDT1 after migration"
19625         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19626
19627         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19628         $LFS getdirstripe $DIR/$tdir
19629
19630         files_on_starting_mdt=0
19631         for i in $(seq $total); do
19632                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19633                         error "file $tfile.$i mismatch after 2nd migration"
19634                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19635                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19636         done
19637
19638         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19639         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19640
19641         true
19642 }
19643 run_test 230k "file data not changed after dir migration"
19644
19645 test_230l() {
19646         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19647         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19648                 skip "Need MDS version at least 2.11.56"
19649
19650         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19651         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19652                 error "create files under remote dir failed $i"
19653         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19654 }
19655 run_test 230l "readdir between MDTs won't crash"
19656
19657 test_230m() {
19658         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19659         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19660                 skip "Need MDS version at least 2.11.56"
19661
19662         local MDTIDX=1
19663         local mig_dir=$DIR/$tdir/migrate_dir
19664         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19665         local shortstr="b"
19666         local val
19667
19668         echo "Creating files and dirs with xattrs"
19669         test_mkdir $DIR/$tdir
19670         test_mkdir -i0 -c1 $mig_dir
19671         mkdir $mig_dir/dir
19672         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19673                 error "cannot set xattr attr1 on dir"
19674         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19675                 error "cannot set xattr attr2 on dir"
19676         touch $mig_dir/dir/f0
19677         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19678                 error "cannot set xattr attr1 on file"
19679         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19680                 error "cannot set xattr attr2 on file"
19681         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19682         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19683         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19684         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19685         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19686         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19687         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19688         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19689         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19690
19691         echo "Migrating to MDT1"
19692         $LFS migrate -m $MDTIDX $mig_dir ||
19693                 error "fails on migrating dir to MDT1"
19694
19695         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19696         echo "Checking xattrs"
19697         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19698         [ "$val" = $longstr ] ||
19699                 error "expecting xattr1 $longstr on dir, found $val"
19700         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19701         [ "$val" = $shortstr ] ||
19702                 error "expecting xattr2 $shortstr on dir, found $val"
19703         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19704         [ "$val" = $longstr ] ||
19705                 error "expecting xattr1 $longstr on file, found $val"
19706         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19707         [ "$val" = $shortstr ] ||
19708                 error "expecting xattr2 $shortstr on file, found $val"
19709 }
19710 run_test 230m "xattrs not changed after dir migration"
19711
19712 test_230n() {
19713         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19714         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19715                 skip "Need MDS version at least 2.13.53"
19716
19717         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19718         cat /etc/hosts > $DIR/$tdir/$tfile
19719         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19720         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19721
19722         cmp /etc/hosts $DIR/$tdir/$tfile ||
19723                 error "File data mismatch after migration"
19724 }
19725 run_test 230n "Dir migration with mirrored file"
19726
19727 test_230o() {
19728         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19729         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19730                 skip "Need MDS version at least 2.13.52"
19731
19732         local mdts=$(comma_list $(mdts_nodes))
19733         local timeout=100
19734         local restripe_status
19735         local delta
19736         local i
19737
19738         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19739
19740         # in case "crush" hash type is not set
19741         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19742
19743         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19744                            mdt.*MDT0000.enable_dir_restripe)
19745         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19746         stack_trap "do_nodes $mdts $LCTL set_param \
19747                     mdt.*.enable_dir_restripe=$restripe_status"
19748
19749         mkdir $DIR/$tdir
19750         createmany -m $DIR/$tdir/f 100 ||
19751                 error "create files under remote dir failed $i"
19752         createmany -d $DIR/$tdir/d 100 ||
19753                 error "create dirs under remote dir failed $i"
19754
19755         for i in $(seq 2 $MDSCOUNT); do
19756                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19757                 $LFS setdirstripe -c $i $DIR/$tdir ||
19758                         error "split -c $i $tdir failed"
19759                 wait_update $HOSTNAME \
19760                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19761                         error "dir split not finished"
19762                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19763                         awk '/migrate/ {sum += $2} END { print sum }')
19764                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19765                 # delta is around total_files/stripe_count
19766                 (( $delta < 200 / (i - 1) + 4 )) ||
19767                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19768         done
19769 }
19770 run_test 230o "dir split"
19771
19772 test_230p() {
19773         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19774         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19775                 skip "Need MDS version at least 2.13.52"
19776
19777         local mdts=$(comma_list $(mdts_nodes))
19778         local timeout=100
19779         local restripe_status
19780         local delta
19781         local c
19782
19783         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19784
19785         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19786
19787         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19788                            mdt.*MDT0000.enable_dir_restripe)
19789         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19790         stack_trap "do_nodes $mdts $LCTL set_param \
19791                     mdt.*.enable_dir_restripe=$restripe_status"
19792
19793         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19794         createmany -m $DIR/$tdir/f 100 ||
19795                 error "create files under remote dir failed"
19796         createmany -d $DIR/$tdir/d 100 ||
19797                 error "create dirs under remote dir failed"
19798
19799         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19800                 local mdt_hash="crush"
19801
19802                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19803                 $LFS setdirstripe -c $c $DIR/$tdir ||
19804                         error "split -c $c $tdir failed"
19805                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19806                         mdt_hash="$mdt_hash,fixed"
19807                 elif [ $c -eq 1 ]; then
19808                         mdt_hash="none"
19809                 fi
19810                 wait_update $HOSTNAME \
19811                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19812                         error "dir merge not finished"
19813                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19814                         awk '/migrate/ {sum += $2} END { print sum }')
19815                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19816                 # delta is around total_files/stripe_count
19817                 (( delta < 200 / c + 4 )) ||
19818                         error "$delta files migrated >= $((200 / c + 4))"
19819         done
19820 }
19821 run_test 230p "dir merge"
19822
19823 test_230q() {
19824         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19825         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19826                 skip "Need MDS version at least 2.13.52"
19827
19828         local mdts=$(comma_list $(mdts_nodes))
19829         local saved_threshold=$(do_facet mds1 \
19830                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19831         local saved_delta=$(do_facet mds1 \
19832                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19833         local threshold=100
19834         local delta=2
19835         local total=0
19836         local stripe_count=0
19837         local stripe_index
19838         local nr_files
19839         local create
19840
19841         # test with fewer files on ZFS
19842         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19843
19844         stack_trap "do_nodes $mdts $LCTL set_param \
19845                     mdt.*.dir_split_count=$saved_threshold"
19846         stack_trap "do_nodes $mdts $LCTL set_param \
19847                     mdt.*.dir_split_delta=$saved_delta"
19848         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19849         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19850         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19851         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19852         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19853         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19854
19855         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19856         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19857
19858         create=$((threshold * 3 / 2))
19859         while [ $stripe_count -lt $MDSCOUNT ]; do
19860                 createmany -m $DIR/$tdir/f $total $create ||
19861                         error "create sub files failed"
19862                 stat $DIR/$tdir > /dev/null
19863                 total=$((total + create))
19864                 stripe_count=$((stripe_count + delta))
19865                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19866
19867                 wait_update $HOSTNAME \
19868                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19869                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19870
19871                 wait_update $HOSTNAME \
19872                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19873                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19874
19875                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19876                 echo "$nr_files/$total files on MDT$stripe_index after split"
19877                 # allow 10% margin of imbalance with crush hash
19878                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19879                         error "$nr_files files on MDT$stripe_index after split"
19880
19881                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19882                 [ $nr_files -eq $total ] ||
19883                         error "total sub files $nr_files != $total"
19884         done
19885
19886         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19887
19888         echo "fixed layout directory won't auto split"
19889         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19890         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19891                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19892         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19893                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19894 }
19895 run_test 230q "dir auto split"
19896
19897 test_230r() {
19898         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19899         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19900         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19901                 skip "Need MDS version at least 2.13.54"
19902
19903         # maximum amount of local locks:
19904         # parent striped dir - 2 locks
19905         # new stripe in parent to migrate to - 1 lock
19906         # source and target - 2 locks
19907         # Total 5 locks for regular file
19908         mkdir -p $DIR/$tdir
19909         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19910         touch $DIR/$tdir/dir1/eee
19911
19912         # create 4 hardlink for 4 more locks
19913         # Total: 9 locks > RS_MAX_LOCKS (8)
19914         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19915         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19916         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19917         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19918         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19919         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19920         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19921         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19922
19923         cancel_lru_locks mdc
19924
19925         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19926                 error "migrate dir fails"
19927
19928         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19929 }
19930 run_test 230r "migrate with too many local locks"
19931
19932 test_230s() {
19933         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19934                 skip "Need MDS version at least 2.13.57"
19935
19936         local mdts=$(comma_list $(mdts_nodes))
19937         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19938                                 mdt.*MDT0000.enable_dir_restripe)
19939
19940         stack_trap "do_nodes $mdts $LCTL set_param \
19941                     mdt.*.enable_dir_restripe=$restripe_status"
19942
19943         local st
19944         for st in 0 1; do
19945                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19946                 test_mkdir $DIR/$tdir
19947                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19948                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19949                 rmdir $DIR/$tdir
19950         done
19951 }
19952 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19953
19954 test_230t()
19955 {
19956         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19957         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19958                 skip "Need MDS version at least 2.14.50"
19959
19960         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19961         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19962         $LFS project -p 1 -s $DIR/$tdir ||
19963                 error "set $tdir project id failed"
19964         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19965                 error "set subdir project id failed"
19966         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19967 }
19968 run_test 230t "migrate directory with project ID set"
19969
19970 test_231a()
19971 {
19972         # For simplicity this test assumes that max_pages_per_rpc
19973         # is the same across all OSCs
19974         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19975         local bulk_size=$((max_pages * PAGE_SIZE))
19976         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19977                                        head -n 1)
19978
19979         mkdir -p $DIR/$tdir
19980         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19981                 error "failed to set stripe with -S ${brw_size}M option"
19982
19983         # clear the OSC stats
19984         $LCTL set_param osc.*.stats=0 &>/dev/null
19985         stop_writeback
19986
19987         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19988         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19989                 oflag=direct &>/dev/null || error "dd failed"
19990
19991         sync; sleep 1; sync # just to be safe
19992         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19993         if [ x$nrpcs != "x1" ]; then
19994                 $LCTL get_param osc.*.stats
19995                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19996         fi
19997
19998         start_writeback
19999         # Drop the OSC cache, otherwise we will read from it
20000         cancel_lru_locks osc
20001
20002         # clear the OSC stats
20003         $LCTL set_param osc.*.stats=0 &>/dev/null
20004
20005         # Client reads $bulk_size.
20006         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20007                 iflag=direct &>/dev/null || error "dd failed"
20008
20009         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20010         if [ x$nrpcs != "x1" ]; then
20011                 $LCTL get_param osc.*.stats
20012                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20013         fi
20014 }
20015 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20016
20017 test_231b() {
20018         mkdir -p $DIR/$tdir
20019         local i
20020         for i in {0..1023}; do
20021                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20022                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20023                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20024         done
20025         sync
20026 }
20027 run_test 231b "must not assert on fully utilized OST request buffer"
20028
20029 test_232a() {
20030         mkdir -p $DIR/$tdir
20031         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20032
20033         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20034         do_facet ost1 $LCTL set_param fail_loc=0x31c
20035
20036         # ignore dd failure
20037         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20038
20039         do_facet ost1 $LCTL set_param fail_loc=0
20040         umount_client $MOUNT || error "umount failed"
20041         mount_client $MOUNT || error "mount failed"
20042         stop ost1 || error "cannot stop ost1"
20043         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20044 }
20045 run_test 232a "failed lock should not block umount"
20046
20047 test_232b() {
20048         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20049                 skip "Need MDS version at least 2.10.58"
20050
20051         mkdir -p $DIR/$tdir
20052         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20053         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20054         sync
20055         cancel_lru_locks osc
20056
20057         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20058         do_facet ost1 $LCTL set_param fail_loc=0x31c
20059
20060         # ignore failure
20061         $LFS data_version $DIR/$tdir/$tfile || true
20062
20063         do_facet ost1 $LCTL set_param fail_loc=0
20064         umount_client $MOUNT || error "umount failed"
20065         mount_client $MOUNT || error "mount failed"
20066         stop ost1 || error "cannot stop ost1"
20067         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20068 }
20069 run_test 232b "failed data version lock should not block umount"
20070
20071 test_233a() {
20072         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20073                 skip "Need MDS version at least 2.3.64"
20074         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20075
20076         local fid=$($LFS path2fid $MOUNT)
20077
20078         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20079                 error "cannot access $MOUNT using its FID '$fid'"
20080 }
20081 run_test 233a "checking that OBF of the FS root succeeds"
20082
20083 test_233b() {
20084         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20085                 skip "Need MDS version at least 2.5.90"
20086         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20087
20088         local fid=$($LFS path2fid $MOUNT/.lustre)
20089
20090         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20091                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20092
20093         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20094         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20095                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20096 }
20097 run_test 233b "checking that OBF of the FS .lustre succeeds"
20098
20099 test_234() {
20100         local p="$TMP/sanityN-$TESTNAME.parameters"
20101         save_lustre_params client "llite.*.xattr_cache" > $p
20102         lctl set_param llite.*.xattr_cache 1 ||
20103                 skip_env "xattr cache is not supported"
20104
20105         mkdir -p $DIR/$tdir || error "mkdir failed"
20106         touch $DIR/$tdir/$tfile || error "touch failed"
20107         # OBD_FAIL_LLITE_XATTR_ENOMEM
20108         $LCTL set_param fail_loc=0x1405
20109         getfattr -n user.attr $DIR/$tdir/$tfile &&
20110                 error "getfattr should have failed with ENOMEM"
20111         $LCTL set_param fail_loc=0x0
20112         rm -rf $DIR/$tdir
20113
20114         restore_lustre_params < $p
20115         rm -f $p
20116 }
20117 run_test 234 "xattr cache should not crash on ENOMEM"
20118
20119 test_235() {
20120         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20121                 skip "Need MDS version at least 2.4.52"
20122
20123         flock_deadlock $DIR/$tfile
20124         local RC=$?
20125         case $RC in
20126                 0)
20127                 ;;
20128                 124) error "process hangs on a deadlock"
20129                 ;;
20130                 *) error "error executing flock_deadlock $DIR/$tfile"
20131                 ;;
20132         esac
20133 }
20134 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20135
20136 #LU-2935
20137 test_236() {
20138         check_swap_layouts_support
20139
20140         local ref1=/etc/passwd
20141         local ref2=/etc/group
20142         local file1=$DIR/$tdir/f1
20143         local file2=$DIR/$tdir/f2
20144
20145         test_mkdir -c1 $DIR/$tdir
20146         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20147         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20148         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20149         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20150         local fd=$(free_fd)
20151         local cmd="exec $fd<>$file2"
20152         eval $cmd
20153         rm $file2
20154         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20155                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20156         cmd="exec $fd>&-"
20157         eval $cmd
20158         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20159
20160         #cleanup
20161         rm -rf $DIR/$tdir
20162 }
20163 run_test 236 "Layout swap on open unlinked file"
20164
20165 # LU-4659 linkea consistency
20166 test_238() {
20167         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20168                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20169                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20170                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20171
20172         touch $DIR/$tfile
20173         ln $DIR/$tfile $DIR/$tfile.lnk
20174         touch $DIR/$tfile.new
20175         mv $DIR/$tfile.new $DIR/$tfile
20176         local fid1=$($LFS path2fid $DIR/$tfile)
20177         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20178         local path1=$($LFS fid2path $FSNAME "$fid1")
20179         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20180         local path2=$($LFS fid2path $FSNAME "$fid2")
20181         [ $tfile.lnk == $path2 ] ||
20182                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20183         rm -f $DIR/$tfile*
20184 }
20185 run_test 238 "Verify linkea consistency"
20186
20187 test_239A() { # was test_239
20188         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20189                 skip "Need MDS version at least 2.5.60"
20190
20191         local list=$(comma_list $(mdts_nodes))
20192
20193         mkdir -p $DIR/$tdir
20194         createmany -o $DIR/$tdir/f- 5000
20195         unlinkmany $DIR/$tdir/f- 5000
20196         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20197                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20198         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20199                         osp.*MDT*.sync_in_flight" | calc_sum)
20200         [ "$changes" -eq 0 ] || error "$changes not synced"
20201 }
20202 run_test 239A "osp_sync test"
20203
20204 test_239a() { #LU-5297
20205         remote_mds_nodsh && skip "remote MDS with nodsh"
20206
20207         touch $DIR/$tfile
20208         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20209         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20210         chgrp $RUNAS_GID $DIR/$tfile
20211         wait_delete_completed
20212 }
20213 run_test 239a "process invalid osp sync record correctly"
20214
20215 test_239b() { #LU-5297
20216         remote_mds_nodsh && skip "remote MDS with nodsh"
20217
20218         touch $DIR/$tfile1
20219         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20220         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20221         chgrp $RUNAS_GID $DIR/$tfile1
20222         wait_delete_completed
20223         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20224         touch $DIR/$tfile2
20225         chgrp $RUNAS_GID $DIR/$tfile2
20226         wait_delete_completed
20227 }
20228 run_test 239b "process osp sync record with ENOMEM error correctly"
20229
20230 test_240() {
20231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20232         remote_mds_nodsh && skip "remote MDS with nodsh"
20233
20234         mkdir -p $DIR/$tdir
20235
20236         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20237                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20238         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20239                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20240
20241         umount_client $MOUNT || error "umount failed"
20242         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20243         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20244         mount_client $MOUNT || error "failed to mount client"
20245
20246         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20247         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20248 }
20249 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20250
20251 test_241_bio() {
20252         local count=$1
20253         local bsize=$2
20254
20255         for LOOP in $(seq $count); do
20256                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20257                 cancel_lru_locks $OSC || true
20258         done
20259 }
20260
20261 test_241_dio() {
20262         local count=$1
20263         local bsize=$2
20264
20265         for LOOP in $(seq $1); do
20266                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20267                         2>/dev/null
20268         done
20269 }
20270
20271 test_241a() { # was test_241
20272         local bsize=$PAGE_SIZE
20273
20274         (( bsize < 40960 )) && bsize=40960
20275         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20276         ls -la $DIR/$tfile
20277         cancel_lru_locks $OSC
20278         test_241_bio 1000 $bsize &
20279         PID=$!
20280         test_241_dio 1000 $bsize
20281         wait $PID
20282 }
20283 run_test 241a "bio vs dio"
20284
20285 test_241b() {
20286         local bsize=$PAGE_SIZE
20287
20288         (( bsize < 40960 )) && bsize=40960
20289         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20290         ls -la $DIR/$tfile
20291         test_241_dio 1000 $bsize &
20292         PID=$!
20293         test_241_dio 1000 $bsize
20294         wait $PID
20295 }
20296 run_test 241b "dio vs dio"
20297
20298 test_242() {
20299         remote_mds_nodsh && skip "remote MDS with nodsh"
20300
20301         mkdir_on_mdt0 $DIR/$tdir
20302         touch $DIR/$tdir/$tfile
20303
20304         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20305         do_facet mds1 lctl set_param fail_loc=0x105
20306         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20307
20308         do_facet mds1 lctl set_param fail_loc=0
20309         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20310 }
20311 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20312
20313 test_243()
20314 {
20315         test_mkdir $DIR/$tdir
20316         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20317 }
20318 run_test 243 "various group lock tests"
20319
20320 test_244a()
20321 {
20322         test_mkdir $DIR/$tdir
20323         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20324         sendfile_grouplock $DIR/$tdir/$tfile || \
20325                 error "sendfile+grouplock failed"
20326         rm -rf $DIR/$tdir
20327 }
20328 run_test 244a "sendfile with group lock tests"
20329
20330 test_244b()
20331 {
20332         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20333
20334         local threads=50
20335         local size=$((1024*1024))
20336
20337         test_mkdir $DIR/$tdir
20338         for i in $(seq 1 $threads); do
20339                 local file=$DIR/$tdir/file_$((i / 10))
20340                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20341                 local pids[$i]=$!
20342         done
20343         for i in $(seq 1 $threads); do
20344                 wait ${pids[$i]}
20345         done
20346 }
20347 run_test 244b "multi-threaded write with group lock"
20348
20349 test_245() {
20350         local flagname="multi_mod_rpcs"
20351         local connect_data_name="max_mod_rpcs"
20352         local out
20353
20354         # check if multiple modify RPCs flag is set
20355         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20356                 grep "connect_flags:")
20357         echo "$out"
20358
20359         echo "$out" | grep -qw $flagname
20360         if [ $? -ne 0 ]; then
20361                 echo "connect flag $flagname is not set"
20362                 return
20363         fi
20364
20365         # check if multiple modify RPCs data is set
20366         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20367         echo "$out"
20368
20369         echo "$out" | grep -qw $connect_data_name ||
20370                 error "import should have connect data $connect_data_name"
20371 }
20372 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20373
20374 cleanup_247() {
20375         local submount=$1
20376
20377         trap 0
20378         umount_client $submount
20379         rmdir $submount
20380 }
20381
20382 test_247a() {
20383         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20384                 grep -q subtree ||
20385                 skip_env "Fileset feature is not supported"
20386
20387         local submount=${MOUNT}_$tdir
20388
20389         mkdir $MOUNT/$tdir
20390         mkdir -p $submount || error "mkdir $submount failed"
20391         FILESET="$FILESET/$tdir" mount_client $submount ||
20392                 error "mount $submount failed"
20393         trap "cleanup_247 $submount" EXIT
20394         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20395         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20396                 error "read $MOUNT/$tdir/$tfile failed"
20397         cleanup_247 $submount
20398 }
20399 run_test 247a "mount subdir as fileset"
20400
20401 test_247b() {
20402         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20403                 skip_env "Fileset feature is not supported"
20404
20405         local submount=${MOUNT}_$tdir
20406
20407         rm -rf $MOUNT/$tdir
20408         mkdir -p $submount || error "mkdir $submount failed"
20409         SKIP_FILESET=1
20410         FILESET="$FILESET/$tdir" mount_client $submount &&
20411                 error "mount $submount should fail"
20412         rmdir $submount
20413 }
20414 run_test 247b "mount subdir that dose not exist"
20415
20416 test_247c() {
20417         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20418                 skip_env "Fileset feature is not supported"
20419
20420         local submount=${MOUNT}_$tdir
20421
20422         mkdir -p $MOUNT/$tdir/dir1
20423         mkdir -p $submount || error "mkdir $submount failed"
20424         trap "cleanup_247 $submount" EXIT
20425         FILESET="$FILESET/$tdir" mount_client $submount ||
20426                 error "mount $submount failed"
20427         local fid=$($LFS path2fid $MOUNT/)
20428         $LFS fid2path $submount $fid && error "fid2path should fail"
20429         cleanup_247 $submount
20430 }
20431 run_test 247c "running fid2path outside subdirectory root"
20432
20433 test_247d() {
20434         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20435                 skip "Fileset feature is not supported"
20436
20437         local submount=${MOUNT}_$tdir
20438
20439         mkdir -p $MOUNT/$tdir/dir1
20440         mkdir -p $submount || error "mkdir $submount failed"
20441         FILESET="$FILESET/$tdir" mount_client $submount ||
20442                 error "mount $submount failed"
20443         trap "cleanup_247 $submount" EXIT
20444
20445         local td=$submount/dir1
20446         local fid=$($LFS path2fid $td)
20447         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20448
20449         # check that we get the same pathname back
20450         local rootpath
20451         local found
20452         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20453                 echo "$rootpath $fid"
20454                 found=$($LFS fid2path $rootpath "$fid")
20455                 [ -n "found" ] || error "fid2path should succeed"
20456                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20457         done
20458         # check wrong root path format
20459         rootpath=$submount"_wrong"
20460         found=$($LFS fid2path $rootpath "$fid")
20461         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20462
20463         cleanup_247 $submount
20464 }
20465 run_test 247d "running fid2path inside subdirectory root"
20466
20467 # LU-8037
20468 test_247e() {
20469         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20470                 grep -q subtree ||
20471                 skip "Fileset feature is not supported"
20472
20473         local submount=${MOUNT}_$tdir
20474
20475         mkdir $MOUNT/$tdir
20476         mkdir -p $submount || error "mkdir $submount failed"
20477         FILESET="$FILESET/.." mount_client $submount &&
20478                 error "mount $submount should fail"
20479         rmdir $submount
20480 }
20481 run_test 247e "mount .. as fileset"
20482
20483 test_247f() {
20484         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20485         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20486                 skip "Need at least version 2.13.52"
20487         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20488                 skip "Need at least version 2.14.50"
20489         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20490                 grep -q subtree ||
20491                 skip "Fileset feature is not supported"
20492
20493         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20494         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20495                 error "mkdir remote failed"
20496         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20497                 error "mkdir remote/subdir failed"
20498         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20499                 error "mkdir striped failed"
20500         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20501
20502         local submount=${MOUNT}_$tdir
20503
20504         mkdir -p $submount || error "mkdir $submount failed"
20505         stack_trap "rmdir $submount"
20506
20507         local dir
20508         local stat
20509         local fileset=$FILESET
20510         local mdts=$(comma_list $(mdts_nodes))
20511
20512         stat=$(do_facet mds1 $LCTL get_param -n \
20513                 mdt.*MDT0000.enable_remote_subdir_mount)
20514         stack_trap "do_nodes $mdts $LCTL set_param \
20515                 mdt.*.enable_remote_subdir_mount=$stat"
20516
20517         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20518         stack_trap "umount_client $submount"
20519         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20520                 error "mount remote dir $dir should fail"
20521
20522         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20523                 $tdir/striped/. ; do
20524                 FILESET="$fileset/$dir" mount_client $submount ||
20525                         error "mount $dir failed"
20526                 umount_client $submount
20527         done
20528
20529         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20530         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20531                 error "mount $tdir/remote failed"
20532 }
20533 run_test 247f "mount striped or remote directory as fileset"
20534
20535 test_247g() {
20536         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20537         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20538                 skip "Need at least version 2.14.50"
20539
20540         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20541                 error "mkdir $tdir failed"
20542         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20543
20544         local submount=${MOUNT}_$tdir
20545
20546         mkdir -p $submount || error "mkdir $submount failed"
20547         stack_trap "rmdir $submount"
20548
20549         FILESET="$fileset/$tdir" mount_client $submount ||
20550                 error "mount $dir failed"
20551         stack_trap "umount $submount"
20552
20553         local mdts=$(comma_list $(mdts_nodes))
20554
20555         local nrpcs
20556
20557         stat $submount > /dev/null
20558         cancel_lru_locks $MDC
20559         stat $submount > /dev/null
20560         stat $submount/$tfile > /dev/null
20561         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20562         stat $submount/$tfile > /dev/null
20563         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20564                 awk '/getattr/ {sum += $2} END {print sum}')
20565
20566         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20567 }
20568 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20569
20570 test_248a() {
20571         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20572         [ -z "$fast_read_sav" ] && skip "no fast read support"
20573
20574         # create a large file for fast read verification
20575         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20576
20577         # make sure the file is created correctly
20578         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20579                 { rm -f $DIR/$tfile; skip "file creation error"; }
20580
20581         echo "Test 1: verify that fast read is 4 times faster on cache read"
20582
20583         # small read with fast read enabled
20584         $LCTL set_param -n llite.*.fast_read=1
20585         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20586                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20587                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20588         # small read with fast read disabled
20589         $LCTL set_param -n llite.*.fast_read=0
20590         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20591                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20592                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20593
20594         # verify that fast read is 4 times faster for cache read
20595         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20596                 error_not_in_vm "fast read was not 4 times faster: " \
20597                            "$t_fast vs $t_slow"
20598
20599         echo "Test 2: verify the performance between big and small read"
20600         $LCTL set_param -n llite.*.fast_read=1
20601
20602         # 1k non-cache read
20603         cancel_lru_locks osc
20604         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20605                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20606                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20607
20608         # 1M non-cache read
20609         cancel_lru_locks osc
20610         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20611                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20612                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20613
20614         # verify that big IO is not 4 times faster than small IO
20615         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20616                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20617
20618         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20619         rm -f $DIR/$tfile
20620 }
20621 run_test 248a "fast read verification"
20622
20623 test_248b() {
20624         # Default short_io_bytes=16384, try both smaller and larger sizes.
20625         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20626         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20627         echo "bs=53248 count=113 normal buffered write"
20628         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20629                 error "dd of initial data file failed"
20630         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20631
20632         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20633         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20634                 error "dd with sync normal writes failed"
20635         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20636
20637         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20638         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20639                 error "dd with sync small writes failed"
20640         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20641
20642         cancel_lru_locks osc
20643
20644         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20645         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20646         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20647         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20648                 iflag=direct || error "dd with O_DIRECT small read failed"
20649         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20650         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20651                 error "compare $TMP/$tfile.1 failed"
20652
20653         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20654         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20655
20656         # just to see what the maximum tunable value is, and test parsing
20657         echo "test invalid parameter 2MB"
20658         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20659                 error "too-large short_io_bytes allowed"
20660         echo "test maximum parameter 512KB"
20661         # if we can set a larger short_io_bytes, run test regardless of version
20662         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20663                 # older clients may not allow setting it this large, that's OK
20664                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20665                         skip "Need at least client version 2.13.50"
20666                 error "medium short_io_bytes failed"
20667         fi
20668         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20669         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20670
20671         echo "test large parameter 64KB"
20672         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20673         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20674
20675         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20676         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20677                 error "dd with sync large writes failed"
20678         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20679
20680         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20681         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20682         num=$((113 * 4096 / PAGE_SIZE))
20683         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20684         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20685                 error "dd with O_DIRECT large writes failed"
20686         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20687                 error "compare $DIR/$tfile.3 failed"
20688
20689         cancel_lru_locks osc
20690
20691         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20692         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20693                 error "dd with O_DIRECT large read failed"
20694         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20695                 error "compare $TMP/$tfile.2 failed"
20696
20697         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20698         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20699                 error "dd with O_DIRECT large read failed"
20700         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20701                 error "compare $TMP/$tfile.3 failed"
20702 }
20703 run_test 248b "test short_io read and write for both small and large sizes"
20704
20705 test_249() { # LU-7890
20706         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20707                 skip "Need at least version 2.8.54"
20708
20709         rm -f $DIR/$tfile
20710         $LFS setstripe -c 1 $DIR/$tfile
20711         # Offset 2T == 4k * 512M
20712         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20713                 error "dd to 2T offset failed"
20714 }
20715 run_test 249 "Write above 2T file size"
20716
20717 test_250() {
20718         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20719          && skip "no 16TB file size limit on ZFS"
20720
20721         $LFS setstripe -c 1 $DIR/$tfile
20722         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20723         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20724         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20725         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20726                 conv=notrunc,fsync && error "append succeeded"
20727         return 0
20728 }
20729 run_test 250 "Write above 16T limit"
20730
20731 test_251() {
20732         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20733
20734         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20735         #Skip once - writing the first stripe will succeed
20736         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20737         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20738                 error "short write happened"
20739
20740         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20741         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20742                 error "short read happened"
20743
20744         rm -f $DIR/$tfile
20745 }
20746 run_test 251 "Handling short read and write correctly"
20747
20748 test_252() {
20749         remote_mds_nodsh && skip "remote MDS with nodsh"
20750         remote_ost_nodsh && skip "remote OST with nodsh"
20751         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20752                 skip_env "ldiskfs only test"
20753         fi
20754
20755         local tgt
20756         local dev
20757         local out
20758         local uuid
20759         local num
20760         local gen
20761
20762         # check lr_reader on OST0000
20763         tgt=ost1
20764         dev=$(facet_device $tgt)
20765         out=$(do_facet $tgt $LR_READER $dev)
20766         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20767         echo "$out"
20768         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20769         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20770                 error "Invalid uuid returned by $LR_READER on target $tgt"
20771         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20772
20773         # check lr_reader -c on MDT0000
20774         tgt=mds1
20775         dev=$(facet_device $tgt)
20776         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20777                 skip "$LR_READER does not support additional options"
20778         fi
20779         out=$(do_facet $tgt $LR_READER -c $dev)
20780         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20781         echo "$out"
20782         num=$(echo "$out" | grep -c "mdtlov")
20783         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20784                 error "Invalid number of mdtlov clients returned by $LR_READER"
20785         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20786
20787         # check lr_reader -cr on MDT0000
20788         out=$(do_facet $tgt $LR_READER -cr $dev)
20789         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20790         echo "$out"
20791         echo "$out" | grep -q "^reply_data:$" ||
20792                 error "$LR_READER should have returned 'reply_data' section"
20793         num=$(echo "$out" | grep -c "client_generation")
20794         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20795 }
20796 run_test 252 "check lr_reader tool"
20797
20798 test_253() {
20799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20800         remote_mds_nodsh && skip "remote MDS with nodsh"
20801         remote_mgs_nodsh && skip "remote MGS with nodsh"
20802
20803         local ostidx=0
20804         local rc=0
20805         local ost_name=$(ostname_from_index $ostidx)
20806
20807         # on the mdt's osc
20808         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20809         do_facet $SINGLEMDS $LCTL get_param -n \
20810                 osp.$mdtosc_proc1.reserved_mb_high ||
20811                 skip  "remote MDS does not support reserved_mb_high"
20812
20813         rm -rf $DIR/$tdir
20814         wait_mds_ost_sync
20815         wait_delete_completed
20816         mkdir $DIR/$tdir
20817
20818         pool_add $TESTNAME || error "Pool creation failed"
20819         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20820
20821         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20822                 error "Setstripe failed"
20823
20824         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20825
20826         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20827                     grep "watermarks")
20828         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20829
20830         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20831                         osp.$mdtosc_proc1.prealloc_status)
20832         echo "prealloc_status $oa_status"
20833
20834         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20835                 error "File creation should fail"
20836
20837         #object allocation was stopped, but we still able to append files
20838         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20839                 oflag=append || error "Append failed"
20840
20841         rm -f $DIR/$tdir/$tfile.0
20842
20843         # For this test, we want to delete the files we created to go out of
20844         # space but leave the watermark, so we remain nearly out of space
20845         ost_watermarks_enospc_delete_files $tfile $ostidx
20846
20847         wait_delete_completed
20848
20849         sleep_maxage
20850
20851         for i in $(seq 10 12); do
20852                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20853                         2>/dev/null || error "File creation failed after rm"
20854         done
20855
20856         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20857                         osp.$mdtosc_proc1.prealloc_status)
20858         echo "prealloc_status $oa_status"
20859
20860         if (( oa_status != 0 )); then
20861                 error "Object allocation still disable after rm"
20862         fi
20863 }
20864 run_test 253 "Check object allocation limit"
20865
20866 test_254() {
20867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20868         remote_mds_nodsh && skip "remote MDS with nodsh"
20869         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20870                 skip "MDS does not support changelog_size"
20871
20872         local cl_user
20873         local MDT0=$(facet_svc $SINGLEMDS)
20874
20875         changelog_register || error "changelog_register failed"
20876
20877         changelog_clear 0 || error "changelog_clear failed"
20878
20879         local size1=$(do_facet $SINGLEMDS \
20880                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20881         echo "Changelog size $size1"
20882
20883         rm -rf $DIR/$tdir
20884         $LFS mkdir -i 0 $DIR/$tdir
20885         # change something
20886         mkdir -p $DIR/$tdir/pics/2008/zachy
20887         touch $DIR/$tdir/pics/2008/zachy/timestamp
20888         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20889         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20890         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20891         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20892         rm $DIR/$tdir/pics/desktop.jpg
20893
20894         local size2=$(do_facet $SINGLEMDS \
20895                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20896         echo "Changelog size after work $size2"
20897
20898         (( $size2 > $size1 )) ||
20899                 error "new Changelog size=$size2 less than old size=$size1"
20900 }
20901 run_test 254 "Check changelog size"
20902
20903 ladvise_no_type()
20904 {
20905         local type=$1
20906         local file=$2
20907
20908         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20909                 awk -F: '{print $2}' | grep $type > /dev/null
20910         if [ $? -ne 0 ]; then
20911                 return 0
20912         fi
20913         return 1
20914 }
20915
20916 ladvise_no_ioctl()
20917 {
20918         local file=$1
20919
20920         lfs ladvise -a willread $file > /dev/null 2>&1
20921         if [ $? -eq 0 ]; then
20922                 return 1
20923         fi
20924
20925         lfs ladvise -a willread $file 2>&1 |
20926                 grep "Inappropriate ioctl for device" > /dev/null
20927         if [ $? -eq 0 ]; then
20928                 return 0
20929         fi
20930         return 1
20931 }
20932
20933 percent() {
20934         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20935 }
20936
20937 # run a random read IO workload
20938 # usage: random_read_iops <filename> <filesize> <iosize>
20939 random_read_iops() {
20940         local file=$1
20941         local fsize=$2
20942         local iosize=${3:-4096}
20943
20944         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20945                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20946 }
20947
20948 drop_file_oss_cache() {
20949         local file="$1"
20950         local nodes="$2"
20951
20952         $LFS ladvise -a dontneed $file 2>/dev/null ||
20953                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20954 }
20955
20956 ladvise_willread_performance()
20957 {
20958         local repeat=10
20959         local average_origin=0
20960         local average_cache=0
20961         local average_ladvise=0
20962
20963         for ((i = 1; i <= $repeat; i++)); do
20964                 echo "Iter $i/$repeat: reading without willread hint"
20965                 cancel_lru_locks osc
20966                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20967                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20968                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20969                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20970
20971                 cancel_lru_locks osc
20972                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20973                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20974                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20975
20976                 cancel_lru_locks osc
20977                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20978                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20979                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20980                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20981                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20982         done
20983         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20984         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20985         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20986
20987         speedup_cache=$(percent $average_cache $average_origin)
20988         speedup_ladvise=$(percent $average_ladvise $average_origin)
20989
20990         echo "Average uncached read: $average_origin"
20991         echo "Average speedup with OSS cached read: " \
20992                 "$average_cache = +$speedup_cache%"
20993         echo "Average speedup with ladvise willread: " \
20994                 "$average_ladvise = +$speedup_ladvise%"
20995
20996         local lowest_speedup=20
20997         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20998                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20999                         "got $average_cache%. Skipping ladvise willread check."
21000                 return 0
21001         fi
21002
21003         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21004         # it is still good to run until then to exercise 'ladvise willread'
21005         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21006                 [ "$ost1_FSTYPE" = "zfs" ] &&
21007                 echo "osd-zfs does not support dontneed or drop_caches" &&
21008                 return 0
21009
21010         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21011         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21012                 error_not_in_vm "Speedup with willread is less than " \
21013                         "$lowest_speedup%, got $average_ladvise%"
21014 }
21015
21016 test_255a() {
21017         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21018                 skip "lustre < 2.8.54 does not support ladvise "
21019         remote_ost_nodsh && skip "remote OST with nodsh"
21020
21021         stack_trap "rm -f $DIR/$tfile"
21022         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21023
21024         ladvise_no_type willread $DIR/$tfile &&
21025                 skip "willread ladvise is not supported"
21026
21027         ladvise_no_ioctl $DIR/$tfile &&
21028                 skip "ladvise ioctl is not supported"
21029
21030         local size_mb=100
21031         local size=$((size_mb * 1048576))
21032         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21033                 error "dd to $DIR/$tfile failed"
21034
21035         lfs ladvise -a willread $DIR/$tfile ||
21036                 error "Ladvise failed with no range argument"
21037
21038         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21039                 error "Ladvise failed with no -l or -e argument"
21040
21041         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21042                 error "Ladvise failed with only -e argument"
21043
21044         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21045                 error "Ladvise failed with only -l argument"
21046
21047         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21048                 error "End offset should not be smaller than start offset"
21049
21050         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21051                 error "End offset should not be equal to start offset"
21052
21053         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21054                 error "Ladvise failed with overflowing -s argument"
21055
21056         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21057                 error "Ladvise failed with overflowing -e argument"
21058
21059         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21060                 error "Ladvise failed with overflowing -l argument"
21061
21062         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21063                 error "Ladvise succeeded with conflicting -l and -e arguments"
21064
21065         echo "Synchronous ladvise should wait"
21066         local delay=4
21067 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21068         do_nodes $(comma_list $(osts_nodes)) \
21069                 $LCTL set_param fail_val=$delay fail_loc=0x237
21070
21071         local start_ts=$SECONDS
21072         lfs ladvise -a willread $DIR/$tfile ||
21073                 error "Ladvise failed with no range argument"
21074         local end_ts=$SECONDS
21075         local inteval_ts=$((end_ts - start_ts))
21076
21077         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21078                 error "Synchronous advice didn't wait reply"
21079         fi
21080
21081         echo "Asynchronous ladvise shouldn't wait"
21082         local start_ts=$SECONDS
21083         lfs ladvise -a willread -b $DIR/$tfile ||
21084                 error "Ladvise failed with no range argument"
21085         local end_ts=$SECONDS
21086         local inteval_ts=$((end_ts - start_ts))
21087
21088         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21089                 error "Asynchronous advice blocked"
21090         fi
21091
21092         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21093         ladvise_willread_performance
21094 }
21095 run_test 255a "check 'lfs ladvise -a willread'"
21096
21097 facet_meminfo() {
21098         local facet=$1
21099         local info=$2
21100
21101         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21102 }
21103
21104 test_255b() {
21105         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21106                 skip "lustre < 2.8.54 does not support ladvise "
21107         remote_ost_nodsh && skip "remote OST with nodsh"
21108
21109         stack_trap "rm -f $DIR/$tfile"
21110         lfs setstripe -c 1 -i 0 $DIR/$tfile
21111
21112         ladvise_no_type dontneed $DIR/$tfile &&
21113                 skip "dontneed ladvise is not supported"
21114
21115         ladvise_no_ioctl $DIR/$tfile &&
21116                 skip "ladvise ioctl is not supported"
21117
21118         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21119                 [ "$ost1_FSTYPE" = "zfs" ] &&
21120                 skip "zfs-osd does not support 'ladvise dontneed'"
21121
21122         local size_mb=100
21123         local size=$((size_mb * 1048576))
21124         # In order to prevent disturbance of other processes, only check 3/4
21125         # of the memory usage
21126         local kibibytes=$((size_mb * 1024 * 3 / 4))
21127
21128         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21129                 error "dd to $DIR/$tfile failed"
21130
21131         #force write to complete before dropping OST cache & checking memory
21132         sync
21133
21134         local total=$(facet_meminfo ost1 MemTotal)
21135         echo "Total memory: $total KiB"
21136
21137         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21138         local before_read=$(facet_meminfo ost1 Cached)
21139         echo "Cache used before read: $before_read KiB"
21140
21141         lfs ladvise -a willread $DIR/$tfile ||
21142                 error "Ladvise willread failed"
21143         local after_read=$(facet_meminfo ost1 Cached)
21144         echo "Cache used after read: $after_read KiB"
21145
21146         lfs ladvise -a dontneed $DIR/$tfile ||
21147                 error "Ladvise dontneed again failed"
21148         local no_read=$(facet_meminfo ost1 Cached)
21149         echo "Cache used after dontneed ladvise: $no_read KiB"
21150
21151         if [ $total -lt $((before_read + kibibytes)) ]; then
21152                 echo "Memory is too small, abort checking"
21153                 return 0
21154         fi
21155
21156         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21157                 error "Ladvise willread should use more memory" \
21158                         "than $kibibytes KiB"
21159         fi
21160
21161         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21162                 error "Ladvise dontneed should release more memory" \
21163                         "than $kibibytes KiB"
21164         fi
21165 }
21166 run_test 255b "check 'lfs ladvise -a dontneed'"
21167
21168 test_255c() {
21169         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21170                 skip "lustre < 2.10.50 does not support lockahead"
21171
21172         local ost1_imp=$(get_osc_import_name client ost1)
21173         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21174                          cut -d'.' -f2)
21175         local count
21176         local new_count
21177         local difference
21178         local i
21179         local rc
21180
21181         test_mkdir -p $DIR/$tdir
21182         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21183
21184         #test 10 returns only success/failure
21185         i=10
21186         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21187         rc=$?
21188         if [ $rc -eq 255 ]; then
21189                 error "Ladvise test${i} failed, ${rc}"
21190         fi
21191
21192         #test 11 counts lock enqueue requests, all others count new locks
21193         i=11
21194         count=$(do_facet ost1 \
21195                 $LCTL get_param -n ost.OSS.ost.stats)
21196         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21197
21198         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21199         rc=$?
21200         if [ $rc -eq 255 ]; then
21201                 error "Ladvise test${i} failed, ${rc}"
21202         fi
21203
21204         new_count=$(do_facet ost1 \
21205                 $LCTL get_param -n ost.OSS.ost.stats)
21206         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21207                    awk '{ print $2 }')
21208
21209         difference="$((new_count - count))"
21210         if [ $difference -ne $rc ]; then
21211                 error "Ladvise test${i}, bad enqueue count, returned " \
21212                       "${rc}, actual ${difference}"
21213         fi
21214
21215         for i in $(seq 12 21); do
21216                 # If we do not do this, we run the risk of having too many
21217                 # locks and starting lock cancellation while we are checking
21218                 # lock counts.
21219                 cancel_lru_locks osc
21220
21221                 count=$($LCTL get_param -n \
21222                        ldlm.namespaces.$imp_name.lock_unused_count)
21223
21224                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21225                 rc=$?
21226                 if [ $rc -eq 255 ]; then
21227                         error "Ladvise test ${i} failed, ${rc}"
21228                 fi
21229
21230                 new_count=$($LCTL get_param -n \
21231                        ldlm.namespaces.$imp_name.lock_unused_count)
21232                 difference="$((new_count - count))"
21233
21234                 # Test 15 output is divided by 100 to map down to valid return
21235                 if [ $i -eq 15 ]; then
21236                         rc="$((rc * 100))"
21237                 fi
21238
21239                 if [ $difference -ne $rc ]; then
21240                         error "Ladvise test ${i}, bad lock count, returned " \
21241                               "${rc}, actual ${difference}"
21242                 fi
21243         done
21244
21245         #test 22 returns only success/failure
21246         i=22
21247         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21248         rc=$?
21249         if [ $rc -eq 255 ]; then
21250                 error "Ladvise test${i} failed, ${rc}"
21251         fi
21252 }
21253 run_test 255c "suite of ladvise lockahead tests"
21254
21255 test_256() {
21256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21257         remote_mds_nodsh && skip "remote MDS with nodsh"
21258         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21259         changelog_users $SINGLEMDS | grep "^cl" &&
21260                 skip "active changelog user"
21261
21262         local cl_user
21263         local cat_sl
21264         local mdt_dev
21265
21266         mdt_dev=$(mdsdevname 1)
21267         echo $mdt_dev
21268
21269         changelog_register || error "changelog_register failed"
21270
21271         rm -rf $DIR/$tdir
21272         mkdir_on_mdt0 $DIR/$tdir
21273
21274         changelog_clear 0 || error "changelog_clear failed"
21275
21276         # change something
21277         touch $DIR/$tdir/{1..10}
21278
21279         # stop the MDT
21280         stop $SINGLEMDS || error "Fail to stop MDT"
21281
21282         # remount the MDT
21283
21284         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21285
21286         #after mount new plainllog is used
21287         touch $DIR/$tdir/{11..19}
21288         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21289         stack_trap "rm -f $tmpfile"
21290         cat_sl=$(do_facet $SINGLEMDS "sync; \
21291                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21292                  llog_reader $tmpfile | grep -c type=1064553b")
21293         do_facet $SINGLEMDS llog_reader $tmpfile
21294
21295         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21296
21297         changelog_clear 0 || error "changelog_clear failed"
21298
21299         cat_sl=$(do_facet $SINGLEMDS "sync; \
21300                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21301                  llog_reader $tmpfile | grep -c type=1064553b")
21302
21303         if (( cat_sl == 2 )); then
21304                 error "Empty plain llog was not deleted from changelog catalog"
21305         elif (( cat_sl != 1 )); then
21306                 error "Active plain llog shouldn't be deleted from catalog"
21307         fi
21308 }
21309 run_test 256 "Check llog delete for empty and not full state"
21310
21311 test_257() {
21312         remote_mds_nodsh && skip "remote MDS with nodsh"
21313         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21314                 skip "Need MDS version at least 2.8.55"
21315
21316         test_mkdir $DIR/$tdir
21317
21318         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21319                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21320         stat $DIR/$tdir
21321
21322 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21323         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21324         local facet=mds$((mdtidx + 1))
21325         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21326         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21327
21328         stop $facet || error "stop MDS failed"
21329         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21330                 error "start MDS fail"
21331         wait_recovery_complete $facet
21332 }
21333 run_test 257 "xattr locks are not lost"
21334
21335 # Verify we take the i_mutex when security requires it
21336 test_258a() {
21337 #define OBD_FAIL_IMUTEX_SEC 0x141c
21338         $LCTL set_param fail_loc=0x141c
21339         touch $DIR/$tfile
21340         chmod u+s $DIR/$tfile
21341         chmod a+rwx $DIR/$tfile
21342         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21343         RC=$?
21344         if [ $RC -ne 0 ]; then
21345                 error "error, failed to take i_mutex, rc=$?"
21346         fi
21347         rm -f $DIR/$tfile
21348 }
21349 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21350
21351 # Verify we do NOT take the i_mutex in the normal case
21352 test_258b() {
21353 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21354         $LCTL set_param fail_loc=0x141d
21355         touch $DIR/$tfile
21356         chmod a+rwx $DIR
21357         chmod a+rw $DIR/$tfile
21358         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21359         RC=$?
21360         if [ $RC -ne 0 ]; then
21361                 error "error, took i_mutex unnecessarily, rc=$?"
21362         fi
21363         rm -f $DIR/$tfile
21364
21365 }
21366 run_test 258b "verify i_mutex security behavior"
21367
21368 test_259() {
21369         local file=$DIR/$tfile
21370         local before
21371         local after
21372
21373         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21374
21375         stack_trap "rm -f $file" EXIT
21376
21377         wait_delete_completed
21378         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21379         echo "before: $before"
21380
21381         $LFS setstripe -i 0 -c 1 $file
21382         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21383         sync_all_data
21384         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21385         echo "after write: $after"
21386
21387 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21388         do_facet ost1 $LCTL set_param fail_loc=0x2301
21389         $TRUNCATE $file 0
21390         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21391         echo "after truncate: $after"
21392
21393         stop ost1
21394         do_facet ost1 $LCTL set_param fail_loc=0
21395         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21396         sleep 2
21397         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21398         echo "after restart: $after"
21399         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21400                 error "missing truncate?"
21401
21402         return 0
21403 }
21404 run_test 259 "crash at delayed truncate"
21405
21406 test_260() {
21407 #define OBD_FAIL_MDC_CLOSE               0x806
21408         $LCTL set_param fail_loc=0x80000806
21409         touch $DIR/$tfile
21410
21411 }
21412 run_test 260 "Check mdc_close fail"
21413
21414 ### Data-on-MDT sanity tests ###
21415 test_270a() {
21416         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21417                 skip "Need MDS version at least 2.10.55 for DoM"
21418
21419         # create DoM file
21420         local dom=$DIR/$tdir/dom_file
21421         local tmp=$DIR/$tdir/tmp_file
21422
21423         mkdir_on_mdt0 $DIR/$tdir
21424
21425         # basic checks for DoM component creation
21426         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21427                 error "Can set MDT layout to non-first entry"
21428
21429         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21430                 error "Can define multiple entries as MDT layout"
21431
21432         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21433
21434         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21435         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21436         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21437
21438         local mdtidx=$($LFS getstripe -m $dom)
21439         local mdtname=MDT$(printf %04x $mdtidx)
21440         local facet=mds$((mdtidx + 1))
21441         local space_check=1
21442
21443         # Skip free space checks with ZFS
21444         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21445
21446         # write
21447         sync
21448         local size_tmp=$((65536 * 3))
21449         local mdtfree1=$(do_facet $facet \
21450                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21451
21452         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21453         # check also direct IO along write
21454         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21455         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21456         sync
21457         cmp $tmp $dom || error "file data is different"
21458         [ $(stat -c%s $dom) == $size_tmp ] ||
21459                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21460         if [ $space_check == 1 ]; then
21461                 local mdtfree2=$(do_facet $facet \
21462                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21463
21464                 # increase in usage from by $size_tmp
21465                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21466                         error "MDT free space wrong after write: " \
21467                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21468         fi
21469
21470         # truncate
21471         local size_dom=10000
21472
21473         $TRUNCATE $dom $size_dom
21474         [ $(stat -c%s $dom) == $size_dom ] ||
21475                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21476         if [ $space_check == 1 ]; then
21477                 mdtfree1=$(do_facet $facet \
21478                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21479                 # decrease in usage from $size_tmp to new $size_dom
21480                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21481                   $(((size_tmp - size_dom) / 1024)) ] ||
21482                         error "MDT free space is wrong after truncate: " \
21483                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21484         fi
21485
21486         # append
21487         cat $tmp >> $dom
21488         sync
21489         size_dom=$((size_dom + size_tmp))
21490         [ $(stat -c%s $dom) == $size_dom ] ||
21491                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21492         if [ $space_check == 1 ]; then
21493                 mdtfree2=$(do_facet $facet \
21494                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21495                 # increase in usage by $size_tmp from previous
21496                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21497                         error "MDT free space is wrong after append: " \
21498                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21499         fi
21500
21501         # delete
21502         rm $dom
21503         if [ $space_check == 1 ]; then
21504                 mdtfree1=$(do_facet $facet \
21505                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21506                 # decrease in usage by $size_dom from previous
21507                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21508                         error "MDT free space is wrong after removal: " \
21509                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21510         fi
21511
21512         # combined striping
21513         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21514                 error "Can't create DoM + OST striping"
21515
21516         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21517         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21518         # check also direct IO along write
21519         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21520         sync
21521         cmp $tmp $dom || error "file data is different"
21522         [ $(stat -c%s $dom) == $size_tmp ] ||
21523                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21524         rm $dom $tmp
21525
21526         return 0
21527 }
21528 run_test 270a "DoM: basic functionality tests"
21529
21530 test_270b() {
21531         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21532                 skip "Need MDS version at least 2.10.55"
21533
21534         local dom=$DIR/$tdir/dom_file
21535         local max_size=1048576
21536
21537         mkdir -p $DIR/$tdir
21538         $LFS setstripe -E $max_size -L mdt $dom
21539
21540         # truncate over the limit
21541         $TRUNCATE $dom $(($max_size + 1)) &&
21542                 error "successful truncate over the maximum size"
21543         # write over the limit
21544         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21545                 error "successful write over the maximum size"
21546         # append over the limit
21547         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21548         echo "12345" >> $dom && error "successful append over the maximum size"
21549         rm $dom
21550
21551         return 0
21552 }
21553 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21554
21555 test_270c() {
21556         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21557                 skip "Need MDS version at least 2.10.55"
21558
21559         mkdir -p $DIR/$tdir
21560         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21561
21562         # check files inherit DoM EA
21563         touch $DIR/$tdir/first
21564         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21565                 error "bad pattern"
21566         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21567                 error "bad stripe count"
21568         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21569                 error "bad stripe size"
21570
21571         # check directory inherits DoM EA and uses it as default
21572         mkdir $DIR/$tdir/subdir
21573         touch $DIR/$tdir/subdir/second
21574         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21575                 error "bad pattern in sub-directory"
21576         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21577                 error "bad stripe count in sub-directory"
21578         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21579                 error "bad stripe size in sub-directory"
21580         return 0
21581 }
21582 run_test 270c "DoM: DoM EA inheritance tests"
21583
21584 test_270d() {
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
21589         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21590
21591         # inherit default DoM striping
21592         mkdir $DIR/$tdir/subdir
21593         touch $DIR/$tdir/subdir/f1
21594
21595         # change default directory striping
21596         $LFS setstripe -c 1 $DIR/$tdir/subdir
21597         touch $DIR/$tdir/subdir/f2
21598         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21599                 error "wrong default striping in file 2"
21600         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21601                 error "bad pattern in file 2"
21602         return 0
21603 }
21604 run_test 270d "DoM: change striping from DoM to RAID0"
21605
21606 test_270e() {
21607         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21608                 skip "Need MDS version at least 2.10.55"
21609
21610         mkdir -p $DIR/$tdir/dom
21611         mkdir -p $DIR/$tdir/norm
21612         DOMFILES=20
21613         NORMFILES=10
21614         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21615         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21616
21617         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21618         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21619
21620         # find DoM files by layout
21621         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21622         [ $NUM -eq  $DOMFILES ] ||
21623                 error "lfs find -L: found $NUM, expected $DOMFILES"
21624         echo "Test 1: lfs find 20 DOM files by layout: OK"
21625
21626         # there should be 1 dir with default DOM striping
21627         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21628         [ $NUM -eq  1 ] ||
21629                 error "lfs find -L: found $NUM, expected 1 dir"
21630         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21631
21632         # find DoM files by stripe size
21633         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21634         [ $NUM -eq  $DOMFILES ] ||
21635                 error "lfs find -S: found $NUM, expected $DOMFILES"
21636         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21637
21638         # find files by stripe offset except DoM files
21639         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21640         [ $NUM -eq  $NORMFILES ] ||
21641                 error "lfs find -i: found $NUM, expected $NORMFILES"
21642         echo "Test 5: lfs find no DOM files by stripe index: OK"
21643         return 0
21644 }
21645 run_test 270e "DoM: lfs find with DoM files test"
21646
21647 test_270f() {
21648         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21649                 skip "Need MDS version at least 2.10.55"
21650
21651         local mdtname=${FSNAME}-MDT0000-mdtlov
21652         local dom=$DIR/$tdir/dom_file
21653         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21654                                                 lod.$mdtname.dom_stripesize)
21655         local dom_limit=131072
21656
21657         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21658         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21659                                                 lod.$mdtname.dom_stripesize)
21660         [ ${dom_limit} -eq ${dom_current} ] ||
21661                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21662
21663         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21664         $LFS setstripe -d $DIR/$tdir
21665         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21666                 error "Can't set directory default striping"
21667
21668         # exceed maximum stripe size
21669         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21670                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21671         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21672                 error "Able to create DoM component size more than LOD limit"
21673
21674         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21675         dom_current=$(do_facet mds1 $LCTL get_param -n \
21676                                                 lod.$mdtname.dom_stripesize)
21677         [ 0 -eq ${dom_current} ] ||
21678                 error "Can't set zero DoM stripe limit"
21679         rm $dom
21680
21681         # attempt to create DoM file on server with disabled DoM should
21682         # remove DoM entry from layout and be succeed
21683         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21684                 error "Can't create DoM file (DoM is disabled)"
21685         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21686                 error "File has DoM component while DoM is disabled"
21687         rm $dom
21688
21689         # attempt to create DoM file with only DoM stripe should return error
21690         $LFS setstripe -E $dom_limit -L mdt $dom &&
21691                 error "Able to create DoM-only file while DoM is disabled"
21692
21693         # too low values to be aligned with smallest stripe size 64K
21694         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21695         dom_current=$(do_facet mds1 $LCTL get_param -n \
21696                                                 lod.$mdtname.dom_stripesize)
21697         [ 30000 -eq ${dom_current} ] &&
21698                 error "Can set too small DoM stripe limit"
21699
21700         # 64K is a minimal stripe size in Lustre, expect limit of that size
21701         [ 65536 -eq ${dom_current} ] ||
21702                 error "Limit is not set to 64K but ${dom_current}"
21703
21704         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21705         dom_current=$(do_facet mds1 $LCTL get_param -n \
21706                                                 lod.$mdtname.dom_stripesize)
21707         echo $dom_current
21708         [ 2147483648 -eq ${dom_current} ] &&
21709                 error "Can set too large DoM stripe limit"
21710
21711         do_facet mds1 $LCTL set_param -n \
21712                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21713         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21714                 error "Can't create DoM component size after limit change"
21715         do_facet mds1 $LCTL set_param -n \
21716                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21717         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21718                 error "Can't create DoM file after limit decrease"
21719         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21720                 error "Can create big DoM component after limit decrease"
21721         touch ${dom}_def ||
21722                 error "Can't create file with old default layout"
21723
21724         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21725         return 0
21726 }
21727 run_test 270f "DoM: maximum DoM stripe size checks"
21728
21729 test_270g() {
21730         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21731                 skip "Need MDS version at least 2.13.52"
21732         local dom=$DIR/$tdir/$tfile
21733
21734         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21735         local lodname=${FSNAME}-MDT0000-mdtlov
21736
21737         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21738         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21739         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21740         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21741
21742         local dom_limit=1024
21743         local dom_threshold="50%"
21744
21745         $LFS setstripe -d $DIR/$tdir
21746         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21747                 error "Can't set directory default striping"
21748
21749         do_facet mds1 $LCTL set_param -n \
21750                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21751         # set 0 threshold and create DOM file to change tunable stripesize
21752         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21753         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21754                 error "Failed to create $dom file"
21755         # now tunable dom_cur_stripesize should reach maximum
21756         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21757                                         lod.${lodname}.dom_stripesize_cur_kb)
21758         [[ $dom_current == $dom_limit ]] ||
21759                 error "Current DOM stripesize is not maximum"
21760         rm $dom
21761
21762         # set threshold for further tests
21763         do_facet mds1 $LCTL set_param -n \
21764                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21765         echo "DOM threshold is $dom_threshold free space"
21766         local dom_def
21767         local dom_set
21768         # Spoof bfree to exceed threshold
21769         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21770         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21771         for spfree in 40 20 0 15 30 55; do
21772                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21773                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21774                         error "Failed to create $dom file"
21775                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21776                                         lod.${lodname}.dom_stripesize_cur_kb)
21777                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21778                 [[ $dom_def != $dom_current ]] ||
21779                         error "Default stripe size was not changed"
21780                 if [[ $spfree > 0 ]] ; then
21781                         dom_set=$($LFS getstripe -S $dom)
21782                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21783                                 error "DOM component size is still old"
21784                 else
21785                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21786                                 error "DoM component is set with no free space"
21787                 fi
21788                 rm $dom
21789                 dom_current=$dom_def
21790         done
21791 }
21792 run_test 270g "DoM: default DoM stripe size depends on free space"
21793
21794 test_270h() {
21795         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21796                 skip "Need MDS version at least 2.13.53"
21797
21798         local mdtname=${FSNAME}-MDT0000-mdtlov
21799         local dom=$DIR/$tdir/$tfile
21800         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21801
21802         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21803         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21804
21805         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21806         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21807                 error "can't create OST file"
21808         # mirrored file with DOM entry in the second mirror
21809         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21810                 error "can't create mirror with DoM component"
21811
21812         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21813
21814         # DOM component in the middle and has other enries in the same mirror,
21815         # should succeed but lost DoM component
21816         $LFS setstripe --copy=${dom}_1 $dom ||
21817                 error "Can't create file from OST|DOM mirror layout"
21818         # check new file has no DoM layout after all
21819         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21820                 error "File has DoM component while DoM is disabled"
21821 }
21822 run_test 270h "DoM: DoM stripe removal when disabled on server"
21823
21824 test_271a() {
21825         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21826                 skip "Need MDS version at least 2.10.55"
21827
21828         local dom=$DIR/$tdir/dom
21829
21830         mkdir -p $DIR/$tdir
21831
21832         $LFS setstripe -E 1024K -L mdt $dom
21833
21834         lctl set_param -n mdc.*.stats=clear
21835         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21836         cat $dom > /dev/null
21837         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21838         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21839         ls $dom
21840         rm -f $dom
21841 }
21842 run_test 271a "DoM: data is cached for read after write"
21843
21844 test_271b() {
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         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21856         cancel_lru_locks mdc
21857         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21858         # second stat to check size is cached on client
21859         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21860         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21861         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21862         rm -f $dom
21863 }
21864 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21865
21866 test_271ba() {
21867         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21868                 skip "Need MDS version at least 2.10.55"
21869
21870         local dom=$DIR/$tdir/dom
21871
21872         mkdir -p $DIR/$tdir
21873
21874         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21875
21876         lctl set_param -n mdc.*.stats=clear
21877         lctl set_param -n osc.*.stats=clear
21878         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21879         cancel_lru_locks mdc
21880         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21881         # second stat to check size is cached on client
21882         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21883         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21884         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21885         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21886         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21887         rm -f $dom
21888 }
21889 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21890
21891
21892 get_mdc_stats() {
21893         local mdtidx=$1
21894         local param=$2
21895         local mdt=MDT$(printf %04x $mdtidx)
21896
21897         if [ -z $param ]; then
21898                 lctl get_param -n mdc.*$mdt*.stats
21899         else
21900                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21901         fi
21902 }
21903
21904 test_271c() {
21905         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21906                 skip "Need MDS version at least 2.10.55"
21907
21908         local dom=$DIR/$tdir/dom
21909
21910         mkdir -p $DIR/$tdir
21911
21912         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21913
21914         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21915         local facet=mds$((mdtidx + 1))
21916
21917         cancel_lru_locks mdc
21918         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21919         createmany -o $dom 1000
21920         lctl set_param -n mdc.*.stats=clear
21921         smalliomany -w $dom 1000 200
21922         get_mdc_stats $mdtidx
21923         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21924         # Each file has 1 open, 1 IO enqueues, total 2000
21925         # but now we have also +1 getxattr for security.capability, total 3000
21926         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21927         unlinkmany $dom 1000
21928
21929         cancel_lru_locks mdc
21930         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21931         createmany -o $dom 1000
21932         lctl set_param -n mdc.*.stats=clear
21933         smalliomany -w $dom 1000 200
21934         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21935         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21936         # for OPEN and IO lock.
21937         [ $((enq - enq_2)) -ge 1000 ] ||
21938                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21939         unlinkmany $dom 1000
21940         return 0
21941 }
21942 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21943
21944 cleanup_271def_tests() {
21945         trap 0
21946         rm -f $1
21947 }
21948
21949 test_271d() {
21950         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21951                 skip "Need MDS version at least 2.10.57"
21952
21953         local dom=$DIR/$tdir/dom
21954         local tmp=$TMP/$tfile
21955         trap "cleanup_271def_tests $tmp" EXIT
21956
21957         mkdir -p $DIR/$tdir
21958
21959         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21960
21961         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21962
21963         cancel_lru_locks mdc
21964         dd if=/dev/urandom of=$tmp bs=1000 count=1
21965         dd if=$tmp of=$dom bs=1000 count=1
21966         cancel_lru_locks mdc
21967
21968         cat /etc/hosts >> $tmp
21969         lctl set_param -n mdc.*.stats=clear
21970
21971         # append data to the same file it should update local page
21972         echo "Append to the same page"
21973         cat /etc/hosts >> $dom
21974         local num=$(get_mdc_stats $mdtidx ost_read)
21975         local ra=$(get_mdc_stats $mdtidx req_active)
21976         local rw=$(get_mdc_stats $mdtidx req_waittime)
21977
21978         [ -z $num ] || error "$num READ RPC occured"
21979         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21980         echo "... DONE"
21981
21982         # compare content
21983         cmp $tmp $dom || error "file miscompare"
21984
21985         cancel_lru_locks mdc
21986         lctl set_param -n mdc.*.stats=clear
21987
21988         echo "Open and read file"
21989         cat $dom > /dev/null
21990         local num=$(get_mdc_stats $mdtidx ost_read)
21991         local ra=$(get_mdc_stats $mdtidx req_active)
21992         local rw=$(get_mdc_stats $mdtidx req_waittime)
21993
21994         [ -z $num ] || error "$num READ RPC occured"
21995         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21996         echo "... DONE"
21997
21998         # compare content
21999         cmp $tmp $dom || error "file miscompare"
22000
22001         return 0
22002 }
22003 run_test 271d "DoM: read on open (1K file in reply buffer)"
22004
22005 test_271f() {
22006         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22007                 skip "Need MDS version at least 2.10.57"
22008
22009         local dom=$DIR/$tdir/dom
22010         local tmp=$TMP/$tfile
22011         trap "cleanup_271def_tests $tmp" EXIT
22012
22013         mkdir -p $DIR/$tdir
22014
22015         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22016
22017         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22018
22019         cancel_lru_locks mdc
22020         dd if=/dev/urandom of=$tmp bs=265000 count=1
22021         dd if=$tmp of=$dom bs=265000 count=1
22022         cancel_lru_locks mdc
22023         cat /etc/hosts >> $tmp
22024         lctl set_param -n mdc.*.stats=clear
22025
22026         echo "Append to the same page"
22027         cat /etc/hosts >> $dom
22028         local num=$(get_mdc_stats $mdtidx ost_read)
22029         local ra=$(get_mdc_stats $mdtidx req_active)
22030         local rw=$(get_mdc_stats $mdtidx req_waittime)
22031
22032         [ -z $num ] || error "$num READ RPC occured"
22033         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22034         echo "... DONE"
22035
22036         # compare content
22037         cmp $tmp $dom || error "file miscompare"
22038
22039         cancel_lru_locks mdc
22040         lctl set_param -n mdc.*.stats=clear
22041
22042         echo "Open and read file"
22043         cat $dom > /dev/null
22044         local num=$(get_mdc_stats $mdtidx ost_read)
22045         local ra=$(get_mdc_stats $mdtidx req_active)
22046         local rw=$(get_mdc_stats $mdtidx req_waittime)
22047
22048         [ -z $num ] && num=0
22049         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22050         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22051         echo "... DONE"
22052
22053         # compare content
22054         cmp $tmp $dom || error "file miscompare"
22055
22056         return 0
22057 }
22058 run_test 271f "DoM: read on open (200K file and read tail)"
22059
22060 test_271g() {
22061         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22062                 skip "Skipping due to old client or server version"
22063
22064         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22065         # to get layout
22066         $CHECKSTAT -t file $DIR1/$tfile
22067
22068         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22069         MULTIOP_PID=$!
22070         sleep 1
22071         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22072         $LCTL set_param fail_loc=0x80000314
22073         rm $DIR1/$tfile || error "Unlink fails"
22074         RC=$?
22075         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22076         [ $RC -eq 0 ] || error "Failed write to stale object"
22077 }
22078 run_test 271g "Discard DoM data vs client flush race"
22079
22080 test_272a() {
22081         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22082                 skip "Need MDS version at least 2.11.50"
22083
22084         local dom=$DIR/$tdir/dom
22085         mkdir -p $DIR/$tdir
22086
22087         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22088         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22089                 error "failed to write data into $dom"
22090         local old_md5=$(md5sum $dom)
22091
22092         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22093                 error "failed to migrate to the same DoM component"
22094
22095         local new_md5=$(md5sum $dom)
22096
22097         [ "$old_md5" == "$new_md5" ] ||
22098                 error "md5sum differ: $old_md5, $new_md5"
22099
22100         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22101                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22102 }
22103 run_test 272a "DoM migration: new layout with the same DOM component"
22104
22105 test_272b() {
22106         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22107                 skip "Need MDS version at least 2.11.50"
22108
22109         local dom=$DIR/$tdir/dom
22110         mkdir -p $DIR/$tdir
22111         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22112
22113         local mdtidx=$($LFS getstripe -m $dom)
22114         local mdtname=MDT$(printf %04x $mdtidx)
22115         local facet=mds$((mdtidx + 1))
22116
22117         local mdtfree1=$(do_facet $facet \
22118                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22119         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22120                 error "failed to write data into $dom"
22121         local old_md5=$(md5sum $dom)
22122         cancel_lru_locks mdc
22123         local mdtfree1=$(do_facet $facet \
22124                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22125
22126         $LFS migrate -c2 $dom ||
22127                 error "failed to migrate to the new composite layout"
22128         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22129                 error "MDT stripe was not removed"
22130
22131         cancel_lru_locks mdc
22132         local new_md5=$(md5sum $dom)
22133         [ "$old_md5" == "$new_md5" ] ||
22134                 error "$old_md5 != $new_md5"
22135
22136         # Skip free space checks with ZFS
22137         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22138                 local mdtfree2=$(do_facet $facet \
22139                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22140                 [ $mdtfree2 -gt $mdtfree1 ] ||
22141                         error "MDT space is not freed after migration"
22142         fi
22143         return 0
22144 }
22145 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22146
22147 test_272c() {
22148         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22149                 skip "Need MDS version at least 2.11.50"
22150
22151         local dom=$DIR/$tdir/$tfile
22152         mkdir -p $DIR/$tdir
22153         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22154
22155         local mdtidx=$($LFS getstripe -m $dom)
22156         local mdtname=MDT$(printf %04x $mdtidx)
22157         local facet=mds$((mdtidx + 1))
22158
22159         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22160                 error "failed to write data into $dom"
22161         local old_md5=$(md5sum $dom)
22162         cancel_lru_locks mdc
22163         local mdtfree1=$(do_facet $facet \
22164                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22165
22166         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22167                 error "failed to migrate to the new composite layout"
22168         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22169                 error "MDT stripe was not removed"
22170
22171         cancel_lru_locks mdc
22172         local new_md5=$(md5sum $dom)
22173         [ "$old_md5" == "$new_md5" ] ||
22174                 error "$old_md5 != $new_md5"
22175
22176         # Skip free space checks with ZFS
22177         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22178                 local mdtfree2=$(do_facet $facet \
22179                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22180                 [ $mdtfree2 -gt $mdtfree1 ] ||
22181                         error "MDS space is not freed after migration"
22182         fi
22183         return 0
22184 }
22185 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22186
22187 test_272d() {
22188         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22189                 skip "Need MDS version at least 2.12.55"
22190
22191         local dom=$DIR/$tdir/$tfile
22192         mkdir -p $DIR/$tdir
22193         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22194
22195         local mdtidx=$($LFS getstripe -m $dom)
22196         local mdtname=MDT$(printf %04x $mdtidx)
22197         local facet=mds$((mdtidx + 1))
22198
22199         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22200                 error "failed to write data into $dom"
22201         local old_md5=$(md5sum $dom)
22202         cancel_lru_locks mdc
22203         local mdtfree1=$(do_facet $facet \
22204                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22205
22206         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22207                 error "failed mirroring to the new composite layout"
22208         $LFS mirror resync $dom ||
22209                 error "failed mirror resync"
22210         $LFS mirror split --mirror-id 1 -d $dom ||
22211                 error "failed mirror split"
22212
22213         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22214                 error "MDT stripe was not removed"
22215
22216         cancel_lru_locks mdc
22217         local new_md5=$(md5sum $dom)
22218         [ "$old_md5" == "$new_md5" ] ||
22219                 error "$old_md5 != $new_md5"
22220
22221         # Skip free space checks with ZFS
22222         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22223                 local mdtfree2=$(do_facet $facet \
22224                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22225                 [ $mdtfree2 -gt $mdtfree1 ] ||
22226                         error "MDS space is not freed after DOM mirror deletion"
22227         fi
22228         return 0
22229 }
22230 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22231
22232 test_272e() {
22233         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22234                 skip "Need MDS version at least 2.12.55"
22235
22236         local dom=$DIR/$tdir/$tfile
22237         mkdir -p $DIR/$tdir
22238         $LFS setstripe -c 2 $dom
22239
22240         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22241                 error "failed to write data into $dom"
22242         local old_md5=$(md5sum $dom)
22243         cancel_lru_locks mdc
22244
22245         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22246                 error "failed mirroring to the DOM layout"
22247         $LFS mirror resync $dom ||
22248                 error "failed mirror resync"
22249         $LFS mirror split --mirror-id 1 -d $dom ||
22250                 error "failed mirror split"
22251
22252         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22253                 error "MDT stripe was not removed"
22254
22255         cancel_lru_locks mdc
22256         local new_md5=$(md5sum $dom)
22257         [ "$old_md5" == "$new_md5" ] ||
22258                 error "$old_md5 != $new_md5"
22259
22260         return 0
22261 }
22262 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22263
22264 test_272f() {
22265         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22266                 skip "Need MDS version at least 2.12.55"
22267
22268         local dom=$DIR/$tdir/$tfile
22269         mkdir -p $DIR/$tdir
22270         $LFS setstripe -c 2 $dom
22271
22272         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22273                 error "failed to write data into $dom"
22274         local old_md5=$(md5sum $dom)
22275         cancel_lru_locks mdc
22276
22277         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22278                 error "failed migrating to the DOM file"
22279
22280         cancel_lru_locks mdc
22281         local new_md5=$(md5sum $dom)
22282         [ "$old_md5" != "$new_md5" ] &&
22283                 error "$old_md5 != $new_md5"
22284
22285         return 0
22286 }
22287 run_test 272f "DoM migration: OST-striped file to DOM file"
22288
22289 test_273a() {
22290         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22291                 skip "Need MDS version at least 2.11.50"
22292
22293         # Layout swap cannot be done if either file has DOM component,
22294         # this will never be supported, migration should be used instead
22295
22296         local dom=$DIR/$tdir/$tfile
22297         mkdir -p $DIR/$tdir
22298
22299         $LFS setstripe -c2 ${dom}_plain
22300         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22301         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22302                 error "can swap layout with DoM component"
22303         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22304                 error "can swap layout with DoM component"
22305
22306         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22307         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22308                 error "can swap layout with DoM component"
22309         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22310                 error "can swap layout with DoM component"
22311         return 0
22312 }
22313 run_test 273a "DoM: layout swapping should fail with DOM"
22314
22315 test_273b() {
22316         mkdir -p $DIR/$tdir
22317         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22318
22319 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22320         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22321
22322         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22323 }
22324 run_test 273b "DoM: race writeback and object destroy"
22325
22326 test_275() {
22327         remote_ost_nodsh && skip "remote OST with nodsh"
22328         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22329                 skip "Need OST version >= 2.10.57"
22330
22331         local file=$DIR/$tfile
22332         local oss
22333
22334         oss=$(comma_list $(osts_nodes))
22335
22336         dd if=/dev/urandom of=$file bs=1M count=2 ||
22337                 error "failed to create a file"
22338         cancel_lru_locks osc
22339
22340         #lock 1
22341         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22342                 error "failed to read a file"
22343
22344 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22345         $LCTL set_param fail_loc=0x8000031f
22346
22347         cancel_lru_locks osc &
22348         sleep 1
22349
22350 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22351         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22352         #IO takes another lock, but matches the PENDING one
22353         #and places it to the IO RPC
22354         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22355                 error "failed to read a file with PENDING lock"
22356 }
22357 run_test 275 "Read on a canceled duplicate lock"
22358
22359 test_276() {
22360         remote_ost_nodsh && skip "remote OST with nodsh"
22361         local pid
22362
22363         do_facet ost1 "(while true; do \
22364                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22365                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22366         pid=$!
22367
22368         for LOOP in $(seq 20); do
22369                 stop ost1
22370                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22371         done
22372         kill -9 $pid
22373         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22374                 rm $TMP/sanity_276_pid"
22375 }
22376 run_test 276 "Race between mount and obd_statfs"
22377
22378 test_277() {
22379         $LCTL set_param ldlm.namespaces.*.lru_size=0
22380         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22381         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22382                         grep ^used_mb | awk '{print $2}')
22383         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22384         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22385                 oflag=direct conv=notrunc
22386         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22387                         grep ^used_mb | awk '{print $2}')
22388         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22389 }
22390 run_test 277 "Direct IO shall drop page cache"
22391
22392 test_278() {
22393         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22394         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22395         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22396                 skip "needs the same host for mdt1 mdt2" && return
22397
22398         local pid1
22399         local pid2
22400
22401 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22402         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22403         stop mds2 &
22404         pid2=$!
22405
22406         stop mds1
22407
22408         echo "Starting MDTs"
22409         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22410         wait $pid2
22411 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22412 #will return NULL
22413         do_facet mds2 $LCTL set_param fail_loc=0
22414
22415         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22416         wait_recovery_complete mds2
22417 }
22418 run_test 278 "Race starting MDS between MDTs stop/start"
22419
22420 test_280() {
22421         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22422                 skip "Need MGS version at least 2.13.52"
22423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22424         combined_mgs_mds || skip "needs combined MGS/MDT"
22425
22426         umount_client $MOUNT
22427 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22428         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22429
22430         mount_client $MOUNT &
22431         sleep 1
22432         stop mgs || error "stop mgs failed"
22433         #for a race mgs would crash
22434         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22435         # make sure we unmount client before remounting
22436         wait
22437         umount_client $MOUNT
22438         mount_client $MOUNT || error "mount client failed"
22439 }
22440 run_test 280 "Race between MGS umount and client llog processing"
22441
22442 cleanup_test_300() {
22443         trap 0
22444         umask $SAVE_UMASK
22445 }
22446 test_striped_dir() {
22447         local mdt_index=$1
22448         local stripe_count
22449         local stripe_index
22450
22451         mkdir -p $DIR/$tdir
22452
22453         SAVE_UMASK=$(umask)
22454         trap cleanup_test_300 RETURN EXIT
22455
22456         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22457                                                 $DIR/$tdir/striped_dir ||
22458                 error "set striped dir error"
22459
22460         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22461         [ "$mode" = "755" ] || error "expect 755 got $mode"
22462
22463         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22464                 error "getdirstripe failed"
22465         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22466         if [ "$stripe_count" != "2" ]; then
22467                 error "1:stripe_count is $stripe_count, expect 2"
22468         fi
22469         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22470         if [ "$stripe_count" != "2" ]; then
22471                 error "2:stripe_count is $stripe_count, expect 2"
22472         fi
22473
22474         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22475         if [ "$stripe_index" != "$mdt_index" ]; then
22476                 error "stripe_index is $stripe_index, expect $mdt_index"
22477         fi
22478
22479         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22480                 error "nlink error after create striped dir"
22481
22482         mkdir $DIR/$tdir/striped_dir/a
22483         mkdir $DIR/$tdir/striped_dir/b
22484
22485         stat $DIR/$tdir/striped_dir/a ||
22486                 error "create dir under striped dir failed"
22487         stat $DIR/$tdir/striped_dir/b ||
22488                 error "create dir under striped dir failed"
22489
22490         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22491                 error "nlink error after mkdir"
22492
22493         rmdir $DIR/$tdir/striped_dir/a
22494         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22495                 error "nlink error after rmdir"
22496
22497         rmdir $DIR/$tdir/striped_dir/b
22498         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22499                 error "nlink error after rmdir"
22500
22501         chattr +i $DIR/$tdir/striped_dir
22502         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22503                 error "immutable flags not working under striped dir!"
22504         chattr -i $DIR/$tdir/striped_dir
22505
22506         rmdir $DIR/$tdir/striped_dir ||
22507                 error "rmdir striped dir error"
22508
22509         cleanup_test_300
22510
22511         true
22512 }
22513
22514 test_300a() {
22515         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22516                 skip "skipped for lustre < 2.7.0"
22517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22518         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22519
22520         test_striped_dir 0 || error "failed on striped dir on MDT0"
22521         test_striped_dir 1 || error "failed on striped dir on MDT0"
22522 }
22523 run_test 300a "basic striped dir sanity test"
22524
22525 test_300b() {
22526         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22527                 skip "skipped for lustre < 2.7.0"
22528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22530
22531         local i
22532         local mtime1
22533         local mtime2
22534         local mtime3
22535
22536         test_mkdir $DIR/$tdir || error "mkdir fail"
22537         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22538                 error "set striped dir error"
22539         for i in {0..9}; do
22540                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22541                 sleep 1
22542                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22543                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22544                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22545                 sleep 1
22546                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22547                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22548                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22549         done
22550         true
22551 }
22552 run_test 300b "check ctime/mtime for striped dir"
22553
22554 test_300c() {
22555         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22556                 skip "skipped for lustre < 2.7.0"
22557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22559
22560         local file_count
22561
22562         mkdir_on_mdt0 $DIR/$tdir
22563         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22564                 error "set striped dir error"
22565
22566         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22567                 error "chown striped dir failed"
22568
22569         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22570                 error "create 5k files failed"
22571
22572         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22573
22574         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22575
22576         rm -rf $DIR/$tdir
22577 }
22578 run_test 300c "chown && check ls under striped directory"
22579
22580 test_300d() {
22581         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22582                 skip "skipped for lustre < 2.7.0"
22583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22585
22586         local stripe_count
22587         local file
22588
22589         mkdir -p $DIR/$tdir
22590         $LFS setstripe -c 2 $DIR/$tdir
22591
22592         #local striped directory
22593         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22594                 error "set striped dir error"
22595         #look at the directories for debug purposes
22596         ls -l $DIR/$tdir
22597         $LFS getdirstripe $DIR/$tdir
22598         ls -l $DIR/$tdir/striped_dir
22599         $LFS getdirstripe $DIR/$tdir/striped_dir
22600         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22601                 error "create 10 files failed"
22602
22603         #remote striped directory
22604         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22605                 error "set striped dir error"
22606         #look at the directories for debug purposes
22607         ls -l $DIR/$tdir
22608         $LFS getdirstripe $DIR/$tdir
22609         ls -l $DIR/$tdir/remote_striped_dir
22610         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22611         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22612                 error "create 10 files failed"
22613
22614         for file in $(find $DIR/$tdir); do
22615                 stripe_count=$($LFS getstripe -c $file)
22616                 [ $stripe_count -eq 2 ] ||
22617                         error "wrong stripe $stripe_count for $file"
22618         done
22619
22620         rm -rf $DIR/$tdir
22621 }
22622 run_test 300d "check default stripe under striped directory"
22623
22624 test_300e() {
22625         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22626                 skip "Need MDS version at least 2.7.55"
22627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22629
22630         local stripe_count
22631         local file
22632
22633         mkdir -p $DIR/$tdir
22634
22635         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22636                 error "set striped dir error"
22637
22638         touch $DIR/$tdir/striped_dir/a
22639         touch $DIR/$tdir/striped_dir/b
22640         touch $DIR/$tdir/striped_dir/c
22641
22642         mkdir $DIR/$tdir/striped_dir/dir_a
22643         mkdir $DIR/$tdir/striped_dir/dir_b
22644         mkdir $DIR/$tdir/striped_dir/dir_c
22645
22646         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22647                 error "set striped adir under striped dir error"
22648
22649         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22650                 error "set striped bdir under striped dir error"
22651
22652         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22653                 error "set striped cdir under striped dir error"
22654
22655         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22656                 error "rename dir under striped dir fails"
22657
22658         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22659                 error "rename dir under different stripes fails"
22660
22661         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22662                 error "rename file under striped dir should succeed"
22663
22664         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22665                 error "rename dir under striped dir should succeed"
22666
22667         rm -rf $DIR/$tdir
22668 }
22669 run_test 300e "check rename under striped directory"
22670
22671 test_300f() {
22672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22674         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22675                 skip "Need MDS version at least 2.7.55"
22676
22677         local stripe_count
22678         local file
22679
22680         rm -rf $DIR/$tdir
22681         mkdir -p $DIR/$tdir
22682
22683         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22684                 error "set striped dir error"
22685
22686         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22687                 error "set striped dir error"
22688
22689         touch $DIR/$tdir/striped_dir/a
22690         mkdir $DIR/$tdir/striped_dir/dir_a
22691         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22692                 error "create striped dir under striped dir fails"
22693
22694         touch $DIR/$tdir/striped_dir1/b
22695         mkdir $DIR/$tdir/striped_dir1/dir_b
22696         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22697                 error "create striped dir under striped dir fails"
22698
22699         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22700                 error "rename dir under different striped dir should fail"
22701
22702         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22703                 error "rename striped dir under diff striped dir should fail"
22704
22705         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22706                 error "rename file under diff striped dirs fails"
22707
22708         rm -rf $DIR/$tdir
22709 }
22710 run_test 300f "check rename cross striped directory"
22711
22712 test_300_check_default_striped_dir()
22713 {
22714         local dirname=$1
22715         local default_count=$2
22716         local default_index=$3
22717         local stripe_count
22718         local stripe_index
22719         local dir_stripe_index
22720         local dir
22721
22722         echo "checking $dirname $default_count $default_index"
22723         $LFS setdirstripe -D -c $default_count -i $default_index \
22724                                 -H all_char $DIR/$tdir/$dirname ||
22725                 error "set default stripe on striped dir error"
22726         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22727         [ $stripe_count -eq $default_count ] ||
22728                 error "expect $default_count get $stripe_count for $dirname"
22729
22730         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22731         [ $stripe_index -eq $default_index ] ||
22732                 error "expect $default_index get $stripe_index for $dirname"
22733
22734         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22735                                                 error "create dirs failed"
22736
22737         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22738         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22739         for dir in $(find $DIR/$tdir/$dirname/*); do
22740                 stripe_count=$($LFS getdirstripe -c $dir)
22741                 (( $stripe_count == $default_count )) ||
22742                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22743                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22744                 error "stripe count $default_count != $stripe_count for $dir"
22745
22746                 stripe_index=$($LFS getdirstripe -i $dir)
22747                 [ $default_index -eq -1 ] ||
22748                         [ $stripe_index -eq $default_index ] ||
22749                         error "$stripe_index != $default_index for $dir"
22750
22751                 #check default stripe
22752                 stripe_count=$($LFS getdirstripe -D -c $dir)
22753                 [ $stripe_count -eq $default_count ] ||
22754                 error "default count $default_count != $stripe_count for $dir"
22755
22756                 stripe_index=$($LFS getdirstripe -D -i $dir)
22757                 [ $stripe_index -eq $default_index ] ||
22758                 error "default index $default_index != $stripe_index for $dir"
22759         done
22760         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22761 }
22762
22763 test_300g() {
22764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22765         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22766                 skip "Need MDS version at least 2.7.55"
22767
22768         local dir
22769         local stripe_count
22770         local stripe_index
22771
22772         mkdir_on_mdt0 $DIR/$tdir
22773         mkdir $DIR/$tdir/normal_dir
22774
22775         #Checking when client cache stripe index
22776         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22777         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22778                 error "create striped_dir failed"
22779
22780         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22781                 error "create dir0 fails"
22782         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22783         [ $stripe_index -eq 0 ] ||
22784                 error "dir0 expect index 0 got $stripe_index"
22785
22786         mkdir $DIR/$tdir/striped_dir/dir1 ||
22787                 error "create dir1 fails"
22788         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22789         [ $stripe_index -eq 1 ] ||
22790                 error "dir1 expect index 1 got $stripe_index"
22791
22792         #check default stripe count/stripe index
22793         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22794         test_300_check_default_striped_dir normal_dir 1 0
22795         test_300_check_default_striped_dir normal_dir -1 1
22796         test_300_check_default_striped_dir normal_dir 2 -1
22797
22798         #delete default stripe information
22799         echo "delete default stripeEA"
22800         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22801                 error "set default stripe on striped dir error"
22802
22803         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22804         for dir in $(find $DIR/$tdir/normal_dir/*); do
22805                 stripe_count=$($LFS getdirstripe -c $dir)
22806                 [ $stripe_count -eq 0 ] ||
22807                         error "expect 1 get $stripe_count for $dir"
22808         done
22809 }
22810 run_test 300g "check default striped directory for normal directory"
22811
22812 test_300h() {
22813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22814         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22815                 skip "Need MDS version at least 2.7.55"
22816
22817         local dir
22818         local stripe_count
22819
22820         mkdir $DIR/$tdir
22821         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22822                 error "set striped dir error"
22823
22824         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22825         test_300_check_default_striped_dir striped_dir 1 0
22826         test_300_check_default_striped_dir striped_dir -1 1
22827         test_300_check_default_striped_dir striped_dir 2 -1
22828
22829         #delete default stripe information
22830         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22831                 error "set default stripe on striped dir error"
22832
22833         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22834         for dir in $(find $DIR/$tdir/striped_dir/*); do
22835                 stripe_count=$($LFS getdirstripe -c $dir)
22836                 [ $stripe_count -eq 0 ] ||
22837                         error "expect 1 get $stripe_count for $dir"
22838         done
22839 }
22840 run_test 300h "check default striped directory for striped directory"
22841
22842 test_300i() {
22843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22844         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22845         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22846                 skip "Need MDS version at least 2.7.55"
22847
22848         local stripe_count
22849         local file
22850
22851         mkdir $DIR/$tdir
22852
22853         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22854                 error "set striped dir error"
22855
22856         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22857                 error "create files under striped dir failed"
22858
22859         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22860                 error "set striped hashdir error"
22861
22862         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22863                 error "create dir0 under hash dir failed"
22864         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22865                 error "create dir1 under hash dir failed"
22866         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22867                 error "create dir2 under hash dir failed"
22868
22869         # unfortunately, we need to umount to clear dir layout cache for now
22870         # once we fully implement dir layout, we can drop this
22871         umount_client $MOUNT || error "umount failed"
22872         mount_client $MOUNT || error "mount failed"
22873
22874         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22875         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22876         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22877
22878         #set the stripe to be unknown hash type
22879         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22880         $LCTL set_param fail_loc=0x1901
22881         for ((i = 0; i < 10; i++)); do
22882                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22883                         error "stat f-$i failed"
22884                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22885         done
22886
22887         touch $DIR/$tdir/striped_dir/f0 &&
22888                 error "create under striped dir with unknown hash should fail"
22889
22890         $LCTL set_param fail_loc=0
22891
22892         umount_client $MOUNT || error "umount failed"
22893         mount_client $MOUNT || error "mount failed"
22894
22895         return 0
22896 }
22897 run_test 300i "client handle unknown hash type striped directory"
22898
22899 test_300j() {
22900         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22902         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22903                 skip "Need MDS version at least 2.7.55"
22904
22905         local stripe_count
22906         local file
22907
22908         mkdir $DIR/$tdir
22909
22910         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22911         $LCTL set_param fail_loc=0x1702
22912         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22913                 error "set striped dir error"
22914
22915         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22916                 error "create files under striped dir failed"
22917
22918         $LCTL set_param fail_loc=0
22919
22920         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22921
22922         return 0
22923 }
22924 run_test 300j "test large update record"
22925
22926 test_300k() {
22927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22928         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22929         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22930                 skip "Need MDS version at least 2.7.55"
22931
22932         # this test needs a huge transaction
22933         local kb
22934         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22935              osd*.$FSNAME-MDT0000.kbytestotal")
22936         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22937
22938         local stripe_count
22939         local file
22940
22941         mkdir $DIR/$tdir
22942
22943         #define OBD_FAIL_LARGE_STRIPE   0x1703
22944         $LCTL set_param fail_loc=0x1703
22945         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22946                 error "set striped dir error"
22947         $LCTL set_param fail_loc=0
22948
22949         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22950                 error "getstripeddir fails"
22951         rm -rf $DIR/$tdir/striped_dir ||
22952                 error "unlink striped dir fails"
22953
22954         return 0
22955 }
22956 run_test 300k "test large striped directory"
22957
22958 test_300l() {
22959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22960         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22961         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22962                 skip "Need MDS version at least 2.7.55"
22963
22964         local stripe_index
22965
22966         test_mkdir -p $DIR/$tdir/striped_dir
22967         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22968                         error "chown $RUNAS_ID failed"
22969         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22970                 error "set default striped dir failed"
22971
22972         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22973         $LCTL set_param fail_loc=0x80000158
22974         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22975
22976         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22977         [ $stripe_index -eq 1 ] ||
22978                 error "expect 1 get $stripe_index for $dir"
22979 }
22980 run_test 300l "non-root user to create dir under striped dir with stale layout"
22981
22982 test_300m() {
22983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22984         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22985         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22986                 skip "Need MDS version at least 2.7.55"
22987
22988         mkdir -p $DIR/$tdir/striped_dir
22989         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22990                 error "set default stripes dir error"
22991
22992         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22993
22994         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22995         [ $stripe_count -eq 0 ] ||
22996                         error "expect 0 get $stripe_count for a"
22997
22998         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22999                 error "set default stripes dir error"
23000
23001         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23002
23003         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23004         [ $stripe_count -eq 0 ] ||
23005                         error "expect 0 get $stripe_count for b"
23006
23007         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23008                 error "set default stripes dir error"
23009
23010         mkdir $DIR/$tdir/striped_dir/c &&
23011                 error "default stripe_index is invalid, mkdir c should fails"
23012
23013         rm -rf $DIR/$tdir || error "rmdir fails"
23014 }
23015 run_test 300m "setstriped directory on single MDT FS"
23016
23017 cleanup_300n() {
23018         local list=$(comma_list $(mdts_nodes))
23019
23020         trap 0
23021         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23022 }
23023
23024 test_300n() {
23025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23026         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23027         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23028                 skip "Need MDS version at least 2.7.55"
23029         remote_mds_nodsh && skip "remote MDS with nodsh"
23030
23031         local stripe_index
23032         local list=$(comma_list $(mdts_nodes))
23033
23034         trap cleanup_300n RETURN EXIT
23035         mkdir -p $DIR/$tdir
23036         chmod 777 $DIR/$tdir
23037         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23038                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23039                 error "create striped dir succeeds with gid=0"
23040
23041         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23042         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23043                 error "create striped dir fails with gid=-1"
23044
23045         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23046         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23047                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23048                 error "set default striped dir succeeds with gid=0"
23049
23050
23051         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23052         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23053                 error "set default striped dir fails with gid=-1"
23054
23055
23056         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23057         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23058                                         error "create test_dir fails"
23059         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23060                                         error "create test_dir1 fails"
23061         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23062                                         error "create test_dir2 fails"
23063         cleanup_300n
23064 }
23065 run_test 300n "non-root user to create dir under striped dir with default EA"
23066
23067 test_300o() {
23068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23070         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23071                 skip "Need MDS version at least 2.7.55"
23072
23073         local numfree1
23074         local numfree2
23075
23076         mkdir -p $DIR/$tdir
23077
23078         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23079         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23080         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23081                 skip "not enough free inodes $numfree1 $numfree2"
23082         fi
23083
23084         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23085         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23086         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23087                 skip "not enough free space $numfree1 $numfree2"
23088         fi
23089
23090         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23091                 error "setdirstripe fails"
23092
23093         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23094                 error "create dirs fails"
23095
23096         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23097         ls $DIR/$tdir/striped_dir > /dev/null ||
23098                 error "ls striped dir fails"
23099         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23100                 error "unlink big striped dir fails"
23101 }
23102 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23103
23104 test_300p() {
23105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23106         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23107         remote_mds_nodsh && skip "remote MDS with nodsh"
23108
23109         mkdir_on_mdt0 $DIR/$tdir
23110
23111         #define OBD_FAIL_OUT_ENOSPC     0x1704
23112         do_facet mds2 lctl set_param fail_loc=0x80001704
23113         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23114                  && error "create striped directory should fail"
23115
23116         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23117
23118         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23119         true
23120 }
23121 run_test 300p "create striped directory without space"
23122
23123 test_300q() {
23124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23125         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23126
23127         local fd=$(free_fd)
23128         local cmd="exec $fd<$tdir"
23129         cd $DIR
23130         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23131         eval $cmd
23132         cmd="exec $fd<&-"
23133         trap "eval $cmd" EXIT
23134         cd $tdir || error "cd $tdir fails"
23135         rmdir  ../$tdir || error "rmdir $tdir fails"
23136         mkdir local_dir && error "create dir succeeds"
23137         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23138         eval $cmd
23139         return 0
23140 }
23141 run_test 300q "create remote directory under orphan directory"
23142
23143 test_300r() {
23144         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23145                 skip "Need MDS version at least 2.7.55" && return
23146         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23147
23148         mkdir $DIR/$tdir
23149
23150         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23151                 error "set striped dir error"
23152
23153         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23154                 error "getstripeddir fails"
23155
23156         local stripe_count
23157         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23158                       awk '/lmv_stripe_count:/ { print $2 }')
23159
23160         [ $MDSCOUNT -ne $stripe_count ] &&
23161                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23162
23163         rm -rf $DIR/$tdir/striped_dir ||
23164                 error "unlink striped dir fails"
23165 }
23166 run_test 300r "test -1 striped directory"
23167
23168 test_300s_helper() {
23169         local count=$1
23170
23171         local stripe_dir=$DIR/$tdir/striped_dir.$count
23172
23173         $LFS mkdir -c $count $stripe_dir ||
23174                 error "lfs mkdir -c error"
23175
23176         $LFS getdirstripe $stripe_dir ||
23177                 error "lfs getdirstripe fails"
23178
23179         local stripe_count
23180         stripe_count=$($LFS getdirstripe $stripe_dir |
23181                       awk '/lmv_stripe_count:/ { print $2 }')
23182
23183         [ $count -ne $stripe_count ] &&
23184                 error_noexit "bad stripe count $stripe_count expected $count"
23185
23186         local dupe_stripes
23187         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23188                 awk '/0x/ {count[$1] += 1}; END {
23189                         for (idx in count) {
23190                                 if (count[idx]>1) {
23191                                         print "index " idx " count " count[idx]
23192                                 }
23193                         }
23194                 }')
23195
23196         if [[ -n "$dupe_stripes" ]] ; then
23197                 lfs getdirstripe $stripe_dir
23198                 error_noexit "Dupe MDT above: $dupe_stripes "
23199         fi
23200
23201         rm -rf $stripe_dir ||
23202                 error_noexit "unlink $stripe_dir fails"
23203 }
23204
23205 test_300s() {
23206         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23207                 skip "Need MDS version at least 2.7.55" && return
23208         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23209
23210         mkdir $DIR/$tdir
23211         for count in $(seq 2 $MDSCOUNT); do
23212                 test_300s_helper $count
23213         done
23214 }
23215 run_test 300s "test lfs mkdir -c without -i"
23216
23217
23218 prepare_remote_file() {
23219         mkdir $DIR/$tdir/src_dir ||
23220                 error "create remote source failed"
23221
23222         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23223                  error "cp to remote source failed"
23224         touch $DIR/$tdir/src_dir/a
23225
23226         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23227                 error "create remote target dir failed"
23228
23229         touch $DIR/$tdir/tgt_dir/b
23230
23231         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23232                 error "rename dir cross MDT failed!"
23233
23234         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23235                 error "src_child still exists after rename"
23236
23237         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23238                 error "missing file(a) after rename"
23239
23240         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23241                 error "diff after rename"
23242 }
23243
23244 test_310a() {
23245         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23247
23248         local remote_file=$DIR/$tdir/tgt_dir/b
23249
23250         mkdir -p $DIR/$tdir
23251
23252         prepare_remote_file || error "prepare remote file failed"
23253
23254         #open-unlink file
23255         $OPENUNLINK $remote_file $remote_file ||
23256                 error "openunlink $remote_file failed"
23257         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23258 }
23259 run_test 310a "open unlink remote file"
23260
23261 test_310b() {
23262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23264
23265         local remote_file=$DIR/$tdir/tgt_dir/b
23266
23267         mkdir -p $DIR/$tdir
23268
23269         prepare_remote_file || error "prepare remote file failed"
23270
23271         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23272         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23273         $CHECKSTAT -t file $remote_file || error "check file failed"
23274 }
23275 run_test 310b "unlink remote file with multiple links while open"
23276
23277 test_310c() {
23278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23279         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23280
23281         local remote_file=$DIR/$tdir/tgt_dir/b
23282
23283         mkdir -p $DIR/$tdir
23284
23285         prepare_remote_file || error "prepare remote file failed"
23286
23287         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23288         multiop_bg_pause $remote_file O_uc ||
23289                         error "mulitop failed for remote file"
23290         MULTIPID=$!
23291         $MULTIOP $DIR/$tfile Ouc
23292         kill -USR1 $MULTIPID
23293         wait $MULTIPID
23294 }
23295 run_test 310c "open-unlink remote file with multiple links"
23296
23297 #LU-4825
23298 test_311() {
23299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23300         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23301         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23302                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23303         remote_mds_nodsh && skip "remote MDS with nodsh"
23304
23305         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23306         local mdts=$(comma_list $(mdts_nodes))
23307
23308         mkdir -p $DIR/$tdir
23309         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23310         createmany -o $DIR/$tdir/$tfile. 1000
23311
23312         # statfs data is not real time, let's just calculate it
23313         old_iused=$((old_iused + 1000))
23314
23315         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23316                         osp.*OST0000*MDT0000.create_count")
23317         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23318                                 osp.*OST0000*MDT0000.max_create_count")
23319         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23320
23321         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23322         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23323         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23324
23325         unlinkmany $DIR/$tdir/$tfile. 1000
23326
23327         do_nodes $mdts "$LCTL set_param -n \
23328                         osp.*OST0000*.max_create_count=$max_count"
23329         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23330                 do_nodes $mdts "$LCTL set_param -n \
23331                                 osp.*OST0000*.create_count=$count"
23332         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23333                         grep "=0" && error "create_count is zero"
23334
23335         local new_iused
23336         for i in $(seq 120); do
23337                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23338                 # system may be too busy to destroy all objs in time, use
23339                 # a somewhat small value to not fail autotest
23340                 [ $((old_iused - new_iused)) -gt 400 ] && break
23341                 sleep 1
23342         done
23343
23344         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23345         [ $((old_iused - new_iused)) -gt 400 ] ||
23346                 error "objs not destroyed after unlink"
23347 }
23348 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23349
23350 zfs_oid_to_objid()
23351 {
23352         local ost=$1
23353         local objid=$2
23354
23355         local vdevdir=$(dirname $(facet_vdevice $ost))
23356         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23357         local zfs_zapid=$(do_facet $ost $cmd |
23358                           grep -w "/O/0/d$((objid%32))" -C 5 |
23359                           awk '/Object/{getline; print $1}')
23360         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23361                           awk "/$objid = /"'{printf $3}')
23362
23363         echo $zfs_objid
23364 }
23365
23366 zfs_object_blksz() {
23367         local ost=$1
23368         local objid=$2
23369
23370         local vdevdir=$(dirname $(facet_vdevice $ost))
23371         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23372         local blksz=$(do_facet $ost $cmd $objid |
23373                       awk '/dblk/{getline; printf $4}')
23374
23375         case "${blksz: -1}" in
23376                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23377                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23378                 *) ;;
23379         esac
23380
23381         echo $blksz
23382 }
23383
23384 test_312() { # LU-4856
23385         remote_ost_nodsh && skip "remote OST with nodsh"
23386         [ "$ost1_FSTYPE" = "zfs" ] ||
23387                 skip_env "the test only applies to zfs"
23388
23389         local max_blksz=$(do_facet ost1 \
23390                           $ZFS get -p recordsize $(facet_device ost1) |
23391                           awk '!/VALUE/{print $3}')
23392
23393         # to make life a little bit easier
23394         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23395         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23396
23397         local tf=$DIR/$tdir/$tfile
23398         touch $tf
23399         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23400
23401         # Get ZFS object id
23402         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23403         # block size change by sequential overwrite
23404         local bs
23405
23406         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23407                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23408
23409                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23410                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23411         done
23412         rm -f $tf
23413
23414         # block size change by sequential append write
23415         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23416         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23417         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23418         local count
23419
23420         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23421                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23422                         oflag=sync conv=notrunc
23423
23424                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23425                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23426                         error "blksz error, actual $blksz, " \
23427                                 "expected: 2 * $count * $PAGE_SIZE"
23428         done
23429         rm -f $tf
23430
23431         # random write
23432         touch $tf
23433         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23434         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23435
23436         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23437         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23438         [ $blksz -eq $PAGE_SIZE ] ||
23439                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23440
23441         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23442         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23443         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23444
23445         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23446         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23447         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23448 }
23449 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23450
23451 test_313() {
23452         remote_ost_nodsh && skip "remote OST with nodsh"
23453
23454         local file=$DIR/$tfile
23455
23456         rm -f $file
23457         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23458
23459         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23460         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23461         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23462                 error "write should failed"
23463         do_facet ost1 "$LCTL set_param fail_loc=0"
23464         rm -f $file
23465 }
23466 run_test 313 "io should fail after last_rcvd update fail"
23467
23468 test_314() {
23469         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23470
23471         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23472         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23473         rm -f $DIR/$tfile
23474         wait_delete_completed
23475         do_facet ost1 "$LCTL set_param fail_loc=0"
23476 }
23477 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23478
23479 test_315() { # LU-618
23480         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23481
23482         local file=$DIR/$tfile
23483         rm -f $file
23484
23485         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23486                 error "multiop file write failed"
23487         $MULTIOP $file oO_RDONLY:r4063232_c &
23488         PID=$!
23489
23490         sleep 2
23491
23492         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23493         kill -USR1 $PID
23494
23495         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23496         rm -f $file
23497 }
23498 run_test 315 "read should be accounted"
23499
23500 test_316() {
23501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23502         large_xattr_enabled || skip_env "ea_inode feature disabled"
23503
23504         rm -rf $DIR/$tdir/d
23505         mkdir -p $DIR/$tdir/d
23506         chown nobody $DIR/$tdir/d
23507         touch $DIR/$tdir/d/file
23508
23509         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23510 }
23511 run_test 316 "lfs mv"
23512
23513 test_317() {
23514         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23515                 skip "Need MDS version at least 2.11.53"
23516         if [ "$ost1_FSTYPE" == "zfs" ]; then
23517                 skip "LU-10370: no implementation for ZFS"
23518         fi
23519
23520         local trunc_sz
23521         local grant_blk_size
23522
23523         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23524                         awk '/grant_block_size:/ { print $2; exit; }')
23525         #
23526         # Create File of size 5M. Truncate it to below size's and verify
23527         # blocks count.
23528         #
23529         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23530                 error "Create file $DIR/$tfile failed"
23531         stack_trap "rm -f $DIR/$tfile" EXIT
23532
23533         for trunc_sz in 2097152 4097 4000 509 0; do
23534                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23535                         error "truncate $tfile to $trunc_sz failed"
23536                 local sz=$(stat --format=%s $DIR/$tfile)
23537                 local blk=$(stat --format=%b $DIR/$tfile)
23538                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23539                                      grant_blk_size) * 8))
23540
23541                 if [[ $blk -ne $trunc_blk ]]; then
23542                         $(which stat) $DIR/$tfile
23543                         error "Expected Block $trunc_blk got $blk for $tfile"
23544                 fi
23545
23546                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23547                         error "Expected Size $trunc_sz got $sz for $tfile"
23548         done
23549
23550         #
23551         # sparse file test
23552         # Create file with a hole and write actual two blocks. Block count
23553         # must be 16.
23554         #
23555         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23556                 conv=fsync || error "Create file : $DIR/$tfile"
23557
23558         # Calculate the final truncate size.
23559         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23560
23561         #
23562         # truncate to size $trunc_sz bytes. Strip the last block
23563         # The block count must drop to 8
23564         #
23565         $TRUNCATE $DIR/$tfile $trunc_sz ||
23566                 error "truncate $tfile to $trunc_sz failed"
23567
23568         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23569         sz=$(stat --format=%s $DIR/$tfile)
23570         blk=$(stat --format=%b $DIR/$tfile)
23571
23572         if [[ $blk -ne $trunc_bsz ]]; then
23573                 $(which stat) $DIR/$tfile
23574                 error "Expected Block $trunc_bsz got $blk for $tfile"
23575         fi
23576
23577         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23578                 error "Expected Size $trunc_sz got $sz for $tfile"
23579 }
23580 run_test 317 "Verify blocks get correctly update after truncate"
23581
23582 test_318() {
23583         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23584         local old_max_active=$($LCTL get_param -n \
23585                             ${llite_name}.max_read_ahead_async_active \
23586                             2>/dev/null)
23587
23588         $LCTL set_param llite.*.max_read_ahead_async_active=256
23589         local max_active=$($LCTL get_param -n \
23590                            ${llite_name}.max_read_ahead_async_active \
23591                            2>/dev/null)
23592         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23593
23594         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23595                 error "set max_read_ahead_async_active should succeed"
23596
23597         $LCTL set_param llite.*.max_read_ahead_async_active=512
23598         max_active=$($LCTL get_param -n \
23599                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23600         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23601
23602         # restore @max_active
23603         [ $old_max_active -ne 0 ] && $LCTL set_param \
23604                 llite.*.max_read_ahead_async_active=$old_max_active
23605
23606         local old_threshold=$($LCTL get_param -n \
23607                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23608         local max_per_file_mb=$($LCTL get_param -n \
23609                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23610
23611         local invalid=$(($max_per_file_mb + 1))
23612         $LCTL set_param \
23613                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23614                         && error "set $invalid should fail"
23615
23616         local valid=$(($invalid - 1))
23617         $LCTL set_param \
23618                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23619                         error "set $valid should succeed"
23620         local threshold=$($LCTL get_param -n \
23621                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23622         [ $threshold -eq $valid ] || error \
23623                 "expect threshold $valid got $threshold"
23624         $LCTL set_param \
23625                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23626 }
23627 run_test 318 "Verify async readahead tunables"
23628
23629 test_319() {
23630         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23631
23632         local before=$(date +%s)
23633         local evict
23634         local mdir=$DIR/$tdir
23635         local file=$mdir/xxx
23636
23637         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23638         touch $file
23639
23640 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23641         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23642         $LFS mv -m1 $file &
23643
23644         sleep 1
23645         dd if=$file of=/dev/null
23646         wait
23647         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23648           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23649
23650         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23651 }
23652 run_test 319 "lost lease lock on migrate error"
23653
23654 test_398a() { # LU-4198
23655         local ost1_imp=$(get_osc_import_name client ost1)
23656         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23657                          cut -d'.' -f2)
23658
23659         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23660         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23661
23662         # request a new lock on client
23663         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23664
23665         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23666         local lock_count=$($LCTL get_param -n \
23667                            ldlm.namespaces.$imp_name.lru_size)
23668         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23669
23670         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23671
23672         # no lock cached, should use lockless IO and not enqueue new lock
23673         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23674         lock_count=$($LCTL get_param -n \
23675                      ldlm.namespaces.$imp_name.lru_size)
23676         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23677 }
23678 run_test 398a "direct IO should cancel lock otherwise lockless"
23679
23680 test_398b() { # LU-4198
23681         which fio || skip_env "no fio installed"
23682         $LFS setstripe -c -1 $DIR/$tfile
23683
23684         local size=12
23685         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23686
23687         local njobs=4
23688         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23689         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23690                 --numjobs=$njobs --fallocate=none \
23691                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23692                 --filename=$DIR/$tfile &
23693         bg_pid=$!
23694
23695         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23696         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23697                 --numjobs=$njobs --fallocate=none \
23698                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23699                 --filename=$DIR/$tfile || true
23700         wait $bg_pid
23701
23702         rm -f $DIR/$tfile
23703 }
23704 run_test 398b "DIO and buffer IO race"
23705
23706 test_398c() { # LU-4198
23707         local ost1_imp=$(get_osc_import_name client ost1)
23708         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23709                          cut -d'.' -f2)
23710
23711         which fio || skip_env "no fio installed"
23712
23713         saved_debug=$($LCTL get_param -n debug)
23714         $LCTL set_param debug=0
23715
23716         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23717         ((size /= 1024)) # by megabytes
23718         ((size /= 2)) # write half of the OST at most
23719         [ $size -gt 40 ] && size=40 #reduce test time anyway
23720
23721         $LFS setstripe -c 1 $DIR/$tfile
23722
23723         # it seems like ldiskfs reserves more space than necessary if the
23724         # writing blocks are not mapped, so it extends the file firstly
23725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23726         cancel_lru_locks osc
23727
23728         # clear and verify rpc_stats later
23729         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23730
23731         local njobs=4
23732         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23733         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23734                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23735                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23736                 --filename=$DIR/$tfile
23737         [ $? -eq 0 ] || error "fio write error"
23738
23739         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23740                 error "Locks were requested while doing AIO"
23741
23742         # get the percentage of 1-page I/O
23743         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23744                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23745                 awk '{print $7}')
23746         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23747
23748         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23749         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23750                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23751                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23752                 --filename=$DIR/$tfile
23753         [ $? -eq 0 ] || error "fio mixed read write error"
23754
23755         echo "AIO with large block size ${size}M"
23756         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23757                 --numjobs=1 --fallocate=none --ioengine=libaio \
23758                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23759                 --filename=$DIR/$tfile
23760         [ $? -eq 0 ] || error "fio large block size failed"
23761
23762         rm -f $DIR/$tfile
23763         $LCTL set_param debug="$saved_debug"
23764 }
23765 run_test 398c "run fio to test AIO"
23766
23767 test_398d() { #  LU-13846
23768         which aiocp || skip_env "no aiocp installed"
23769         local aio_file=$DIR/$tfile.aio
23770
23771         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23772
23773         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23774         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23775         stack_trap "rm -f $DIR/$tfile $aio_file"
23776
23777         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23778
23779         # make sure we don't crash and fail properly
23780         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23781                 error "aio not aligned with PAGE SIZE should fail"
23782
23783         rm -f $DIR/$tfile $aio_file
23784 }
23785 run_test 398d "run aiocp to verify block size > stripe size"
23786
23787 test_398e() {
23788         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23789         touch $DIR/$tfile.new
23790         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23791 }
23792 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23793
23794 test_398f() { #  LU-14687
23795         which aiocp || skip_env "no aiocp installed"
23796         local aio_file=$DIR/$tfile.aio
23797
23798         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23799
23800         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23801         stack_trap "rm -f $DIR/$tfile $aio_file"
23802
23803         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23804         $LCTL set_param fail_loc=0x1418
23805         # make sure we don't crash and fail properly
23806         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23807                 error "aio with page allocation failure succeeded"
23808         $LCTL set_param fail_loc=0
23809         diff $DIR/$tfile $aio_file
23810         [[ $? != 0 ]] || error "no diff after failed aiocp"
23811 }
23812 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23813
23814 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23815 # stripe and i/o size must be > stripe size
23816 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23817 # single RPC in flight.  This test shows async DIO submission is working by
23818 # showing multiple RPCs in flight.
23819 test_398g() { #  LU-13798
23820         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23821
23822         # We need to do some i/o first to acquire enough grant to put our RPCs
23823         # in flight; otherwise a new connection may not have enough grant
23824         # available
23825         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23826                 error "parallel dio failed"
23827         stack_trap "rm -f $DIR/$tfile"
23828
23829         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23830         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23831         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23832         stack_trap "$LCTL set_param -n $pages_per_rpc"
23833
23834         # Recreate file so it's empty
23835         rm -f $DIR/$tfile
23836         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23837         #Pause rpc completion to guarantee we see multiple rpcs in flight
23838         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23839         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23840         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23841
23842         # Clear rpc stats
23843         $LCTL set_param osc.*.rpc_stats=c
23844
23845         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23846                 error "parallel dio failed"
23847         stack_trap "rm -f $DIR/$tfile"
23848
23849         $LCTL get_param osc.*-OST0000-*.rpc_stats
23850         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23851                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23852                 grep "8:" | awk '{print $8}')
23853         # We look at the "8 rpcs in flight" field, and verify A) it is present
23854         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23855         # as expected for an 8M DIO to a file with 1M stripes.
23856         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23857
23858         # Verify turning off parallel dio works as expected
23859         # Clear rpc stats
23860         $LCTL set_param osc.*.rpc_stats=c
23861         $LCTL set_param llite.*.parallel_dio=0
23862         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23863
23864         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23865                 error "dio with parallel dio disabled failed"
23866
23867         # Ideally, we would see only one RPC in flight here, but there is an
23868         # unavoidable race between i/o completion and RPC in flight counting,
23869         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23870         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23871         # So instead we just verify it's always < 8.
23872         $LCTL get_param osc.*-OST0000-*.rpc_stats
23873         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23874                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23875                 grep '^$' -B1 | grep . | awk '{print $1}')
23876         [ $ret != "8:" ] ||
23877                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23878 }
23879 run_test 398g "verify parallel dio async RPC submission"
23880
23881 test_398h() { #  LU-13798
23882         local dio_file=$DIR/$tfile.dio
23883
23884         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23885
23886         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23887         stack_trap "rm -f $DIR/$tfile $dio_file"
23888
23889         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23890                 error "parallel dio failed"
23891         diff $DIR/$tfile $dio_file
23892         [[ $? == 0 ]] || error "file diff after aiocp"
23893 }
23894 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23895
23896 test_398i() { #  LU-13798
23897         local dio_file=$DIR/$tfile.dio
23898
23899         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23900
23901         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23902         stack_trap "rm -f $DIR/$tfile $dio_file"
23903
23904         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23905         $LCTL set_param fail_loc=0x1418
23906         # make sure we don't crash and fail properly
23907         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23908                 error "parallel dio page allocation failure succeeded"
23909         diff $DIR/$tfile $dio_file
23910         [[ $? != 0 ]] || error "no diff after failed aiocp"
23911 }
23912 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23913
23914 test_398j() { #  LU-13798
23915         # Stripe size > RPC size but less than i/o size tests split across
23916         # stripes and RPCs for individual i/o op
23917         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23918
23919         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23920         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23921         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23922         stack_trap "$LCTL set_param -n $pages_per_rpc"
23923
23924         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23925                 error "parallel dio write failed"
23926         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23927
23928         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23929                 error "parallel dio read failed"
23930         diff $DIR/$tfile $DIR/$tfile.2
23931         [[ $? == 0 ]] || error "file diff after parallel dio read"
23932 }
23933 run_test 398j "test parallel dio where stripe size > rpc_size"
23934
23935 test_398k() { #  LU-13798
23936         wait_delete_completed
23937         wait_mds_ost_sync
23938
23939         # 4 stripe file; we will cause out of space on OST0
23940         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23941
23942         # Fill OST0 (if it's not too large)
23943         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23944                    head -n1)
23945         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23946                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23947         fi
23948         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23949         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23950                 error "dd should fill OST0"
23951         stack_trap "rm -f $DIR/$tfile.1"
23952
23953         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23954         err=$?
23955
23956         ls -la $DIR/$tfile
23957         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23958                 error "file is not 0 bytes in size"
23959
23960         # dd above should not succeed, but don't error until here so we can
23961         # get debug info above
23962         [[ $err != 0 ]] ||
23963                 error "parallel dio write with enospc succeeded"
23964         stack_trap "rm -f $DIR/$tfile"
23965 }
23966 run_test 398k "test enospc on first stripe"
23967
23968 test_398l() { #  LU-13798
23969         wait_delete_completed
23970         wait_mds_ost_sync
23971
23972         # 4 stripe file; we will cause out of space on OST0
23973         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23974         # happens on the second i/o chunk we issue
23975         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23976
23977         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23978         stack_trap "rm -f $DIR/$tfile"
23979
23980         # Fill OST0 (if it's not too large)
23981         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23982                    head -n1)
23983         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23984                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23985         fi
23986         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23987         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23988                 error "dd should fill OST0"
23989         stack_trap "rm -f $DIR/$tfile.1"
23990
23991         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23992         err=$?
23993         stack_trap "rm -f $DIR/$tfile.2"
23994
23995         # Check that short write completed as expected
23996         ls -la $DIR/$tfile.2
23997         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23998                 error "file is not 1M in size"
23999
24000         # dd above should not succeed, but don't error until here so we can
24001         # get debug info above
24002         [[ $err != 0 ]] ||
24003                 error "parallel dio write with enospc succeeded"
24004
24005         # Truncate source file to same length as output file and diff them
24006         $TRUNCATE $DIR/$tfile 1048576
24007         diff $DIR/$tfile $DIR/$tfile.2
24008         [[ $? == 0 ]] || error "data incorrect after short write"
24009 }
24010 run_test 398l "test enospc on intermediate stripe/RPC"
24011
24012 test_398m() { #  LU-13798
24013         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24014
24015         # Set up failure on OST0, the first stripe:
24016         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24017         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24018         # So this fail_val specifies OST0
24019         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24020         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24021
24022         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24023                 error "parallel dio write with failure on first stripe succeeded"
24024         stack_trap "rm -f $DIR/$tfile"
24025         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24026
24027         # Place data in file for read
24028         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24029                 error "parallel dio write failed"
24030
24031         # Fail read on OST0, first stripe
24032         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24033         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24034         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24035                 error "parallel dio read with error on first stripe succeeded"
24036         rm -f $DIR/$tfile.2
24037         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24038
24039         # Switch to testing on OST1, second stripe
24040         # Clear file contents, maintain striping
24041         echo > $DIR/$tfile
24042         # Set up failure on OST1, second stripe:
24043         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24044         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24045
24046         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24047                 error "parallel dio write with failure on first stripe succeeded"
24048         stack_trap "rm -f $DIR/$tfile"
24049         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24050
24051         # Place data in file for read
24052         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24053                 error "parallel dio write failed"
24054
24055         # Fail read on OST1, second stripe
24056         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24057         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24058         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24059                 error "parallel dio read with error on first stripe succeeded"
24060         rm -f $DIR/$tfile.2
24061         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24062 }
24063 run_test 398m "test RPC failures with parallel dio"
24064
24065 # Parallel submission of DIO should not cause problems for append, but it's
24066 # important to verify.
24067 test_398n() { #  LU-13798
24068         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24069
24070         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24071                 error "dd to create source file failed"
24072         stack_trap "rm -f $DIR/$tfile"
24073
24074         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24075                 error "parallel dio write with failure on second stripe succeeded"
24076         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24077         diff $DIR/$tfile $DIR/$tfile.1
24078         [[ $? == 0 ]] || error "data incorrect after append"
24079
24080 }
24081 run_test 398n "test append with parallel DIO"
24082
24083 test_fake_rw() {
24084         local read_write=$1
24085         if [ "$read_write" = "write" ]; then
24086                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24087         elif [ "$read_write" = "read" ]; then
24088                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24089         else
24090                 error "argument error"
24091         fi
24092
24093         # turn off debug for performance testing
24094         local saved_debug=$($LCTL get_param -n debug)
24095         $LCTL set_param debug=0
24096
24097         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24098
24099         # get ost1 size - $FSNAME-OST0000
24100         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24101         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24102         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24103
24104         if [ "$read_write" = "read" ]; then
24105                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24106         fi
24107
24108         local start_time=$(date +%s.%N)
24109         $dd_cmd bs=1M count=$blocks oflag=sync ||
24110                 error "real dd $read_write error"
24111         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24112
24113         if [ "$read_write" = "write" ]; then
24114                 rm -f $DIR/$tfile
24115         fi
24116
24117         # define OBD_FAIL_OST_FAKE_RW           0x238
24118         do_facet ost1 $LCTL set_param fail_loc=0x238
24119
24120         local start_time=$(date +%s.%N)
24121         $dd_cmd bs=1M count=$blocks oflag=sync ||
24122                 error "fake dd $read_write error"
24123         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24124
24125         if [ "$read_write" = "write" ]; then
24126                 # verify file size
24127                 cancel_lru_locks osc
24128                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24129                         error "$tfile size not $blocks MB"
24130         fi
24131         do_facet ost1 $LCTL set_param fail_loc=0
24132
24133         echo "fake $read_write $duration_fake vs. normal $read_write" \
24134                 "$duration in seconds"
24135         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24136                 error_not_in_vm "fake write is slower"
24137
24138         $LCTL set_param -n debug="$saved_debug"
24139         rm -f $DIR/$tfile
24140 }
24141 test_399a() { # LU-7655 for OST fake write
24142         remote_ost_nodsh && skip "remote OST with nodsh"
24143
24144         test_fake_rw write
24145 }
24146 run_test 399a "fake write should not be slower than normal write"
24147
24148 test_399b() { # LU-8726 for OST fake read
24149         remote_ost_nodsh && skip "remote OST with nodsh"
24150         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24151                 skip_env "ldiskfs only test"
24152         fi
24153
24154         test_fake_rw read
24155 }
24156 run_test 399b "fake read should not be slower than normal read"
24157
24158 test_400a() { # LU-1606, was conf-sanity test_74
24159         if ! which $CC > /dev/null 2>&1; then
24160                 skip_env "$CC is not installed"
24161         fi
24162
24163         local extra_flags=''
24164         local out=$TMP/$tfile
24165         local prefix=/usr/include/lustre
24166         local prog
24167
24168         # Oleg removes c files in his test rig so test if any c files exist
24169         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24170                 skip_env "Needed c test files are missing"
24171
24172         if ! [[ -d $prefix ]]; then
24173                 # Assume we're running in tree and fixup the include path.
24174                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24175                 extra_flags+=" -L$LUSTRE/utils/.lib"
24176         fi
24177
24178         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24179                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24180                         error "client api broken"
24181         done
24182         rm -f $out
24183 }
24184 run_test 400a "Lustre client api program can compile and link"
24185
24186 test_400b() { # LU-1606, LU-5011
24187         local header
24188         local out=$TMP/$tfile
24189         local prefix=/usr/include/linux/lustre
24190
24191         # We use a hard coded prefix so that this test will not fail
24192         # when run in tree. There are headers in lustre/include/lustre/
24193         # that are not packaged (like lustre_idl.h) and have more
24194         # complicated include dependencies (like config.h and lnet/types.h).
24195         # Since this test about correct packaging we just skip them when
24196         # they don't exist (see below) rather than try to fixup cppflags.
24197
24198         if ! which $CC > /dev/null 2>&1; then
24199                 skip_env "$CC is not installed"
24200         fi
24201
24202         for header in $prefix/*.h; do
24203                 if ! [[ -f "$header" ]]; then
24204                         continue
24205                 fi
24206
24207                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24208                         continue # lustre_ioctl.h is internal header
24209                 fi
24210
24211                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24212                         error "cannot compile '$header'"
24213         done
24214         rm -f $out
24215 }
24216 run_test 400b "packaged headers can be compiled"
24217
24218 test_401a() { #LU-7437
24219         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24220         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24221
24222         #count the number of parameters by "list_param -R"
24223         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24224         #count the number of parameters by listing proc files
24225         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24226         echo "proc_dirs='$proc_dirs'"
24227         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24228         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24229                       sort -u | wc -l)
24230
24231         [ $params -eq $procs ] ||
24232                 error "found $params parameters vs. $procs proc files"
24233
24234         # test the list_param -D option only returns directories
24235         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24236         #count the number of parameters by listing proc directories
24237         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24238                 sort -u | wc -l)
24239
24240         [ $params -eq $procs ] ||
24241                 error "found $params parameters vs. $procs proc files"
24242 }
24243 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24244
24245 test_401b() {
24246         # jobid_var may not allow arbitrary values, so use jobid_name
24247         # if available
24248         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24249                 local testname=jobid_name tmp='testing%p'
24250         else
24251                 local testname=jobid_var tmp=testing
24252         fi
24253
24254         local save=$($LCTL get_param -n $testname)
24255
24256         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24257                 error "no error returned when setting bad parameters"
24258
24259         local jobid_new=$($LCTL get_param -n foe $testname baz)
24260         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24261
24262         $LCTL set_param -n fog=bam $testname=$save bat=fog
24263         local jobid_old=$($LCTL get_param -n foe $testname bag)
24264         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24265 }
24266 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24267
24268 test_401c() {
24269         # jobid_var may not allow arbitrary values, so use jobid_name
24270         # if available
24271         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24272                 local testname=jobid_name
24273         else
24274                 local testname=jobid_var
24275         fi
24276
24277         local jobid_var_old=$($LCTL get_param -n $testname)
24278         local jobid_var_new
24279
24280         $LCTL set_param $testname= &&
24281                 error "no error returned for 'set_param a='"
24282
24283         jobid_var_new=$($LCTL get_param -n $testname)
24284         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24285                 error "$testname was changed by setting without value"
24286
24287         $LCTL set_param $testname &&
24288                 error "no error returned for 'set_param a'"
24289
24290         jobid_var_new=$($LCTL get_param -n $testname)
24291         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24292                 error "$testname was changed by setting without value"
24293 }
24294 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24295
24296 test_401d() {
24297         # jobid_var may not allow arbitrary values, so use jobid_name
24298         # if available
24299         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24300                 local testname=jobid_name new_value='foo=bar%p'
24301         else
24302                 local testname=jobid_var new_valuie=foo=bar
24303         fi
24304
24305         local jobid_var_old=$($LCTL get_param -n $testname)
24306         local jobid_var_new
24307
24308         $LCTL set_param $testname=$new_value ||
24309                 error "'set_param a=b' did not accept a value containing '='"
24310
24311         jobid_var_new=$($LCTL get_param -n $testname)
24312         [[ "$jobid_var_new" == "$new_value" ]] ||
24313                 error "'set_param a=b' failed on a value containing '='"
24314
24315         # Reset the $testname to test the other format
24316         $LCTL set_param $testname=$jobid_var_old
24317         jobid_var_new=$($LCTL get_param -n $testname)
24318         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24319                 error "failed to reset $testname"
24320
24321         $LCTL set_param $testname $new_value ||
24322                 error "'set_param a b' did not accept a value containing '='"
24323
24324         jobid_var_new=$($LCTL get_param -n $testname)
24325         [[ "$jobid_var_new" == "$new_value" ]] ||
24326                 error "'set_param a b' failed on a value containing '='"
24327
24328         $LCTL set_param $testname $jobid_var_old
24329         jobid_var_new=$($LCTL get_param -n $testname)
24330         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24331                 error "failed to reset $testname"
24332 }
24333 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24334
24335 test_401e() { # LU-14779
24336         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24337                 error "lctl list_param MGC* failed"
24338         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24339         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24340                 error "lctl get_param lru_size failed"
24341 }
24342 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24343
24344 test_402() {
24345         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24346         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24347                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24348         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24349                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24350                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24351         remote_mds_nodsh && skip "remote MDS with nodsh"
24352
24353         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24354 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24355         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24356         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24357                 echo "Touch failed - OK"
24358 }
24359 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24360
24361 test_403() {
24362         local file1=$DIR/$tfile.1
24363         local file2=$DIR/$tfile.2
24364         local tfile=$TMP/$tfile
24365
24366         rm -f $file1 $file2 $tfile
24367
24368         touch $file1
24369         ln $file1 $file2
24370
24371         # 30 sec OBD_TIMEOUT in ll_getattr()
24372         # right before populating st_nlink
24373         $LCTL set_param fail_loc=0x80001409
24374         stat -c %h $file1 > $tfile &
24375
24376         # create an alias, drop all locks and reclaim the dentry
24377         < $file2
24378         cancel_lru_locks mdc
24379         cancel_lru_locks osc
24380         sysctl -w vm.drop_caches=2
24381
24382         wait
24383
24384         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24385
24386         rm -f $tfile $file1 $file2
24387 }
24388 run_test 403 "i_nlink should not drop to zero due to aliasing"
24389
24390 test_404() { # LU-6601
24391         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24392                 skip "Need server version newer than 2.8.52"
24393         remote_mds_nodsh && skip "remote MDS with nodsh"
24394
24395         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24396                 awk '/osp .*-osc-MDT/ { print $4}')
24397
24398         local osp
24399         for osp in $mosps; do
24400                 echo "Deactivate: " $osp
24401                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24402                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24403                         awk -vp=$osp '$4 == p { print $2 }')
24404                 [ $stat = IN ] || {
24405                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24406                         error "deactivate error"
24407                 }
24408                 echo "Activate: " $osp
24409                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24410                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24411                         awk -vp=$osp '$4 == p { print $2 }')
24412                 [ $stat = UP ] || {
24413                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24414                         error "activate error"
24415                 }
24416         done
24417 }
24418 run_test 404 "validate manual {de}activated works properly for OSPs"
24419
24420 test_405() {
24421         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24422         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24423                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24424                         skip "Layout swap lock is not supported"
24425
24426         check_swap_layouts_support
24427         check_swap_layout_no_dom $DIR
24428
24429         test_mkdir $DIR/$tdir
24430         swap_lock_test -d $DIR/$tdir ||
24431                 error "One layout swap locked test failed"
24432 }
24433 run_test 405 "Various layout swap lock tests"
24434
24435 test_406() {
24436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24437         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24438         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24440         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24441                 skip "Need MDS version at least 2.8.50"
24442
24443         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24444         local test_pool=$TESTNAME
24445
24446         pool_add $test_pool || error "pool_add failed"
24447         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24448                 error "pool_add_targets failed"
24449
24450         save_layout_restore_at_exit $MOUNT
24451
24452         # parent set default stripe count only, child will stripe from both
24453         # parent and fs default
24454         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24455                 error "setstripe $MOUNT failed"
24456         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24457         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24458         for i in $(seq 10); do
24459                 local f=$DIR/$tdir/$tfile.$i
24460                 touch $f || error "touch failed"
24461                 local count=$($LFS getstripe -c $f)
24462                 [ $count -eq $OSTCOUNT ] ||
24463                         error "$f stripe count $count != $OSTCOUNT"
24464                 local offset=$($LFS getstripe -i $f)
24465                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24466                 local size=$($LFS getstripe -S $f)
24467                 [ $size -eq $((def_stripe_size * 2)) ] ||
24468                         error "$f stripe size $size != $((def_stripe_size * 2))"
24469                 local pool=$($LFS getstripe -p $f)
24470                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24471         done
24472
24473         # change fs default striping, delete parent default striping, now child
24474         # will stripe from new fs default striping only
24475         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24476                 error "change $MOUNT default stripe failed"
24477         $LFS setstripe -c 0 $DIR/$tdir ||
24478                 error "delete $tdir default stripe failed"
24479         for i in $(seq 11 20); do
24480                 local f=$DIR/$tdir/$tfile.$i
24481                 touch $f || error "touch $f failed"
24482                 local count=$($LFS getstripe -c $f)
24483                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24484                 local offset=$($LFS getstripe -i $f)
24485                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24486                 local size=$($LFS getstripe -S $f)
24487                 [ $size -eq $def_stripe_size ] ||
24488                         error "$f stripe size $size != $def_stripe_size"
24489                 local pool=$($LFS getstripe -p $f)
24490                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24491         done
24492
24493         unlinkmany $DIR/$tdir/$tfile. 1 20
24494
24495         local f=$DIR/$tdir/$tfile
24496         pool_remove_all_targets $test_pool $f
24497         pool_remove $test_pool $f
24498 }
24499 run_test 406 "DNE support fs default striping"
24500
24501 test_407() {
24502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24503         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24504                 skip "Need MDS version at least 2.8.55"
24505         remote_mds_nodsh && skip "remote MDS with nodsh"
24506
24507         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24508                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24509         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24510                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24511         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24512
24513         #define OBD_FAIL_DT_TXN_STOP    0x2019
24514         for idx in $(seq $MDSCOUNT); do
24515                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24516         done
24517         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24518         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24519                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24520         true
24521 }
24522 run_test 407 "transaction fail should cause operation fail"
24523
24524 test_408() {
24525         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24526
24527         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24528         lctl set_param fail_loc=0x8000040a
24529         # let ll_prepare_partial_page() fail
24530         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24531
24532         rm -f $DIR/$tfile
24533
24534         # create at least 100 unused inodes so that
24535         # shrink_icache_memory(0) should not return 0
24536         touch $DIR/$tfile-{0..100}
24537         rm -f $DIR/$tfile-{0..100}
24538         sync
24539
24540         echo 2 > /proc/sys/vm/drop_caches
24541 }
24542 run_test 408 "drop_caches should not hang due to page leaks"
24543
24544 test_409()
24545 {
24546         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24547
24548         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24549         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24550         touch $DIR/$tdir/guard || error "(2) Fail to create"
24551
24552         local PREFIX=$(str_repeat 'A' 128)
24553         echo "Create 1K hard links start at $(date)"
24554         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24555                 error "(3) Fail to hard link"
24556
24557         echo "Links count should be right although linkEA overflow"
24558         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24559         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24560         [ $linkcount -eq 1001 ] ||
24561                 error "(5) Unexpected hard links count: $linkcount"
24562
24563         echo "List all links start at $(date)"
24564         ls -l $DIR/$tdir/foo > /dev/null ||
24565                 error "(6) Fail to list $DIR/$tdir/foo"
24566
24567         echo "Unlink hard links start at $(date)"
24568         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24569                 error "(7) Fail to unlink"
24570         echo "Unlink hard links finished at $(date)"
24571 }
24572 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24573
24574 test_410()
24575 {
24576         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24577                 skip "Need client version at least 2.9.59"
24578         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24579                 skip "Need MODULES build"
24580
24581         # Create a file, and stat it from the kernel
24582         local testfile=$DIR/$tfile
24583         touch $testfile
24584
24585         local run_id=$RANDOM
24586         local my_ino=$(stat --format "%i" $testfile)
24587
24588         # Try to insert the module. This will always fail as the
24589         # module is designed to not be inserted.
24590         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24591             &> /dev/null
24592
24593         # Anything but success is a test failure
24594         dmesg | grep -q \
24595             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24596             error "no inode match"
24597 }
24598 run_test 410 "Test inode number returned from kernel thread"
24599
24600 cleanup_test411_cgroup() {
24601         trap 0
24602         rmdir "$1"
24603 }
24604
24605 test_411() {
24606         local cg_basedir=/sys/fs/cgroup/memory
24607         # LU-9966
24608         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24609                 skip "no setup for cgroup"
24610
24611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24612                 error "test file creation failed"
24613         cancel_lru_locks osc
24614
24615         # Create a very small memory cgroup to force a slab allocation error
24616         local cgdir=$cg_basedir/osc_slab_alloc
24617         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24618         trap "cleanup_test411_cgroup $cgdir" EXIT
24619         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24620         echo 1M > $cgdir/memory.limit_in_bytes
24621
24622         # Should not LBUG, just be killed by oom-killer
24623         # dd will return 0 even allocation failure in some environment.
24624         # So don't check return value
24625         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24626         cleanup_test411_cgroup $cgdir
24627
24628         return 0
24629 }
24630 run_test 411 "Slab allocation error with cgroup does not LBUG"
24631
24632 test_412() {
24633         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24634         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24635                 skip "Need server version at least 2.10.55"
24636         fi
24637
24638         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24639                 error "mkdir failed"
24640         $LFS getdirstripe $DIR/$tdir
24641         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24642         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24643                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24644         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24645         [ $stripe_count -eq 2 ] ||
24646                 error "expect 2 get $stripe_count"
24647 }
24648 run_test 412 "mkdir on specific MDTs"
24649
24650 generate_uneven_mdts() {
24651         local threshold=$1
24652         local ffree
24653         local bavail
24654         local max
24655         local min
24656         local max_index
24657         local min_index
24658         local tmp
24659         local i
24660
24661         echo
24662         echo "Check for uneven MDTs: "
24663
24664         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24665         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24666         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24667
24668         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24669         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24670         max_index=0
24671         min_index=0
24672         for ((i = 1; i < ${#ffree[@]}; i++)); do
24673                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24674                 if [ $tmp -gt $max ]; then
24675                         max=$tmp
24676                         max_index=$i
24677                 fi
24678                 if [ $tmp -lt $min ]; then
24679                         min=$tmp
24680                         min_index=$i
24681                 fi
24682         done
24683
24684         # Check if we need to generate uneven MDTs
24685         local diff=$(((max - min) * 100 / min))
24686         local testdir=$DIR/$tdir-fillmdt
24687
24688         mkdir -p $testdir
24689
24690         i=0
24691         while (( diff < threshold )); do
24692                 # generate uneven MDTs, create till $threshold% diff
24693                 echo -n "weight diff=$diff% must be > $threshold% ..."
24694                 echo "Fill MDT$min_index with 100 files: loop $i"
24695                 testdir=$DIR/$tdir-fillmdt/$i
24696                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24697                         error "mkdir $testdir failed"
24698                 $LFS setstripe -E 1M -L mdt $testdir ||
24699                         error "setstripe $testdir failed"
24700                 for F in f.{0..99}; do
24701                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24702                                 /dev/null 2>&1 || error "dd $F failed"
24703                 done
24704
24705                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24706                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24707                 max=$(((${ffree[max_index]} >> 8) * \
24708                         (${bavail[max_index]} * bsize >> 16)))
24709                 min=$(((${ffree[min_index]} >> 8) * \
24710                         (${bavail[min_index]} * bsize >> 16)))
24711                 diff=$(((max - min) * 100 / min))
24712                 i=$((i + 1))
24713         done
24714
24715         echo "MDT filesfree available: ${ffree[@]}"
24716         echo "MDT blocks available: ${bavail[@]}"
24717         echo "weight diff=$diff%"
24718 }
24719
24720 test_qos_mkdir() {
24721         local mkdir_cmd=$1
24722         local stripe_count=$2
24723         local mdts=$(comma_list $(mdts_nodes))
24724
24725         local testdir
24726         local lmv_qos_prio_free
24727         local lmv_qos_threshold_rr
24728         local lmv_qos_maxage
24729         local lod_qos_prio_free
24730         local lod_qos_threshold_rr
24731         local lod_qos_maxage
24732         local count
24733         local i
24734
24735         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24736         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24737         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24738                 head -n1)
24739         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24740         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24741         stack_trap "$LCTL set_param \
24742                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24743         stack_trap "$LCTL set_param \
24744                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24745         stack_trap "$LCTL set_param \
24746                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24747
24748         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24749                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24750         lod_qos_prio_free=${lod_qos_prio_free%%%}
24751         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24752                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24753         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24754         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24755                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24756         stack_trap "do_nodes $mdts $LCTL set_param \
24757                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24758         stack_trap "do_nodes $mdts $LCTL set_param \
24759                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24760         stack_trap "do_nodes $mdts $LCTL set_param \
24761                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24762
24763         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24764         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24765
24766         testdir=$DIR/$tdir-s$stripe_count/rr
24767
24768         local stripe_index=$($LFS getstripe -m $testdir)
24769         local test_mkdir_rr=true
24770
24771         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24772         getfattr -d -m dmv -e hex $testdir | grep dmv
24773         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24774                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24775                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24776                         test_mkdir_rr=false
24777         fi
24778
24779         echo
24780         $test_mkdir_rr &&
24781                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24782                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24783
24784         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24785         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24786                 eval $mkdir_cmd $testdir/subdir$i ||
24787                         error "$mkdir_cmd subdir$i failed"
24788         done
24789
24790         for (( i = 0; i < $MDSCOUNT; i++ )); do
24791                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24792                 echo "$count directories created on MDT$i"
24793                 if $test_mkdir_rr; then
24794                         (( $count == 100 )) ||
24795                                 error "subdirs are not evenly distributed"
24796                 elif (( $i == $stripe_index )); then
24797                         (( $count == 100 * MDSCOUNT )) ||
24798                                 error "$count subdirs created on MDT$i"
24799                 else
24800                         (( $count == 0 )) ||
24801                                 error "$count subdirs created on MDT$i"
24802                 fi
24803
24804                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24805                         count=$($LFS getdirstripe $testdir/* |
24806                                 grep -c -P "^\s+$i\t")
24807                         echo "$count stripes created on MDT$i"
24808                         # deviation should < 5% of average
24809                         (( $count >= 95 * stripe_count &&
24810                            $count <= 105 * stripe_count)) ||
24811                                 error "stripes are not evenly distributed"
24812                 fi
24813         done
24814
24815         echo
24816         echo "Check for uneven MDTs: "
24817
24818         local ffree
24819         local bavail
24820         local max
24821         local min
24822         local max_index
24823         local min_index
24824         local tmp
24825
24826         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24827         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24828         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24829
24830         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24831         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24832         max_index=0
24833         min_index=0
24834         for ((i = 1; i < ${#ffree[@]}; i++)); do
24835                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24836                 if [ $tmp -gt $max ]; then
24837                         max=$tmp
24838                         max_index=$i
24839                 fi
24840                 if [ $tmp -lt $min ]; then
24841                         min=$tmp
24842                         min_index=$i
24843                 fi
24844         done
24845
24846         (( ${ffree[min_index]} > 0 )) ||
24847                 skip "no free files in MDT$min_index"
24848         (( ${ffree[min_index]} < 100000000 )) ||
24849                 skip "too many free files in MDT$min_index"
24850
24851         echo "MDT filesfree available: ${ffree[@]}"
24852         echo "MDT blocks available: ${bavail[@]}"
24853         echo "weight diff=$(((max - min) * 100 / min))%"
24854         echo
24855         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24856
24857         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24858         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24859         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24860         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24861         # decrease statfs age, so that it can be updated in time
24862         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24863         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24864
24865         sleep 1
24866
24867         testdir=$DIR/$tdir-s$stripe_count/qos
24868         local num=200
24869
24870         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24871         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24872                 eval $mkdir_cmd $testdir/subdir$i ||
24873                         error "$mkdir_cmd subdir$i failed"
24874         done
24875
24876         for (( i = 0; i < $MDSCOUNT; i++ )); do
24877                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24878                 echo "$count directories created on MDT$i"
24879
24880                 if [ $stripe_count -gt 1 ]; then
24881                         count=$($LFS getdirstripe $testdir/* |
24882                                 grep -c -P "^\s+$i\t")
24883                         echo "$count stripes created on MDT$i"
24884                 fi
24885         done
24886
24887         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24888         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24889
24890         # D-value should > 10% of averge
24891         (( max - min >= num / 10 )) ||
24892                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24893
24894         # 5% for stripes
24895         if (( stripe_count > 1 )); then
24896                 max=$($LFS getdirstripe $testdir/* |
24897                       grep -c -P "^\s+$max_index\t")
24898                 min=$($LFS getdirstripe $testdir/* |
24899                         grep -c -P "^\s+$min_index\t")
24900                 (( max - min >= num * stripe_count / 20 )) ||
24901                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24902         fi
24903 }
24904
24905 most_full_mdt() {
24906         local ffree
24907         local bavail
24908         local bsize
24909         local min
24910         local min_index
24911         local tmp
24912
24913         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24914         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24915         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24916
24917         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24918         min_index=0
24919         for ((i = 1; i < ${#ffree[@]}; i++)); do
24920                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24921                 (( tmp < min )) && min=$tmp && min_index=$i
24922         done
24923
24924         echo -n $min_index
24925 }
24926
24927 test_413a() {
24928         [ $MDSCOUNT -lt 2 ] &&
24929                 skip "We need at least 2 MDTs for this test"
24930
24931         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24932                 skip "Need server version at least 2.12.52"
24933
24934         local stripe_count
24935
24936         generate_uneven_mdts 100
24937         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24938                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24939                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24940                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
24941                         error "mkdir failed"
24942                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
24943         done
24944 }
24945 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24946
24947 test_413b() {
24948         [ $MDSCOUNT -lt 2 ] &&
24949                 skip "We need at least 2 MDTs for this test"
24950
24951         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24952                 skip "Need server version at least 2.12.52"
24953
24954         local testdir
24955         local stripe_count
24956
24957         generate_uneven_mdts 100
24958         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24959                 testdir=$DIR/$tdir-s$stripe_count
24960                 mkdir $testdir || error "mkdir $testdir failed"
24961                 mkdir $testdir/rr || error "mkdir rr failed"
24962                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
24963                         error "mkdir qos failed"
24964                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24965                         $testdir/rr || error "setdirstripe rr failed"
24966                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24967                         error "setdirstripe failed"
24968                 test_qos_mkdir "mkdir" $stripe_count
24969         done
24970 }
24971 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24972
24973 test_413c() {
24974         (( $MDSCOUNT >= 2 )) ||
24975                 skip "We need at least 2 MDTs for this test"
24976
24977         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
24978                 skip "Need server version at least 2.14.51"
24979
24980         local testdir
24981         local inherit
24982         local inherit_rr
24983
24984         testdir=$DIR/${tdir}-s1
24985         mkdir $testdir || error "mkdir $testdir failed"
24986         mkdir $testdir/rr || error "mkdir rr failed"
24987         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
24988         # default max_inherit is -1, default max_inherit_rr is 0
24989         $LFS setdirstripe -D -c 1 $testdir/rr ||
24990                 error "setdirstripe rr failed"
24991         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24992                 error "setdirstripe qos failed"
24993         test_qos_mkdir "mkdir" 1
24994
24995         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24996         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24997         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24998         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24999         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25000
25001         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25002         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25003         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25004         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25005         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25006         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25007         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25008                 error "level2 shouldn't have default LMV" || true
25009 }
25010 run_test 413c "mkdir with default LMV max inherit rr"
25011
25012 test_413d() {
25013         (( MDSCOUNT >= 2 )) ||
25014                 skip "We need at least 2 MDTs for this test"
25015
25016         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25017                 skip "Need server version at least 2.14.51"
25018
25019         local lmv_qos_threshold_rr
25020
25021         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25022                 head -n1)
25023         stack_trap "$LCTL set_param \
25024                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25025
25026         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25027         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25028         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25029                 error "$tdir shouldn't have default LMV"
25030         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25031                 error "mkdir sub failed"
25032
25033         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25034
25035         (( count == 100 )) || error "$count subdirs on MDT0"
25036 }
25037 run_test 413d "inherit ROOT default LMV"
25038
25039 test_413z() {
25040         local pids=""
25041         local subdir
25042         local pid
25043
25044         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25045                 unlinkmany $subdir/f. 100 &
25046                 pids="$pids $!"
25047         done
25048
25049         for pid in $pids; do
25050                 wait $pid
25051         done
25052 }
25053 run_test 413z "413 test cleanup"
25054
25055 test_414() {
25056 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25057         $LCTL set_param fail_loc=0x80000521
25058         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25059         rm -f $DIR/$tfile
25060 }
25061 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25062
25063 test_415() {
25064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25065         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25066                 skip "Need server version at least 2.11.52"
25067
25068         # LU-11102
25069         local total
25070         local setattr_pid
25071         local start_time
25072         local end_time
25073         local duration
25074
25075         total=500
25076         # this test may be slow on ZFS
25077         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25078
25079         # though this test is designed for striped directory, let's test normal
25080         # directory too since lock is always saved as CoS lock.
25081         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25082         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25083
25084         (
25085                 while true; do
25086                         touch $DIR/$tdir
25087                 done
25088         ) &
25089         setattr_pid=$!
25090
25091         start_time=$(date +%s)
25092         for i in $(seq $total); do
25093                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25094                         > /dev/null
25095         done
25096         end_time=$(date +%s)
25097         duration=$((end_time - start_time))
25098
25099         kill -9 $setattr_pid
25100
25101         echo "rename $total files took $duration sec"
25102         [ $duration -lt 100 ] || error "rename took $duration sec"
25103 }
25104 run_test 415 "lock revoke is not missing"
25105
25106 test_416() {
25107         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25108                 skip "Need server version at least 2.11.55"
25109
25110         # define OBD_FAIL_OSD_TXN_START    0x19a
25111         do_facet mds1 lctl set_param fail_loc=0x19a
25112
25113         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25114
25115         true
25116 }
25117 run_test 416 "transaction start failure won't cause system hung"
25118
25119 cleanup_417() {
25120         trap 0
25121         do_nodes $(comma_list $(mdts_nodes)) \
25122                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25123         do_nodes $(comma_list $(mdts_nodes)) \
25124                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25125         do_nodes $(comma_list $(mdts_nodes)) \
25126                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25127 }
25128
25129 test_417() {
25130         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25131         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25132                 skip "Need MDS version at least 2.11.56"
25133
25134         trap cleanup_417 RETURN EXIT
25135
25136         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25137         do_nodes $(comma_list $(mdts_nodes)) \
25138                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25139         $LFS migrate -m 0 $DIR/$tdir.1 &&
25140                 error "migrate dir $tdir.1 should fail"
25141
25142         do_nodes $(comma_list $(mdts_nodes)) \
25143                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25144         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25145                 error "create remote dir $tdir.2 should fail"
25146
25147         do_nodes $(comma_list $(mdts_nodes)) \
25148                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25149         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25150                 error "create striped dir $tdir.3 should fail"
25151         true
25152 }
25153 run_test 417 "disable remote dir, striped dir and dir migration"
25154
25155 # Checks that the outputs of df [-i] and lfs df [-i] match
25156 #
25157 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25158 check_lfs_df() {
25159         local dir=$2
25160         local inodes
25161         local df_out
25162         local lfs_df_out
25163         local count
25164         local passed=false
25165
25166         # blocks or inodes
25167         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25168
25169         for count in {1..100}; do
25170                 do_rpc_nodes "$CLIENTS" cancel_lru_locks
25171                 sync; sleep 0.2
25172
25173                 # read the lines of interest
25174                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25175                         error "df $inodes $dir | tail -n +2 failed"
25176                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25177                         error "lfs df $inodes $dir | grep summary: failed"
25178
25179                 # skip first substrings of each output as they are different
25180                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25181                 # compare the two outputs
25182                 passed=true
25183                 for i in {1..5}; do
25184                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25185                 done
25186                 $passed && break
25187         done
25188
25189         if ! $passed; then
25190                 df -P $inodes $dir
25191                 echo
25192                 lfs df $inodes $dir
25193                 error "df and lfs df $1 output mismatch: "      \
25194                       "df ${inodes}: ${df_out[*]}, "            \
25195                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25196         fi
25197 }
25198
25199 test_418() {
25200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25201
25202         local dir=$DIR/$tdir
25203         local numfiles=$((RANDOM % 4096 + 2))
25204         local numblocks=$((RANDOM % 256 + 1))
25205
25206         wait_delete_completed
25207         test_mkdir $dir
25208
25209         # check block output
25210         check_lfs_df blocks $dir
25211         # check inode output
25212         check_lfs_df inodes $dir
25213
25214         # create a single file and retest
25215         echo "Creating a single file and testing"
25216         createmany -o $dir/$tfile- 1 &>/dev/null ||
25217                 error "creating 1 file in $dir failed"
25218         check_lfs_df blocks $dir
25219         check_lfs_df inodes $dir
25220
25221         # create a random number of files
25222         echo "Creating $((numfiles - 1)) files and testing"
25223         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25224                 error "creating $((numfiles - 1)) files in $dir failed"
25225
25226         # write a random number of blocks to the first test file
25227         echo "Writing $numblocks 4K blocks and testing"
25228         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25229                 count=$numblocks &>/dev/null ||
25230                 error "dd to $dir/${tfile}-0 failed"
25231
25232         # retest
25233         check_lfs_df blocks $dir
25234         check_lfs_df inodes $dir
25235
25236         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25237                 error "unlinking $numfiles files in $dir failed"
25238 }
25239 run_test 418 "df and lfs df outputs match"
25240
25241 test_419()
25242 {
25243         local dir=$DIR/$tdir
25244
25245         mkdir -p $dir
25246         touch $dir/file
25247
25248         cancel_lru_locks mdc
25249
25250         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25251         $LCTL set_param fail_loc=0x1410
25252         cat $dir/file
25253         $LCTL set_param fail_loc=0
25254         rm -rf $dir
25255 }
25256 run_test 419 "Verify open file by name doesn't crash kernel"
25257
25258 test_420()
25259 {
25260         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25261                 skip "Need MDS version at least 2.12.53"
25262
25263         local SAVE_UMASK=$(umask)
25264         local dir=$DIR/$tdir
25265         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25266
25267         mkdir -p $dir
25268         umask 0000
25269         mkdir -m03777 $dir/testdir
25270         ls -dn $dir/testdir
25271         # Need to remove trailing '.' when SELinux is enabled
25272         local dirperms=$(ls -dn $dir/testdir |
25273                          awk '{ sub(/\.$/, "", $1); print $1}')
25274         [ $dirperms == "drwxrwsrwt" ] ||
25275                 error "incorrect perms on $dir/testdir"
25276
25277         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25278                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25279         ls -n $dir/testdir/testfile
25280         local fileperms=$(ls -n $dir/testdir/testfile |
25281                           awk '{ sub(/\.$/, "", $1); print $1}')
25282         [ $fileperms == "-rwxr-xr-x" ] ||
25283                 error "incorrect perms on $dir/testdir/testfile"
25284
25285         umask $SAVE_UMASK
25286 }
25287 run_test 420 "clear SGID bit on non-directories for non-members"
25288
25289 test_421a() {
25290         local cnt
25291         local fid1
25292         local fid2
25293
25294         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25295                 skip "Need MDS version at least 2.12.54"
25296
25297         test_mkdir $DIR/$tdir
25298         createmany -o $DIR/$tdir/f 3
25299         cnt=$(ls -1 $DIR/$tdir | wc -l)
25300         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25301
25302         fid1=$(lfs path2fid $DIR/$tdir/f1)
25303         fid2=$(lfs path2fid $DIR/$tdir/f2)
25304         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25305
25306         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25307         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25308
25309         cnt=$(ls -1 $DIR/$tdir | wc -l)
25310         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25311
25312         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25313         createmany -o $DIR/$tdir/f 3
25314         cnt=$(ls -1 $DIR/$tdir | wc -l)
25315         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25316
25317         fid1=$(lfs path2fid $DIR/$tdir/f1)
25318         fid2=$(lfs path2fid $DIR/$tdir/f2)
25319         echo "remove using fsname $FSNAME"
25320         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25321
25322         cnt=$(ls -1 $DIR/$tdir | wc -l)
25323         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25324 }
25325 run_test 421a "simple rm by fid"
25326
25327 test_421b() {
25328         local cnt
25329         local FID1
25330         local FID2
25331
25332         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25333                 skip "Need MDS version at least 2.12.54"
25334
25335         test_mkdir $DIR/$tdir
25336         createmany -o $DIR/$tdir/f 3
25337         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25338         MULTIPID=$!
25339
25340         FID1=$(lfs path2fid $DIR/$tdir/f1)
25341         FID2=$(lfs path2fid $DIR/$tdir/f2)
25342         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25343
25344         kill -USR1 $MULTIPID
25345         wait
25346
25347         cnt=$(ls $DIR/$tdir | wc -l)
25348         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25349 }
25350 run_test 421b "rm by fid on open file"
25351
25352 test_421c() {
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 3
25361         touch $DIR/$tdir/$tfile
25362         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25363         cnt=$(ls -1 $DIR/$tdir | wc -l)
25364         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25365
25366         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25367         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25368
25369         cnt=$(ls $DIR/$tdir | wc -l)
25370         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25371 }
25372 run_test 421c "rm by fid against hardlinked files"
25373
25374 test_421d() {
25375         local cnt
25376         local FIDS
25377
25378         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25379                 skip "Need MDS version at least 2.12.54"
25380
25381         test_mkdir $DIR/$tdir
25382         createmany -o $DIR/$tdir/f 4097
25383         cnt=$(ls -1 $DIR/$tdir | wc -l)
25384         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25385
25386         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25387         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25388
25389         cnt=$(ls $DIR/$tdir | wc -l)
25390         rm -rf $DIR/$tdir
25391         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25392 }
25393 run_test 421d "rmfid en masse"
25394
25395 test_421e() {
25396         local cnt
25397         local FID
25398
25399         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25400         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25401                 skip "Need MDS version at least 2.12.54"
25402
25403         mkdir -p $DIR/$tdir
25404         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25405         createmany -o $DIR/$tdir/striped_dir/f 512
25406         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25407         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25408
25409         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25410                 sed "s/[/][^:]*://g")
25411         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25412
25413         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25414         rm -rf $DIR/$tdir
25415         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25416 }
25417 run_test 421e "rmfid in DNE"
25418
25419 test_421f() {
25420         local cnt
25421         local FID
25422
25423         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25424                 skip "Need MDS version at least 2.12.54"
25425
25426         test_mkdir $DIR/$tdir
25427         touch $DIR/$tdir/f
25428         cnt=$(ls -1 $DIR/$tdir | wc -l)
25429         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25430
25431         FID=$(lfs path2fid $DIR/$tdir/f)
25432         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25433         # rmfid should fail
25434         cnt=$(ls -1 $DIR/$tdir | wc -l)
25435         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25436
25437         chmod a+rw $DIR/$tdir
25438         ls -la $DIR/$tdir
25439         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25440         # rmfid should fail
25441         cnt=$(ls -1 $DIR/$tdir | wc -l)
25442         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25443
25444         rm -f $DIR/$tdir/f
25445         $RUNAS touch $DIR/$tdir/f
25446         FID=$(lfs path2fid $DIR/$tdir/f)
25447         echo "rmfid as root"
25448         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25449         cnt=$(ls -1 $DIR/$tdir | wc -l)
25450         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25451
25452         rm -f $DIR/$tdir/f
25453         $RUNAS touch $DIR/$tdir/f
25454         cnt=$(ls -1 $DIR/$tdir | wc -l)
25455         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25456         FID=$(lfs path2fid $DIR/$tdir/f)
25457         # rmfid w/o user_fid2path mount option should fail
25458         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25459         cnt=$(ls -1 $DIR/$tdir | wc -l)
25460         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25461
25462         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25463         stack_trap "rmdir $tmpdir"
25464         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25465                 error "failed to mount client'"
25466         stack_trap "umount_client $tmpdir"
25467
25468         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25469         # rmfid should succeed
25470         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25471         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25472
25473         # rmfid shouldn't allow to remove files due to dir's permission
25474         chmod a+rwx $tmpdir/$tdir
25475         touch $tmpdir/$tdir/f
25476         ls -la $tmpdir/$tdir
25477         FID=$(lfs path2fid $tmpdir/$tdir/f)
25478         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25479         return 0
25480 }
25481 run_test 421f "rmfid checks permissions"
25482
25483 test_421g() {
25484         local cnt
25485         local FIDS
25486
25487         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25488         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25489                 skip "Need MDS version at least 2.12.54"
25490
25491         mkdir -p $DIR/$tdir
25492         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25493         createmany -o $DIR/$tdir/striped_dir/f 512
25494         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25495         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25496
25497         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25498                 sed "s/[/][^:]*://g")
25499
25500         rm -f $DIR/$tdir/striped_dir/f1*
25501         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25502         removed=$((512 - cnt))
25503
25504         # few files have been just removed, so we expect
25505         # rmfid to fail on their fids
25506         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25507         [ $removed != $errors ] && error "$errors != $removed"
25508
25509         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25510         rm -rf $DIR/$tdir
25511         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25512 }
25513 run_test 421g "rmfid to return errors properly"
25514
25515 test_422() {
25516         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25517         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25518         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25519         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25520         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25521
25522         local amc=$(at_max_get client)
25523         local amo=$(at_max_get mds1)
25524         local timeout=`lctl get_param -n timeout`
25525
25526         at_max_set 0 client
25527         at_max_set 0 mds1
25528
25529 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25530         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25531                         fail_val=$(((2*timeout + 10)*1000))
25532         touch $DIR/$tdir/d3/file &
25533         sleep 2
25534 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25535         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25536                         fail_val=$((2*timeout + 5))
25537         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25538         local pid=$!
25539         sleep 1
25540         kill -9 $pid
25541         sleep $((2 * timeout))
25542         echo kill $pid
25543         kill -9 $pid
25544         lctl mark touch
25545         touch $DIR/$tdir/d2/file3
25546         touch $DIR/$tdir/d2/file4
25547         touch $DIR/$tdir/d2/file5
25548
25549         wait
25550         at_max_set $amc client
25551         at_max_set $amo mds1
25552
25553         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25554         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25555                 error "Watchdog is always throttled"
25556 }
25557 run_test 422 "kill a process with RPC in progress"
25558
25559 stat_test() {
25560     df -h $MOUNT &
25561     df -h $MOUNT &
25562     df -h $MOUNT &
25563     df -h $MOUNT &
25564     df -h $MOUNT &
25565     df -h $MOUNT &
25566 }
25567
25568 test_423() {
25569     local _stats
25570     # ensure statfs cache is expired
25571     sleep 2;
25572
25573     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25574     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25575
25576     return 0
25577 }
25578 run_test 423 "statfs should return a right data"
25579
25580 test_424() {
25581 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25582         $LCTL set_param fail_loc=0x80000522
25583         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25584         rm -f $DIR/$tfile
25585 }
25586 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25587
25588 test_425() {
25589         test_mkdir -c -1 $DIR/$tdir
25590         $LFS setstripe -c -1 $DIR/$tdir
25591
25592         lru_resize_disable "" 100
25593         stack_trap "lru_resize_enable" EXIT
25594
25595         sleep 5
25596
25597         for i in $(seq $((MDSCOUNT * 125))); do
25598                 local t=$DIR/$tdir/$tfile_$i
25599
25600                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25601                         error_noexit "Create file $t"
25602         done
25603         stack_trap "rm -rf $DIR/$tdir" EXIT
25604
25605         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25606                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25607                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25608
25609                 [ $lock_count -le $lru_size ] ||
25610                         error "osc lock count $lock_count > lru size $lru_size"
25611         done
25612
25613         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25614                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25615                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25616
25617                 [ $lock_count -le $lru_size ] ||
25618                         error "mdc lock count $lock_count > lru size $lru_size"
25619         done
25620 }
25621 run_test 425 "lock count should not exceed lru size"
25622
25623 test_426() {
25624         splice-test -r $DIR/$tfile
25625         splice-test -rd $DIR/$tfile
25626         splice-test $DIR/$tfile
25627         splice-test -d $DIR/$tfile
25628 }
25629 run_test 426 "splice test on Lustre"
25630
25631 test_427() {
25632         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25633         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25634                 skip "Need MDS version at least 2.12.4"
25635         local log
25636
25637         mkdir $DIR/$tdir
25638         mkdir $DIR/$tdir/1
25639         mkdir $DIR/$tdir/2
25640         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25641         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25642
25643         $LFS getdirstripe $DIR/$tdir/1/dir
25644
25645         #first setfattr for creating updatelog
25646         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25647
25648 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25649         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25650         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25651         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25652
25653         sleep 2
25654         fail mds2
25655         wait_recovery_complete mds2 $((2*TIMEOUT))
25656
25657         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25658         echo $log | grep "get update log failed" &&
25659                 error "update log corruption is detected" || true
25660 }
25661 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25662
25663 test_428() {
25664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25665         local cache_limit=$CACHE_MAX
25666
25667         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25668         $LCTL set_param -n llite.*.max_cached_mb=64
25669
25670         mkdir $DIR/$tdir
25671         $LFS setstripe -c 1 $DIR/$tdir
25672         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25673         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25674         #test write
25675         for f in $(seq 4); do
25676                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25677         done
25678         wait
25679
25680         cancel_lru_locks osc
25681         # Test read
25682         for f in $(seq 4); do
25683                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25684         done
25685         wait
25686 }
25687 run_test 428 "large block size IO should not hang"
25688
25689 test_429() { # LU-7915 / LU-10948
25690         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25691         local testfile=$DIR/$tfile
25692         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25693         local new_flag=1
25694         local first_rpc
25695         local second_rpc
25696         local third_rpc
25697
25698         $LCTL get_param $ll_opencache_threshold_count ||
25699                 skip "client does not have opencache parameter"
25700
25701         set_opencache $new_flag
25702         stack_trap "restore_opencache"
25703         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25704                 error "enable opencache failed"
25705         touch $testfile
25706         # drop MDC DLM locks
25707         cancel_lru_locks mdc
25708         # clear MDC RPC stats counters
25709         $LCTL set_param $mdc_rpcstats=clear
25710
25711         # According to the current implementation, we need to run 3 times
25712         # open & close file to verify if opencache is enabled correctly.
25713         # 1st, RPCs are sent for lookup/open and open handle is released on
25714         #      close finally.
25715         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25716         #      so open handle won't be released thereafter.
25717         # 3rd, No RPC is sent out.
25718         $MULTIOP $testfile oc || error "multiop failed"
25719         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25720         echo "1st: $first_rpc RPCs in flight"
25721
25722         $MULTIOP $testfile oc || error "multiop failed"
25723         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25724         echo "2nd: $second_rpc RPCs in flight"
25725
25726         $MULTIOP $testfile oc || error "multiop failed"
25727         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25728         echo "3rd: $third_rpc RPCs in flight"
25729
25730         #verify no MDC RPC is sent
25731         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25732 }
25733 run_test 429 "verify if opencache flag on client side does work"
25734
25735 lseek_test_430() {
25736         local offset
25737         local file=$1
25738
25739         # data at [200K, 400K)
25740         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25741                 error "256K->512K dd fails"
25742         # data at [2M, 3M)
25743         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25744                 error "2M->3M dd fails"
25745         # data at [4M, 5M)
25746         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25747                 error "4M->5M dd fails"
25748         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25749         # start at first component hole #1
25750         printf "Seeking hole from 1000 ... "
25751         offset=$(lseek_test -l 1000 $file)
25752         echo $offset
25753         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25754         printf "Seeking data from 1000 ... "
25755         offset=$(lseek_test -d 1000 $file)
25756         echo $offset
25757         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25758
25759         # start at first component data block
25760         printf "Seeking hole from 300000 ... "
25761         offset=$(lseek_test -l 300000 $file)
25762         echo $offset
25763         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25764         printf "Seeking data from 300000 ... "
25765         offset=$(lseek_test -d 300000 $file)
25766         echo $offset
25767         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25768
25769         # start at the first component but beyond end of object size
25770         printf "Seeking hole from 1000000 ... "
25771         offset=$(lseek_test -l 1000000 $file)
25772         echo $offset
25773         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25774         printf "Seeking data from 1000000 ... "
25775         offset=$(lseek_test -d 1000000 $file)
25776         echo $offset
25777         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25778
25779         # start at second component stripe 2 (empty file)
25780         printf "Seeking hole from 1500000 ... "
25781         offset=$(lseek_test -l 1500000 $file)
25782         echo $offset
25783         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25784         printf "Seeking data from 1500000 ... "
25785         offset=$(lseek_test -d 1500000 $file)
25786         echo $offset
25787         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25788
25789         # start at second component stripe 1 (all data)
25790         printf "Seeking hole from 3000000 ... "
25791         offset=$(lseek_test -l 3000000 $file)
25792         echo $offset
25793         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25794         printf "Seeking data from 3000000 ... "
25795         offset=$(lseek_test -d 3000000 $file)
25796         echo $offset
25797         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25798
25799         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25800                 error "2nd dd fails"
25801         echo "Add data block at 640K...1280K"
25802
25803         # start at before new data block, in hole
25804         printf "Seeking hole from 600000 ... "
25805         offset=$(lseek_test -l 600000 $file)
25806         echo $offset
25807         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25808         printf "Seeking data from 600000 ... "
25809         offset=$(lseek_test -d 600000 $file)
25810         echo $offset
25811         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25812
25813         # start at the first component new data block
25814         printf "Seeking hole from 1000000 ... "
25815         offset=$(lseek_test -l 1000000 $file)
25816         echo $offset
25817         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25818         printf "Seeking data from 1000000 ... "
25819         offset=$(lseek_test -d 1000000 $file)
25820         echo $offset
25821         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25822
25823         # start at second component stripe 2, new data
25824         printf "Seeking hole from 1200000 ... "
25825         offset=$(lseek_test -l 1200000 $file)
25826         echo $offset
25827         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25828         printf "Seeking data from 1200000 ... "
25829         offset=$(lseek_test -d 1200000 $file)
25830         echo $offset
25831         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25832
25833         # start beyond file end
25834         printf "Using offset > filesize ... "
25835         lseek_test -l 4000000 $file && error "lseek should fail"
25836         printf "Using offset > filesize ... "
25837         lseek_test -d 4000000 $file && error "lseek should fail"
25838
25839         printf "Done\n\n"
25840 }
25841
25842 test_430a() {
25843         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25844                 skip "MDT does not support SEEK_HOLE"
25845
25846         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25847                 skip "OST does not support SEEK_HOLE"
25848
25849         local file=$DIR/$tdir/$tfile
25850
25851         mkdir -p $DIR/$tdir
25852
25853         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25854         # OST stripe #1 will have continuous data at [1M, 3M)
25855         # OST stripe #2 is empty
25856         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25857         lseek_test_430 $file
25858         rm $file
25859         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25860         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25861         lseek_test_430 $file
25862         rm $file
25863         $LFS setstripe -c2 -S 512K $file
25864         echo "Two stripes, stripe size 512K"
25865         lseek_test_430 $file
25866         rm $file
25867         # FLR with stale mirror
25868         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25869                        -N -c2 -S 1M $file
25870         echo "Mirrored file:"
25871         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25872         echo "Plain 2 stripes 1M"
25873         lseek_test_430 $file
25874         rm $file
25875 }
25876 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25877
25878 test_430b() {
25879         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25880                 skip "OST does not support SEEK_HOLE"
25881
25882         local offset
25883         local file=$DIR/$tdir/$tfile
25884
25885         mkdir -p $DIR/$tdir
25886         # Empty layout lseek should fail
25887         $MCREATE $file
25888         # seek from 0
25889         printf "Seeking hole from 0 ... "
25890         lseek_test -l 0 $file && error "lseek should fail"
25891         printf "Seeking data from 0 ... "
25892         lseek_test -d 0 $file && error "lseek should fail"
25893         rm $file
25894
25895         # 1M-hole file
25896         $LFS setstripe -E 1M -c2 -E eof $file
25897         $TRUNCATE $file 1048576
25898         printf "Seeking hole from 1000000 ... "
25899         offset=$(lseek_test -l 1000000 $file)
25900         echo $offset
25901         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25902         printf "Seeking data from 1000000 ... "
25903         lseek_test -d 1000000 $file && error "lseek should fail"
25904         rm $file
25905
25906         # full component followed by non-inited one
25907         $LFS setstripe -E 1M -c2 -E eof $file
25908         dd if=/dev/urandom of=$file bs=1M count=1
25909         printf "Seeking hole from 1000000 ... "
25910         offset=$(lseek_test -l 1000000 $file)
25911         echo $offset
25912         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25913         printf "Seeking hole from 1048576 ... "
25914         lseek_test -l 1048576 $file && error "lseek should fail"
25915         # init second component and truncate back
25916         echo "123" >> $file
25917         $TRUNCATE $file 1048576
25918         printf "Seeking hole from 1000000 ... "
25919         offset=$(lseek_test -l 1000000 $file)
25920         echo $offset
25921         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25922         printf "Seeking hole from 1048576 ... "
25923         lseek_test -l 1048576 $file && error "lseek should fail"
25924         # boundary checks for big values
25925         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25926         offset=$(lseek_test -d 0 $file.10g)
25927         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25928         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25929         offset=$(lseek_test -d 0 $file.100g)
25930         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25931         return 0
25932 }
25933 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25934
25935 test_430c() {
25936         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25937                 skip "OST does not support SEEK_HOLE"
25938
25939         local file=$DIR/$tdir/$tfile
25940         local start
25941
25942         mkdir -p $DIR/$tdir
25943         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25944
25945         # cp version 8.33+ prefers lseek over fiemap
25946         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25947                 start=$SECONDS
25948                 time cp $file /dev/null
25949                 (( SECONDS - start < 5 )) ||
25950                         error "cp: too long runtime $((SECONDS - start))"
25951
25952         fi
25953         # tar version 1.29+ supports SEEK_HOLE/DATA
25954         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25955                 start=$SECONDS
25956                 time tar cS $file - | cat > /dev/null
25957                 (( SECONDS - start < 5 )) ||
25958                         error "tar: too long runtime $((SECONDS - start))"
25959         fi
25960 }
25961 run_test 430c "lseek: external tools check"
25962
25963 test_431() { # LU-14187
25964         local file=$DIR/$tdir/$tfile
25965
25966         mkdir -p $DIR/$tdir
25967         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25968         dd if=/dev/urandom of=$file bs=4k count=1
25969         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25970         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25971         #define OBD_FAIL_OST_RESTART_IO 0x251
25972         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25973         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25974         cp $file $file.0
25975         cancel_lru_locks
25976         sync_all_data
25977         echo 3 > /proc/sys/vm/drop_caches
25978         diff  $file $file.0 || error "data diff"
25979 }
25980 run_test 431 "Restart transaction for IO"
25981
25982 cleanup_test_432() {
25983         do_facet mgs $LCTL nodemap_activate 0
25984         wait_nm_sync active
25985 }
25986
25987 test_432() {
25988         local tmpdir=$TMP/dir432
25989
25990         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
25991                 skip "Need MDS version at least 2.14.52"
25992
25993         stack_trap cleanup_test_432 EXIT
25994         mkdir $DIR/$tdir
25995         mkdir $tmpdir
25996
25997         do_facet mgs $LCTL nodemap_activate 1
25998         wait_nm_sync active
25999         do_facet mgs $LCTL nodemap_modify --name default \
26000                 --property admin --value 1
26001         do_facet mgs $LCTL nodemap_modify --name default \
26002                 --property trusted --value 1
26003         cancel_lru_locks mdc
26004         wait_nm_sync default admin_nodemap
26005         wait_nm_sync default trusted_nodemap
26006
26007         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26008                grep -ci "Operation not permitted") -ne 0 ]; then
26009                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26010         fi
26011 }
26012 run_test 432 "mv dir from outside Lustre"
26013
26014 prep_801() {
26015         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26016         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26017                 skip "Need server version at least 2.9.55"
26018
26019         start_full_debug_logging
26020 }
26021
26022 post_801() {
26023         stop_full_debug_logging
26024 }
26025
26026 barrier_stat() {
26027         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26028                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26029                            awk '/The barrier for/ { print $7 }')
26030                 echo $st
26031         else
26032                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26033                 echo \'$st\'
26034         fi
26035 }
26036
26037 barrier_expired() {
26038         local expired
26039
26040         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26041                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26042                           awk '/will be expired/ { print $7 }')
26043         else
26044                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26045         fi
26046
26047         echo $expired
26048 }
26049
26050 test_801a() {
26051         prep_801
26052
26053         echo "Start barrier_freeze at: $(date)"
26054         #define OBD_FAIL_BARRIER_DELAY          0x2202
26055         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26056         # Do not reduce barrier time - See LU-11873
26057         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26058
26059         sleep 2
26060         local b_status=$(barrier_stat)
26061         echo "Got barrier status at: $(date)"
26062         [ "$b_status" = "'freezing_p1'" ] ||
26063                 error "(1) unexpected barrier status $b_status"
26064
26065         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26066         wait
26067         b_status=$(barrier_stat)
26068         [ "$b_status" = "'frozen'" ] ||
26069                 error "(2) unexpected barrier status $b_status"
26070
26071         local expired=$(barrier_expired)
26072         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26073         sleep $((expired + 3))
26074
26075         b_status=$(barrier_stat)
26076         [ "$b_status" = "'expired'" ] ||
26077                 error "(3) unexpected barrier status $b_status"
26078
26079         # Do not reduce barrier time - See LU-11873
26080         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26081                 error "(4) fail to freeze barrier"
26082
26083         b_status=$(barrier_stat)
26084         [ "$b_status" = "'frozen'" ] ||
26085                 error "(5) unexpected barrier status $b_status"
26086
26087         echo "Start barrier_thaw at: $(date)"
26088         #define OBD_FAIL_BARRIER_DELAY          0x2202
26089         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26090         do_facet mgs $LCTL barrier_thaw $FSNAME &
26091
26092         sleep 2
26093         b_status=$(barrier_stat)
26094         echo "Got barrier status at: $(date)"
26095         [ "$b_status" = "'thawing'" ] ||
26096                 error "(6) unexpected barrier status $b_status"
26097
26098         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26099         wait
26100         b_status=$(barrier_stat)
26101         [ "$b_status" = "'thawed'" ] ||
26102                 error "(7) unexpected barrier status $b_status"
26103
26104         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26105         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26106         do_facet mgs $LCTL barrier_freeze $FSNAME
26107
26108         b_status=$(barrier_stat)
26109         [ "$b_status" = "'failed'" ] ||
26110                 error "(8) unexpected barrier status $b_status"
26111
26112         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26113         do_facet mgs $LCTL barrier_thaw $FSNAME
26114
26115         post_801
26116 }
26117 run_test 801a "write barrier user interfaces and stat machine"
26118
26119 test_801b() {
26120         prep_801
26121
26122         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26123         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26124         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26125         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26126         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26127
26128         cancel_lru_locks mdc
26129
26130         # 180 seconds should be long enough
26131         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26132
26133         local b_status=$(barrier_stat)
26134         [ "$b_status" = "'frozen'" ] ||
26135                 error "(6) unexpected barrier status $b_status"
26136
26137         mkdir $DIR/$tdir/d0/d10 &
26138         mkdir_pid=$!
26139
26140         touch $DIR/$tdir/d1/f13 &
26141         touch_pid=$!
26142
26143         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26144         ln_pid=$!
26145
26146         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26147         mv_pid=$!
26148
26149         rm -f $DIR/$tdir/d4/f12 &
26150         rm_pid=$!
26151
26152         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26153
26154         # To guarantee taht the 'stat' is not blocked
26155         b_status=$(barrier_stat)
26156         [ "$b_status" = "'frozen'" ] ||
26157                 error "(8) unexpected barrier status $b_status"
26158
26159         # let above commands to run at background
26160         sleep 5
26161
26162         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26163         ps -p $touch_pid || error "(10) touch should be blocked"
26164         ps -p $ln_pid || error "(11) link should be blocked"
26165         ps -p $mv_pid || error "(12) rename should be blocked"
26166         ps -p $rm_pid || error "(13) unlink should be blocked"
26167
26168         b_status=$(barrier_stat)
26169         [ "$b_status" = "'frozen'" ] ||
26170                 error "(14) unexpected barrier status $b_status"
26171
26172         do_facet mgs $LCTL barrier_thaw $FSNAME
26173         b_status=$(barrier_stat)
26174         [ "$b_status" = "'thawed'" ] ||
26175                 error "(15) unexpected barrier status $b_status"
26176
26177         wait $mkdir_pid || error "(16) mkdir should succeed"
26178         wait $touch_pid || error "(17) touch should succeed"
26179         wait $ln_pid || error "(18) link should succeed"
26180         wait $mv_pid || error "(19) rename should succeed"
26181         wait $rm_pid || error "(20) unlink should succeed"
26182
26183         post_801
26184 }
26185 run_test 801b "modification will be blocked by write barrier"
26186
26187 test_801c() {
26188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26189
26190         prep_801
26191
26192         stop mds2 || error "(1) Fail to stop mds2"
26193
26194         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26195
26196         local b_status=$(barrier_stat)
26197         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26198                 do_facet mgs $LCTL barrier_thaw $FSNAME
26199                 error "(2) unexpected barrier status $b_status"
26200         }
26201
26202         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26203                 error "(3) Fail to rescan barrier bitmap"
26204
26205         # Do not reduce barrier time - See LU-11873
26206         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26207
26208         b_status=$(barrier_stat)
26209         [ "$b_status" = "'frozen'" ] ||
26210                 error "(4) unexpected barrier status $b_status"
26211
26212         do_facet mgs $LCTL barrier_thaw $FSNAME
26213         b_status=$(barrier_stat)
26214         [ "$b_status" = "'thawed'" ] ||
26215                 error "(5) unexpected barrier status $b_status"
26216
26217         local devname=$(mdsdevname 2)
26218
26219         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26220
26221         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26222                 error "(7) Fail to rescan barrier bitmap"
26223
26224         post_801
26225 }
26226 run_test 801c "rescan barrier bitmap"
26227
26228 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26229 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26230 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26231 saved_MOUNT_OPTS=$MOUNT_OPTS
26232
26233 cleanup_802a() {
26234         trap 0
26235
26236         stopall
26237         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26238         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26239         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26240         MOUNT_OPTS=$saved_MOUNT_OPTS
26241         setupall
26242 }
26243
26244 test_802a() {
26245         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26246         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26247         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26248                 skip "Need server version at least 2.9.55"
26249
26250         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26251
26252         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26253
26254         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26255                 error "(2) Fail to copy"
26256
26257         trap cleanup_802a EXIT
26258
26259         # sync by force before remount as readonly
26260         sync; sync_all_data; sleep 3; sync_all_data
26261
26262         stopall
26263
26264         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26265         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26266         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26267
26268         echo "Mount the server as read only"
26269         setupall server_only || error "(3) Fail to start servers"
26270
26271         echo "Mount client without ro should fail"
26272         mount_client $MOUNT &&
26273                 error "(4) Mount client without 'ro' should fail"
26274
26275         echo "Mount client with ro should succeed"
26276         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26277         mount_client $MOUNT ||
26278                 error "(5) Mount client with 'ro' should succeed"
26279
26280         echo "Modify should be refused"
26281         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26282
26283         echo "Read should be allowed"
26284         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26285                 error "(7) Read should succeed under ro mode"
26286
26287         cleanup_802a
26288 }
26289 run_test 802a "simulate readonly device"
26290
26291 test_802b() {
26292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26293         remote_mds_nodsh && skip "remote MDS with nodsh"
26294
26295         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26296                 skip "readonly option not available"
26297
26298         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26299
26300         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26301                 error "(2) Fail to copy"
26302
26303         # write back all cached data before setting MDT to readonly
26304         cancel_lru_locks
26305         sync_all_data
26306
26307         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26308         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26309
26310         echo "Modify should be refused"
26311         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26312
26313         echo "Read should be allowed"
26314         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26315                 error "(7) Read should succeed under ro mode"
26316
26317         # disable readonly
26318         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26319 }
26320 run_test 802b "be able to set MDTs to readonly"
26321
26322 test_803a() {
26323         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26324         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26325                 skip "MDS needs to be newer than 2.10.54"
26326
26327         mkdir_on_mdt0 $DIR/$tdir
26328         # Create some objects on all MDTs to trigger related logs objects
26329         for idx in $(seq $MDSCOUNT); do
26330                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26331                         $DIR/$tdir/dir${idx} ||
26332                         error "Fail to create $DIR/$tdir/dir${idx}"
26333         done
26334
26335         sync; sleep 3
26336         wait_delete_completed # ensure old test cleanups are finished
26337         echo "before create:"
26338         $LFS df -i $MOUNT
26339         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26340
26341         for i in {1..10}; do
26342                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26343                         error "Fail to create $DIR/$tdir/foo$i"
26344         done
26345
26346         sync; sleep 3
26347         echo "after create:"
26348         $LFS df -i $MOUNT
26349         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26350
26351         # allow for an llog to be cleaned up during the test
26352         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26353                 error "before ($before_used) + 10 > after ($after_used)"
26354
26355         for i in {1..10}; do
26356                 rm -rf $DIR/$tdir/foo$i ||
26357                         error "Fail to remove $DIR/$tdir/foo$i"
26358         done
26359
26360         sleep 3 # avoid MDT return cached statfs
26361         wait_delete_completed
26362         echo "after unlink:"
26363         $LFS df -i $MOUNT
26364         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26365
26366         # allow for an llog to be created during the test
26367         [ $after_used -le $((before_used + 1)) ] ||
26368                 error "after ($after_used) > before ($before_used) + 1"
26369 }
26370 run_test 803a "verify agent object for remote object"
26371
26372 test_803b() {
26373         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26374         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26375                 skip "MDS needs to be newer than 2.13.56"
26376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26377
26378         for i in $(seq 0 $((MDSCOUNT - 1))); do
26379                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26380         done
26381
26382         local before=0
26383         local after=0
26384
26385         local tmp
26386
26387         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26388         for i in $(seq 0 $((MDSCOUNT - 1))); do
26389                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26390                         awk '/getattr/ { print $2 }')
26391                 before=$((before + tmp))
26392         done
26393         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26394         for i in $(seq 0 $((MDSCOUNT - 1))); do
26395                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26396                         awk '/getattr/ { print $2 }')
26397                 after=$((after + tmp))
26398         done
26399
26400         [ $before -eq $after ] || error "getattr count $before != $after"
26401 }
26402 run_test 803b "remote object can getattr from cache"
26403
26404 test_804() {
26405         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26406         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26407                 skip "MDS needs to be newer than 2.10.54"
26408         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26409
26410         mkdir -p $DIR/$tdir
26411         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26412                 error "Fail to create $DIR/$tdir/dir0"
26413
26414         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26415         local dev=$(mdsdevname 2)
26416
26417         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26418                 grep ${fid} || error "NOT found agent entry for dir0"
26419
26420         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26421                 error "Fail to create $DIR/$tdir/dir1"
26422
26423         touch $DIR/$tdir/dir1/foo0 ||
26424                 error "Fail to create $DIR/$tdir/dir1/foo0"
26425         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26426         local rc=0
26427
26428         for idx in $(seq $MDSCOUNT); do
26429                 dev=$(mdsdevname $idx)
26430                 do_facet mds${idx} \
26431                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26432                         grep ${fid} && rc=$idx
26433         done
26434
26435         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26436                 error "Fail to rename foo0 to foo1"
26437         if [ $rc -eq 0 ]; then
26438                 for idx in $(seq $MDSCOUNT); do
26439                         dev=$(mdsdevname $idx)
26440                         do_facet mds${idx} \
26441                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26442                         grep ${fid} && rc=$idx
26443                 done
26444         fi
26445
26446         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26447                 error "Fail to rename foo1 to foo2"
26448         if [ $rc -eq 0 ]; then
26449                 for idx in $(seq $MDSCOUNT); do
26450                         dev=$(mdsdevname $idx)
26451                         do_facet mds${idx} \
26452                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26453                         grep ${fid} && rc=$idx
26454                 done
26455         fi
26456
26457         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26458
26459         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26460                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26461         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26462                 error "Fail to rename foo2 to foo0"
26463         unlink $DIR/$tdir/dir1/foo0 ||
26464                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26465         rm -rf $DIR/$tdir/dir0 ||
26466                 error "Fail to rm $DIR/$tdir/dir0"
26467
26468         for idx in $(seq $MDSCOUNT); do
26469                 dev=$(mdsdevname $idx)
26470                 rc=0
26471
26472                 stop mds${idx}
26473                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26474                         rc=$?
26475                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26476                         error "mount mds$idx failed"
26477                 df $MOUNT > /dev/null 2>&1
26478
26479                 # e2fsck should not return error
26480                 [ $rc -eq 0 ] ||
26481                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26482         done
26483 }
26484 run_test 804 "verify agent entry for remote entry"
26485
26486 cleanup_805() {
26487         do_facet $SINGLEMDS zfs set quota=$old $fsset
26488         unlinkmany $DIR/$tdir/f- 1000000
26489         trap 0
26490 }
26491
26492 test_805() {
26493         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26494         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26495         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26496                 skip "netfree not implemented before 0.7"
26497         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26498                 skip "Need MDS version at least 2.10.57"
26499
26500         local fsset
26501         local freekb
26502         local usedkb
26503         local old
26504         local quota
26505         local pref="osd-zfs.$FSNAME-MDT0000."
26506
26507         # limit available space on MDS dataset to meet nospace issue
26508         # quickly. then ZFS 0.7.2 can use reserved space if asked
26509         # properly (using netfree flag in osd_declare_destroy()
26510         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26511         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26512                 gawk '{print $3}')
26513         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26514         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26515         let "usedkb=usedkb-freekb"
26516         let "freekb=freekb/2"
26517         if let "freekb > 5000"; then
26518                 let "freekb=5000"
26519         fi
26520         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26521         trap cleanup_805 EXIT
26522         mkdir_on_mdt0 $DIR/$tdir
26523         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26524                 error "Can't set PFL layout"
26525         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26526         rm -rf $DIR/$tdir || error "not able to remove"
26527         do_facet $SINGLEMDS zfs set quota=$old $fsset
26528         trap 0
26529 }
26530 run_test 805 "ZFS can remove from full fs"
26531
26532 # Size-on-MDS test
26533 check_lsom_data()
26534 {
26535         local file=$1
26536         local expect=$(stat -c %s $file)
26537
26538         check_lsom_size $1 $expect
26539
26540         local blocks=$($LFS getsom -b $file)
26541         expect=$(stat -c %b $file)
26542         [[ $blocks == $expect ]] ||
26543                 error "$file expected blocks: $expect, got: $blocks"
26544 }
26545
26546 check_lsom_size()
26547 {
26548         local size
26549         local expect=$2
26550
26551         cancel_lru_locks mdc
26552
26553         size=$($LFS getsom -s $1)
26554         [[ $size == $expect ]] ||
26555                 error "$file expected size: $expect, got: $size"
26556 }
26557
26558 test_806() {
26559         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26560                 skip "Need MDS version at least 2.11.52"
26561
26562         local bs=1048576
26563
26564         touch $DIR/$tfile || error "touch $tfile failed"
26565
26566         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26567         save_lustre_params client "llite.*.xattr_cache" > $save
26568         lctl set_param llite.*.xattr_cache=0
26569         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26570
26571         # single-threaded write
26572         echo "Test SOM for single-threaded write"
26573         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26574                 error "write $tfile failed"
26575         check_lsom_size $DIR/$tfile $bs
26576
26577         local num=32
26578         local size=$(($num * $bs))
26579         local offset=0
26580         local i
26581
26582         echo "Test SOM for single client multi-threaded($num) write"
26583         $TRUNCATE $DIR/$tfile 0
26584         for ((i = 0; i < $num; i++)); do
26585                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26586                 local pids[$i]=$!
26587                 offset=$((offset + $bs))
26588         done
26589         for (( i=0; i < $num; i++ )); do
26590                 wait ${pids[$i]}
26591         done
26592         check_lsom_size $DIR/$tfile $size
26593
26594         $TRUNCATE $DIR/$tfile 0
26595         for ((i = 0; i < $num; i++)); do
26596                 offset=$((offset - $bs))
26597                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26598                 local pids[$i]=$!
26599         done
26600         for (( i=0; i < $num; i++ )); do
26601                 wait ${pids[$i]}
26602         done
26603         check_lsom_size $DIR/$tfile $size
26604
26605         # multi-client writes
26606         num=$(get_node_count ${CLIENTS//,/ })
26607         size=$(($num * $bs))
26608         offset=0
26609         i=0
26610
26611         echo "Test SOM for multi-client ($num) writes"
26612         $TRUNCATE $DIR/$tfile 0
26613         for client in ${CLIENTS//,/ }; do
26614                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26615                 local pids[$i]=$!
26616                 i=$((i + 1))
26617                 offset=$((offset + $bs))
26618         done
26619         for (( i=0; i < $num; i++ )); do
26620                 wait ${pids[$i]}
26621         done
26622         check_lsom_size $DIR/$tfile $offset
26623
26624         i=0
26625         $TRUNCATE $DIR/$tfile 0
26626         for client in ${CLIENTS//,/ }; do
26627                 offset=$((offset - $bs))
26628                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26629                 local pids[$i]=$!
26630                 i=$((i + 1))
26631         done
26632         for (( i=0; i < $num; i++ )); do
26633                 wait ${pids[$i]}
26634         done
26635         check_lsom_size $DIR/$tfile $size
26636
26637         # verify truncate
26638         echo "Test SOM for truncate"
26639         $TRUNCATE $DIR/$tfile 1048576
26640         check_lsom_size $DIR/$tfile 1048576
26641         $TRUNCATE $DIR/$tfile 1234
26642         check_lsom_size $DIR/$tfile 1234
26643
26644         # verify SOM blocks count
26645         echo "Verify SOM block count"
26646         $TRUNCATE $DIR/$tfile 0
26647         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26648                 error "failed to write file $tfile"
26649         check_lsom_data $DIR/$tfile
26650 }
26651 run_test 806 "Verify Lazy Size on MDS"
26652
26653 test_807() {
26654         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26655         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26656                 skip "Need MDS version at least 2.11.52"
26657
26658         # Registration step
26659         changelog_register || error "changelog_register failed"
26660         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26661         changelog_users $SINGLEMDS | grep -q $cl_user ||
26662                 error "User $cl_user not found in changelog_users"
26663
26664         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26665         save_lustre_params client "llite.*.xattr_cache" > $save
26666         lctl set_param llite.*.xattr_cache=0
26667         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26668
26669         rm -rf $DIR/$tdir || error "rm $tdir failed"
26670         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26671         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26672         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26673         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26674                 error "truncate $tdir/trunc failed"
26675
26676         local bs=1048576
26677         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26678                 error "write $tfile failed"
26679
26680         # multi-client wirtes
26681         local num=$(get_node_count ${CLIENTS//,/ })
26682         local offset=0
26683         local i=0
26684
26685         echo "Test SOM for multi-client ($num) writes"
26686         touch $DIR/$tfile || error "touch $tfile failed"
26687         $TRUNCATE $DIR/$tfile 0
26688         for client in ${CLIENTS//,/ }; do
26689                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26690                 local pids[$i]=$!
26691                 i=$((i + 1))
26692                 offset=$((offset + $bs))
26693         done
26694         for (( i=0; i < $num; i++ )); do
26695                 wait ${pids[$i]}
26696         done
26697
26698         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26699         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26700         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26701         check_lsom_data $DIR/$tdir/trunc
26702         check_lsom_data $DIR/$tdir/single_dd
26703         check_lsom_data $DIR/$tfile
26704
26705         rm -rf $DIR/$tdir
26706         # Deregistration step
26707         changelog_deregister || error "changelog_deregister failed"
26708 }
26709 run_test 807 "verify LSOM syncing tool"
26710
26711 check_som_nologged()
26712 {
26713         local lines=$($LFS changelog $FSNAME-MDT0000 |
26714                 grep 'x=trusted.som' | wc -l)
26715         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26716 }
26717
26718 test_808() {
26719         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26720                 skip "Need MDS version at least 2.11.55"
26721
26722         # Registration step
26723         changelog_register || error "changelog_register failed"
26724
26725         touch $DIR/$tfile || error "touch $tfile failed"
26726         check_som_nologged
26727
26728         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26729                 error "write $tfile failed"
26730         check_som_nologged
26731
26732         $TRUNCATE $DIR/$tfile 1234
26733         check_som_nologged
26734
26735         $TRUNCATE $DIR/$tfile 1048576
26736         check_som_nologged
26737
26738         # Deregistration step
26739         changelog_deregister || error "changelog_deregister failed"
26740 }
26741 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26742
26743 check_som_nodata()
26744 {
26745         $LFS getsom $1
26746         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26747 }
26748
26749 test_809() {
26750         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26751                 skip "Need MDS version at least 2.11.56"
26752
26753         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26754                 error "failed to create DoM-only file $DIR/$tfile"
26755         touch $DIR/$tfile || error "touch $tfile failed"
26756         check_som_nodata $DIR/$tfile
26757
26758         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26759                 error "write $tfile failed"
26760         check_som_nodata $DIR/$tfile
26761
26762         $TRUNCATE $DIR/$tfile 1234
26763         check_som_nodata $DIR/$tfile
26764
26765         $TRUNCATE $DIR/$tfile 4097
26766         check_som_nodata $DIR/$file
26767 }
26768 run_test 809 "Verify no SOM xattr store for DoM-only files"
26769
26770 test_810() {
26771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26772         $GSS && skip_env "could not run with gss"
26773         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26774                 skip "OST < 2.12.58 doesn't align checksum"
26775
26776         set_checksums 1
26777         stack_trap "set_checksums $ORIG_CSUM" EXIT
26778         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26779
26780         local csum
26781         local before
26782         local after
26783         for csum in $CKSUM_TYPES; do
26784                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26785                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26786                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26787                         eval set -- $i
26788                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26789                         before=$(md5sum $DIR/$tfile)
26790                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26791                         after=$(md5sum $DIR/$tfile)
26792                         [ "$before" == "$after" ] ||
26793                                 error "$csum: $before != $after bs=$1 seek=$2"
26794                 done
26795         done
26796 }
26797 run_test 810 "partial page writes on ZFS (LU-11663)"
26798
26799 test_812a() {
26800         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26801                 skip "OST < 2.12.51 doesn't support this fail_loc"
26802
26803         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26804         # ensure ost1 is connected
26805         stat $DIR/$tfile >/dev/null || error "can't stat"
26806         wait_osc_import_state client ost1 FULL
26807         # no locks, no reqs to let the connection idle
26808         cancel_lru_locks osc
26809
26810         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26811 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26812         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26813         wait_osc_import_state client ost1 CONNECTING
26814         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26815
26816         stat $DIR/$tfile >/dev/null || error "can't stat file"
26817 }
26818 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26819
26820 test_812b() { # LU-12378
26821         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26822                 skip "OST < 2.12.51 doesn't support this fail_loc"
26823
26824         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26825         # ensure ost1 is connected
26826         stat $DIR/$tfile >/dev/null || error "can't stat"
26827         wait_osc_import_state client ost1 FULL
26828         # no locks, no reqs to let the connection idle
26829         cancel_lru_locks osc
26830
26831         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26832 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26833         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26834         wait_osc_import_state client ost1 CONNECTING
26835         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26836
26837         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26838         wait_osc_import_state client ost1 IDLE
26839 }
26840 run_test 812b "do not drop no resend request for idle connect"
26841
26842 test_812c() {
26843         local old
26844
26845         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26846
26847         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26848         $LFS getstripe $DIR/$tfile
26849         $LCTL set_param osc.*.idle_timeout=10
26850         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26851         # ensure ost1 is connected
26852         stat $DIR/$tfile >/dev/null || error "can't stat"
26853         wait_osc_import_state client ost1 FULL
26854         # no locks, no reqs to let the connection idle
26855         cancel_lru_locks osc
26856
26857 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26858         $LCTL set_param fail_loc=0x80000533
26859         sleep 15
26860         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26861 }
26862 run_test 812c "idle import vs lock enqueue race"
26863
26864 test_813() {
26865         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26866         [ -z "$file_heat_sav" ] && skip "no file heat support"
26867
26868         local readsample
26869         local writesample
26870         local readbyte
26871         local writebyte
26872         local readsample1
26873         local writesample1
26874         local readbyte1
26875         local writebyte1
26876
26877         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26878         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26879
26880         $LCTL set_param -n llite.*.file_heat=1
26881         echo "Turn on file heat"
26882         echo "Period second: $period_second, Decay percentage: $decay_pct"
26883
26884         echo "QQQQ" > $DIR/$tfile
26885         echo "QQQQ" > $DIR/$tfile
26886         echo "QQQQ" > $DIR/$tfile
26887         cat $DIR/$tfile > /dev/null
26888         cat $DIR/$tfile > /dev/null
26889         cat $DIR/$tfile > /dev/null
26890         cat $DIR/$tfile > /dev/null
26891
26892         local out=$($LFS heat_get $DIR/$tfile)
26893
26894         $LFS heat_get $DIR/$tfile
26895         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26896         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26897         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26898         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26899
26900         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26901         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26902         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26903         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26904
26905         sleep $((period_second + 3))
26906         echo "Sleep $((period_second + 3)) seconds..."
26907         # The recursion formula to calculate the heat of the file f is as
26908         # follow:
26909         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26910         # Where Hi is the heat value in the period between time points i*I and
26911         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26912         # to the weight of Ci.
26913         out=$($LFS heat_get $DIR/$tfile)
26914         $LFS heat_get $DIR/$tfile
26915         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26916         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26917         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26918         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26919
26920         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26921                 error "read sample ($readsample) is wrong"
26922         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26923                 error "write sample ($writesample) is wrong"
26924         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26925                 error "read bytes ($readbyte) is wrong"
26926         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26927                 error "write bytes ($writebyte) is wrong"
26928
26929         echo "QQQQ" > $DIR/$tfile
26930         echo "QQQQ" > $DIR/$tfile
26931         echo "QQQQ" > $DIR/$tfile
26932         cat $DIR/$tfile > /dev/null
26933         cat $DIR/$tfile > /dev/null
26934         cat $DIR/$tfile > /dev/null
26935         cat $DIR/$tfile > /dev/null
26936
26937         sleep $((period_second + 3))
26938         echo "Sleep $((period_second + 3)) seconds..."
26939
26940         out=$($LFS heat_get $DIR/$tfile)
26941         $LFS heat_get $DIR/$tfile
26942         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26943         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26944         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26945         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26946
26947         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26948                 4 * $decay_pct) / 100") -eq 1 ] ||
26949                 error "read sample ($readsample1) is wrong"
26950         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26951                 3 * $decay_pct) / 100") -eq 1 ] ||
26952                 error "write sample ($writesample1) is wrong"
26953         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26954                 20 * $decay_pct) / 100") -eq 1 ] ||
26955                 error "read bytes ($readbyte1) is wrong"
26956         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26957                 15 * $decay_pct) / 100") -eq 1 ] ||
26958                 error "write bytes ($writebyte1) is wrong"
26959
26960         echo "Turn off file heat for the file $DIR/$tfile"
26961         $LFS heat_set -o $DIR/$tfile
26962
26963         echo "QQQQ" > $DIR/$tfile
26964         echo "QQQQ" > $DIR/$tfile
26965         echo "QQQQ" > $DIR/$tfile
26966         cat $DIR/$tfile > /dev/null
26967         cat $DIR/$tfile > /dev/null
26968         cat $DIR/$tfile > /dev/null
26969         cat $DIR/$tfile > /dev/null
26970
26971         out=$($LFS heat_get $DIR/$tfile)
26972         $LFS heat_get $DIR/$tfile
26973         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26974         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26975         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26976         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26977
26978         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26979         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26980         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26981         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26982
26983         echo "Trun on file heat for the file $DIR/$tfile"
26984         $LFS heat_set -O $DIR/$tfile
26985
26986         echo "QQQQ" > $DIR/$tfile
26987         echo "QQQQ" > $DIR/$tfile
26988         echo "QQQQ" > $DIR/$tfile
26989         cat $DIR/$tfile > /dev/null
26990         cat $DIR/$tfile > /dev/null
26991         cat $DIR/$tfile > /dev/null
26992         cat $DIR/$tfile > /dev/null
26993
26994         out=$($LFS heat_get $DIR/$tfile)
26995         $LFS heat_get $DIR/$tfile
26996         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26997         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26998         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26999         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27000
27001         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27002         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27003         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27004         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27005
27006         $LFS heat_set -c $DIR/$tfile
27007         $LCTL set_param -n llite.*.file_heat=0
27008         echo "Turn off file heat support for the Lustre filesystem"
27009
27010         echo "QQQQ" > $DIR/$tfile
27011         echo "QQQQ" > $DIR/$tfile
27012         echo "QQQQ" > $DIR/$tfile
27013         cat $DIR/$tfile > /dev/null
27014         cat $DIR/$tfile > /dev/null
27015         cat $DIR/$tfile > /dev/null
27016         cat $DIR/$tfile > /dev/null
27017
27018         out=$($LFS heat_get $DIR/$tfile)
27019         $LFS heat_get $DIR/$tfile
27020         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27021         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27022         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27023         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27024
27025         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27026         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27027         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27028         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27029
27030         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27031         rm -f $DIR/$tfile
27032 }
27033 run_test 813 "File heat verfication"
27034
27035 test_814()
27036 {
27037         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27038         echo -n y >> $DIR/$tfile
27039         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27040         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27041 }
27042 run_test 814 "sparse cp works as expected (LU-12361)"
27043
27044 test_815()
27045 {
27046         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27047         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27048 }
27049 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27050
27051 test_816() {
27052         local ost1_imp=$(get_osc_import_name client ost1)
27053         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27054                          cut -d'.' -f2)
27055
27056         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27057         # ensure ost1 is connected
27058
27059         stat $DIR/$tfile >/dev/null || error "can't stat"
27060         wait_osc_import_state client ost1 FULL
27061         # no locks, no reqs to let the connection idle
27062         cancel_lru_locks osc
27063         lru_resize_disable osc
27064         local before
27065         local now
27066         before=$($LCTL get_param -n \
27067                  ldlm.namespaces.$imp_name.lru_size)
27068
27069         wait_osc_import_state client ost1 IDLE
27070         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27071         now=$($LCTL get_param -n \
27072               ldlm.namespaces.$imp_name.lru_size)
27073         [ $before == $now ] || error "lru_size changed $before != $now"
27074 }
27075 run_test 816 "do not reset lru_resize on idle reconnect"
27076
27077 cleanup_817() {
27078         umount $tmpdir
27079         exportfs -u localhost:$DIR/nfsexp
27080         rm -rf $DIR/nfsexp
27081 }
27082
27083 test_817() {
27084         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27085
27086         mkdir -p $DIR/nfsexp
27087         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27088                 error "failed to export nfs"
27089
27090         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27091         stack_trap cleanup_817 EXIT
27092
27093         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27094                 error "failed to mount nfs to $tmpdir"
27095
27096         cp /bin/true $tmpdir
27097         $DIR/nfsexp/true || error "failed to execute 'true' command"
27098 }
27099 run_test 817 "nfsd won't cache write lock for exec file"
27100
27101 test_818() {
27102         mkdir $DIR/$tdir
27103         $LFS setstripe -c1 -i0 $DIR/$tfile
27104         $LFS setstripe -c1 -i1 $DIR/$tfile
27105         stop $SINGLEMDS
27106         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27107         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27108         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27109                 error "start $SINGLEMDS failed"
27110         rm -rf $DIR/$tdir
27111 }
27112 run_test 818 "unlink with failed llog"
27113
27114 test_819a() {
27115         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27116         cancel_lru_locks osc
27117         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27118         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27119         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27120         rm -f $TDIR/$tfile
27121 }
27122 run_test 819a "too big niobuf in read"
27123
27124 test_819b() {
27125         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27126         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27127         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27128         cancel_lru_locks osc
27129         sleep 1
27130         rm -f $TDIR/$tfile
27131 }
27132 run_test 819b "too big niobuf in write"
27133
27134
27135 function test_820_start_ost() {
27136         sleep 5
27137
27138         for num in $(seq $OSTCOUNT); do
27139                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27140         done
27141 }
27142
27143 test_820() {
27144         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27145
27146         mkdir $DIR/$tdir
27147         umount_client $MOUNT || error "umount failed"
27148         for num in $(seq $OSTCOUNT); do
27149                 stop ost$num
27150         done
27151
27152         # mount client with no active OSTs
27153         # so that the client can't initialize max LOV EA size
27154         # from OSC notifications
27155         mount_client $MOUNT || error "mount failed"
27156         # delay OST starting to keep this 0 max EA size for a while
27157         test_820_start_ost &
27158
27159         # create a directory on MDS2
27160         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27161                 error "Failed to create directory"
27162         # open intent should update default EA size
27163         # see mdc_update_max_ea_from_body()
27164         # notice this is the very first RPC to MDS2
27165         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27166         ret=$?
27167         echo $out
27168         # With SSK, this situation can lead to -EPERM being returned.
27169         # In that case, simply retry.
27170         if [ $ret -ne 0 ] && $SHARED_KEY; then
27171                 if echo "$out" | grep -q "not permitted"; then
27172                         cp /etc/services $DIR/$tdir/mds2
27173                         ret=$?
27174                 fi
27175         fi
27176         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27177 }
27178 run_test 820 "update max EA from open intent"
27179
27180 test_822() {
27181         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27182
27183         save_lustre_params mds1 \
27184                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27185         do_facet $SINGLEMDS "$LCTL set_param -n \
27186                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27187         do_facet $SINGLEMDS "$LCTL set_param -n \
27188                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27189
27190         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27191         local maxage=$(do_facet mds1 $LCTL get_param -n \
27192                        osp.$FSNAME-OST0000*MDT0000.maxage)
27193         sleep $((maxage + 1))
27194
27195         #define OBD_FAIL_NET_ERROR_RPC          0x532
27196         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27197
27198         stack_trap "restore_lustre_params < $p; rm $p"
27199
27200         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27201                       osp.$FSNAME-OST0000*MDT0000.create_count")
27202         for i in $(seq 1 $count); do
27203                 touch $DIR/$tfile.${i} || error "touch failed"
27204         done
27205 }
27206 run_test 822 "test precreate failure"
27207
27208 #
27209 # tests that do cleanup/setup should be run at the end
27210 #
27211
27212 test_900() {
27213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27214         local ls
27215
27216         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27217         $LCTL set_param fail_loc=0x903
27218
27219         cancel_lru_locks MGC
27220
27221         FAIL_ON_ERROR=true cleanup
27222         FAIL_ON_ERROR=true setup
27223 }
27224 run_test 900 "umount should not race with any mgc requeue thread"
27225
27226 # LUS-6253/LU-11185
27227 test_901() {
27228         local oldc
27229         local newc
27230         local olds
27231         local news
27232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27233
27234         # some get_param have a bug to handle dot in param name
27235         cancel_lru_locks MGC
27236         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27237         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27238         umount_client $MOUNT || error "umount failed"
27239         mount_client $MOUNT || error "mount failed"
27240         cancel_lru_locks MGC
27241         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27242         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27243
27244         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27245         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27246
27247         return 0
27248 }
27249 run_test 901 "don't leak a mgc lock on client umount"
27250
27251 # LU-13377
27252 test_902() {
27253         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27254                 skip "client does not have LU-13377 fix"
27255         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27256         $LCTL set_param fail_loc=0x1415
27257         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27258         cancel_lru_locks osc
27259         rm -f $DIR/$tfile
27260 }
27261 run_test 902 "test short write doesn't hang lustre"
27262
27263 # LU-14711
27264 test_903() {
27265         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27266         echo "blah" > $DIR/${tfile}-2
27267         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27268         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27269         $LCTL set_param fail_loc=0x417 fail_val=20
27270
27271         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27272         sleep 1 # To start the destroy
27273         wait_destroy_complete 150 || error "Destroy taking too long"
27274         cat $DIR/$tfile > /dev/null || error "Evicted"
27275 }
27276 run_test 903 "Test long page discard does not cause evictions"
27277
27278 complete $SECONDS
27279 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27280 check_and_cleanup_lustre
27281 if [ "$I_MOUNTED" != "yes" ]; then
27282         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27283 fi
27284 exit_status