Whamcloud - gitweb
LU-14816 tests: mark sanity test_230d SLOW
[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  15   (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 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 test_56e() {
6135         err_enoent=2 # No such file or directory
6136         err_eopnotsupp=95 # Operation not supported
6137
6138         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6139         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6140
6141         # Check for handling of path not exists
6142         output=$($LFS df $enoent_mnt 2>&1)
6143         ret=$?
6144
6145         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6146         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6147                 error "expect failure $err_enoent, not $ret"
6148
6149         # Check for handling of non-Lustre FS
6150         output=$($LFS df $notsup_mnt)
6151         ret=$?
6152
6153         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6154         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6155                 error "expect success $err_eopnotsupp, not $ret"
6156
6157         # Check for multiple LustreFS argument
6158         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6159         ret=$?
6160
6161         [[ $output -eq 3 && $ret -eq 0 ]] ||
6162                 error "expect success 3, not $output, rc = $ret"
6163
6164         # Check for correct non-Lustre FS handling among multiple
6165         # LustreFS argument
6166         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6167                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6168         ret=$?
6169
6170         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6171                 error "expect success 2, not $output, rc = $ret"
6172 }
6173 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6174
6175 NUMFILES=3
6176 NUMDIRS=3
6177 setup_56() {
6178         local local_tdir="$1"
6179         local local_numfiles="$2"
6180         local local_numdirs="$3"
6181         local dir_params="$4"
6182         local dir_stripe_params="$5"
6183
6184         if [ ! -d "$local_tdir" ] ; then
6185                 test_mkdir -p $dir_stripe_params $local_tdir
6186                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6187                 for i in $(seq $local_numfiles) ; do
6188                         touch $local_tdir/file$i
6189                 done
6190                 for i in $(seq $local_numdirs) ; do
6191                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6192                         for j in $(seq $local_numfiles) ; do
6193                                 touch $local_tdir/dir$i/file$j
6194                         done
6195                 done
6196         fi
6197 }
6198
6199 setup_56_special() {
6200         local local_tdir=$1
6201         local local_numfiles=$2
6202         local local_numdirs=$3
6203
6204         setup_56 $local_tdir $local_numfiles $local_numdirs
6205
6206         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6207                 for i in $(seq $local_numfiles) ; do
6208                         mknod $local_tdir/loop${i}b b 7 $i
6209                         mknod $local_tdir/null${i}c c 1 3
6210                         ln -s $local_tdir/file1 $local_tdir/link${i}
6211                 done
6212                 for i in $(seq $local_numdirs) ; do
6213                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6214                         mknod $local_tdir/dir$i/null${i}c c 1 3
6215                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6216                 done
6217         fi
6218 }
6219
6220 test_56g() {
6221         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6222         local expected=$(($NUMDIRS + 2))
6223
6224         setup_56 $dir $NUMFILES $NUMDIRS
6225
6226         # test lfs find with -name
6227         for i in $(seq $NUMFILES) ; do
6228                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6229
6230                 [ $nums -eq $expected ] ||
6231                         error "lfs find -name '*$i' $dir wrong: "\
6232                               "found $nums, expected $expected"
6233         done
6234 }
6235 run_test 56g "check lfs find -name"
6236
6237 test_56h() {
6238         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6239         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6240
6241         setup_56 $dir $NUMFILES $NUMDIRS
6242
6243         # test lfs find with ! -name
6244         for i in $(seq $NUMFILES) ; do
6245                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6246
6247                 [ $nums -eq $expected ] ||
6248                         error "lfs find ! -name '*$i' $dir wrong: "\
6249                               "found $nums, expected $expected"
6250         done
6251 }
6252 run_test 56h "check lfs find ! -name"
6253
6254 test_56i() {
6255         local dir=$DIR/$tdir
6256
6257         test_mkdir $dir
6258
6259         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6260         local out=$($cmd)
6261
6262         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6263 }
6264 run_test 56i "check 'lfs find -ost UUID' skips directories"
6265
6266 test_56j() {
6267         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6268
6269         setup_56_special $dir $NUMFILES $NUMDIRS
6270
6271         local expected=$((NUMDIRS + 1))
6272         local cmd="$LFS find -type d $dir"
6273         local nums=$($cmd | wc -l)
6274
6275         [ $nums -eq $expected ] ||
6276                 error "'$cmd' wrong: found $nums, expected $expected"
6277 }
6278 run_test 56j "check lfs find -type d"
6279
6280 test_56k() {
6281         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6282
6283         setup_56_special $dir $NUMFILES $NUMDIRS
6284
6285         local expected=$(((NUMDIRS + 1) * NUMFILES))
6286         local cmd="$LFS find -type f $dir"
6287         local nums=$($cmd | wc -l)
6288
6289         [ $nums -eq $expected ] ||
6290                 error "'$cmd' wrong: found $nums, expected $expected"
6291 }
6292 run_test 56k "check lfs find -type f"
6293
6294 test_56l() {
6295         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6296
6297         setup_56_special $dir $NUMFILES $NUMDIRS
6298
6299         local expected=$((NUMDIRS + NUMFILES))
6300         local cmd="$LFS find -type b $dir"
6301         local nums=$($cmd | wc -l)
6302
6303         [ $nums -eq $expected ] ||
6304                 error "'$cmd' wrong: found $nums, expected $expected"
6305 }
6306 run_test 56l "check lfs find -type b"
6307
6308 test_56m() {
6309         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6310
6311         setup_56_special $dir $NUMFILES $NUMDIRS
6312
6313         local expected=$((NUMDIRS + NUMFILES))
6314         local cmd="$LFS find -type c $dir"
6315         local nums=$($cmd | wc -l)
6316         [ $nums -eq $expected ] ||
6317                 error "'$cmd' wrong: found $nums, expected $expected"
6318 }
6319 run_test 56m "check lfs find -type c"
6320
6321 test_56n() {
6322         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6323         setup_56_special $dir $NUMFILES $NUMDIRS
6324
6325         local expected=$((NUMDIRS + NUMFILES))
6326         local cmd="$LFS find -type l $dir"
6327         local nums=$($cmd | wc -l)
6328
6329         [ $nums -eq $expected ] ||
6330                 error "'$cmd' wrong: found $nums, expected $expected"
6331 }
6332 run_test 56n "check lfs find -type l"
6333
6334 test_56o() {
6335         local dir=$DIR/$tdir
6336
6337         setup_56 $dir $NUMFILES $NUMDIRS
6338         utime $dir/file1 > /dev/null || error "utime (1)"
6339         utime $dir/file2 > /dev/null || error "utime (2)"
6340         utime $dir/dir1 > /dev/null || error "utime (3)"
6341         utime $dir/dir2 > /dev/null || error "utime (4)"
6342         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6343         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6344
6345         local expected=4
6346         local nums=$($LFS find -mtime +0 $dir | wc -l)
6347
6348         [ $nums -eq $expected ] ||
6349                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6350
6351         expected=12
6352         cmd="$LFS find -mtime 0 $dir"
6353         nums=$($cmd | wc -l)
6354         [ $nums -eq $expected ] ||
6355                 error "'$cmd' wrong: found $nums, expected $expected"
6356 }
6357 run_test 56o "check lfs find -mtime for old files"
6358
6359 test_56ob() {
6360         local dir=$DIR/$tdir
6361         local expected=1
6362         local count=0
6363
6364         # just to make sure there is something that won't be found
6365         test_mkdir $dir
6366         touch $dir/$tfile.now
6367
6368         for age in year week day hour min; do
6369                 count=$((count + 1))
6370
6371                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6372                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6373                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6374
6375                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6376                 local nums=$($cmd | wc -l)
6377                 [ $nums -eq $expected ] ||
6378                         error "'$cmd' wrong: found $nums, expected $expected"
6379
6380                 cmd="$LFS find $dir -atime $count${age:0:1}"
6381                 nums=$($cmd | wc -l)
6382                 [ $nums -eq $expected ] ||
6383                         error "'$cmd' wrong: found $nums, expected $expected"
6384         done
6385
6386         sleep 2
6387         cmd="$LFS find $dir -ctime +1s -type f"
6388         nums=$($cmd | wc -l)
6389         (( $nums == $count * 2 + 1)) ||
6390                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6391 }
6392 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6393
6394 test_newerXY_base() {
6395         local x=$1
6396         local y=$2
6397         local dir=$DIR/$tdir
6398         local ref
6399         local negref
6400
6401         if [ $y == "t" ]; then
6402                 if [ $x == "b" ]; then
6403                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6404                 else
6405                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6406                 fi
6407         else
6408                 ref=$DIR/$tfile.newer.$x$y
6409                 touch $ref || error "touch $ref failed"
6410         fi
6411
6412         echo "before = $ref"
6413         sleep 2
6414         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6415         sleep 2
6416         if [ $y == "t" ]; then
6417                 if [ $x == "b" ]; then
6418                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6419                 else
6420                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6421                 fi
6422         else
6423                 negref=$DIR/$tfile.negnewer.$x$y
6424                 touch $negref || error "touch $negref failed"
6425         fi
6426
6427         echo "after = $negref"
6428         local cmd="$LFS find $dir -newer$x$y $ref"
6429         local nums=$(eval $cmd | wc -l)
6430         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6431
6432         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6433                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6434
6435         cmd="$LFS find $dir ! -newer$x$y $negref"
6436         nums=$(eval $cmd | wc -l)
6437         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6438                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6439
6440         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6441         nums=$(eval $cmd | wc -l)
6442         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6443                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6444
6445         rm -rf $DIR/*
6446 }
6447
6448 test_56oc() {
6449         test_newerXY_base "a" "a"
6450         test_newerXY_base "a" "m"
6451         test_newerXY_base "a" "c"
6452         test_newerXY_base "m" "a"
6453         test_newerXY_base "m" "m"
6454         test_newerXY_base "m" "c"
6455         test_newerXY_base "c" "a"
6456         test_newerXY_base "c" "m"
6457         test_newerXY_base "c" "c"
6458
6459         [[ -n "$sles_version" ]] &&
6460                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6461
6462         test_newerXY_base "a" "t"
6463         test_newerXY_base "m" "t"
6464         test_newerXY_base "c" "t"
6465
6466         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6467            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6468                 ! btime_supported && echo "btime unsupported" && return 0
6469
6470         test_newerXY_base "b" "b"
6471         test_newerXY_base "b" "t"
6472 }
6473 run_test 56oc "check lfs find -newerXY work"
6474
6475 btime_supported() {
6476         local dir=$DIR/$tdir
6477         local rc
6478
6479         mkdir -p $dir
6480         touch $dir/$tfile
6481         $LFS find $dir -btime -1d -type f
6482         rc=$?
6483         rm -rf $dir
6484         return $rc
6485 }
6486
6487 test_56od() {
6488         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6489                 ! btime_supported && skip "btime unsupported on MDS"
6490
6491         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6492                 ! btime_supported && skip "btime unsupported on clients"
6493
6494         local dir=$DIR/$tdir
6495         local ref=$DIR/$tfile.ref
6496         local negref=$DIR/$tfile.negref
6497
6498         mkdir $dir || error "mkdir $dir failed"
6499         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6500         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6501         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6502         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6503         touch $ref || error "touch $ref failed"
6504         # sleep 3 seconds at least
6505         sleep 3
6506
6507         local before=$(do_facet mds1 date +%s)
6508         local skew=$(($(date +%s) - before + 1))
6509
6510         if (( skew < 0 && skew > -5 )); then
6511                 sleep $((0 - skew + 1))
6512                 skew=0
6513         fi
6514
6515         # Set the dir stripe params to limit files all on MDT0,
6516         # otherwise we need to calc the max clock skew between
6517         # the client and MDTs.
6518         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6519         sleep 2
6520         touch $negref || error "touch $negref failed"
6521
6522         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6523         local nums=$($cmd | wc -l)
6524         local expected=$(((NUMFILES + 1) * NUMDIRS))
6525
6526         [ $nums -eq $expected ] ||
6527                 error "'$cmd' wrong: found $nums, expected $expected"
6528
6529         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6530         nums=$($cmd | wc -l)
6531         expected=$((NUMFILES + 1))
6532         [ $nums -eq $expected ] ||
6533                 error "'$cmd' wrong: found $nums, expected $expected"
6534
6535         [ $skew -lt 0 ] && return
6536
6537         local after=$(do_facet mds1 date +%s)
6538         local age=$((after - before + 1 + skew))
6539
6540         cmd="$LFS find $dir -btime -${age}s -type f"
6541         nums=$($cmd | wc -l)
6542         expected=$(((NUMFILES + 1) * NUMDIRS))
6543
6544         echo "Clock skew between client and server: $skew, age:$age"
6545         [ $nums -eq $expected ] ||
6546                 error "'$cmd' wrong: found $nums, expected $expected"
6547
6548         expected=$(($NUMDIRS + 1))
6549         cmd="$LFS find $dir -btime -${age}s -type d"
6550         nums=$($cmd | wc -l)
6551         [ $nums -eq $expected ] ||
6552                 error "'$cmd' wrong: found $nums, expected $expected"
6553         rm -f $ref $negref || error "Failed to remove $ref $negref"
6554 }
6555 run_test 56od "check lfs find -btime with units"
6556
6557 test_56p() {
6558         [ $RUNAS_ID -eq $UID ] &&
6559                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6560
6561         local dir=$DIR/$tdir
6562
6563         setup_56 $dir $NUMFILES $NUMDIRS
6564         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6565
6566         local expected=$NUMFILES
6567         local cmd="$LFS find -uid $RUNAS_ID $dir"
6568         local nums=$($cmd | wc -l)
6569
6570         [ $nums -eq $expected ] ||
6571                 error "'$cmd' wrong: found $nums, expected $expected"
6572
6573         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6574         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6575         nums=$($cmd | wc -l)
6576         [ $nums -eq $expected ] ||
6577                 error "'$cmd' wrong: found $nums, expected $expected"
6578 }
6579 run_test 56p "check lfs find -uid and ! -uid"
6580
6581 test_56q() {
6582         [ $RUNAS_ID -eq $UID ] &&
6583                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6584
6585         local dir=$DIR/$tdir
6586
6587         setup_56 $dir $NUMFILES $NUMDIRS
6588         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6589
6590         local expected=$NUMFILES
6591         local cmd="$LFS find -gid $RUNAS_GID $dir"
6592         local nums=$($cmd | wc -l)
6593
6594         [ $nums -eq $expected ] ||
6595                 error "'$cmd' wrong: found $nums, expected $expected"
6596
6597         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6598         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6599         nums=$($cmd | wc -l)
6600         [ $nums -eq $expected ] ||
6601                 error "'$cmd' wrong: found $nums, expected $expected"
6602 }
6603 run_test 56q "check lfs find -gid and ! -gid"
6604
6605 test_56r() {
6606         local dir=$DIR/$tdir
6607
6608         setup_56 $dir $NUMFILES $NUMDIRS
6609
6610         local expected=12
6611         local cmd="$LFS find -size 0 -type f -lazy $dir"
6612         local nums=$($cmd | wc -l)
6613
6614         [ $nums -eq $expected ] ||
6615                 error "'$cmd' wrong: found $nums, expected $expected"
6616         cmd="$LFS find -size 0 -type f $dir"
6617         nums=$($cmd | wc -l)
6618         [ $nums -eq $expected ] ||
6619                 error "'$cmd' wrong: found $nums, expected $expected"
6620
6621         expected=0
6622         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6623         nums=$($cmd | wc -l)
6624         [ $nums -eq $expected ] ||
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626         cmd="$LFS find ! -size 0 -type f $dir"
6627         nums=$($cmd | wc -l)
6628         [ $nums -eq $expected ] ||
6629                 error "'$cmd' wrong: found $nums, expected $expected"
6630
6631         echo "test" > $dir/$tfile
6632         echo "test2" > $dir/$tfile.2 && sync
6633         expected=1
6634         cmd="$LFS find -size 5 -type f -lazy $dir"
6635         nums=$($cmd | wc -l)
6636         [ $nums -eq $expected ] ||
6637                 error "'$cmd' wrong: found $nums, expected $expected"
6638         cmd="$LFS find -size 5 -type f $dir"
6639         nums=$($cmd | wc -l)
6640         [ $nums -eq $expected ] ||
6641                 error "'$cmd' wrong: found $nums, expected $expected"
6642
6643         expected=1
6644         cmd="$LFS find -size +5 -type f -lazy $dir"
6645         nums=$($cmd | wc -l)
6646         [ $nums -eq $expected ] ||
6647                 error "'$cmd' wrong: found $nums, expected $expected"
6648         cmd="$LFS find -size +5 -type f $dir"
6649         nums=$($cmd | wc -l)
6650         [ $nums -eq $expected ] ||
6651                 error "'$cmd' wrong: found $nums, expected $expected"
6652
6653         expected=2
6654         cmd="$LFS find -size +0 -type f -lazy $dir"
6655         nums=$($cmd | wc -l)
6656         [ $nums -eq $expected ] ||
6657                 error "'$cmd' wrong: found $nums, expected $expected"
6658         cmd="$LFS find -size +0 -type f $dir"
6659         nums=$($cmd | wc -l)
6660         [ $nums -eq $expected ] ||
6661                 error "'$cmd' wrong: found $nums, expected $expected"
6662
6663         expected=2
6664         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6665         nums=$($cmd | wc -l)
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668         cmd="$LFS find ! -size -5 -type f $dir"
6669         nums=$($cmd | wc -l)
6670         [ $nums -eq $expected ] ||
6671                 error "'$cmd' wrong: found $nums, expected $expected"
6672
6673         expected=12
6674         cmd="$LFS find -size -5 -type f -lazy $dir"
6675         nums=$($cmd | wc -l)
6676         [ $nums -eq $expected ] ||
6677                 error "'$cmd' wrong: found $nums, expected $expected"
6678         cmd="$LFS find -size -5 -type f $dir"
6679         nums=$($cmd | wc -l)
6680         [ $nums -eq $expected ] ||
6681                 error "'$cmd' wrong: found $nums, expected $expected"
6682 }
6683 run_test 56r "check lfs find -size works"
6684
6685 test_56ra_sub() {
6686         local expected=$1
6687         local glimpses=$2
6688         local cmd="$3"
6689
6690         cancel_lru_locks $OSC
6691
6692         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6693         local nums=$($cmd | wc -l)
6694
6695         [ $nums -eq $expected ] ||
6696                 error "'$cmd' wrong: found $nums, expected $expected"
6697
6698         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6699
6700         if (( rpcs_before + glimpses != rpcs_after )); then
6701                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6702                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6703
6704                 if [[ $glimpses == 0 ]]; then
6705                         error "'$cmd' should not send glimpse RPCs to OST"
6706                 else
6707                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6708                 fi
6709         fi
6710 }
6711
6712 test_56ra() {
6713         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6714                 skip "MDS < 2.12.58 doesn't return LSOM data"
6715         local dir=$DIR/$tdir
6716         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6717
6718         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6719
6720         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6721         $LCTL set_param -n llite.*.statahead_agl=0
6722         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6723
6724         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6725         # open and close all files to ensure LSOM is updated
6726         cancel_lru_locks $OSC
6727         find $dir -type f | xargs cat > /dev/null
6728
6729         #   expect_found  glimpse_rpcs  command_to_run
6730         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6731         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6732         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6733         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6734
6735         echo "test" > $dir/$tfile
6736         echo "test2" > $dir/$tfile.2 && sync
6737         cancel_lru_locks $OSC
6738         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6739
6740         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6741         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6742         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6743         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6744
6745         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6746         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6747         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6748         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6749         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6750         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6751 }
6752 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6753
6754 test_56rb() {
6755         local dir=$DIR/$tdir
6756         local tmp=$TMP/$tfile.log
6757         local mdt_idx;
6758
6759         test_mkdir -p $dir || error "failed to mkdir $dir"
6760         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6761                 error "failed to setstripe $dir/$tfile"
6762         mdt_idx=$($LFS getdirstripe -i $dir)
6763         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6764
6765         stack_trap "rm -f $tmp" EXIT
6766         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6767         ! grep -q obd_uuid $tmp ||
6768                 error "failed to find --size +100K --ost 0 $dir"
6769         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6770         ! grep -q obd_uuid $tmp ||
6771                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6772 }
6773 run_test 56rb "check lfs find --size --ost/--mdt works"
6774
6775 test_56rc() {
6776         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6777         local dir=$DIR/$tdir
6778         local found
6779
6780         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6781         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6782         (( $MDSCOUNT > 2 )) &&
6783                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6784         mkdir $dir/$tdir-{1..10}
6785         touch $dir/$tfile-{1..10}
6786
6787         found=$($LFS find $dir --mdt-count 2 | wc -l)
6788         expect=11
6789         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6790
6791         found=$($LFS find $dir -T +1 | wc -l)
6792         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6793         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6794
6795         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6796         expect=11
6797         (( $found == $expect )) || error "found $found all_char, expect $expect"
6798
6799         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6800         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6801         (( $found == $expect )) || error "found $found all_char, expect $expect"
6802 }
6803 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6804
6805 test_56s() { # LU-611 #LU-9369
6806         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6807
6808         local dir=$DIR/$tdir
6809         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6810
6811         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6812         for i in $(seq $NUMDIRS); do
6813                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6814         done
6815
6816         local expected=$NUMDIRS
6817         local cmd="$LFS find -c $OSTCOUNT $dir"
6818         local nums=$($cmd | wc -l)
6819
6820         [ $nums -eq $expected ] || {
6821                 $LFS getstripe -R $dir
6822                 error "'$cmd' wrong: found $nums, expected $expected"
6823         }
6824
6825         expected=$((NUMDIRS + onestripe))
6826         cmd="$LFS find -stripe-count +0 -type f $dir"
6827         nums=$($cmd | wc -l)
6828         [ $nums -eq $expected ] || {
6829                 $LFS getstripe -R $dir
6830                 error "'$cmd' wrong: found $nums, expected $expected"
6831         }
6832
6833         expected=$onestripe
6834         cmd="$LFS find -stripe-count 1 -type f $dir"
6835         nums=$($cmd | wc -l)
6836         [ $nums -eq $expected ] || {
6837                 $LFS getstripe -R $dir
6838                 error "'$cmd' wrong: found $nums, expected $expected"
6839         }
6840
6841         cmd="$LFS find -stripe-count -2 -type f $dir"
6842         nums=$($cmd | wc -l)
6843         [ $nums -eq $expected ] || {
6844                 $LFS getstripe -R $dir
6845                 error "'$cmd' wrong: found $nums, expected $expected"
6846         }
6847
6848         expected=0
6849         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6850         nums=$($cmd | wc -l)
6851         [ $nums -eq $expected ] || {
6852                 $LFS getstripe -R $dir
6853                 error "'$cmd' wrong: found $nums, expected $expected"
6854         }
6855 }
6856 run_test 56s "check lfs find -stripe-count works"
6857
6858 test_56t() { # LU-611 #LU-9369
6859         local dir=$DIR/$tdir
6860
6861         setup_56 $dir 0 $NUMDIRS
6862         for i in $(seq $NUMDIRS); do
6863                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6864         done
6865
6866         local expected=$NUMDIRS
6867         local cmd="$LFS find -S 8M $dir"
6868         local nums=$($cmd | wc -l)
6869
6870         [ $nums -eq $expected ] || {
6871                 $LFS getstripe -R $dir
6872                 error "'$cmd' wrong: found $nums, expected $expected"
6873         }
6874         rm -rf $dir
6875
6876         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6877
6878         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6879
6880         expected=$(((NUMDIRS + 1) * NUMFILES))
6881         cmd="$LFS find -stripe-size 512k -type f $dir"
6882         nums=$($cmd | wc -l)
6883         [ $nums -eq $expected ] ||
6884                 error "'$cmd' wrong: found $nums, expected $expected"
6885
6886         cmd="$LFS find -stripe-size +320k -type f $dir"
6887         nums=$($cmd | wc -l)
6888         [ $nums -eq $expected ] ||
6889                 error "'$cmd' wrong: found $nums, expected $expected"
6890
6891         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6892         cmd="$LFS find -stripe-size +200k -type f $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896
6897         cmd="$LFS find -stripe-size -640k -type f $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] ||
6900                 error "'$cmd' wrong: found $nums, expected $expected"
6901
6902         expected=4
6903         cmd="$LFS find -stripe-size 256k -type f $dir"
6904         nums=$($cmd | wc -l)
6905         [ $nums -eq $expected ] ||
6906                 error "'$cmd' wrong: found $nums, expected $expected"
6907
6908         cmd="$LFS find -stripe-size -320k -type f $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912
6913         expected=0
6914         cmd="$LFS find -stripe-size 1024k -type f $dir"
6915         nums=$($cmd | wc -l)
6916         [ $nums -eq $expected ] ||
6917                 error "'$cmd' wrong: found $nums, expected $expected"
6918 }
6919 run_test 56t "check lfs find -stripe-size works"
6920
6921 test_56u() { # LU-611
6922         local dir=$DIR/$tdir
6923
6924         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6925
6926         if [[ $OSTCOUNT -gt 1 ]]; then
6927                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6928                 onestripe=4
6929         else
6930                 onestripe=0
6931         fi
6932
6933         local expected=$(((NUMDIRS + 1) * NUMFILES))
6934         local cmd="$LFS find -stripe-index 0 -type f $dir"
6935         local nums=$($cmd | wc -l)
6936
6937         [ $nums -eq $expected ] ||
6938                 error "'$cmd' wrong: found $nums, expected $expected"
6939
6940         expected=$onestripe
6941         cmd="$LFS find -stripe-index 1 -type f $dir"
6942         nums=$($cmd | wc -l)
6943         [ $nums -eq $expected ] ||
6944                 error "'$cmd' wrong: found $nums, expected $expected"
6945
6946         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6947         nums=$($cmd | wc -l)
6948         [ $nums -eq $expected ] ||
6949                 error "'$cmd' wrong: found $nums, expected $expected"
6950
6951         expected=0
6952         # This should produce an error and not return any files
6953         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6954         nums=$($cmd 2>/dev/null | wc -l)
6955         [ $nums -eq $expected ] ||
6956                 error "'$cmd' wrong: found $nums, expected $expected"
6957
6958         if [[ $OSTCOUNT -gt 1 ]]; then
6959                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6960                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6961                 nums=$($cmd | wc -l)
6962                 [ $nums -eq $expected ] ||
6963                         error "'$cmd' wrong: found $nums, expected $expected"
6964         fi
6965 }
6966 run_test 56u "check lfs find -stripe-index works"
6967
6968 test_56v() {
6969         local mdt_idx=0
6970         local dir=$DIR/$tdir
6971
6972         setup_56 $dir $NUMFILES $NUMDIRS
6973
6974         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6975         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6976
6977         for file in $($LFS find -m $UUID $dir); do
6978                 file_midx=$($LFS getstripe -m $file)
6979                 [ $file_midx -eq $mdt_idx ] ||
6980                         error "lfs find -m $UUID != getstripe -m $file_midx"
6981         done
6982 }
6983 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6984
6985 test_56w() {
6986         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6988
6989         local dir=$DIR/$tdir
6990
6991         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6992
6993         local stripe_size=$($LFS getstripe -S -d $dir) ||
6994                 error "$LFS getstripe -S -d $dir failed"
6995         stripe_size=${stripe_size%% *}
6996
6997         local file_size=$((stripe_size * OSTCOUNT))
6998         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6999         local required_space=$((file_num * file_size))
7000         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7001                            head -n1)
7002         [[ $free_space -le $((required_space / 1024)) ]] &&
7003                 skip_env "need $required_space, have $free_space kbytes"
7004
7005         local dd_bs=65536
7006         local dd_count=$((file_size / dd_bs))
7007
7008         # write data into the files
7009         local i
7010         local j
7011         local file
7012
7013         for i in $(seq $NUMFILES); do
7014                 file=$dir/file$i
7015                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7016                         error "write data into $file failed"
7017         done
7018         for i in $(seq $NUMDIRS); do
7019                 for j in $(seq $NUMFILES); do
7020                         file=$dir/dir$i/file$j
7021                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7022                                 error "write data into $file failed"
7023                 done
7024         done
7025
7026         # $LFS_MIGRATE will fail if hard link migration is unsupported
7027         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7028                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7029                         error "creating links to $dir/dir1/file1 failed"
7030         fi
7031
7032         local expected=-1
7033
7034         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7035
7036         # lfs_migrate file
7037         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7038
7039         echo "$cmd"
7040         eval $cmd || error "$cmd failed"
7041
7042         check_stripe_count $dir/file1 $expected
7043
7044         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7045         then
7046                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7047                 # OST 1 if it is on OST 0. This file is small enough to
7048                 # be on only one stripe.
7049                 file=$dir/migr_1_ost
7050                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7051                         error "write data into $file failed"
7052                 local obdidx=$($LFS getstripe -i $file)
7053                 local oldmd5=$(md5sum $file)
7054                 local newobdidx=0
7055
7056                 [[ $obdidx -eq 0 ]] && newobdidx=1
7057                 cmd="$LFS migrate -i $newobdidx $file"
7058                 echo $cmd
7059                 eval $cmd || error "$cmd failed"
7060
7061                 local realobdix=$($LFS getstripe -i $file)
7062                 local newmd5=$(md5sum $file)
7063
7064                 [[ $newobdidx -ne $realobdix ]] &&
7065                         error "new OST is different (was=$obdidx, "\
7066                               "wanted=$newobdidx, got=$realobdix)"
7067                 [[ "$oldmd5" != "$newmd5" ]] &&
7068                         error "md5sum differ: $oldmd5, $newmd5"
7069         fi
7070
7071         # lfs_migrate dir
7072         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7073         echo "$cmd"
7074         eval $cmd || error "$cmd failed"
7075
7076         for j in $(seq $NUMFILES); do
7077                 check_stripe_count $dir/dir1/file$j $expected
7078         done
7079
7080         # lfs_migrate works with lfs find
7081         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7082              $LFS_MIGRATE -y -c $expected"
7083         echo "$cmd"
7084         eval $cmd || error "$cmd failed"
7085
7086         for i in $(seq 2 $NUMFILES); do
7087                 check_stripe_count $dir/file$i $expected
7088         done
7089         for i in $(seq 2 $NUMDIRS); do
7090                 for j in $(seq $NUMFILES); do
7091                 check_stripe_count $dir/dir$i/file$j $expected
7092                 done
7093         done
7094 }
7095 run_test 56w "check lfs_migrate -c stripe_count works"
7096
7097 test_56wb() {
7098         local file1=$DIR/$tdir/file1
7099         local create_pool=false
7100         local initial_pool=$($LFS getstripe -p $DIR)
7101         local pool_list=()
7102         local pool=""
7103
7104         echo -n "Creating test dir..."
7105         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7106         echo "done."
7107
7108         echo -n "Creating test file..."
7109         touch $file1 || error "cannot create file"
7110         echo "done."
7111
7112         echo -n "Detecting existing pools..."
7113         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7114
7115         if [ ${#pool_list[@]} -gt 0 ]; then
7116                 echo "${pool_list[@]}"
7117                 for thispool in "${pool_list[@]}"; do
7118                         if [[ -z "$initial_pool" ||
7119                               "$initial_pool" != "$thispool" ]]; then
7120                                 pool="$thispool"
7121                                 echo "Using existing pool '$pool'"
7122                                 break
7123                         fi
7124                 done
7125         else
7126                 echo "none detected."
7127         fi
7128         if [ -z "$pool" ]; then
7129                 pool=${POOL:-testpool}
7130                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7131                 echo -n "Creating pool '$pool'..."
7132                 create_pool=true
7133                 pool_add $pool &> /dev/null ||
7134                         error "pool_add failed"
7135                 echo "done."
7136
7137                 echo -n "Adding target to pool..."
7138                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7139                         error "pool_add_targets failed"
7140                 echo "done."
7141         fi
7142
7143         echo -n "Setting pool using -p option..."
7144         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7145                 error "migrate failed rc = $?"
7146         echo "done."
7147
7148         echo -n "Verifying test file is in pool after migrating..."
7149         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7150                 error "file was not migrated to pool $pool"
7151         echo "done."
7152
7153         echo -n "Removing test file from pool '$pool'..."
7154         # "lfs migrate $file" won't remove the file from the pool
7155         # until some striping information is changed.
7156         $LFS migrate -c 1 $file1 &> /dev/null ||
7157                 error "cannot remove from pool"
7158         [ "$($LFS getstripe -p $file1)" ] &&
7159                 error "pool still set"
7160         echo "done."
7161
7162         echo -n "Setting pool using --pool option..."
7163         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7164                 error "migrate failed rc = $?"
7165         echo "done."
7166
7167         # Clean up
7168         rm -f $file1
7169         if $create_pool; then
7170                 destroy_test_pools 2> /dev/null ||
7171                         error "destroy test pools failed"
7172         fi
7173 }
7174 run_test 56wb "check lfs_migrate pool support"
7175
7176 test_56wc() {
7177         local file1="$DIR/$tdir/file1"
7178         local parent_ssize
7179         local parent_scount
7180         local cur_ssize
7181         local cur_scount
7182         local orig_ssize
7183
7184         echo -n "Creating test dir..."
7185         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7186         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7187                 error "cannot set stripe by '-S 1M -c 1'"
7188         echo "done"
7189
7190         echo -n "Setting initial stripe for test file..."
7191         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7192                 error "cannot set stripe"
7193         cur_ssize=$($LFS getstripe -S "$file1")
7194         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7195         echo "done."
7196
7197         # File currently set to -S 512K -c 1
7198
7199         # Ensure -c and -S options are rejected when -R is set
7200         echo -n "Verifying incompatible options are detected..."
7201         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7202                 error "incompatible -c and -R options not detected"
7203         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7204                 error "incompatible -S and -R options not detected"
7205         echo "done."
7206
7207         # Ensure unrecognized options are passed through to 'lfs migrate'
7208         echo -n "Verifying -S option is passed through to lfs migrate..."
7209         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7210                 error "migration failed"
7211         cur_ssize=$($LFS getstripe -S "$file1")
7212         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7213         echo "done."
7214
7215         # File currently set to -S 1M -c 1
7216
7217         # Ensure long options are supported
7218         echo -n "Verifying long options supported..."
7219         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7220                 error "long option without argument not supported"
7221         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7222                 error "long option with argument not supported"
7223         cur_ssize=$($LFS getstripe -S "$file1")
7224         [ $cur_ssize -eq 524288 ] ||
7225                 error "migrate --stripe-size $cur_ssize != 524288"
7226         echo "done."
7227
7228         # File currently set to -S 512K -c 1
7229
7230         if [ "$OSTCOUNT" -gt 1 ]; then
7231                 echo -n "Verifying explicit stripe count can be set..."
7232                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7233                         error "migrate failed"
7234                 cur_scount=$($LFS getstripe -c "$file1")
7235                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7236                 echo "done."
7237         fi
7238
7239         # File currently set to -S 512K -c 1 or -S 512K -c 2
7240
7241         # Ensure parent striping is used if -R is set, and no stripe
7242         # count or size is specified
7243         echo -n "Setting stripe for parent directory..."
7244         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7245                 error "cannot set stripe '-S 2M -c 1'"
7246         echo "done."
7247
7248         echo -n "Verifying restripe option uses parent stripe settings..."
7249         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7250         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7251         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7252                 error "migrate failed"
7253         cur_ssize=$($LFS getstripe -S "$file1")
7254         [ $cur_ssize -eq $parent_ssize ] ||
7255                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7256         cur_scount=$($LFS getstripe -c "$file1")
7257         [ $cur_scount -eq $parent_scount ] ||
7258                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7259         echo "done."
7260
7261         # File currently set to -S 1M -c 1
7262
7263         # Ensure striping is preserved if -R is not set, and no stripe
7264         # count or size is specified
7265         echo -n "Verifying striping size preserved when not specified..."
7266         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7267         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7268                 error "cannot set stripe on parent directory"
7269         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7270                 error "migrate failed"
7271         cur_ssize=$($LFS getstripe -S "$file1")
7272         [ $cur_ssize -eq $orig_ssize ] ||
7273                 error "migrate by default $cur_ssize != $orig_ssize"
7274         echo "done."
7275
7276         # Ensure file name properly detected when final option has no argument
7277         echo -n "Verifying file name properly detected..."
7278         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7279                 error "file name interpreted as option argument"
7280         echo "done."
7281
7282         # Clean up
7283         rm -f "$file1"
7284 }
7285 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7286
7287 test_56wd() {
7288         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7289
7290         local file1=$DIR/$tdir/file1
7291
7292         echo -n "Creating test dir..."
7293         test_mkdir $DIR/$tdir || error "cannot create dir"
7294         echo "done."
7295
7296         echo -n "Creating test file..."
7297         touch $file1
7298         echo "done."
7299
7300         # Ensure 'lfs migrate' will fail by using a non-existent option,
7301         # and make sure rsync is not called to recover
7302         echo -n "Make sure --no-rsync option works..."
7303         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7304                 grep -q 'refusing to fall back to rsync' ||
7305                 error "rsync was called with --no-rsync set"
7306         echo "done."
7307
7308         # Ensure rsync is called without trying 'lfs migrate' first
7309         echo -n "Make sure --rsync option works..."
7310         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7311                 grep -q 'falling back to rsync' &&
7312                 error "lfs migrate was called with --rsync set"
7313         echo "done."
7314
7315         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7316         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7317                 grep -q 'at the same time' ||
7318                 error "--rsync and --no-rsync accepted concurrently"
7319         echo "done."
7320
7321         # Clean up
7322         rm -f $file1
7323 }
7324 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7325
7326 test_56we() {
7327         local td=$DIR/$tdir
7328         local tf=$td/$tfile
7329
7330         test_mkdir $td || error "cannot create $td"
7331         touch $tf || error "cannot touch $tf"
7332
7333         echo -n "Make sure --non-direct|-D works..."
7334         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7335                 grep -q "lfs migrate --non-direct" ||
7336                 error "--non-direct option cannot work correctly"
7337         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7338                 grep -q "lfs migrate -D" ||
7339                 error "-D option cannot work correctly"
7340         echo "done."
7341 }
7342 run_test 56we "check lfs_migrate --non-direct|-D support"
7343
7344 test_56x() {
7345         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7346         check_swap_layouts_support
7347
7348         local dir=$DIR/$tdir
7349         local ref1=/etc/passwd
7350         local file1=$dir/file1
7351
7352         test_mkdir $dir || error "creating dir $dir"
7353         $LFS setstripe -c 2 $file1
7354         cp $ref1 $file1
7355         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7356         stripe=$($LFS getstripe -c $file1)
7357         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7358         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7359
7360         # clean up
7361         rm -f $file1
7362 }
7363 run_test 56x "lfs migration support"
7364
7365 test_56xa() {
7366         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7367         check_swap_layouts_support
7368
7369         local dir=$DIR/$tdir/$testnum
7370
7371         test_mkdir -p $dir
7372
7373         local ref1=/etc/passwd
7374         local file1=$dir/file1
7375
7376         $LFS setstripe -c 2 $file1
7377         cp $ref1 $file1
7378         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7379
7380         local stripe=$($LFS getstripe -c $file1)
7381
7382         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7383         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7384
7385         # clean up
7386         rm -f $file1
7387 }
7388 run_test 56xa "lfs migration --block support"
7389
7390 check_migrate_links() {
7391         local dir="$1"
7392         local file1="$dir/file1"
7393         local begin="$2"
7394         local count="$3"
7395         local runas="$4"
7396         local total_count=$(($begin + $count - 1))
7397         local symlink_count=10
7398         local uniq_count=10
7399
7400         if [ ! -f "$file1" ]; then
7401                 echo -n "creating initial file..."
7402                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7403                         error "cannot setstripe initial file"
7404                 echo "done"
7405
7406                 echo -n "creating symlinks..."
7407                 for s in $(seq 1 $symlink_count); do
7408                         ln -s "$file1" "$dir/slink$s" ||
7409                                 error "cannot create symlinks"
7410                 done
7411                 echo "done"
7412
7413                 echo -n "creating nonlinked files..."
7414                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7415                         error "cannot create nonlinked files"
7416                 echo "done"
7417         fi
7418
7419         # create hard links
7420         if [ ! -f "$dir/file$total_count" ]; then
7421                 echo -n "creating hard links $begin:$total_count..."
7422                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7423                         /dev/null || error "cannot create hard links"
7424                 echo "done"
7425         fi
7426
7427         echo -n "checking number of hard links listed in xattrs..."
7428         local fid=$($LFS getstripe -F "$file1")
7429         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7430
7431         echo "${#paths[*]}"
7432         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7433                         skip "hard link list has unexpected size, skipping test"
7434         fi
7435         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7436                         error "link names should exceed xattrs size"
7437         fi
7438
7439         echo -n "migrating files..."
7440         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7441         local rc=$?
7442         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7443         echo "done"
7444
7445         # make sure all links have been properly migrated
7446         echo -n "verifying files..."
7447         fid=$($LFS getstripe -F "$file1") ||
7448                 error "cannot get fid for file $file1"
7449         for i in $(seq 2 $total_count); do
7450                 local fid2=$($LFS getstripe -F $dir/file$i)
7451
7452                 [ "$fid2" == "$fid" ] ||
7453                         error "migrated hard link has mismatched FID"
7454         done
7455
7456         # make sure hard links were properly detected, and migration was
7457         # performed only once for the entire link set; nonlinked files should
7458         # also be migrated
7459         local actual=$(grep -c 'done' <<< "$migrate_out")
7460         local expected=$(($uniq_count + 1))
7461
7462         [ "$actual" -eq  "$expected" ] ||
7463                 error "hard links individually migrated ($actual != $expected)"
7464
7465         # make sure the correct number of hard links are present
7466         local hardlinks=$(stat -c '%h' "$file1")
7467
7468         [ $hardlinks -eq $total_count ] ||
7469                 error "num hard links $hardlinks != $total_count"
7470         echo "done"
7471
7472         return 0
7473 }
7474
7475 test_56xb() {
7476         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7477                 skip "Need MDS version at least 2.10.55"
7478
7479         local dir="$DIR/$tdir"
7480
7481         test_mkdir "$dir" || error "cannot create dir $dir"
7482
7483         echo "testing lfs migrate mode when all links fit within xattrs"
7484         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7485
7486         echo "testing rsync mode when all links fit within xattrs"
7487         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7488
7489         echo "testing lfs migrate mode when all links do not fit within xattrs"
7490         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7491
7492         echo "testing rsync mode when all links do not fit within xattrs"
7493         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7494
7495         chown -R $RUNAS_ID $dir
7496         echo "testing non-root lfs migrate mode when not all links are in xattr"
7497         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7498
7499         # clean up
7500         rm -rf $dir
7501 }
7502 run_test 56xb "lfs migration hard link support"
7503
7504 test_56xc() {
7505         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7506
7507         local dir="$DIR/$tdir"
7508
7509         test_mkdir "$dir" || error "cannot create dir $dir"
7510
7511         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7512         echo -n "Setting initial stripe for 20MB test file..."
7513         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7514                 error "cannot setstripe 20MB file"
7515         echo "done"
7516         echo -n "Sizing 20MB test file..."
7517         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7518         echo "done"
7519         echo -n "Verifying small file autostripe count is 1..."
7520         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7521                 error "cannot migrate 20MB file"
7522         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7523                 error "cannot get stripe for $dir/20mb"
7524         [ $stripe_count -eq 1 ] ||
7525                 error "unexpected stripe count $stripe_count for 20MB file"
7526         rm -f "$dir/20mb"
7527         echo "done"
7528
7529         # Test 2: File is small enough to fit within the available space on
7530         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7531         # have at least an additional 1KB for each desired stripe for test 3
7532         echo -n "Setting stripe for 1GB test file..."
7533         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7534         echo "done"
7535         echo -n "Sizing 1GB test file..."
7536         # File size is 1GB + 3KB
7537         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7538         echo "done"
7539
7540         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7541         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7542         if (( avail > 524288 * OSTCOUNT )); then
7543                 echo -n "Migrating 1GB file..."
7544                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7545                         error "cannot migrate 1GB file"
7546                 echo "done"
7547                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7548                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7549                         error "cannot getstripe for 1GB file"
7550                 [ $stripe_count -eq 2 ] ||
7551                         error "unexpected stripe count $stripe_count != 2"
7552                 echo "done"
7553         fi
7554
7555         # Test 3: File is too large to fit within the available space on
7556         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7557         if [ $OSTCOUNT -ge 3 ]; then
7558                 # The required available space is calculated as
7559                 # file size (1GB + 3KB) / OST count (3).
7560                 local kb_per_ost=349526
7561
7562                 echo -n "Migrating 1GB file with limit..."
7563                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7564                         error "cannot migrate 1GB file with limit"
7565                 echo "done"
7566
7567                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7568                 echo -n "Verifying 1GB autostripe count with limited space..."
7569                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7570                         error "unexpected stripe count $stripe_count (min 3)"
7571                 echo "done"
7572         fi
7573
7574         # clean up
7575         rm -rf $dir
7576 }
7577 run_test 56xc "lfs migration autostripe"
7578
7579 test_56xd() {
7580         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7581
7582         local dir=$DIR/$tdir
7583         local f_mgrt=$dir/$tfile.mgrt
7584         local f_yaml=$dir/$tfile.yaml
7585         local f_copy=$dir/$tfile.copy
7586         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7587         local layout_copy="-c 2 -S 2M -i 1"
7588         local yamlfile=$dir/yamlfile
7589         local layout_before;
7590         local layout_after;
7591
7592         test_mkdir "$dir" || error "cannot create dir $dir"
7593         $LFS setstripe $layout_yaml $f_yaml ||
7594                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7595         $LFS getstripe --yaml $f_yaml > $yamlfile
7596         $LFS setstripe $layout_copy $f_copy ||
7597                 error "cannot setstripe $f_copy with layout $layout_copy"
7598         touch $f_mgrt
7599         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7600
7601         # 1. test option --yaml
7602         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7603                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7604         layout_before=$(get_layout_param $f_yaml)
7605         layout_after=$(get_layout_param $f_mgrt)
7606         [ "$layout_after" == "$layout_before" ] ||
7607                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7608
7609         # 2. test option --copy
7610         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7611                 error "cannot migrate $f_mgrt with --copy $f_copy"
7612         layout_before=$(get_layout_param $f_copy)
7613         layout_after=$(get_layout_param $f_mgrt)
7614         [ "$layout_after" == "$layout_before" ] ||
7615                 error "lfs_migrate --copy: $layout_after != $layout_before"
7616 }
7617 run_test 56xd "check lfs_migrate --yaml and --copy support"
7618
7619 test_56xe() {
7620         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7621
7622         local dir=$DIR/$tdir
7623         local f_comp=$dir/$tfile
7624         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7625         local layout_before=""
7626         local layout_after=""
7627
7628         test_mkdir "$dir" || error "cannot create dir $dir"
7629         $LFS setstripe $layout $f_comp ||
7630                 error "cannot setstripe $f_comp with layout $layout"
7631         layout_before=$(get_layout_param $f_comp)
7632         dd if=/dev/zero of=$f_comp bs=1M count=4
7633
7634         # 1. migrate a comp layout file by lfs_migrate
7635         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7636         layout_after=$(get_layout_param $f_comp)
7637         [ "$layout_before" == "$layout_after" ] ||
7638                 error "lfs_migrate: $layout_before != $layout_after"
7639
7640         # 2. migrate a comp layout file by lfs migrate
7641         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7642         layout_after=$(get_layout_param $f_comp)
7643         [ "$layout_before" == "$layout_after" ] ||
7644                 error "lfs migrate: $layout_before != $layout_after"
7645 }
7646 run_test 56xe "migrate a composite layout file"
7647
7648 test_56xf() {
7649         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7650
7651         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7652                 skip "Need server version at least 2.13.53"
7653
7654         local dir=$DIR/$tdir
7655         local f_comp=$dir/$tfile
7656         local layout="-E 1M -c1 -E -1 -c2"
7657         local fid_before=""
7658         local fid_after=""
7659
7660         test_mkdir "$dir" || error "cannot create dir $dir"
7661         $LFS setstripe $layout $f_comp ||
7662                 error "cannot setstripe $f_comp with layout $layout"
7663         fid_before=$($LFS getstripe --fid $f_comp)
7664         dd if=/dev/zero of=$f_comp bs=1M count=4
7665
7666         # 1. migrate a comp layout file to a comp layout
7667         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7668         fid_after=$($LFS getstripe --fid $f_comp)
7669         [ "$fid_before" == "$fid_after" ] ||
7670                 error "comp-to-comp migrate: $fid_before != $fid_after"
7671
7672         # 2. migrate a comp layout file to a plain layout
7673         $LFS migrate -c2 $f_comp ||
7674                 error "cannot migrate $f_comp by lfs migrate"
7675         fid_after=$($LFS getstripe --fid $f_comp)
7676         [ "$fid_before" == "$fid_after" ] ||
7677                 error "comp-to-plain migrate: $fid_before != $fid_after"
7678
7679         # 3. migrate a plain layout file to a comp layout
7680         $LFS migrate $layout $f_comp ||
7681                 error "cannot migrate $f_comp by lfs migrate"
7682         fid_after=$($LFS getstripe --fid $f_comp)
7683         [ "$fid_before" == "$fid_after" ] ||
7684                 error "plain-to-comp migrate: $fid_before != $fid_after"
7685 }
7686 run_test 56xf "FID is not lost during migration of a composite layout file"
7687
7688 check_file_ost_range() {
7689         local file="$1"
7690         shift
7691         local range="$*"
7692         local -a file_range
7693         local idx
7694
7695         file_range=($($LFS getstripe -y "$file" |
7696                 awk '/l_ost_idx:/ { print $NF }'))
7697
7698         if [[ "${#file_range[@]}" = 0 ]]; then
7699                 echo "No osts found for $file"
7700                 return 1
7701         fi
7702
7703         for idx in "${file_range[@]}"; do
7704                 [[ " $range " =~ " $idx " ]] ||
7705                         return 1
7706         done
7707
7708         return 0
7709 }
7710
7711 sub_test_56xg() {
7712         local stripe_opt="$1"
7713         local pool="$2"
7714         shift 2
7715         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7716
7717         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7718                 error "Fail to migrate $tfile on $pool"
7719         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7720                 error "$tfile is not in pool $pool"
7721         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7722                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7723 }
7724
7725 test_56xg() {
7726         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7727         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7728         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7729                 skip "Need MDS version newer than 2.14.52"
7730
7731         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7732         local -a pool_ranges=("0 0" "1 1" "0 1")
7733
7734         # init pools
7735         for i in "${!pool_names[@]}"; do
7736                 pool_add ${pool_names[$i]} ||
7737                         error "pool_add failed (pool: ${pool_names[$i]})"
7738                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7739                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7740         done
7741
7742         # init the file to migrate
7743         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7744                 error "Unable to create $tfile on OST1"
7745         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7746                 error "Unable to write on $tfile"
7747
7748         echo "1. migrate $tfile on pool ${pool_names[0]}"
7749         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7750
7751         echo "2. migrate $tfile on pool ${pool_names[2]}"
7752         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7753
7754         echo "3. migrate $tfile on pool ${pool_names[1]}"
7755         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7756
7757         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7758         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7759         echo
7760
7761         # Clean pools
7762         destroy_test_pools ||
7763                 error "pool_destroy failed"
7764 }
7765 run_test 56xg "lfs migrate pool support"
7766
7767 test_56y() {
7768         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7769                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7770
7771         local res=""
7772         local dir=$DIR/$tdir
7773         local f1=$dir/file1
7774         local f2=$dir/file2
7775
7776         test_mkdir -p $dir || error "creating dir $dir"
7777         touch $f1 || error "creating std file $f1"
7778         $MULTIOP $f2 H2c || error "creating released file $f2"
7779
7780         # a directory can be raid0, so ask only for files
7781         res=$($LFS find $dir -L raid0 -type f | wc -l)
7782         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7783
7784         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7785         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7786
7787         # only files can be released, so no need to force file search
7788         res=$($LFS find $dir -L released)
7789         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7790
7791         res=$($LFS find $dir -type f \! -L released)
7792         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7793 }
7794 run_test 56y "lfs find -L raid0|released"
7795
7796 test_56z() { # LU-4824
7797         # This checks to make sure 'lfs find' continues after errors
7798         # There are two classes of errors that should be caught:
7799         # - If multiple paths are provided, all should be searched even if one
7800         #   errors out
7801         # - If errors are encountered during the search, it should not terminate
7802         #   early
7803         local dir=$DIR/$tdir
7804         local i
7805
7806         test_mkdir $dir
7807         for i in d{0..9}; do
7808                 test_mkdir $dir/$i
7809                 touch $dir/$i/$tfile
7810         done
7811         $LFS find $DIR/non_existent_dir $dir &&
7812                 error "$LFS find did not return an error"
7813         # Make a directory unsearchable. This should NOT be the last entry in
7814         # directory order.  Arbitrarily pick the 6th entry
7815         chmod 700 $($LFS find $dir -type d | sed '6!d')
7816
7817         $RUNAS $LFS find $DIR/non_existent $dir
7818         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7819
7820         # The user should be able to see 10 directories and 9 files
7821         (( count == 19 )) ||
7822                 error "$LFS find found $count != 19 entries after error"
7823 }
7824 run_test 56z "lfs find should continue after an error"
7825
7826 test_56aa() { # LU-5937
7827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7828
7829         local dir=$DIR/$tdir
7830
7831         mkdir $dir
7832         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7833
7834         createmany -o $dir/striped_dir/${tfile}- 1024
7835         local dirs=$($LFS find --size +8k $dir/)
7836
7837         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7838 }
7839 run_test 56aa "lfs find --size under striped dir"
7840
7841 test_56ab() { # LU-10705
7842         test_mkdir $DIR/$tdir
7843         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7844         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7845         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7846         # Flush writes to ensure valid blocks.  Need to be more thorough for
7847         # ZFS, since blocks are not allocated/returned to client immediately.
7848         sync_all_data
7849         wait_zfs_commit ost1 2
7850         cancel_lru_locks osc
7851         ls -ls $DIR/$tdir
7852
7853         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7854
7855         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7856
7857         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7858         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7859
7860         rm -f $DIR/$tdir/$tfile.[123]
7861 }
7862 run_test 56ab "lfs find --blocks"
7863
7864 # LU-11188
7865 test_56aca() {
7866         local dir="$DIR/$tdir"
7867         local perms=(001 002 003 004 005 006 007
7868                      010 020 030 040 050 060 070
7869                      100 200 300 400 500 600 700
7870                      111 222 333 444 555 666 777)
7871         local perm_minus=(8 8 4 8 4 4 2
7872                           8 8 4 8 4 4 2
7873                           8 8 4 8 4 4 2
7874                           4 4 2 4 2 2 1)
7875         local perm_slash=(8  8 12  8 12 12 14
7876                           8  8 12  8 12 12 14
7877                           8  8 12  8 12 12 14
7878                          16 16 24 16 24 24 28)
7879
7880         test_mkdir "$dir"
7881         for perm in ${perms[*]}; do
7882                 touch "$dir/$tfile.$perm"
7883                 chmod $perm "$dir/$tfile.$perm"
7884         done
7885
7886         for ((i = 0; i < ${#perms[*]}; i++)); do
7887                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7888                 (( $num == 1 )) ||
7889                         error "lfs find -perm ${perms[i]}:"\
7890                               "$num != 1"
7891
7892                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7893                 (( $num == ${perm_minus[i]} )) ||
7894                         error "lfs find -perm -${perms[i]}:"\
7895                               "$num != ${perm_minus[i]}"
7896
7897                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7898                 (( $num == ${perm_slash[i]} )) ||
7899                         error "lfs find -perm /${perms[i]}:"\
7900                               "$num != ${perm_slash[i]}"
7901         done
7902 }
7903 run_test 56aca "check lfs find -perm with octal representation"
7904
7905 test_56acb() {
7906         local dir=$DIR/$tdir
7907         # p is the permission of write and execute for user, group and other
7908         # without the umask. It is used to test +wx.
7909         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7910         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7911         local symbolic=(+t  a+t u+t g+t o+t
7912                         g+s u+s o+s +s o+sr
7913                         o=r,ug+o,u+w
7914                         u+ g+ o+ a+ ugo+
7915                         u- g- o- a- ugo-
7916                         u= g= o= a= ugo=
7917                         o=r,ug+o,u+w u=r,a+u,u+w
7918                         g=r,ugo=g,u+w u+x,+X +X
7919                         u+x,u+X u+X u+x,g+X o+r,+X
7920                         u+x,go+X +wx +rwx)
7921
7922         test_mkdir $dir
7923         for perm in ${perms[*]}; do
7924                 touch "$dir/$tfile.$perm"
7925                 chmod $perm "$dir/$tfile.$perm"
7926         done
7927
7928         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7929                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7930
7931                 (( $num == 1 )) ||
7932                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7933         done
7934 }
7935 run_test 56acb "check lfs find -perm with symbolic representation"
7936
7937 test_56acc() {
7938         local dir=$DIR/$tdir
7939         local tests="17777 787 789 abcd
7940                 ug=uu ug=a ug=gu uo=ou urw
7941                 u+xg+x a=r,u+x,"
7942
7943         test_mkdir $dir
7944         for err in $tests; do
7945                 if $LFS find $dir -perm $err 2>/dev/null; then
7946                         error "lfs find -perm $err: parsing should have failed"
7947                 fi
7948         done
7949 }
7950 run_test 56acc "check parsing error for lfs find -perm"
7951
7952 test_56ba() {
7953         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7954                 skip "Need MDS version at least 2.10.50"
7955
7956         # Create composite files with one component
7957         local dir=$DIR/$tdir
7958
7959         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7960         # Create composite files with three components
7961         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7962         # Create non-composite files
7963         createmany -o $dir/${tfile}- 10
7964
7965         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7966
7967         [[ $nfiles == 10 ]] ||
7968                 error "lfs find -E 1M found $nfiles != 10 files"
7969
7970         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7971         [[ $nfiles == 25 ]] ||
7972                 error "lfs find ! -E 1M found $nfiles != 25 files"
7973
7974         # All files have a component that starts at 0
7975         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7976         [[ $nfiles == 35 ]] ||
7977                 error "lfs find --component-start 0 - $nfiles != 35 files"
7978
7979         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7980         [[ $nfiles == 15 ]] ||
7981                 error "lfs find --component-start 2M - $nfiles != 15 files"
7982
7983         # All files created here have a componenet that does not starts at 2M
7984         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7985         [[ $nfiles == 35 ]] ||
7986                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7987
7988         # Find files with a specified number of components
7989         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7990         [[ $nfiles == 15 ]] ||
7991                 error "lfs find --component-count 3 - $nfiles != 15 files"
7992
7993         # Remember non-composite files have a component count of zero
7994         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7995         [[ $nfiles == 10 ]] ||
7996                 error "lfs find --component-count 0 - $nfiles != 10 files"
7997
7998         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7999         [[ $nfiles == 20 ]] ||
8000                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8001
8002         # All files have a flag called "init"
8003         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8004         [[ $nfiles == 35 ]] ||
8005                 error "lfs find --component-flags init - $nfiles != 35 files"
8006
8007         # Multi-component files will have a component not initialized
8008         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8009         [[ $nfiles == 15 ]] ||
8010                 error "lfs find !--component-flags init - $nfiles != 15 files"
8011
8012         rm -rf $dir
8013
8014 }
8015 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8016
8017 test_56ca() {
8018         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8019                 skip "Need MDS version at least 2.10.57"
8020
8021         local td=$DIR/$tdir
8022         local tf=$td/$tfile
8023         local dir
8024         local nfiles
8025         local cmd
8026         local i
8027         local j
8028
8029         # create mirrored directories and mirrored files
8030         mkdir $td || error "mkdir $td failed"
8031         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8032         createmany -o $tf- 10 || error "create $tf- failed"
8033
8034         for i in $(seq 2); do
8035                 dir=$td/dir$i
8036                 mkdir $dir || error "mkdir $dir failed"
8037                 $LFS mirror create -N$((3 + i)) $dir ||
8038                         error "create mirrored dir $dir failed"
8039                 createmany -o $dir/$tfile- 10 ||
8040                         error "create $dir/$tfile- failed"
8041         done
8042
8043         # change the states of some mirrored files
8044         echo foo > $tf-6
8045         for i in $(seq 2); do
8046                 dir=$td/dir$i
8047                 for j in $(seq 4 9); do
8048                         echo foo > $dir/$tfile-$j
8049                 done
8050         done
8051
8052         # find mirrored files with specific mirror count
8053         cmd="$LFS find --mirror-count 3 --type f $td"
8054         nfiles=$($cmd | wc -l)
8055         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8056
8057         cmd="$LFS find ! --mirror-count 3 --type f $td"
8058         nfiles=$($cmd | wc -l)
8059         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8060
8061         cmd="$LFS find --mirror-count +2 --type f $td"
8062         nfiles=$($cmd | wc -l)
8063         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8064
8065         cmd="$LFS find --mirror-count -6 --type f $td"
8066         nfiles=$($cmd | wc -l)
8067         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8068
8069         # find mirrored files with specific file state
8070         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8071         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8072
8073         cmd="$LFS find --mirror-state=ro --type f $td"
8074         nfiles=$($cmd | wc -l)
8075         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8076
8077         cmd="$LFS find ! --mirror-state=ro --type f $td"
8078         nfiles=$($cmd | wc -l)
8079         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8080
8081         cmd="$LFS find --mirror-state=wp --type f $td"
8082         nfiles=$($cmd | wc -l)
8083         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8084
8085         cmd="$LFS find ! --mirror-state=sp --type f $td"
8086         nfiles=$($cmd | wc -l)
8087         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8088 }
8089 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8090
8091 test_56da() { # LU-14179
8092         local path=$DIR/$tdir
8093
8094         test_mkdir $path
8095         cd $path
8096
8097         local longdir=$(str_repeat 'a' 255)
8098
8099         for i in {1..15}; do
8100                 path=$path/$longdir
8101                 test_mkdir $longdir
8102                 cd $longdir
8103         done
8104
8105         local len=${#path}
8106         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8107
8108         test_mkdir $lastdir
8109         cd $lastdir
8110         # PATH_MAX-1
8111         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8112
8113         # NAME_MAX
8114         touch $(str_repeat 'f' 255)
8115
8116         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8117                 error "lfs find reported an error"
8118
8119         rm -rf $DIR/$tdir
8120 }
8121 run_test 56da "test lfs find with long paths"
8122
8123 test_57a() {
8124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8125         # note test will not do anything if MDS is not local
8126         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8127                 skip_env "ldiskfs only test"
8128         fi
8129         remote_mds_nodsh && skip "remote MDS with nodsh"
8130
8131         local MNTDEV="osd*.*MDT*.mntdev"
8132         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8133         [ -z "$DEV" ] && error "can't access $MNTDEV"
8134         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8135                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8136                         error "can't access $DEV"
8137                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8138                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8139                 rm $TMP/t57a.dump
8140         done
8141 }
8142 run_test 57a "verify MDS filesystem created with large inodes =="
8143
8144 test_57b() {
8145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8146         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8147                 skip_env "ldiskfs only test"
8148         fi
8149         remote_mds_nodsh && skip "remote MDS with nodsh"
8150
8151         local dir=$DIR/$tdir
8152         local filecount=100
8153         local file1=$dir/f1
8154         local fileN=$dir/f$filecount
8155
8156         rm -rf $dir || error "removing $dir"
8157         test_mkdir -c1 $dir
8158         local mdtidx=$($LFS getstripe -m $dir)
8159         local mdtname=MDT$(printf %04x $mdtidx)
8160         local facet=mds$((mdtidx + 1))
8161
8162         echo "mcreating $filecount files"
8163         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8164
8165         # verify that files do not have EAs yet
8166         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8167                 error "$file1 has an EA"
8168         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8169                 error "$fileN has an EA"
8170
8171         sync
8172         sleep 1
8173         df $dir  #make sure we get new statfs data
8174         local mdsfree=$(do_facet $facet \
8175                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8176         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8177         local file
8178
8179         echo "opening files to create objects/EAs"
8180         for file in $(seq -f $dir/f%g 1 $filecount); do
8181                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8182                         error "opening $file"
8183         done
8184
8185         # verify that files have EAs now
8186         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8187         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8188
8189         sleep 1  #make sure we get new statfs data
8190         df $dir
8191         local mdsfree2=$(do_facet $facet \
8192                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8193         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8194
8195         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8196                 if [ "$mdsfree" != "$mdsfree2" ]; then
8197                         error "MDC before $mdcfree != after $mdcfree2"
8198                 else
8199                         echo "MDC before $mdcfree != after $mdcfree2"
8200                         echo "unable to confirm if MDS has large inodes"
8201                 fi
8202         fi
8203         rm -rf $dir
8204 }
8205 run_test 57b "default LOV EAs are stored inside large inodes ==="
8206
8207 test_58() {
8208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8209         [ -z "$(which wiretest 2>/dev/null)" ] &&
8210                         skip_env "could not find wiretest"
8211
8212         wiretest
8213 }
8214 run_test 58 "verify cross-platform wire constants =============="
8215
8216 test_59() {
8217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8218
8219         echo "touch 130 files"
8220         createmany -o $DIR/f59- 130
8221         echo "rm 130 files"
8222         unlinkmany $DIR/f59- 130
8223         sync
8224         # wait for commitment of removal
8225         wait_delete_completed
8226 }
8227 run_test 59 "verify cancellation of llog records async ========="
8228
8229 TEST60_HEAD="test_60 run $RANDOM"
8230 test_60a() {
8231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8232         remote_mgs_nodsh && skip "remote MGS with nodsh"
8233         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8234                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8235                         skip_env "missing subtest run-llog.sh"
8236
8237         log "$TEST60_HEAD - from kernel mode"
8238         do_facet mgs "$LCTL dk > /dev/null"
8239         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8240         do_facet mgs $LCTL dk > $TMP/$tfile
8241
8242         # LU-6388: test llog_reader
8243         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8244         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8245         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8246                         skip_env "missing llog_reader"
8247         local fstype=$(facet_fstype mgs)
8248         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8249                 skip_env "Only for ldiskfs or zfs type mgs"
8250
8251         local mntpt=$(facet_mntpt mgs)
8252         local mgsdev=$(mgsdevname 1)
8253         local fid_list
8254         local fid
8255         local rec_list
8256         local rec
8257         local rec_type
8258         local obj_file
8259         local path
8260         local seq
8261         local oid
8262         local pass=true
8263
8264         #get fid and record list
8265         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8266                 tail -n 4))
8267         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8268                 tail -n 4))
8269         #remount mgs as ldiskfs or zfs type
8270         stop mgs || error "stop mgs failed"
8271         mount_fstype mgs || error "remount mgs failed"
8272         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8273                 fid=${fid_list[i]}
8274                 rec=${rec_list[i]}
8275                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8276                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8277                 oid=$((16#$oid))
8278
8279                 case $fstype in
8280                         ldiskfs )
8281                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8282                         zfs )
8283                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8284                 esac
8285                 echo "obj_file is $obj_file"
8286                 do_facet mgs $llog_reader $obj_file
8287
8288                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8289                         awk '{ print $3 }' | sed -e "s/^type=//g")
8290                 if [ $rec_type != $rec ]; then
8291                         echo "FAILED test_60a wrong record type $rec_type," \
8292                               "should be $rec"
8293                         pass=false
8294                         break
8295                 fi
8296
8297                 #check obj path if record type is LLOG_LOGID_MAGIC
8298                 if [ "$rec" == "1064553b" ]; then
8299                         path=$(do_facet mgs $llog_reader $obj_file |
8300                                 grep "path=" | awk '{ print $NF }' |
8301                                 sed -e "s/^path=//g")
8302                         if [ $obj_file != $mntpt/$path ]; then
8303                                 echo "FAILED test_60a wrong obj path" \
8304                                       "$montpt/$path, should be $obj_file"
8305                                 pass=false
8306                                 break
8307                         fi
8308                 fi
8309         done
8310         rm -f $TMP/$tfile
8311         #restart mgs before "error", otherwise it will block the next test
8312         stop mgs || error "stop mgs failed"
8313         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8314         $pass || error "test failed, see FAILED test_60a messages for specifics"
8315 }
8316 run_test 60a "llog_test run from kernel module and test llog_reader"
8317
8318 test_60b() { # bug 6411
8319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8320
8321         dmesg > $DIR/$tfile
8322         LLOG_COUNT=$(do_facet mgs dmesg |
8323                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8324                           /llog_[a-z]*.c:[0-9]/ {
8325                                 if (marker)
8326                                         from_marker++
8327                                 from_begin++
8328                           }
8329                           END {
8330                                 if (marker)
8331                                         print from_marker
8332                                 else
8333                                         print from_begin
8334                           }")
8335
8336         [[ $LLOG_COUNT -gt 120 ]] &&
8337                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8338 }
8339 run_test 60b "limit repeated messages from CERROR/CWARN"
8340
8341 test_60c() {
8342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8343
8344         echo "create 5000 files"
8345         createmany -o $DIR/f60c- 5000
8346 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8347         lctl set_param fail_loc=0x80000137
8348         unlinkmany $DIR/f60c- 5000
8349         lctl set_param fail_loc=0
8350 }
8351 run_test 60c "unlink file when mds full"
8352
8353 test_60d() {
8354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8355
8356         SAVEPRINTK=$(lctl get_param -n printk)
8357         # verify "lctl mark" is even working"
8358         MESSAGE="test message ID $RANDOM $$"
8359         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8360         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8361
8362         lctl set_param printk=0 || error "set lnet.printk failed"
8363         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8364         MESSAGE="new test message ID $RANDOM $$"
8365         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8366         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8367         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8368
8369         lctl set_param -n printk="$SAVEPRINTK"
8370 }
8371 run_test 60d "test printk console message masking"
8372
8373 test_60e() {
8374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8375         remote_mds_nodsh && skip "remote MDS with nodsh"
8376
8377         touch $DIR/$tfile
8378 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8379         do_facet mds1 lctl set_param fail_loc=0x15b
8380         rm $DIR/$tfile
8381 }
8382 run_test 60e "no space while new llog is being created"
8383
8384 test_60f() {
8385         local old_path=$($LCTL get_param -n debug_path)
8386
8387         stack_trap "$LCTL set_param debug_path=$old_path"
8388         stack_trap "rm -f $TMP/$tfile*"
8389         rm -f $TMP/$tfile* 2> /dev/null
8390         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8391         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8392         test_mkdir $DIR/$tdir
8393         # retry in case the open is cached and not released
8394         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8395                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8396                 sleep 0.1
8397         done
8398         ls $TMP/$tfile*
8399         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8400 }
8401 run_test 60f "change debug_path works"
8402
8403 test_60g() {
8404         local pid
8405         local i
8406
8407         test_mkdir -c $MDSCOUNT $DIR/$tdir
8408
8409         (
8410                 local index=0
8411                 while true; do
8412                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8413                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8414                                 2>/dev/null
8415                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8416                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8417                         index=$((index + 1))
8418                 done
8419         ) &
8420
8421         pid=$!
8422
8423         for i in {0..100}; do
8424                 # define OBD_FAIL_OSD_TXN_START    0x19a
8425                 local index=$((i % MDSCOUNT + 1))
8426
8427                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8428                         > /dev/null
8429                 sleep 0.01
8430         done
8431
8432         kill -9 $pid
8433
8434         for i in $(seq $MDSCOUNT); do
8435                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8436         done
8437
8438         mkdir $DIR/$tdir/new || error "mkdir failed"
8439         rmdir $DIR/$tdir/new || error "rmdir failed"
8440
8441         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8442                 -t namespace
8443         for i in $(seq $MDSCOUNT); do
8444                 wait_update_facet mds$i "$LCTL get_param -n \
8445                         mdd.$(facet_svc mds$i).lfsck_namespace |
8446                         awk '/^status/ { print \\\$2 }'" "completed"
8447         done
8448
8449         ls -R $DIR/$tdir || error "ls failed"
8450         rm -rf $DIR/$tdir || error "rmdir failed"
8451 }
8452 run_test 60g "transaction abort won't cause MDT hung"
8453
8454 test_60h() {
8455         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8456                 skip "Need MDS version at least 2.12.52"
8457         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8458
8459         local f
8460
8461         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8462         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8463         for fail_loc in 0x80000188 0x80000189; do
8464                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8465                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8466                         error "mkdir $dir-$fail_loc failed"
8467                 for i in {0..10}; do
8468                         # create may fail on missing stripe
8469                         echo $i > $DIR/$tdir-$fail_loc/$i
8470                 done
8471                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8472                         error "getdirstripe $tdir-$fail_loc failed"
8473                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8474                         error "migrate $tdir-$fail_loc failed"
8475                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8476                         error "getdirstripe $tdir-$fail_loc failed"
8477                 pushd $DIR/$tdir-$fail_loc
8478                 for f in *; do
8479                         echo $f | cmp $f - || error "$f data mismatch"
8480                 done
8481                 popd
8482                 rm -rf $DIR/$tdir-$fail_loc
8483         done
8484 }
8485 run_test 60h "striped directory with missing stripes can be accessed"
8486
8487 function t60i_load() {
8488         mkdir $DIR/$tdir
8489         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8490         $LCTL set_param fail_loc=0x131c fail_val=1
8491         for ((i=0; i<5000; i++)); do
8492                 touch $DIR/$tdir/f$i
8493         done
8494 }
8495
8496 test_60i() {
8497         changelog_register || error "changelog_register failed"
8498         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8499         changelog_users $SINGLEMDS | grep -q $cl_user ||
8500                 error "User $cl_user not found in changelog_users"
8501         changelog_chmask "ALL"
8502         t60i_load &
8503         local PID=$!
8504         for((i=0; i<100; i++)); do
8505                 changelog_dump >/dev/null ||
8506                         error "can't read changelog"
8507         done
8508         kill $PID
8509         wait $PID
8510         changelog_deregister || error "changelog_deregister failed"
8511         $LCTL set_param fail_loc=0
8512 }
8513 run_test 60i "llog: new record vs reader race"
8514
8515 test_61a() {
8516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8517
8518         f="$DIR/f61"
8519         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8520         cancel_lru_locks osc
8521         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8522         sync
8523 }
8524 run_test 61a "mmap() writes don't make sync hang ================"
8525
8526 test_61b() {
8527         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8528 }
8529 run_test 61b "mmap() of unstriped file is successful"
8530
8531 # bug 2330 - insufficient obd_match error checking causes LBUG
8532 test_62() {
8533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8534
8535         f="$DIR/f62"
8536         echo foo > $f
8537         cancel_lru_locks osc
8538         lctl set_param fail_loc=0x405
8539         cat $f && error "cat succeeded, expect -EIO"
8540         lctl set_param fail_loc=0
8541 }
8542 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8543 # match every page all of the time.
8544 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8545
8546 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8547 # Though this test is irrelevant anymore, it helped to reveal some
8548 # other grant bugs (LU-4482), let's keep it.
8549 test_63a() {   # was test_63
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551
8552         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8553
8554         for i in `seq 10` ; do
8555                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8556                 sleep 5
8557                 kill $!
8558                 sleep 1
8559         done
8560
8561         rm -f $DIR/f63 || true
8562 }
8563 run_test 63a "Verify oig_wait interruption does not crash ======="
8564
8565 # bug 2248 - async write errors didn't return to application on sync
8566 # bug 3677 - async write errors left page locked
8567 test_63b() {
8568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8569
8570         debugsave
8571         lctl set_param debug=-1
8572
8573         # ensure we have a grant to do async writes
8574         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8575         rm $DIR/$tfile
8576
8577         sync    # sync lest earlier test intercept the fail_loc
8578
8579         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8580         lctl set_param fail_loc=0x80000406
8581         $MULTIOP $DIR/$tfile Owy && \
8582                 error "sync didn't return ENOMEM"
8583         sync; sleep 2; sync     # do a real sync this time to flush page
8584         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8585                 error "locked page left in cache after async error" || true
8586         debugrestore
8587 }
8588 run_test 63b "async write errors should be returned to fsync ==="
8589
8590 test_64a () {
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592
8593         lfs df $DIR
8594         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8595 }
8596 run_test 64a "verify filter grant calculations (in kernel) ====="
8597
8598 test_64b () {
8599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8600
8601         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8602 }
8603 run_test 64b "check out-of-space detection on client"
8604
8605 test_64c() {
8606         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8607 }
8608 run_test 64c "verify grant shrink"
8609
8610 import_param() {
8611         local tgt=$1
8612         local param=$2
8613
8614         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8615 }
8616
8617 # this does exactly what osc_request.c:osc_announce_cached() does in
8618 # order to calculate max amount of grants to ask from server
8619 want_grant() {
8620         local tgt=$1
8621
8622         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8623         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8624
8625         ((rpc_in_flight++));
8626         nrpages=$((nrpages * rpc_in_flight))
8627
8628         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8629
8630         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8631
8632         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8633         local undirty=$((nrpages * PAGE_SIZE))
8634
8635         local max_extent_pages
8636         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8637         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8638         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8639         local grant_extent_tax
8640         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8641
8642         undirty=$((undirty + nrextents * grant_extent_tax))
8643
8644         echo $undirty
8645 }
8646
8647 # this is size of unit for grant allocation. It should be equal to
8648 # what tgt_grant.c:tgt_grant_chunk() calculates
8649 grant_chunk() {
8650         local tgt=$1
8651         local max_brw_size
8652         local grant_extent_tax
8653
8654         max_brw_size=$(import_param $tgt max_brw_size)
8655
8656         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8657
8658         echo $(((max_brw_size + grant_extent_tax) * 2))
8659 }
8660
8661 test_64d() {
8662         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8663                 skip "OST < 2.10.55 doesn't limit grants enough"
8664
8665         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8666
8667         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8668                 skip "no grant_param connect flag"
8669
8670         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8671
8672         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8673         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8674
8675
8676         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8677         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8678
8679         $LFS setstripe $DIR/$tfile -i 0 -c 1
8680         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8681         ddpid=$!
8682
8683         while kill -0 $ddpid; do
8684                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8685
8686                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8687                         kill $ddpid
8688                         error "cur_grant $cur_grant > $max_cur_granted"
8689                 fi
8690
8691                 sleep 1
8692         done
8693 }
8694 run_test 64d "check grant limit exceed"
8695
8696 check_grants() {
8697         local tgt=$1
8698         local expected=$2
8699         local msg=$3
8700         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8701
8702         ((cur_grants == expected)) ||
8703                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8704 }
8705
8706 round_up_p2() {
8707         echo $((($1 + $2 - 1) & ~($2 - 1)))
8708 }
8709
8710 test_64e() {
8711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8712         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8713                 skip "Need OSS version at least 2.11.56"
8714
8715         # Remount client to reset grant
8716         remount_client $MOUNT || error "failed to remount client"
8717         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8718
8719         local init_grants=$(import_param $osc_tgt initial_grant)
8720
8721         check_grants $osc_tgt $init_grants "init grants"
8722
8723         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8724         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8725         local gbs=$(import_param $osc_tgt grant_block_size)
8726
8727         # write random number of bytes from max_brw_size / 4 to max_brw_size
8728         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8729         # align for direct io
8730         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8731         # round to grant consumption unit
8732         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8733
8734         local grants=$((wb_round_up + extent_tax))
8735
8736         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8737
8738         # define OBD_FAIL_TGT_NO_GRANT 0x725
8739         # make the server not grant more back
8740         do_facet ost1 $LCTL set_param fail_loc=0x725
8741         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8742
8743         do_facet ost1 $LCTL set_param fail_loc=0
8744
8745         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8746
8747         rm -f $DIR/$tfile || error "rm failed"
8748
8749         # Remount client to reset grant
8750         remount_client $MOUNT || error "failed to remount client"
8751         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8752
8753         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8754
8755         # define OBD_FAIL_TGT_NO_GRANT 0x725
8756         # make the server not grant more back
8757         do_facet ost1 $LCTL set_param fail_loc=0x725
8758         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8759         do_facet ost1 $LCTL set_param fail_loc=0
8760
8761         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8762 }
8763 run_test 64e "check grant consumption (no grant allocation)"
8764
8765 test_64f() {
8766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8767
8768         # Remount client to reset grant
8769         remount_client $MOUNT || error "failed to remount client"
8770         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8771
8772         local init_grants=$(import_param $osc_tgt initial_grant)
8773         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8774         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8775         local gbs=$(import_param $osc_tgt grant_block_size)
8776         local chunk=$(grant_chunk $osc_tgt)
8777
8778         # write random number of bytes from max_brw_size / 4 to max_brw_size
8779         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8780         # align for direct io
8781         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8782         # round to grant consumption unit
8783         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8784
8785         local grants=$((wb_round_up + extent_tax))
8786
8787         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8788         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8789                 error "error writing to $DIR/$tfile"
8790
8791         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8792                 "direct io with grant allocation"
8793
8794         rm -f $DIR/$tfile || error "rm failed"
8795
8796         # Remount client to reset grant
8797         remount_client $MOUNT || error "failed to remount client"
8798         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8799
8800         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8801
8802         local cmd="oO_WRONLY:w${write_bytes}_yc"
8803
8804         $MULTIOP $DIR/$tfile $cmd &
8805         MULTIPID=$!
8806         sleep 1
8807
8808         check_grants $osc_tgt $((init_grants - grants)) \
8809                 "buffered io, not write rpc"
8810
8811         kill -USR1 $MULTIPID
8812         wait
8813
8814         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8815                 "buffered io, one RPC"
8816 }
8817 run_test 64f "check grant consumption (with grant allocation)"
8818
8819 # bug 1414 - set/get directories' stripe info
8820 test_65a() {
8821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8822
8823         test_mkdir $DIR/$tdir
8824         touch $DIR/$tdir/f1
8825         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8826 }
8827 run_test 65a "directory with no stripe info"
8828
8829 test_65b() {
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831
8832         test_mkdir $DIR/$tdir
8833         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8834
8835         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8836                                                 error "setstripe"
8837         touch $DIR/$tdir/f2
8838         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8839 }
8840 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8841
8842 test_65c() {
8843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8844         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8845
8846         test_mkdir $DIR/$tdir
8847         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8848
8849         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8850                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8851         touch $DIR/$tdir/f3
8852         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8853 }
8854 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8855
8856 test_65d() {
8857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8858
8859         test_mkdir $DIR/$tdir
8860         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8861         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8862
8863         if [[ $STRIPECOUNT -le 0 ]]; then
8864                 sc=1
8865         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8866                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8867                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8868         else
8869                 sc=$(($STRIPECOUNT - 1))
8870         fi
8871         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8872         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8873         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8874                 error "lverify failed"
8875 }
8876 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8877
8878 test_65e() {
8879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8880
8881         test_mkdir $DIR/$tdir
8882
8883         $LFS setstripe $DIR/$tdir || error "setstripe"
8884         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8885                                         error "no stripe info failed"
8886         touch $DIR/$tdir/f6
8887         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8888 }
8889 run_test 65e "directory setstripe defaults"
8890
8891 test_65f() {
8892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8893
8894         test_mkdir $DIR/${tdir}f
8895         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8896                 error "setstripe succeeded" || true
8897 }
8898 run_test 65f "dir setstripe permission (should return error) ==="
8899
8900 test_65g() {
8901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8902
8903         test_mkdir $DIR/$tdir
8904         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8905
8906         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8907                 error "setstripe -S failed"
8908         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8909         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8910                 error "delete default stripe failed"
8911 }
8912 run_test 65g "directory setstripe -d"
8913
8914 test_65h() {
8915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8916
8917         test_mkdir $DIR/$tdir
8918         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8919
8920         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8921                 error "setstripe -S failed"
8922         test_mkdir $DIR/$tdir/dd1
8923         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8924                 error "stripe info inherit failed"
8925 }
8926 run_test 65h "directory stripe info inherit ===================="
8927
8928 test_65i() {
8929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8930
8931         save_layout_restore_at_exit $MOUNT
8932
8933         # bug6367: set non-default striping on root directory
8934         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8935
8936         # bug12836: getstripe on -1 default directory striping
8937         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8938
8939         # bug12836: getstripe -v on -1 default directory striping
8940         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8941
8942         # bug12836: new find on -1 default directory striping
8943         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8944 }
8945 run_test 65i "various tests to set root directory striping"
8946
8947 test_65j() { # bug6367
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949
8950         sync; sleep 1
8951
8952         # if we aren't already remounting for each test, do so for this test
8953         if [ "$I_MOUNTED" = "yes" ]; then
8954                 cleanup || error "failed to unmount"
8955                 setup
8956         fi
8957
8958         save_layout_restore_at_exit $MOUNT
8959
8960         $LFS setstripe -d $MOUNT || error "setstripe failed"
8961 }
8962 run_test 65j "set default striping on root directory (bug 6367)="
8963
8964 cleanup_65k() {
8965         rm -rf $DIR/$tdir
8966         wait_delete_completed
8967         do_facet $SINGLEMDS "lctl set_param -n \
8968                 osp.$ost*MDT0000.max_create_count=$max_count"
8969         do_facet $SINGLEMDS "lctl set_param -n \
8970                 osp.$ost*MDT0000.create_count=$count"
8971         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8972         echo $INACTIVE_OSC "is Activate"
8973
8974         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8975 }
8976
8977 test_65k() { # bug11679
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8980         remote_mds_nodsh && skip "remote MDS with nodsh"
8981
8982         local disable_precreate=true
8983         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8984                 disable_precreate=false
8985
8986         echo "Check OST status: "
8987         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8988                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8989
8990         for OSC in $MDS_OSCS; do
8991                 echo $OSC "is active"
8992                 do_facet $SINGLEMDS lctl --device %$OSC activate
8993         done
8994
8995         for INACTIVE_OSC in $MDS_OSCS; do
8996                 local ost=$(osc_to_ost $INACTIVE_OSC)
8997                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8998                                lov.*md*.target_obd |
8999                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9000
9001                 mkdir -p $DIR/$tdir
9002                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9003                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9004
9005                 echo "Deactivate: " $INACTIVE_OSC
9006                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9007
9008                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9009                               osp.$ost*MDT0000.create_count")
9010                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9011                                   osp.$ost*MDT0000.max_create_count")
9012                 $disable_precreate &&
9013                         do_facet $SINGLEMDS "lctl set_param -n \
9014                                 osp.$ost*MDT0000.max_create_count=0"
9015
9016                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9017                         [ -f $DIR/$tdir/$idx ] && continue
9018                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9019                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9020                                 { cleanup_65k;
9021                                   error "setstripe $idx should succeed"; }
9022                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9023                 done
9024                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9025                 rmdir $DIR/$tdir
9026
9027                 do_facet $SINGLEMDS "lctl set_param -n \
9028                         osp.$ost*MDT0000.max_create_count=$max_count"
9029                 do_facet $SINGLEMDS "lctl set_param -n \
9030                         osp.$ost*MDT0000.create_count=$count"
9031                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9032                 echo $INACTIVE_OSC "is Activate"
9033
9034                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9035         done
9036 }
9037 run_test 65k "validate manual striping works properly with deactivated OSCs"
9038
9039 test_65l() { # bug 12836
9040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9041
9042         test_mkdir -p $DIR/$tdir/test_dir
9043         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9044         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9045 }
9046 run_test 65l "lfs find on -1 stripe dir ========================"
9047
9048 test_65m() {
9049         local layout=$(save_layout $MOUNT)
9050         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9051                 restore_layout $MOUNT $layout
9052                 error "setstripe should fail by non-root users"
9053         }
9054         true
9055 }
9056 run_test 65m "normal user can't set filesystem default stripe"
9057
9058 test_65n() {
9059         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9060         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9061                 skip "Need MDS version at least 2.12.50"
9062         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9063
9064         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9065         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9066         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9067
9068         save_layout_restore_at_exit $MOUNT
9069
9070         # new subdirectory under root directory should not inherit
9071         # the default layout from root
9072         local dir1=$MOUNT/$tdir-1
9073         mkdir $dir1 || error "mkdir $dir1 failed"
9074         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9075                 error "$dir1 shouldn't have LOV EA"
9076
9077         # delete the default layout on root directory
9078         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9079
9080         local dir2=$MOUNT/$tdir-2
9081         mkdir $dir2 || error "mkdir $dir2 failed"
9082         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9083                 error "$dir2 shouldn't have LOV EA"
9084
9085         # set a new striping pattern on root directory
9086         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9087         local new_def_stripe_size=$((def_stripe_size * 2))
9088         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9089                 error "set stripe size on $MOUNT failed"
9090
9091         # new file created in $dir2 should inherit the new stripe size from
9092         # the filesystem default
9093         local file2=$dir2/$tfile-2
9094         touch $file2 || error "touch $file2 failed"
9095
9096         local file2_stripe_size=$($LFS getstripe -S $file2)
9097         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9098         {
9099                 echo "file2_stripe_size: '$file2_stripe_size'"
9100                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9101                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9102         }
9103
9104         local dir3=$MOUNT/$tdir-3
9105         mkdir $dir3 || error "mkdir $dir3 failed"
9106         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9107         # the root layout, which is the actual default layout that will be used
9108         # when new files are created in $dir3.
9109         local dir3_layout=$(get_layout_param $dir3)
9110         local root_dir_layout=$(get_layout_param $MOUNT)
9111         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9112         {
9113                 echo "dir3_layout: '$dir3_layout'"
9114                 echo "root_dir_layout: '$root_dir_layout'"
9115                 error "$dir3 should show the default layout from $MOUNT"
9116         }
9117
9118         # set OST pool on root directory
9119         local pool=$TESTNAME
9120         pool_add $pool || error "add $pool failed"
9121         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9122                 error "add targets to $pool failed"
9123
9124         $LFS setstripe -p $pool $MOUNT ||
9125                 error "set OST pool on $MOUNT failed"
9126
9127         # new file created in $dir3 should inherit the pool from
9128         # the filesystem default
9129         local file3=$dir3/$tfile-3
9130         touch $file3 || error "touch $file3 failed"
9131
9132         local file3_pool=$($LFS getstripe -p $file3)
9133         [[ "$file3_pool" = "$pool" ]] ||
9134                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9135
9136         local dir4=$MOUNT/$tdir-4
9137         mkdir $dir4 || error "mkdir $dir4 failed"
9138         local dir4_layout=$(get_layout_param $dir4)
9139         root_dir_layout=$(get_layout_param $MOUNT)
9140         echo "$LFS getstripe -d $dir4"
9141         $LFS getstripe -d $dir4
9142         echo "$LFS getstripe -d $MOUNT"
9143         $LFS getstripe -d $MOUNT
9144         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9145         {
9146                 echo "dir4_layout: '$dir4_layout'"
9147                 echo "root_dir_layout: '$root_dir_layout'"
9148                 error "$dir4 should show the default layout from $MOUNT"
9149         }
9150
9151         # new file created in $dir4 should inherit the pool from
9152         # the filesystem default
9153         local file4=$dir4/$tfile-4
9154         touch $file4 || error "touch $file4 failed"
9155
9156         local file4_pool=$($LFS getstripe -p $file4)
9157         [[ "$file4_pool" = "$pool" ]] ||
9158                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9159
9160         # new subdirectory under non-root directory should inherit
9161         # the default layout from its parent directory
9162         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9163                 error "set directory layout on $dir4 failed"
9164
9165         local dir5=$dir4/$tdir-5
9166         mkdir $dir5 || error "mkdir $dir5 failed"
9167
9168         dir4_layout=$(get_layout_param $dir4)
9169         local dir5_layout=$(get_layout_param $dir5)
9170         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9171         {
9172                 echo "dir4_layout: '$dir4_layout'"
9173                 echo "dir5_layout: '$dir5_layout'"
9174                 error "$dir5 should inherit the default layout from $dir4"
9175         }
9176
9177         # though subdir under ROOT doesn't inherit default layout, but
9178         # its sub dir/file should be created with default layout.
9179         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9180         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9181                 skip "Need MDS version at least 2.12.59"
9182
9183         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9184         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9185         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9186
9187         if [ $default_lmv_hash == "none" ]; then
9188                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9189         else
9190                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9191                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9192         fi
9193
9194         $LFS setdirstripe -D -c 2 $MOUNT ||
9195                 error "setdirstripe -D -c 2 failed"
9196         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9197         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9198         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9199 }
9200 run_test 65n "don't inherit default layout from root for new subdirectories"
9201
9202 # bug 2543 - update blocks count on client
9203 test_66() {
9204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9205
9206         COUNT=${COUNT:-8}
9207         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9208         sync; sync_all_data; sync; sync_all_data
9209         cancel_lru_locks osc
9210         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9211         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9212 }
9213 run_test 66 "update inode blocks count on client ==============="
9214
9215 meminfo() {
9216         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9217 }
9218
9219 swap_used() {
9220         swapon -s | awk '($1 == "'$1'") { print $4 }'
9221 }
9222
9223 # bug5265, obdfilter oa2dentry return -ENOENT
9224 # #define OBD_FAIL_SRV_ENOENT 0x217
9225 test_69() {
9226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9227         remote_ost_nodsh && skip "remote OST with nodsh"
9228
9229         f="$DIR/$tfile"
9230         $LFS setstripe -c 1 -i 0 $f
9231
9232         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9233
9234         do_facet ost1 lctl set_param fail_loc=0x217
9235         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9236         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9237
9238         do_facet ost1 lctl set_param fail_loc=0
9239         $DIRECTIO write $f 0 2 || error "write error"
9240
9241         cancel_lru_locks osc
9242         $DIRECTIO read $f 0 1 || error "read error"
9243
9244         do_facet ost1 lctl set_param fail_loc=0x217
9245         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9246
9247         do_facet ost1 lctl set_param fail_loc=0
9248         rm -f $f
9249 }
9250 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9251
9252 test_71() {
9253         test_mkdir $DIR/$tdir
9254         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9255         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9256 }
9257 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9258
9259 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9261         [ "$RUNAS_ID" = "$UID" ] &&
9262                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9263         # Check that testing environment is properly set up. Skip if not
9264         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9265                 skip_env "User $RUNAS_ID does not exist - skipping"
9266
9267         touch $DIR/$tfile
9268         chmod 777 $DIR/$tfile
9269         chmod ug+s $DIR/$tfile
9270         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9271                 error "$RUNAS dd $DIR/$tfile failed"
9272         # See if we are still setuid/sgid
9273         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9274                 error "S/gid is not dropped on write"
9275         # Now test that MDS is updated too
9276         cancel_lru_locks mdc
9277         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9278                 error "S/gid is not dropped on MDS"
9279         rm -f $DIR/$tfile
9280 }
9281 run_test 72a "Test that remove suid works properly (bug5695) ===="
9282
9283 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9284         local perm
9285
9286         [ "$RUNAS_ID" = "$UID" ] &&
9287                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9288         [ "$RUNAS_ID" -eq 0 ] &&
9289                 skip_env "RUNAS_ID = 0 -- skipping"
9290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9291         # Check that testing environment is properly set up. Skip if not
9292         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9293                 skip_env "User $RUNAS_ID does not exist - skipping"
9294
9295         touch $DIR/${tfile}-f{g,u}
9296         test_mkdir $DIR/${tfile}-dg
9297         test_mkdir $DIR/${tfile}-du
9298         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9299         chmod g+s $DIR/${tfile}-{f,d}g
9300         chmod u+s $DIR/${tfile}-{f,d}u
9301         for perm in 777 2777 4777; do
9302                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9303                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9304                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9305                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9306         done
9307         true
9308 }
9309 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9310
9311 # bug 3462 - multiple simultaneous MDC requests
9312 test_73() {
9313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9314
9315         test_mkdir $DIR/d73-1
9316         test_mkdir $DIR/d73-2
9317         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9318         pid1=$!
9319
9320         lctl set_param fail_loc=0x80000129
9321         $MULTIOP $DIR/d73-1/f73-2 Oc &
9322         sleep 1
9323         lctl set_param fail_loc=0
9324
9325         $MULTIOP $DIR/d73-2/f73-3 Oc &
9326         pid3=$!
9327
9328         kill -USR1 $pid1
9329         wait $pid1 || return 1
9330
9331         sleep 25
9332
9333         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9334         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9335         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9336
9337         rm -rf $DIR/d73-*
9338 }
9339 run_test 73 "multiple MDC requests (should not deadlock)"
9340
9341 test_74a() { # bug 6149, 6184
9342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9343
9344         touch $DIR/f74a
9345         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9346         #
9347         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9348         # will spin in a tight reconnection loop
9349         $LCTL set_param fail_loc=0x8000030e
9350         # get any lock that won't be difficult - lookup works.
9351         ls $DIR/f74a
9352         $LCTL set_param fail_loc=0
9353         rm -f $DIR/f74a
9354         true
9355 }
9356 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9357
9358 test_74b() { # bug 13310
9359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9360
9361         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9362         #
9363         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9364         # will spin in a tight reconnection loop
9365         $LCTL set_param fail_loc=0x8000030e
9366         # get a "difficult" lock
9367         touch $DIR/f74b
9368         $LCTL set_param fail_loc=0
9369         rm -f $DIR/f74b
9370         true
9371 }
9372 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9373
9374 test_74c() {
9375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9376
9377         #define OBD_FAIL_LDLM_NEW_LOCK
9378         $LCTL set_param fail_loc=0x319
9379         touch $DIR/$tfile && error "touch successful"
9380         $LCTL set_param fail_loc=0
9381         true
9382 }
9383 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9384
9385 slab_lic=/sys/kernel/slab/lustre_inode_cache
9386 num_objects() {
9387         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9388         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9389                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9390 }
9391
9392 test_76a() { # Now for b=20433, added originally in b=1443
9393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9394
9395         cancel_lru_locks osc
9396         # there may be some slab objects cached per core
9397         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9398         local before=$(num_objects)
9399         local count=$((512 * cpus))
9400         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9401         local margin=$((count / 10))
9402         if [[ -f $slab_lic/aliases ]]; then
9403                 local aliases=$(cat $slab_lic/aliases)
9404                 (( aliases > 0 )) && margin=$((margin * aliases))
9405         fi
9406
9407         echo "before slab objects: $before"
9408         for i in $(seq $count); do
9409                 touch $DIR/$tfile
9410                 rm -f $DIR/$tfile
9411         done
9412         cancel_lru_locks osc
9413         local after=$(num_objects)
9414         echo "created: $count, after slab objects: $after"
9415         # shared slab counts are not very accurate, allow significant margin
9416         # the main goal is that the cache growth is not permanently > $count
9417         while (( after > before + margin )); do
9418                 sleep 1
9419                 after=$(num_objects)
9420                 wait=$((wait + 1))
9421                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9422                 if (( wait > 60 )); then
9423                         error "inode slab grew from $before+$margin to $after"
9424                 fi
9425         done
9426 }
9427 run_test 76a "confirm clients recycle inodes properly ===="
9428
9429 test_76b() {
9430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9431         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9432
9433         local count=512
9434         local before=$(num_objects)
9435
9436         for i in $(seq $count); do
9437                 mkdir $DIR/$tdir
9438                 rmdir $DIR/$tdir
9439         done
9440
9441         local after=$(num_objects)
9442         local wait=0
9443
9444         while (( after > before )); do
9445                 sleep 1
9446                 after=$(num_objects)
9447                 wait=$((wait + 1))
9448                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9449                 if (( wait > 60 )); then
9450                         error "inode slab grew from $before to $after"
9451                 fi
9452         done
9453
9454         echo "slab objects before: $before, after: $after"
9455 }
9456 run_test 76b "confirm clients recycle directory inodes properly ===="
9457
9458 export ORIG_CSUM=""
9459 set_checksums()
9460 {
9461         # Note: in sptlrpc modes which enable its own bulk checksum, the
9462         # original crc32_le bulk checksum will be automatically disabled,
9463         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9464         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9465         # In this case set_checksums() will not be no-op, because sptlrpc
9466         # bulk checksum will be enabled all through the test.
9467
9468         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9469         lctl set_param -n osc.*.checksums $1
9470         return 0
9471 }
9472
9473 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9474                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9475 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9476                              tr -d [] | head -n1)}
9477 set_checksum_type()
9478 {
9479         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9480         rc=$?
9481         log "set checksum type to $1, rc = $rc"
9482         return $rc
9483 }
9484
9485 get_osc_checksum_type()
9486 {
9487         # arugment 1: OST name, like OST0000
9488         ost=$1
9489         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9490                         sed 's/.*\[\(.*\)\].*/\1/g')
9491         rc=$?
9492         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9493         echo $checksum_type
9494 }
9495
9496 F77_TMP=$TMP/f77-temp
9497 F77SZ=8
9498 setup_f77() {
9499         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9500                 error "error writing to $F77_TMP"
9501 }
9502
9503 test_77a() { # bug 10889
9504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9505         $GSS && skip_env "could not run with gss"
9506
9507         [ ! -f $F77_TMP ] && setup_f77
9508         set_checksums 1
9509         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9510         set_checksums 0
9511         rm -f $DIR/$tfile
9512 }
9513 run_test 77a "normal checksum read/write operation"
9514
9515 test_77b() { # bug 10889
9516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9517         $GSS && skip_env "could not run with gss"
9518
9519         [ ! -f $F77_TMP ] && setup_f77
9520         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9521         $LCTL set_param fail_loc=0x80000409
9522         set_checksums 1
9523
9524         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9525                 error "dd error: $?"
9526         $LCTL set_param fail_loc=0
9527
9528         for algo in $CKSUM_TYPES; do
9529                 cancel_lru_locks osc
9530                 set_checksum_type $algo
9531                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9532                 $LCTL set_param fail_loc=0x80000408
9533                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9534                 $LCTL set_param fail_loc=0
9535         done
9536         set_checksums 0
9537         set_checksum_type $ORIG_CSUM_TYPE
9538         rm -f $DIR/$tfile
9539 }
9540 run_test 77b "checksum error on client write, read"
9541
9542 cleanup_77c() {
9543         trap 0
9544         set_checksums 0
9545         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9546         $check_ost &&
9547                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9548         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9549         $check_ost && [ -n "$ost_file_prefix" ] &&
9550                 do_facet ost1 rm -f ${ost_file_prefix}\*
9551 }
9552
9553 test_77c() {
9554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9555         $GSS && skip_env "could not run with gss"
9556         remote_ost_nodsh && skip "remote OST with nodsh"
9557
9558         local bad1
9559         local osc_file_prefix
9560         local osc_file
9561         local check_ost=false
9562         local ost_file_prefix
9563         local ost_file
9564         local orig_cksum
9565         local dump_cksum
9566         local fid
9567
9568         # ensure corruption will occur on first OSS/OST
9569         $LFS setstripe -i 0 $DIR/$tfile
9570
9571         [ ! -f $F77_TMP ] && setup_f77
9572         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9573                 error "dd write error: $?"
9574         fid=$($LFS path2fid $DIR/$tfile)
9575
9576         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9577         then
9578                 check_ost=true
9579                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9580                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9581         else
9582                 echo "OSS do not support bulk pages dump upon error"
9583         fi
9584
9585         osc_file_prefix=$($LCTL get_param -n debug_path)
9586         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9587
9588         trap cleanup_77c EXIT
9589
9590         set_checksums 1
9591         # enable bulk pages dump upon error on Client
9592         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9593         # enable bulk pages dump upon error on OSS
9594         $check_ost &&
9595                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9596
9597         # flush Client cache to allow next read to reach OSS
9598         cancel_lru_locks osc
9599
9600         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9601         $LCTL set_param fail_loc=0x80000408
9602         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9603         $LCTL set_param fail_loc=0
9604
9605         rm -f $DIR/$tfile
9606
9607         # check cksum dump on Client
9608         osc_file=$(ls ${osc_file_prefix}*)
9609         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9610         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9611         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9612         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9613         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9614                      cksum)
9615         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9616         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9617                 error "dump content does not match on Client"
9618
9619         $check_ost || skip "No need to check cksum dump on OSS"
9620
9621         # check cksum dump on OSS
9622         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9623         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9624         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9625         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9626         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9627                 error "dump content does not match on OSS"
9628
9629         cleanup_77c
9630 }
9631 run_test 77c "checksum error on client read with debug"
9632
9633 test_77d() { # bug 10889
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635         $GSS && skip_env "could not run with gss"
9636
9637         stack_trap "rm -f $DIR/$tfile"
9638         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9639         $LCTL set_param fail_loc=0x80000409
9640         set_checksums 1
9641         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9642                 error "direct write: rc=$?"
9643         $LCTL set_param fail_loc=0
9644         set_checksums 0
9645
9646         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9647         $LCTL set_param fail_loc=0x80000408
9648         set_checksums 1
9649         cancel_lru_locks osc
9650         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9651                 error "direct read: rc=$?"
9652         $LCTL set_param fail_loc=0
9653         set_checksums 0
9654 }
9655 run_test 77d "checksum error on OST direct write, read"
9656
9657 test_77f() { # bug 10889
9658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9659         $GSS && skip_env "could not run with gss"
9660
9661         set_checksums 1
9662         stack_trap "rm -f $DIR/$tfile"
9663         for algo in $CKSUM_TYPES; do
9664                 cancel_lru_locks osc
9665                 set_checksum_type $algo
9666                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9667                 $LCTL set_param fail_loc=0x409
9668                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9669                         error "direct write succeeded"
9670                 $LCTL set_param fail_loc=0
9671         done
9672         set_checksum_type $ORIG_CSUM_TYPE
9673         set_checksums 0
9674 }
9675 run_test 77f "repeat checksum error on write (expect error)"
9676
9677 test_77g() { # bug 10889
9678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9679         $GSS && skip_env "could not run with gss"
9680         remote_ost_nodsh && skip "remote OST with nodsh"
9681
9682         [ ! -f $F77_TMP ] && setup_f77
9683
9684         local file=$DIR/$tfile
9685         stack_trap "rm -f $file" EXIT
9686
9687         $LFS setstripe -c 1 -i 0 $file
9688         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9689         do_facet ost1 lctl set_param fail_loc=0x8000021a
9690         set_checksums 1
9691         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9692                 error "write error: rc=$?"
9693         do_facet ost1 lctl set_param fail_loc=0
9694         set_checksums 0
9695
9696         cancel_lru_locks osc
9697         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9698         do_facet ost1 lctl set_param fail_loc=0x8000021b
9699         set_checksums 1
9700         cmp $F77_TMP $file || error "file compare failed"
9701         do_facet ost1 lctl set_param fail_loc=0
9702         set_checksums 0
9703 }
9704 run_test 77g "checksum error on OST write, read"
9705
9706 test_77k() { # LU-10906
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708         $GSS && skip_env "could not run with gss"
9709
9710         local cksum_param="osc.$FSNAME*.checksums"
9711         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9712         local checksum
9713         local i
9714
9715         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9716         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9717         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9718
9719         for i in 0 1; do
9720                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9721                         error "failed to set checksum=$i on MGS"
9722                 wait_update $HOSTNAME "$get_checksum" $i
9723                 #remount
9724                 echo "remount client, checksum should be $i"
9725                 remount_client $MOUNT || error "failed to remount client"
9726                 checksum=$(eval $get_checksum)
9727                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9728         done
9729         # remove persistent param to avoid races with checksum mountopt below
9730         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9731                 error "failed to delete checksum on MGS"
9732
9733         for opt in "checksum" "nochecksum"; do
9734                 #remount with mount option
9735                 echo "remount client with option $opt, checksum should be $i"
9736                 umount_client $MOUNT || error "failed to umount client"
9737                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9738                         error "failed to mount client with option '$opt'"
9739                 checksum=$(eval $get_checksum)
9740                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9741                 i=$((i - 1))
9742         done
9743
9744         remount_client $MOUNT || error "failed to remount client"
9745 }
9746 run_test 77k "enable/disable checksum correctly"
9747
9748 test_77l() {
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         $GSS && skip_env "could not run with gss"
9751
9752         set_checksums 1
9753         stack_trap "set_checksums $ORIG_CSUM" EXIT
9754         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9755
9756         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9757
9758         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9759         for algo in $CKSUM_TYPES; do
9760                 set_checksum_type $algo || error "fail to set checksum type $algo"
9761                 osc_algo=$(get_osc_checksum_type OST0000)
9762                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9763
9764                 # no locks, no reqs to let the connection idle
9765                 cancel_lru_locks osc
9766                 lru_resize_disable osc
9767                 wait_osc_import_state client ost1 IDLE
9768
9769                 # ensure ost1 is connected
9770                 stat $DIR/$tfile >/dev/null || error "can't stat"
9771                 wait_osc_import_state client ost1 FULL
9772
9773                 osc_algo=$(get_osc_checksum_type OST0000)
9774                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9775         done
9776         return 0
9777 }
9778 run_test 77l "preferred checksum type is remembered after reconnected"
9779
9780 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9781 rm -f $F77_TMP
9782 unset F77_TMP
9783
9784 test_77m() {
9785         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9786                 skip "Need at least version 2.14.52"
9787         local param=checksum_speed
9788
9789         $LCTL get_param $param || error "reading $param failed"
9790
9791         csum_speeds=$($LCTL get_param -n $param)
9792
9793         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9794                 error "known checksum types are missing"
9795 }
9796 run_test 77m "Verify checksum_speed is correctly read"
9797
9798 check_filefrag_77n() {
9799         local nr_ext=0
9800         local starts=()
9801         local ends=()
9802
9803         while read extidx a b start end rest; do
9804                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9805                         nr_ext=$(( $nr_ext + 1 ))
9806                         starts+=( ${start%..} )
9807                         ends+=( ${end%:} )
9808                 fi
9809         done < <( filefrag -sv $1 )
9810
9811         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9812         return 1
9813 }
9814
9815 test_77n() {
9816         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9817
9818         touch $DIR/$tfile
9819         $TRUNCATE $DIR/$tfile 0
9820         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9821         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9822         check_filefrag_77n $DIR/$tfile ||
9823                 skip "$tfile blocks not contiguous around hole"
9824
9825         set_checksums 1
9826         stack_trap "set_checksums $ORIG_CSUM" EXIT
9827         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9828         stack_trap "rm -f $DIR/$tfile"
9829
9830         for algo in $CKSUM_TYPES; do
9831                 if [[ "$algo" =~ ^t10 ]]; then
9832                         set_checksum_type $algo ||
9833                                 error "fail to set checksum type $algo"
9834                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9835                                 error "fail to read $tfile with $algo"
9836                 fi
9837         done
9838         rm -f $DIR/$tfile
9839         return 0
9840 }
9841 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9842
9843 cleanup_test_78() {
9844         trap 0
9845         rm -f $DIR/$tfile
9846 }
9847
9848 test_78() { # bug 10901
9849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9850         remote_ost || skip_env "local OST"
9851
9852         NSEQ=5
9853         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9854         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9855         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9856         echo "MemTotal: $MEMTOTAL"
9857
9858         # reserve 256MB of memory for the kernel and other running processes,
9859         # and then take 1/2 of the remaining memory for the read/write buffers.
9860         if [ $MEMTOTAL -gt 512 ] ;then
9861                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9862         else
9863                 # for those poor memory-starved high-end clusters...
9864                 MEMTOTAL=$((MEMTOTAL / 2))
9865         fi
9866         echo "Mem to use for directio: $MEMTOTAL"
9867
9868         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9869         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9870         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9871         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9872                 head -n1)
9873         echo "Smallest OST: $SMALLESTOST"
9874         [[ $SMALLESTOST -lt 10240 ]] &&
9875                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9876
9877         trap cleanup_test_78 EXIT
9878
9879         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9880                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9881
9882         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9883         echo "File size: $F78SIZE"
9884         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9885         for i in $(seq 1 $NSEQ); do
9886                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9887                 echo directIO rdwr round $i of $NSEQ
9888                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9889         done
9890
9891         cleanup_test_78
9892 }
9893 run_test 78 "handle large O_DIRECT writes correctly ============"
9894
9895 test_79() { # bug 12743
9896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9897
9898         wait_delete_completed
9899
9900         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9901         BKFREE=$(calc_osc_kbytes kbytesfree)
9902         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9903
9904         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9905         DFTOTAL=`echo $STRING | cut -d, -f1`
9906         DFUSED=`echo $STRING  | cut -d, -f2`
9907         DFAVAIL=`echo $STRING | cut -d, -f3`
9908         DFFREE=$(($DFTOTAL - $DFUSED))
9909
9910         ALLOWANCE=$((64 * $OSTCOUNT))
9911
9912         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9913            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9914                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9915         fi
9916         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9917            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9918                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9919         fi
9920         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9921            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9922                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9923         fi
9924 }
9925 run_test 79 "df report consistency check ======================="
9926
9927 test_80() { # bug 10718
9928         remote_ost_nodsh && skip "remote OST with nodsh"
9929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9930
9931         # relax strong synchronous semantics for slow backends like ZFS
9932         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9933                 local soc="obdfilter.*.sync_lock_cancel"
9934                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9935
9936                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9937                 if [ -z "$save" ]; then
9938                         soc="obdfilter.*.sync_on_lock_cancel"
9939                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9940                 fi
9941
9942                 if [ "$save" != "never" ]; then
9943                         local hosts=$(comma_list $(osts_nodes))
9944
9945                         do_nodes $hosts $LCTL set_param $soc=never
9946                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9947                 fi
9948         fi
9949
9950         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9951         sync; sleep 1; sync
9952         local before=$(date +%s)
9953         cancel_lru_locks osc
9954         local after=$(date +%s)
9955         local diff=$((after - before))
9956         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9957
9958         rm -f $DIR/$tfile
9959 }
9960 run_test 80 "Page eviction is equally fast at high offsets too"
9961
9962 test_81a() { # LU-456
9963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9964         remote_ost_nodsh && skip "remote OST with nodsh"
9965
9966         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9967         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9968         do_facet ost1 lctl set_param fail_loc=0x80000228
9969
9970         # write should trigger a retry and success
9971         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9972         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9973         RC=$?
9974         if [ $RC -ne 0 ] ; then
9975                 error "write should success, but failed for $RC"
9976         fi
9977 }
9978 run_test 81a "OST should retry write when get -ENOSPC ==============="
9979
9980 test_81b() { # LU-456
9981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9982         remote_ost_nodsh && skip "remote OST with nodsh"
9983
9984         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9985         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9986         do_facet ost1 lctl set_param fail_loc=0x228
9987
9988         # write should retry several times and return -ENOSPC finally
9989         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9990         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9991         RC=$?
9992         ENOSPC=28
9993         if [ $RC -ne $ENOSPC ] ; then
9994                 error "dd should fail for -ENOSPC, but succeed."
9995         fi
9996 }
9997 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9998
9999 test_99() {
10000         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10001
10002         test_mkdir $DIR/$tdir.cvsroot
10003         chown $RUNAS_ID $DIR/$tdir.cvsroot
10004
10005         cd $TMP
10006         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10007
10008         cd /etc/init.d
10009         # some versions of cvs import exit(1) when asked to import links or
10010         # files they can't read.  ignore those files.
10011         local toignore=$(find . -type l -printf '-I %f\n' -o \
10012                          ! -perm /4 -printf '-I %f\n')
10013         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10014                 $tdir.reposname vtag rtag
10015
10016         cd $DIR
10017         test_mkdir $DIR/$tdir.reposname
10018         chown $RUNAS_ID $DIR/$tdir.reposname
10019         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10020
10021         cd $DIR/$tdir.reposname
10022         $RUNAS touch foo99
10023         $RUNAS cvs add -m 'addmsg' foo99
10024         $RUNAS cvs update
10025         $RUNAS cvs commit -m 'nomsg' foo99
10026         rm -fr $DIR/$tdir.cvsroot
10027 }
10028 run_test 99 "cvs strange file/directory operations"
10029
10030 test_100() {
10031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10032         [[ "$NETTYPE" =~ tcp ]] ||
10033                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10034         remote_ost_nodsh && skip "remote OST with nodsh"
10035         remote_mds_nodsh && skip "remote MDS with nodsh"
10036         remote_servers ||
10037                 skip "useless for local single node setup"
10038
10039         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10040                 [ "$PROT" != "tcp" ] && continue
10041                 RPORT=$(echo $REMOTE | cut -d: -f2)
10042                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10043
10044                 rc=0
10045                 LPORT=`echo $LOCAL | cut -d: -f2`
10046                 if [ $LPORT -ge 1024 ]; then
10047                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10048                         netstat -tna
10049                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10050                 fi
10051         done
10052         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10053 }
10054 run_test 100 "check local port using privileged port ==========="
10055
10056 function get_named_value()
10057 {
10058     local tag=$1
10059
10060     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10061 }
10062
10063 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10064                    awk '/^max_cached_mb/ { print $2 }')
10065
10066 cleanup_101a() {
10067         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10068         trap 0
10069 }
10070
10071 test_101a() {
10072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10073
10074         local s
10075         local discard
10076         local nreads=10000
10077         local cache_limit=32
10078
10079         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10080         trap cleanup_101a EXIT
10081         $LCTL set_param -n llite.*.read_ahead_stats=0
10082         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10083
10084         #
10085         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10086         #
10087         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10088         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10089
10090         discard=0
10091         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10092                    get_named_value 'read.but.discarded'); do
10093                         discard=$(($discard + $s))
10094         done
10095         cleanup_101a
10096
10097         $LCTL get_param osc.*-osc*.rpc_stats
10098         $LCTL get_param llite.*.read_ahead_stats
10099
10100         # Discard is generally zero, but sometimes a few random reads line up
10101         # and trigger larger readahead, which is wasted & leads to discards.
10102         if [[ $(($discard)) -gt $nreads ]]; then
10103                 error "too many ($discard) discarded pages"
10104         fi
10105         rm -f $DIR/$tfile || true
10106 }
10107 run_test 101a "check read-ahead for random reads"
10108
10109 setup_test101bc() {
10110         test_mkdir $DIR/$tdir
10111         local ssize=$1
10112         local FILE_LENGTH=$2
10113         STRIPE_OFFSET=0
10114
10115         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10116
10117         local list=$(comma_list $(osts_nodes))
10118         set_osd_param $list '' read_cache_enable 0
10119         set_osd_param $list '' writethrough_cache_enable 0
10120
10121         trap cleanup_test101bc EXIT
10122         # prepare the read-ahead file
10123         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10124
10125         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10126                                 count=$FILE_SIZE_MB 2> /dev/null
10127
10128 }
10129
10130 cleanup_test101bc() {
10131         trap 0
10132         rm -rf $DIR/$tdir
10133         rm -f $DIR/$tfile
10134
10135         local list=$(comma_list $(osts_nodes))
10136         set_osd_param $list '' read_cache_enable 1
10137         set_osd_param $list '' writethrough_cache_enable 1
10138 }
10139
10140 calc_total() {
10141         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10142 }
10143
10144 ra_check_101() {
10145         local READ_SIZE=$1
10146         local STRIPE_SIZE=$2
10147         local FILE_LENGTH=$3
10148         local RA_INC=1048576
10149         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10150         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10151                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10152         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10153                   get_named_value 'read.but.discarded' | calc_total)
10154         if [[ $DISCARD -gt $discard_limit ]]; then
10155                 $LCTL get_param llite.*.read_ahead_stats
10156                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10157         else
10158                 echo "Read-ahead success for size ${READ_SIZE}"
10159         fi
10160 }
10161
10162 test_101b() {
10163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10164         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10165
10166         local STRIPE_SIZE=1048576
10167         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10168
10169         if [ $SLOW == "yes" ]; then
10170                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10171         else
10172                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10173         fi
10174
10175         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10176
10177         # prepare the read-ahead file
10178         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10179         cancel_lru_locks osc
10180         for BIDX in 2 4 8 16 32 64 128 256
10181         do
10182                 local BSIZE=$((BIDX*4096))
10183                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10184                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10185                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10186                 $LCTL set_param -n llite.*.read_ahead_stats=0
10187                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10188                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10189                 cancel_lru_locks osc
10190                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10191         done
10192         cleanup_test101bc
10193         true
10194 }
10195 run_test 101b "check stride-io mode read-ahead ================="
10196
10197 test_101c() {
10198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10199
10200         local STRIPE_SIZE=1048576
10201         local FILE_LENGTH=$((STRIPE_SIZE*100))
10202         local nreads=10000
10203         local rsize=65536
10204         local osc_rpc_stats
10205
10206         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10207
10208         cancel_lru_locks osc
10209         $LCTL set_param osc.*.rpc_stats=0
10210         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10211         $LCTL get_param osc.*.rpc_stats
10212         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10213                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10214                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10215                 local size
10216
10217                 if [ $lines -le 20 ]; then
10218                         echo "continue debug"
10219                         continue
10220                 fi
10221                 for size in 1 2 4 8; do
10222                         local rpc=$(echo "$stats" |
10223                                     awk '($1 == "'$size':") {print $2; exit; }')
10224                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10225                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10226                 done
10227                 echo "$osc_rpc_stats check passed!"
10228         done
10229         cleanup_test101bc
10230         true
10231 }
10232 run_test 101c "check stripe_size aligned read-ahead"
10233
10234 test_101d() {
10235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10236
10237         local file=$DIR/$tfile
10238         local sz_MB=${FILESIZE_101d:-80}
10239         local ra_MB=${READAHEAD_MB:-40}
10240
10241         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10242         [ $free_MB -lt $sz_MB ] &&
10243                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10244
10245         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10246         $LFS setstripe -c -1 $file || error "setstripe failed"
10247
10248         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10249         echo Cancel LRU locks on lustre client to flush the client cache
10250         cancel_lru_locks osc
10251
10252         echo Disable read-ahead
10253         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10254         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10255         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10256         $LCTL get_param -n llite.*.max_read_ahead_mb
10257
10258         echo "Reading the test file $file with read-ahead disabled"
10259         local sz_KB=$((sz_MB * 1024 / 4))
10260         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10261         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10262         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10263                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10264
10265         echo "Cancel LRU locks on lustre client to flush the client cache"
10266         cancel_lru_locks osc
10267         echo Enable read-ahead with ${ra_MB}MB
10268         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10269
10270         echo "Reading the test file $file with read-ahead enabled"
10271         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10272                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10273
10274         echo "read-ahead disabled time read $raOFF"
10275         echo "read-ahead enabled time read $raON"
10276
10277         rm -f $file
10278         wait_delete_completed
10279
10280         # use awk for this check instead of bash because it handles decimals
10281         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10282                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10283 }
10284 run_test 101d "file read with and without read-ahead enabled"
10285
10286 test_101e() {
10287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10288
10289         local file=$DIR/$tfile
10290         local size_KB=500  #KB
10291         local count=100
10292         local bsize=1024
10293
10294         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10295         local need_KB=$((count * size_KB))
10296         [[ $free_KB -le $need_KB ]] &&
10297                 skip_env "Need free space $need_KB, have $free_KB"
10298
10299         echo "Creating $count ${size_KB}K test files"
10300         for ((i = 0; i < $count; i++)); do
10301                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10302         done
10303
10304         echo "Cancel LRU locks on lustre client to flush the client cache"
10305         cancel_lru_locks $OSC
10306
10307         echo "Reset readahead stats"
10308         $LCTL set_param -n llite.*.read_ahead_stats=0
10309
10310         for ((i = 0; i < $count; i++)); do
10311                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10312         done
10313
10314         $LCTL get_param llite.*.max_cached_mb
10315         $LCTL get_param llite.*.read_ahead_stats
10316         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10317                      get_named_value 'misses' | calc_total)
10318
10319         for ((i = 0; i < $count; i++)); do
10320                 rm -rf $file.$i 2>/dev/null
10321         done
10322
10323         #10000 means 20% reads are missing in readahead
10324         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10325 }
10326 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10327
10328 test_101f() {
10329         which iozone || skip_env "no iozone installed"
10330
10331         local old_debug=$($LCTL get_param debug)
10332         old_debug=${old_debug#*=}
10333         $LCTL set_param debug="reada mmap"
10334
10335         # create a test file
10336         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10337
10338         echo Cancel LRU locks on lustre client to flush the client cache
10339         cancel_lru_locks osc
10340
10341         echo Reset readahead stats
10342         $LCTL set_param -n llite.*.read_ahead_stats=0
10343
10344         echo mmap read the file with small block size
10345         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10346                 > /dev/null 2>&1
10347
10348         echo checking missing pages
10349         $LCTL get_param llite.*.read_ahead_stats
10350         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10351                         get_named_value 'misses' | calc_total)
10352
10353         $LCTL set_param debug="$old_debug"
10354         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10355         rm -f $DIR/$tfile
10356 }
10357 run_test 101f "check mmap read performance"
10358
10359 test_101g_brw_size_test() {
10360         local mb=$1
10361         local pages=$((mb * 1048576 / PAGE_SIZE))
10362         local file=$DIR/$tfile
10363
10364         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10365                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10366         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10367                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10368                         return 2
10369         done
10370
10371         stack_trap "rm -f $file" EXIT
10372         $LCTL set_param -n osc.*.rpc_stats=0
10373
10374         # 10 RPCs should be enough for the test
10375         local count=10
10376         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10377                 { error "dd write ${mb} MB blocks failed"; return 3; }
10378         cancel_lru_locks osc
10379         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10380                 { error "dd write ${mb} MB blocks failed"; return 4; }
10381
10382         # calculate number of full-sized read and write RPCs
10383         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10384                 sed -n '/pages per rpc/,/^$/p' |
10385                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10386                 END { print reads,writes }'))
10387         # allow one extra full-sized read RPC for async readahead
10388         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10389                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10390         [[ ${rpcs[1]} == $count ]] ||
10391                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10392 }
10393
10394 test_101g() {
10395         remote_ost_nodsh && skip "remote OST with nodsh"
10396
10397         local rpcs
10398         local osts=$(get_facets OST)
10399         local list=$(comma_list $(osts_nodes))
10400         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10401         local brw_size="obdfilter.*.brw_size"
10402
10403         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10404
10405         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10406
10407         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10408                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10409                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10410            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10411                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10412                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10413
10414                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10415                         suffix="M"
10416
10417                 if [[ $orig_mb -lt 16 ]]; then
10418                         save_lustre_params $osts "$brw_size" > $p
10419                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10420                                 error "set 16MB RPC size failed"
10421
10422                         echo "remount client to enable new RPC size"
10423                         remount_client $MOUNT || error "remount_client failed"
10424                 fi
10425
10426                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10427                 # should be able to set brw_size=12, but no rpc_stats for that
10428                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10429         fi
10430
10431         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10432
10433         if [[ $orig_mb -lt 16 ]]; then
10434                 restore_lustre_params < $p
10435                 remount_client $MOUNT || error "remount_client restore failed"
10436         fi
10437
10438         rm -f $p $DIR/$tfile
10439 }
10440 run_test 101g "Big bulk(4/16 MiB) readahead"
10441
10442 test_101h() {
10443         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10444
10445         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10446                 error "dd 70M file failed"
10447         echo Cancel LRU locks on lustre client to flush the client cache
10448         cancel_lru_locks osc
10449
10450         echo "Reset readahead stats"
10451         $LCTL set_param -n llite.*.read_ahead_stats 0
10452
10453         echo "Read 10M of data but cross 64M bundary"
10454         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10455         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10456                      get_named_value 'misses' | calc_total)
10457         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10458         rm -f $p $DIR/$tfile
10459 }
10460 run_test 101h "Readahead should cover current read window"
10461
10462 test_101i() {
10463         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10464                 error "dd 10M file failed"
10465
10466         local max_per_file_mb=$($LCTL get_param -n \
10467                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10468         cancel_lru_locks osc
10469         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10470         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10471                 error "set max_read_ahead_per_file_mb to 1 failed"
10472
10473         echo "Reset readahead stats"
10474         $LCTL set_param llite.*.read_ahead_stats=0
10475
10476         dd if=$DIR/$tfile of=/dev/null bs=2M
10477
10478         $LCTL get_param llite.*.read_ahead_stats
10479         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10480                      awk '/misses/ { print $2 }')
10481         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10482         rm -f $DIR/$tfile
10483 }
10484 run_test 101i "allow current readahead to exceed reservation"
10485
10486 test_101j() {
10487         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10488                 error "setstripe $DIR/$tfile failed"
10489         local file_size=$((1048576 * 16))
10490         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10491         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10492
10493         echo Disable read-ahead
10494         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10495
10496         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10497         for blk in $PAGE_SIZE 1048576 $file_size; do
10498                 cancel_lru_locks osc
10499                 echo "Reset readahead stats"
10500                 $LCTL set_param -n llite.*.read_ahead_stats=0
10501                 local count=$(($file_size / $blk))
10502                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10503                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10504                              get_named_value 'failed.to.fast.read' | calc_total)
10505                 $LCTL get_param -n llite.*.read_ahead_stats
10506                 [ $miss -eq $count ] || error "expected $count got $miss"
10507         done
10508
10509         rm -f $p $DIR/$tfile
10510 }
10511 run_test 101j "A complete read block should be submitted when no RA"
10512
10513 setup_test102() {
10514         test_mkdir $DIR/$tdir
10515         chown $RUNAS_ID $DIR/$tdir
10516         STRIPE_SIZE=65536
10517         STRIPE_OFFSET=1
10518         STRIPE_COUNT=$OSTCOUNT
10519         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10520
10521         trap cleanup_test102 EXIT
10522         cd $DIR
10523         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10524         cd $DIR/$tdir
10525         for num in 1 2 3 4; do
10526                 for count in $(seq 1 $STRIPE_COUNT); do
10527                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10528                                 local size=`expr $STRIPE_SIZE \* $num`
10529                                 local file=file"$num-$idx-$count"
10530                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10531                         done
10532                 done
10533         done
10534
10535         cd $DIR
10536         $1 tar cf $TMP/f102.tar $tdir --xattrs
10537 }
10538
10539 cleanup_test102() {
10540         trap 0
10541         rm -f $TMP/f102.tar
10542         rm -rf $DIR/d0.sanity/d102
10543 }
10544
10545 test_102a() {
10546         [ "$UID" != 0 ] && skip "must run as root"
10547         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10548                 skip_env "must have user_xattr"
10549
10550         [ -z "$(which setfattr 2>/dev/null)" ] &&
10551                 skip_env "could not find setfattr"
10552
10553         local testfile=$DIR/$tfile
10554
10555         touch $testfile
10556         echo "set/get xattr..."
10557         setfattr -n trusted.name1 -v value1 $testfile ||
10558                 error "setfattr -n trusted.name1=value1 $testfile failed"
10559         getfattr -n trusted.name1 $testfile 2> /dev/null |
10560           grep "trusted.name1=.value1" ||
10561                 error "$testfile missing trusted.name1=value1"
10562
10563         setfattr -n user.author1 -v author1 $testfile ||
10564                 error "setfattr -n user.author1=author1 $testfile failed"
10565         getfattr -n user.author1 $testfile 2> /dev/null |
10566           grep "user.author1=.author1" ||
10567                 error "$testfile missing trusted.author1=author1"
10568
10569         echo "listxattr..."
10570         setfattr -n trusted.name2 -v value2 $testfile ||
10571                 error "$testfile unable to set trusted.name2"
10572         setfattr -n trusted.name3 -v value3 $testfile ||
10573                 error "$testfile unable to set trusted.name3"
10574         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10575             grep "trusted.name" | wc -l) -eq 3 ] ||
10576                 error "$testfile missing 3 trusted.name xattrs"
10577
10578         setfattr -n user.author2 -v author2 $testfile ||
10579                 error "$testfile unable to set user.author2"
10580         setfattr -n user.author3 -v author3 $testfile ||
10581                 error "$testfile unable to set user.author3"
10582         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10583             grep "user.author" | wc -l) -eq 3 ] ||
10584                 error "$testfile missing 3 user.author xattrs"
10585
10586         echo "remove xattr..."
10587         setfattr -x trusted.name1 $testfile ||
10588                 error "$testfile error deleting trusted.name1"
10589         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10590                 error "$testfile did not delete trusted.name1 xattr"
10591
10592         setfattr -x user.author1 $testfile ||
10593                 error "$testfile error deleting user.author1"
10594         echo "set lustre special xattr ..."
10595         $LFS setstripe -c1 $testfile
10596         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10597                 awk -F "=" '/trusted.lov/ { print $2 }' )
10598         setfattr -n "trusted.lov" -v $lovea $testfile ||
10599                 error "$testfile doesn't ignore setting trusted.lov again"
10600         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10601                 error "$testfile allow setting invalid trusted.lov"
10602         rm -f $testfile
10603 }
10604 run_test 102a "user xattr test =================================="
10605
10606 check_102b_layout() {
10607         local layout="$*"
10608         local testfile=$DIR/$tfile
10609
10610         echo "test layout '$layout'"
10611         $LFS setstripe $layout $testfile || error "setstripe failed"
10612         $LFS getstripe -y $testfile
10613
10614         echo "get/set/list trusted.lov xattr ..." # b=10930
10615         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10616         [[ "$value" =~ "trusted.lov" ]] ||
10617                 error "can't get trusted.lov from $testfile"
10618         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10619                 error "getstripe failed"
10620
10621         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10622
10623         value=$(cut -d= -f2 <<<$value)
10624         # LU-13168: truncated xattr should fail if short lov_user_md header
10625         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10626                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10627         for len in $lens; do
10628                 echo "setfattr $len $testfile.2"
10629                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10630                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10631         done
10632         local stripe_size=$($LFS getstripe -S $testfile.2)
10633         local stripe_count=$($LFS getstripe -c $testfile.2)
10634         [[ $stripe_size -eq 65536 ]] ||
10635                 error "stripe size $stripe_size != 65536"
10636         [[ $stripe_count -eq $stripe_count_orig ]] ||
10637                 error "stripe count $stripe_count != $stripe_count_orig"
10638         rm $testfile $testfile.2
10639 }
10640
10641 test_102b() {
10642         [ -z "$(which setfattr 2>/dev/null)" ] &&
10643                 skip_env "could not find setfattr"
10644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10645
10646         # check plain layout
10647         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10648
10649         # and also check composite layout
10650         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10651
10652 }
10653 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10654
10655 test_102c() {
10656         [ -z "$(which setfattr 2>/dev/null)" ] &&
10657                 skip_env "could not find setfattr"
10658         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10659
10660         # b10930: get/set/list lustre.lov xattr
10661         echo "get/set/list lustre.lov xattr ..."
10662         test_mkdir $DIR/$tdir
10663         chown $RUNAS_ID $DIR/$tdir
10664         local testfile=$DIR/$tdir/$tfile
10665         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10666                 error "setstripe failed"
10667         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10668                 error "getstripe failed"
10669         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10670         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10671
10672         local testfile2=${testfile}2
10673         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10674                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10675
10676         $RUNAS $MCREATE $testfile2
10677         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10678         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10679         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10680         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10681         [ $stripe_count -eq $STRIPECOUNT ] ||
10682                 error "stripe count $stripe_count != $STRIPECOUNT"
10683 }
10684 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10685
10686 compare_stripe_info1() {
10687         local stripe_index_all_zero=true
10688
10689         for num in 1 2 3 4; do
10690                 for count in $(seq 1 $STRIPE_COUNT); do
10691                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10692                                 local size=$((STRIPE_SIZE * num))
10693                                 local file=file"$num-$offset-$count"
10694                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10695                                 [[ $stripe_size -ne $size ]] &&
10696                                     error "$file: size $stripe_size != $size"
10697                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10698                                 # allow fewer stripes to be created, ORI-601
10699                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10700                                     error "$file: count $stripe_count != $count"
10701                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10702                                 [[ $stripe_index -ne 0 ]] &&
10703                                         stripe_index_all_zero=false
10704                         done
10705                 done
10706         done
10707         $stripe_index_all_zero &&
10708                 error "all files are being extracted starting from OST index 0"
10709         return 0
10710 }
10711
10712 have_xattrs_include() {
10713         tar --help | grep -q xattrs-include &&
10714                 echo --xattrs-include="lustre.*"
10715 }
10716
10717 test_102d() {
10718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10719         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10720
10721         XINC=$(have_xattrs_include)
10722         setup_test102
10723         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10724         cd $DIR/$tdir/$tdir
10725         compare_stripe_info1
10726 }
10727 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10728
10729 test_102f() {
10730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10731         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10732
10733         XINC=$(have_xattrs_include)
10734         setup_test102
10735         test_mkdir $DIR/$tdir.restore
10736         cd $DIR
10737         tar cf - --xattrs $tdir | tar xf - \
10738                 -C $DIR/$tdir.restore --xattrs $XINC
10739         cd $DIR/$tdir.restore/$tdir
10740         compare_stripe_info1
10741 }
10742 run_test 102f "tar copy files, not keep osts"
10743
10744 grow_xattr() {
10745         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10746                 skip "must have user_xattr"
10747         [ -z "$(which setfattr 2>/dev/null)" ] &&
10748                 skip_env "could not find setfattr"
10749         [ -z "$(which getfattr 2>/dev/null)" ] &&
10750                 skip_env "could not find getfattr"
10751
10752         local xsize=${1:-1024}  # in bytes
10753         local file=$DIR/$tfile
10754         local value="$(generate_string $xsize)"
10755         local xbig=trusted.big
10756         local toobig=$2
10757
10758         touch $file
10759         log "save $xbig on $file"
10760         if [ -z "$toobig" ]
10761         then
10762                 setfattr -n $xbig -v $value $file ||
10763                         error "saving $xbig on $file failed"
10764         else
10765                 setfattr -n $xbig -v $value $file &&
10766                         error "saving $xbig on $file succeeded"
10767                 return 0
10768         fi
10769
10770         local orig=$(get_xattr_value $xbig $file)
10771         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10772
10773         local xsml=trusted.sml
10774         log "save $xsml on $file"
10775         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10776
10777         local new=$(get_xattr_value $xbig $file)
10778         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10779
10780         log "grow $xsml on $file"
10781         setfattr -n $xsml -v "$value" $file ||
10782                 error "growing $xsml on $file failed"
10783
10784         new=$(get_xattr_value $xbig $file)
10785         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10786         log "$xbig still valid after growing $xsml"
10787
10788         rm -f $file
10789 }
10790
10791 test_102h() { # bug 15777
10792         grow_xattr 1024
10793 }
10794 run_test 102h "grow xattr from inside inode to external block"
10795
10796 test_102ha() {
10797         large_xattr_enabled || skip_env "ea_inode feature disabled"
10798
10799         echo "setting xattr of max xattr size: $(max_xattr_size)"
10800         grow_xattr $(max_xattr_size)
10801
10802         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10803         echo "This should fail:"
10804         grow_xattr $(($(max_xattr_size) + 10)) 1
10805 }
10806 run_test 102ha "grow xattr from inside inode to external inode"
10807
10808 test_102i() { # bug 17038
10809         [ -z "$(which getfattr 2>/dev/null)" ] &&
10810                 skip "could not find getfattr"
10811
10812         touch $DIR/$tfile
10813         ln -s $DIR/$tfile $DIR/${tfile}link
10814         getfattr -n trusted.lov $DIR/$tfile ||
10815                 error "lgetxattr on $DIR/$tfile failed"
10816         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10817                 grep -i "no such attr" ||
10818                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10819         rm -f $DIR/$tfile $DIR/${tfile}link
10820 }
10821 run_test 102i "lgetxattr test on symbolic link ============"
10822
10823 test_102j() {
10824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10825         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10826
10827         XINC=$(have_xattrs_include)
10828         setup_test102 "$RUNAS"
10829         chown $RUNAS_ID $DIR/$tdir
10830         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10831         cd $DIR/$tdir/$tdir
10832         compare_stripe_info1 "$RUNAS"
10833 }
10834 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10835
10836 test_102k() {
10837         [ -z "$(which setfattr 2>/dev/null)" ] &&
10838                 skip "could not find setfattr"
10839
10840         touch $DIR/$tfile
10841         # b22187 just check that does not crash for regular file.
10842         setfattr -n trusted.lov $DIR/$tfile
10843         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10844         local test_kdir=$DIR/$tdir
10845         test_mkdir $test_kdir
10846         local default_size=$($LFS getstripe -S $test_kdir)
10847         local default_count=$($LFS getstripe -c $test_kdir)
10848         local default_offset=$($LFS getstripe -i $test_kdir)
10849         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10850                 error 'dir setstripe failed'
10851         setfattr -n trusted.lov $test_kdir
10852         local stripe_size=$($LFS getstripe -S $test_kdir)
10853         local stripe_count=$($LFS getstripe -c $test_kdir)
10854         local stripe_offset=$($LFS getstripe -i $test_kdir)
10855         [ $stripe_size -eq $default_size ] ||
10856                 error "stripe size $stripe_size != $default_size"
10857         [ $stripe_count -eq $default_count ] ||
10858                 error "stripe count $stripe_count != $default_count"
10859         [ $stripe_offset -eq $default_offset ] ||
10860                 error "stripe offset $stripe_offset != $default_offset"
10861         rm -rf $DIR/$tfile $test_kdir
10862 }
10863 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10864
10865 test_102l() {
10866         [ -z "$(which getfattr 2>/dev/null)" ] &&
10867                 skip "could not find getfattr"
10868
10869         # LU-532 trusted. xattr is invisible to non-root
10870         local testfile=$DIR/$tfile
10871
10872         touch $testfile
10873
10874         echo "listxattr as user..."
10875         chown $RUNAS_ID $testfile
10876         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10877             grep -q "trusted" &&
10878                 error "$testfile trusted xattrs are user visible"
10879
10880         return 0;
10881 }
10882 run_test 102l "listxattr size test =================================="
10883
10884 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10885         local path=$DIR/$tfile
10886         touch $path
10887
10888         listxattr_size_check $path || error "listattr_size_check $path failed"
10889 }
10890 run_test 102m "Ensure listxattr fails on small bufffer ========"
10891
10892 cleanup_test102
10893
10894 getxattr() { # getxattr path name
10895         # Return the base64 encoding of the value of xattr name on path.
10896         local path=$1
10897         local name=$2
10898
10899         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10900         # file: $path
10901         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10902         #
10903         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10904
10905         getfattr --absolute-names --encoding=base64 --name=$name $path |
10906                 awk -F= -v name=$name '$1 == name {
10907                         print substr($0, index($0, "=") + 1);
10908         }'
10909 }
10910
10911 test_102n() { # LU-4101 mdt: protect internal xattrs
10912         [ -z "$(which setfattr 2>/dev/null)" ] &&
10913                 skip "could not find setfattr"
10914         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10915         then
10916                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10917         fi
10918
10919         local file0=$DIR/$tfile.0
10920         local file1=$DIR/$tfile.1
10921         local xattr0=$TMP/$tfile.0
10922         local xattr1=$TMP/$tfile.1
10923         local namelist="lov lma lmv link fid version som hsm"
10924         local name
10925         local value
10926
10927         rm -rf $file0 $file1 $xattr0 $xattr1
10928         touch $file0 $file1
10929
10930         # Get 'before' xattrs of $file1.
10931         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10932
10933         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10934                 namelist+=" lfsck_namespace"
10935         for name in $namelist; do
10936                 # Try to copy xattr from $file0 to $file1.
10937                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10938
10939                 setfattr --name=trusted.$name --value="$value" $file1 ||
10940                         error "setxattr 'trusted.$name' failed"
10941
10942                 # Try to set a garbage xattr.
10943                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10944
10945                 if [[ x$name == "xlov" ]]; then
10946                         setfattr --name=trusted.lov --value="$value" $file1 &&
10947                         error "setxattr invalid 'trusted.lov' success"
10948                 else
10949                         setfattr --name=trusted.$name --value="$value" $file1 ||
10950                                 error "setxattr invalid 'trusted.$name' failed"
10951                 fi
10952
10953                 # Try to remove the xattr from $file1. We don't care if this
10954                 # appears to succeed or fail, we just don't want there to be
10955                 # any changes or crashes.
10956                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10957         done
10958
10959         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10960         then
10961                 name="lfsck_ns"
10962                 # Try to copy xattr from $file0 to $file1.
10963                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10964
10965                 setfattr --name=trusted.$name --value="$value" $file1 ||
10966                         error "setxattr 'trusted.$name' failed"
10967
10968                 # Try to set a garbage xattr.
10969                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10970
10971                 setfattr --name=trusted.$name --value="$value" $file1 ||
10972                         error "setxattr 'trusted.$name' failed"
10973
10974                 # Try to remove the xattr from $file1. We don't care if this
10975                 # appears to succeed or fail, we just don't want there to be
10976                 # any changes or crashes.
10977                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10978         fi
10979
10980         # Get 'after' xattrs of file1.
10981         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10982
10983         if ! diff $xattr0 $xattr1; then
10984                 error "before and after xattrs of '$file1' differ"
10985         fi
10986
10987         rm -rf $file0 $file1 $xattr0 $xattr1
10988
10989         return 0
10990 }
10991 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10992
10993 test_102p() { # LU-4703 setxattr did not check ownership
10994         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10995                 skip "MDS needs to be at least 2.5.56"
10996
10997         local testfile=$DIR/$tfile
10998
10999         touch $testfile
11000
11001         echo "setfacl as user..."
11002         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11003         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11004
11005         echo "setfattr as user..."
11006         setfacl -m "u:$RUNAS_ID:---" $testfile
11007         $RUNAS setfattr -x system.posix_acl_access $testfile
11008         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11009 }
11010 run_test 102p "check setxattr(2) correctly fails without permission"
11011
11012 test_102q() {
11013         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11014                 skip "MDS needs to be at least 2.6.92"
11015
11016         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11017 }
11018 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11019
11020 test_102r() {
11021         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11022                 skip "MDS needs to be at least 2.6.93"
11023
11024         touch $DIR/$tfile || error "touch"
11025         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11026         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11027         rm $DIR/$tfile || error "rm"
11028
11029         #normal directory
11030         mkdir -p $DIR/$tdir || error "mkdir"
11031         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11032         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11033         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11034                 error "$testfile error deleting user.author1"
11035         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11036                 grep "user.$(basename $tdir)" &&
11037                 error "$tdir did not delete user.$(basename $tdir)"
11038         rmdir $DIR/$tdir || error "rmdir"
11039
11040         #striped directory
11041         test_mkdir $DIR/$tdir
11042         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11043         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11044         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11045                 error "$testfile error deleting user.author1"
11046         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11047                 grep "user.$(basename $tdir)" &&
11048                 error "$tdir did not delete user.$(basename $tdir)"
11049         rmdir $DIR/$tdir || error "rm striped dir"
11050 }
11051 run_test 102r "set EAs with empty values"
11052
11053 test_102s() {
11054         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11055                 skip "MDS needs to be at least 2.11.52"
11056
11057         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11058
11059         save_lustre_params client "llite.*.xattr_cache" > $save
11060
11061         for cache in 0 1; do
11062                 lctl set_param llite.*.xattr_cache=$cache
11063
11064                 rm -f $DIR/$tfile
11065                 touch $DIR/$tfile || error "touch"
11066                 for prefix in lustre security system trusted user; do
11067                         # Note getxattr() may fail with 'Operation not
11068                         # supported' or 'No such attribute' depending
11069                         # on prefix and cache.
11070                         getfattr -n $prefix.n102s $DIR/$tfile &&
11071                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11072                 done
11073         done
11074
11075         restore_lustre_params < $save
11076 }
11077 run_test 102s "getting nonexistent xattrs should fail"
11078
11079 test_102t() {
11080         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11081                 skip "MDS needs to be at least 2.11.52"
11082
11083         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11084
11085         save_lustre_params client "llite.*.xattr_cache" > $save
11086
11087         for cache in 0 1; do
11088                 lctl set_param llite.*.xattr_cache=$cache
11089
11090                 for buf_size in 0 256; do
11091                         rm -f $DIR/$tfile
11092                         touch $DIR/$tfile || error "touch"
11093                         setfattr -n user.multiop $DIR/$tfile
11094                         $MULTIOP $DIR/$tfile oa$buf_size ||
11095                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11096                 done
11097         done
11098
11099         restore_lustre_params < $save
11100 }
11101 run_test 102t "zero length xattr values handled correctly"
11102
11103 run_acl_subtest()
11104 {
11105     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11106     return $?
11107 }
11108
11109 test_103a() {
11110         [ "$UID" != 0 ] && skip "must run as root"
11111         $GSS && skip_env "could not run under gss"
11112         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11113                 skip_env "must have acl enabled"
11114         [ -z "$(which setfacl 2>/dev/null)" ] &&
11115                 skip_env "could not find setfacl"
11116         remote_mds_nodsh && skip "remote MDS with nodsh"
11117
11118         gpasswd -a daemon bin                           # LU-5641
11119         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11120
11121         declare -a identity_old
11122
11123         for num in $(seq $MDSCOUNT); do
11124                 switch_identity $num true || identity_old[$num]=$?
11125         done
11126
11127         SAVE_UMASK=$(umask)
11128         umask 0022
11129         mkdir -p $DIR/$tdir
11130         cd $DIR/$tdir
11131
11132         echo "performing cp ..."
11133         run_acl_subtest cp || error "run_acl_subtest cp failed"
11134         echo "performing getfacl-noacl..."
11135         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11136         echo "performing misc..."
11137         run_acl_subtest misc || error  "misc test failed"
11138         echo "performing permissions..."
11139         run_acl_subtest permissions || error "permissions failed"
11140         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11141         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11142                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11143                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11144         then
11145                 echo "performing permissions xattr..."
11146                 run_acl_subtest permissions_xattr ||
11147                         error "permissions_xattr failed"
11148         fi
11149         echo "performing setfacl..."
11150         run_acl_subtest setfacl || error  "setfacl test failed"
11151
11152         # inheritance test got from HP
11153         echo "performing inheritance..."
11154         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11155         chmod +x make-tree || error "chmod +x failed"
11156         run_acl_subtest inheritance || error "inheritance test failed"
11157         rm -f make-tree
11158
11159         echo "LU-974 ignore umask when acl is enabled..."
11160         run_acl_subtest 974 || error "LU-974 umask test failed"
11161         if [ $MDSCOUNT -ge 2 ]; then
11162                 run_acl_subtest 974_remote ||
11163                         error "LU-974 umask test failed under remote dir"
11164         fi
11165
11166         echo "LU-2561 newly created file is same size as directory..."
11167         if [ "$mds1_FSTYPE" != "zfs" ]; then
11168                 run_acl_subtest 2561 || error "LU-2561 test failed"
11169         else
11170                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11171         fi
11172
11173         run_acl_subtest 4924 || error "LU-4924 test failed"
11174
11175         cd $SAVE_PWD
11176         umask $SAVE_UMASK
11177
11178         for num in $(seq $MDSCOUNT); do
11179                 if [ "${identity_old[$num]}" = 1 ]; then
11180                         switch_identity $num false || identity_old[$num]=$?
11181                 fi
11182         done
11183 }
11184 run_test 103a "acl test"
11185
11186 test_103b() {
11187         declare -a pids
11188         local U
11189
11190         for U in {0..511}; do
11191                 {
11192                 local O=$(printf "%04o" $U)
11193
11194                 umask $(printf "%04o" $((511 ^ $O)))
11195                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11196                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11197
11198                 (( $S == ($O & 0666) )) ||
11199                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11200
11201                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11202                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11203                 (( $S == ($O & 0666) )) ||
11204                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11205
11206                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11207                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11208                 (( $S == ($O & 0666) )) ||
11209                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11210                 rm -f $DIR/$tfile.[smp]$0
11211                 } &
11212                 local pid=$!
11213
11214                 # limit the concurrently running threads to 64. LU-11878
11215                 local idx=$((U % 64))
11216                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11217                 pids[idx]=$pid
11218         done
11219         wait
11220 }
11221 run_test 103b "umask lfs setstripe"
11222
11223 test_103c() {
11224         mkdir -p $DIR/$tdir
11225         cp -rp $DIR/$tdir $DIR/$tdir.bak
11226
11227         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11228                 error "$DIR/$tdir shouldn't contain default ACL"
11229         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11230                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11231         true
11232 }
11233 run_test 103c "'cp -rp' won't set empty acl"
11234
11235 test_103e() {
11236         local numacl
11237         local fileacl
11238         local saved_debug=$($LCTL get_param -n debug)
11239
11240         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11241                 skip "MDS needs to be at least 2.14.0"
11242
11243         large_xattr_enabled || skip_env "ea_inode feature disabled"
11244
11245         mkdir -p $DIR/$tdir
11246         # add big LOV EA to cause reply buffer overflow earlier
11247         $LFS setstripe -C 1000 $DIR/$tdir
11248         lctl set_param mdc.*-mdc*.stats=clear
11249
11250         $LCTL set_param debug=0
11251         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11252         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11253
11254         # add a large number of default ACLs (expect 8000+ for 2.13+)
11255         for U in {2..7000}; do
11256                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11257                         error "Able to add just $U default ACLs"
11258         done
11259         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11260         echo "$numacl default ACLs created"
11261
11262         stat $DIR/$tdir || error "Cannot stat directory"
11263         # check file creation
11264         touch $DIR/$tdir/$tfile ||
11265                 error "failed to create $tfile with $numacl default ACLs"
11266         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11267         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11268         echo "$fileacl ACLs were inherited"
11269         (( $fileacl == $numacl )) ||
11270                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11271         # check that new ACLs creation adds new ACLs to inherited ACLs
11272         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11273                 error "Cannot set new ACL"
11274         numacl=$((numacl + 1))
11275         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11276         (( $fileacl == $numacl )) ||
11277                 error "failed to add new ACL: $fileacl != $numacl as expected"
11278         # adds more ACLs to a file to reach their maximum at 8000+
11279         numacl=0
11280         for U in {20000..25000}; do
11281                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11282                 numacl=$((numacl + 1))
11283         done
11284         echo "Added $numacl more ACLs to the file"
11285         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11286         echo "Total $fileacl ACLs in file"
11287         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11288         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11289         rmdir $DIR/$tdir || error "Cannot remove directory"
11290 }
11291 run_test 103e "inheritance of big amount of default ACLs"
11292
11293 test_103f() {
11294         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11295                 skip "MDS needs to be at least 2.14.51"
11296
11297         large_xattr_enabled || skip_env "ea_inode feature disabled"
11298
11299         # enable changelog to consume more internal MDD buffers
11300         changelog_register
11301
11302         mkdir -p $DIR/$tdir
11303         # add big LOV EA
11304         $LFS setstripe -C 1000 $DIR/$tdir
11305         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11306         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11307         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11308         rmdir $DIR/$tdir || error "Cannot remove directory"
11309 }
11310 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11311
11312 test_104a() {
11313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11314
11315         touch $DIR/$tfile
11316         lfs df || error "lfs df failed"
11317         lfs df -ih || error "lfs df -ih failed"
11318         lfs df -h $DIR || error "lfs df -h $DIR failed"
11319         lfs df -i $DIR || error "lfs df -i $DIR failed"
11320         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11321         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11322
11323         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11324         lctl --device %$OSC deactivate
11325         lfs df || error "lfs df with deactivated OSC failed"
11326         lctl --device %$OSC activate
11327         # wait the osc back to normal
11328         wait_osc_import_ready client ost
11329
11330         lfs df || error "lfs df with reactivated OSC failed"
11331         rm -f $DIR/$tfile
11332 }
11333 run_test 104a "lfs df [-ih] [path] test ========================="
11334
11335 test_104b() {
11336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11337         [ $RUNAS_ID -eq $UID ] &&
11338                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11339
11340         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11341                         grep "Permission denied" | wc -l)))
11342         if [ $denied_cnt -ne 0 ]; then
11343                 error "lfs check servers test failed"
11344         fi
11345 }
11346 run_test 104b "$RUNAS lfs check servers test ===================="
11347
11348 #
11349 # Verify $1 is within range of $2.
11350 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11351 # $1 is <= 2% of $2. Else Fail.
11352 #
11353 value_in_range() {
11354         # Strip all units (M, G, T)
11355         actual=$(echo $1 | tr -d A-Z)
11356         expect=$(echo $2 | tr -d A-Z)
11357
11358         expect_lo=$(($expect * 98 / 100)) # 2% below
11359         expect_hi=$(($expect * 102 / 100)) # 2% above
11360
11361         # permit 2% drift above and below
11362         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11363 }
11364
11365 test_104c() {
11366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11367         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11368
11369         local ost_param="osd-zfs.$FSNAME-OST0000."
11370         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11371         local ofacets=$(get_facets OST)
11372         local mfacets=$(get_facets MDS)
11373         local saved_ost_blocks=
11374         local saved_mdt_blocks=
11375
11376         echo "Before recordsize change"
11377         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11378         df=($(df -h | grep "/mnt/lustre"$))
11379
11380         # For checking.
11381         echo "lfs output : ${lfs_df[*]}"
11382         echo "df  output : ${df[*]}"
11383
11384         for facet in ${ofacets//,/ }; do
11385                 if [ -z $saved_ost_blocks ]; then
11386                         saved_ost_blocks=$(do_facet $facet \
11387                                 lctl get_param -n $ost_param.blocksize)
11388                         echo "OST Blocksize: $saved_ost_blocks"
11389                 fi
11390                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11391                 do_facet $facet zfs set recordsize=32768 $ost
11392         done
11393
11394         # BS too small. Sufficient for functional testing.
11395         for facet in ${mfacets//,/ }; do
11396                 if [ -z $saved_mdt_blocks ]; then
11397                         saved_mdt_blocks=$(do_facet $facet \
11398                                 lctl get_param -n $mdt_param.blocksize)
11399                         echo "MDT Blocksize: $saved_mdt_blocks"
11400                 fi
11401                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11402                 do_facet $facet zfs set recordsize=32768 $mdt
11403         done
11404
11405         # Give new values chance to reflect change
11406         sleep 2
11407
11408         echo "After recordsize change"
11409         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11410         df_after=($(df -h | grep "/mnt/lustre"$))
11411
11412         # For checking.
11413         echo "lfs output : ${lfs_df_after[*]}"
11414         echo "df  output : ${df_after[*]}"
11415
11416         # Verify lfs df
11417         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11418                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11419         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11420                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11421         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11422                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11423
11424         # Verify df
11425         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11426                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11427         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11428                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11429         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11430                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11431
11432         # Restore MDT recordize back to original
11433         for facet in ${mfacets//,/ }; do
11434                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11435                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11436         done
11437
11438         # Restore OST recordize back to original
11439         for facet in ${ofacets//,/ }; do
11440                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11441                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11442         done
11443
11444         return 0
11445 }
11446 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11447
11448 test_105a() {
11449         # doesn't work on 2.4 kernels
11450         touch $DIR/$tfile
11451         if $(flock_is_enabled); then
11452                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11453         else
11454                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11455         fi
11456         rm -f $DIR/$tfile
11457 }
11458 run_test 105a "flock when mounted without -o flock test ========"
11459
11460 test_105b() {
11461         touch $DIR/$tfile
11462         if $(flock_is_enabled); then
11463                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11464         else
11465                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11466         fi
11467         rm -f $DIR/$tfile
11468 }
11469 run_test 105b "fcntl when mounted without -o flock test ========"
11470
11471 test_105c() {
11472         touch $DIR/$tfile
11473         if $(flock_is_enabled); then
11474                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11475         else
11476                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11477         fi
11478         rm -f $DIR/$tfile
11479 }
11480 run_test 105c "lockf when mounted without -o flock test"
11481
11482 test_105d() { # bug 15924
11483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11484
11485         test_mkdir $DIR/$tdir
11486         flock_is_enabled || skip_env "mount w/o flock enabled"
11487         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11488         $LCTL set_param fail_loc=0x80000315
11489         flocks_test 2 $DIR/$tdir
11490 }
11491 run_test 105d "flock race (should not freeze) ========"
11492
11493 test_105e() { # bug 22660 && 22040
11494         flock_is_enabled || skip_env "mount w/o flock enabled"
11495
11496         touch $DIR/$tfile
11497         flocks_test 3 $DIR/$tfile
11498 }
11499 run_test 105e "Two conflicting flocks from same process"
11500
11501 test_106() { #bug 10921
11502         test_mkdir $DIR/$tdir
11503         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11504         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11505 }
11506 run_test 106 "attempt exec of dir followed by chown of that dir"
11507
11508 test_107() {
11509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11510
11511         CDIR=`pwd`
11512         local file=core
11513
11514         cd $DIR
11515         rm -f $file
11516
11517         local save_pattern=$(sysctl -n kernel.core_pattern)
11518         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11519         sysctl -w kernel.core_pattern=$file
11520         sysctl -w kernel.core_uses_pid=0
11521
11522         ulimit -c unlimited
11523         sleep 60 &
11524         SLEEPPID=$!
11525
11526         sleep 1
11527
11528         kill -s 11 $SLEEPPID
11529         wait $SLEEPPID
11530         if [ -e $file ]; then
11531                 size=`stat -c%s $file`
11532                 [ $size -eq 0 ] && error "Fail to create core file $file"
11533         else
11534                 error "Fail to create core file $file"
11535         fi
11536         rm -f $file
11537         sysctl -w kernel.core_pattern=$save_pattern
11538         sysctl -w kernel.core_uses_pid=$save_uses_pid
11539         cd $CDIR
11540 }
11541 run_test 107 "Coredump on SIG"
11542
11543 test_110() {
11544         test_mkdir $DIR/$tdir
11545         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11546         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11547                 error "mkdir with 256 char should fail, but did not"
11548         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11549                 error "create with 255 char failed"
11550         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11551                 error "create with 256 char should fail, but did not"
11552
11553         ls -l $DIR/$tdir
11554         rm -rf $DIR/$tdir
11555 }
11556 run_test 110 "filename length checking"
11557
11558 #
11559 # Purpose: To verify dynamic thread (OSS) creation.
11560 #
11561 test_115() {
11562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11563         remote_ost_nodsh && skip "remote OST with nodsh"
11564
11565         # Lustre does not stop service threads once they are started.
11566         # Reset number of running threads to default.
11567         stopall
11568         setupall
11569
11570         local OSTIO_pre
11571         local save_params="$TMP/sanity-$TESTNAME.parameters"
11572
11573         # Get ll_ost_io count before I/O
11574         OSTIO_pre=$(do_facet ost1 \
11575                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11576         # Exit if lustre is not running (ll_ost_io not running).
11577         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11578
11579         echo "Starting with $OSTIO_pre threads"
11580         local thread_max=$((OSTIO_pre * 2))
11581         local rpc_in_flight=$((thread_max * 2))
11582         # Number of I/O Process proposed to be started.
11583         local nfiles
11584         local facets=$(get_facets OST)
11585
11586         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11587         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11588
11589         # Set in_flight to $rpc_in_flight
11590         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11591                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11592         nfiles=${rpc_in_flight}
11593         # Set ost thread_max to $thread_max
11594         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11595
11596         # 5 Minutes should be sufficient for max number of OSS
11597         # threads(thread_max) to be created.
11598         local timeout=300
11599
11600         # Start I/O.
11601         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11602         test_mkdir $DIR/$tdir
11603         for i in $(seq $nfiles); do
11604                 local file=$DIR/$tdir/${tfile}-$i
11605                 $LFS setstripe -c -1 -i 0 $file
11606                 ($WTL $file $timeout)&
11607         done
11608
11609         # I/O Started - Wait for thread_started to reach thread_max or report
11610         # error if thread_started is more than thread_max.
11611         echo "Waiting for thread_started to reach thread_max"
11612         local thread_started=0
11613         local end_time=$((SECONDS + timeout))
11614
11615         while [ $SECONDS -le $end_time ] ; do
11616                 echo -n "."
11617                 # Get ost i/o thread_started count.
11618                 thread_started=$(do_facet ost1 \
11619                         "$LCTL get_param \
11620                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11621                 # Break out if thread_started is equal/greater than thread_max
11622                 if [[ $thread_started -ge $thread_max ]]; then
11623                         echo ll_ost_io thread_started $thread_started, \
11624                                 equal/greater than thread_max $thread_max
11625                         break
11626                 fi
11627                 sleep 1
11628         done
11629
11630         # Cleanup - We have the numbers, Kill i/o jobs if running.
11631         jobcount=($(jobs -p))
11632         for i in $(seq 0 $((${#jobcount[@]}-1)))
11633         do
11634                 kill -9 ${jobcount[$i]}
11635                 if [ $? -ne 0 ] ; then
11636                         echo Warning: \
11637                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11638                 fi
11639         done
11640
11641         # Cleanup files left by WTL binary.
11642         for i in $(seq $nfiles); do
11643                 local file=$DIR/$tdir/${tfile}-$i
11644                 rm -rf $file
11645                 if [ $? -ne 0 ] ; then
11646                         echo "Warning: Failed to delete file $file"
11647                 fi
11648         done
11649
11650         restore_lustre_params <$save_params
11651         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11652
11653         # Error out if no new thread has started or Thread started is greater
11654         # than thread max.
11655         if [[ $thread_started -le $OSTIO_pre ||
11656                         $thread_started -gt $thread_max ]]; then
11657                 error "ll_ost_io: thread_started $thread_started" \
11658                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11659                       "No new thread started or thread started greater " \
11660                       "than thread_max."
11661         fi
11662 }
11663 run_test 115 "verify dynamic thread creation===================="
11664
11665 free_min_max () {
11666         wait_delete_completed
11667         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11668         echo "OST kbytes available: ${AVAIL[@]}"
11669         MAXV=${AVAIL[0]}
11670         MAXI=0
11671         MINV=${AVAIL[0]}
11672         MINI=0
11673         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11674                 #echo OST $i: ${AVAIL[i]}kb
11675                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11676                         MAXV=${AVAIL[i]}
11677                         MAXI=$i
11678                 fi
11679                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11680                         MINV=${AVAIL[i]}
11681                         MINI=$i
11682                 fi
11683         done
11684         echo "Min free space: OST $MINI: $MINV"
11685         echo "Max free space: OST $MAXI: $MAXV"
11686 }
11687
11688 test_116a() { # was previously test_116()
11689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11690         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11691         remote_mds_nodsh && skip "remote MDS with nodsh"
11692
11693         echo -n "Free space priority "
11694         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11695                 head -n1
11696         declare -a AVAIL
11697         free_min_max
11698
11699         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11700         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11701         trap simple_cleanup_common EXIT
11702
11703         # Check if we need to generate uneven OSTs
11704         test_mkdir -p $DIR/$tdir/OST${MINI}
11705         local FILL=$((MINV / 4))
11706         local DIFF=$((MAXV - MINV))
11707         local DIFF2=$((DIFF * 100 / MINV))
11708
11709         local threshold=$(do_facet $SINGLEMDS \
11710                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11711         threshold=${threshold%%%}
11712         echo -n "Check for uneven OSTs: "
11713         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11714
11715         if [[ $DIFF2 -gt $threshold ]]; then
11716                 echo "ok"
11717                 echo "Don't need to fill OST$MINI"
11718         else
11719                 # generate uneven OSTs. Write 2% over the QOS threshold value
11720                 echo "no"
11721                 DIFF=$((threshold - DIFF2 + 2))
11722                 DIFF2=$((MINV * DIFF / 100))
11723                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11724                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11725                         error "setstripe failed"
11726                 DIFF=$((DIFF2 / 2048))
11727                 i=0
11728                 while [ $i -lt $DIFF ]; do
11729                         i=$((i + 1))
11730                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11731                                 bs=2M count=1 2>/dev/null
11732                         echo -n .
11733                 done
11734                 echo .
11735                 sync
11736                 sleep_maxage
11737                 free_min_max
11738         fi
11739
11740         DIFF=$((MAXV - MINV))
11741         DIFF2=$((DIFF * 100 / MINV))
11742         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11743         if [ $DIFF2 -gt $threshold ]; then
11744                 echo "ok"
11745         else
11746                 echo "failed - QOS mode won't be used"
11747                 simple_cleanup_common
11748                 skip "QOS imbalance criteria not met"
11749         fi
11750
11751         MINI1=$MINI
11752         MINV1=$MINV
11753         MAXI1=$MAXI
11754         MAXV1=$MAXV
11755
11756         # now fill using QOS
11757         $LFS setstripe -c 1 $DIR/$tdir
11758         FILL=$((FILL / 200))
11759         if [ $FILL -gt 600 ]; then
11760                 FILL=600
11761         fi
11762         echo "writing $FILL files to QOS-assigned OSTs"
11763         i=0
11764         while [ $i -lt $FILL ]; do
11765                 i=$((i + 1))
11766                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11767                         count=1 2>/dev/null
11768                 echo -n .
11769         done
11770         echo "wrote $i 200k files"
11771         sync
11772         sleep_maxage
11773
11774         echo "Note: free space may not be updated, so measurements might be off"
11775         free_min_max
11776         DIFF2=$((MAXV - MINV))
11777         echo "free space delta: orig $DIFF final $DIFF2"
11778         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11779         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11780         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11781         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11782         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11783         if [[ $DIFF -gt 0 ]]; then
11784                 FILL=$((DIFF2 * 100 / DIFF - 100))
11785                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11786         fi
11787
11788         # Figure out which files were written where
11789         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11790                awk '/'$MINI1': / {print $2; exit}')
11791         echo $UUID
11792         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11793         echo "$MINC files created on smaller OST $MINI1"
11794         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11795                awk '/'$MAXI1': / {print $2; exit}')
11796         echo $UUID
11797         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11798         echo "$MAXC files created on larger OST $MAXI1"
11799         if [[ $MINC -gt 0 ]]; then
11800                 FILL=$((MAXC * 100 / MINC - 100))
11801                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11802         fi
11803         [[ $MAXC -gt $MINC ]] ||
11804                 error_ignore LU-9 "stripe QOS didn't balance free space"
11805         simple_cleanup_common
11806 }
11807 run_test 116a "stripe QOS: free space balance ==================="
11808
11809 test_116b() { # LU-2093
11810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11811         remote_mds_nodsh && skip "remote MDS with nodsh"
11812
11813 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11814         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11815                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11816         [ -z "$old_rr" ] && skip "no QOS"
11817         do_facet $SINGLEMDS lctl set_param \
11818                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11819         mkdir -p $DIR/$tdir
11820         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11821         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11822         do_facet $SINGLEMDS lctl set_param fail_loc=0
11823         rm -rf $DIR/$tdir
11824         do_facet $SINGLEMDS lctl set_param \
11825                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11826 }
11827 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11828
11829 test_117() # bug 10891
11830 {
11831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11832
11833         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11834         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11835         lctl set_param fail_loc=0x21e
11836         > $DIR/$tfile || error "truncate failed"
11837         lctl set_param fail_loc=0
11838         echo "Truncate succeeded."
11839         rm -f $DIR/$tfile
11840 }
11841 run_test 117 "verify osd extend =========="
11842
11843 NO_SLOW_RESENDCOUNT=4
11844 export OLD_RESENDCOUNT=""
11845 set_resend_count () {
11846         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11847         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11848         lctl set_param -n $PROC_RESENDCOUNT $1
11849         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11850 }
11851
11852 # for reduce test_118* time (b=14842)
11853 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11854
11855 # Reset async IO behavior after error case
11856 reset_async() {
11857         FILE=$DIR/reset_async
11858
11859         # Ensure all OSCs are cleared
11860         $LFS setstripe -c -1 $FILE
11861         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11862         sync
11863         rm $FILE
11864 }
11865
11866 test_118a() #bug 11710
11867 {
11868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11869
11870         reset_async
11871
11872         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11873         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11874         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11875
11876         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11877                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11878                 return 1;
11879         fi
11880         rm -f $DIR/$tfile
11881 }
11882 run_test 118a "verify O_SYNC works =========="
11883
11884 test_118b()
11885 {
11886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11887         remote_ost_nodsh && skip "remote OST with nodsh"
11888
11889         reset_async
11890
11891         #define OBD_FAIL_SRV_ENOENT 0x217
11892         set_nodes_failloc "$(osts_nodes)" 0x217
11893         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11894         RC=$?
11895         set_nodes_failloc "$(osts_nodes)" 0
11896         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11897         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11898                     grep -c writeback)
11899
11900         if [[ $RC -eq 0 ]]; then
11901                 error "Must return error due to dropped pages, rc=$RC"
11902                 return 1;
11903         fi
11904
11905         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11906                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11907                 return 1;
11908         fi
11909
11910         echo "Dirty pages not leaked on ENOENT"
11911
11912         # Due to the above error the OSC will issue all RPCs syncronously
11913         # until a subsequent RPC completes successfully without error.
11914         $MULTIOP $DIR/$tfile Ow4096yc
11915         rm -f $DIR/$tfile
11916
11917         return 0
11918 }
11919 run_test 118b "Reclaim dirty pages on fatal error =========="
11920
11921 test_118c()
11922 {
11923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11924
11925         # for 118c, restore the original resend count, LU-1940
11926         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11927                                 set_resend_count $OLD_RESENDCOUNT
11928         remote_ost_nodsh && skip "remote OST with nodsh"
11929
11930         reset_async
11931
11932         #define OBD_FAIL_OST_EROFS               0x216
11933         set_nodes_failloc "$(osts_nodes)" 0x216
11934
11935         # multiop should block due to fsync until pages are written
11936         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11937         MULTIPID=$!
11938         sleep 1
11939
11940         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11941                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11942         fi
11943
11944         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11945                     grep -c writeback)
11946         if [[ $WRITEBACK -eq 0 ]]; then
11947                 error "No page in writeback, writeback=$WRITEBACK"
11948         fi
11949
11950         set_nodes_failloc "$(osts_nodes)" 0
11951         wait $MULTIPID
11952         RC=$?
11953         if [[ $RC -ne 0 ]]; then
11954                 error "Multiop fsync failed, rc=$RC"
11955         fi
11956
11957         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11958         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11959                     grep -c writeback)
11960         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11961                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11962         fi
11963
11964         rm -f $DIR/$tfile
11965         echo "Dirty pages flushed via fsync on EROFS"
11966         return 0
11967 }
11968 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11969
11970 # continue to use small resend count to reduce test_118* time (b=14842)
11971 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11972
11973 test_118d()
11974 {
11975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11976         remote_ost_nodsh && skip "remote OST with nodsh"
11977
11978         reset_async
11979
11980         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11981         set_nodes_failloc "$(osts_nodes)" 0x214
11982         # multiop should block due to fsync until pages are written
11983         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11984         MULTIPID=$!
11985         sleep 1
11986
11987         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11988                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11989         fi
11990
11991         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11992                     grep -c writeback)
11993         if [[ $WRITEBACK -eq 0 ]]; then
11994                 error "No page in writeback, writeback=$WRITEBACK"
11995         fi
11996
11997         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11998         set_nodes_failloc "$(osts_nodes)" 0
11999
12000         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12001         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12002                     grep -c writeback)
12003         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12004                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12005         fi
12006
12007         rm -f $DIR/$tfile
12008         echo "Dirty pages gaurenteed flushed via fsync"
12009         return 0
12010 }
12011 run_test 118d "Fsync validation inject a delay of the bulk =========="
12012
12013 test_118f() {
12014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12015
12016         reset_async
12017
12018         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12019         lctl set_param fail_loc=0x8000040a
12020
12021         # Should simulate EINVAL error which is fatal
12022         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12023         RC=$?
12024         if [[ $RC -eq 0 ]]; then
12025                 error "Must return error due to dropped pages, rc=$RC"
12026         fi
12027
12028         lctl set_param fail_loc=0x0
12029
12030         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12031         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12032         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12033                     grep -c writeback)
12034         if [[ $LOCKED -ne 0 ]]; then
12035                 error "Locked pages remain in cache, locked=$LOCKED"
12036         fi
12037
12038         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12039                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12040         fi
12041
12042         rm -f $DIR/$tfile
12043         echo "No pages locked after fsync"
12044
12045         reset_async
12046         return 0
12047 }
12048 run_test 118f "Simulate unrecoverable OSC side error =========="
12049
12050 test_118g() {
12051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12052
12053         reset_async
12054
12055         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12056         lctl set_param fail_loc=0x406
12057
12058         # simulate local -ENOMEM
12059         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12060         RC=$?
12061
12062         lctl set_param fail_loc=0
12063         if [[ $RC -eq 0 ]]; then
12064                 error "Must return error due to dropped pages, rc=$RC"
12065         fi
12066
12067         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12068         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12069         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12070                         grep -c writeback)
12071         if [[ $LOCKED -ne 0 ]]; then
12072                 error "Locked pages remain in cache, locked=$LOCKED"
12073         fi
12074
12075         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12076                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12077         fi
12078
12079         rm -f $DIR/$tfile
12080         echo "No pages locked after fsync"
12081
12082         reset_async
12083         return 0
12084 }
12085 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12086
12087 test_118h() {
12088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12089         remote_ost_nodsh && skip "remote OST with nodsh"
12090
12091         reset_async
12092
12093         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12094         set_nodes_failloc "$(osts_nodes)" 0x20e
12095         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12096         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12097         RC=$?
12098
12099         set_nodes_failloc "$(osts_nodes)" 0
12100         if [[ $RC -eq 0 ]]; then
12101                 error "Must return error due to dropped pages, rc=$RC"
12102         fi
12103
12104         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12105         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12106         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12107                     grep -c writeback)
12108         if [[ $LOCKED -ne 0 ]]; then
12109                 error "Locked pages remain in cache, locked=$LOCKED"
12110         fi
12111
12112         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12113                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12114         fi
12115
12116         rm -f $DIR/$tfile
12117         echo "No pages locked after fsync"
12118
12119         return 0
12120 }
12121 run_test 118h "Verify timeout in handling recoverables errors  =========="
12122
12123 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12124
12125 test_118i() {
12126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12127         remote_ost_nodsh && skip "remote OST with nodsh"
12128
12129         reset_async
12130
12131         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12132         set_nodes_failloc "$(osts_nodes)" 0x20e
12133
12134         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12135         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12136         PID=$!
12137         sleep 5
12138         set_nodes_failloc "$(osts_nodes)" 0
12139
12140         wait $PID
12141         RC=$?
12142         if [[ $RC -ne 0 ]]; then
12143                 error "got error, but should be not, rc=$RC"
12144         fi
12145
12146         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12147         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12148         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12149         if [[ $LOCKED -ne 0 ]]; then
12150                 error "Locked pages remain in cache, locked=$LOCKED"
12151         fi
12152
12153         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12154                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12155         fi
12156
12157         rm -f $DIR/$tfile
12158         echo "No pages locked after fsync"
12159
12160         return 0
12161 }
12162 run_test 118i "Fix error before timeout in recoverable error  =========="
12163
12164 [ "$SLOW" = "no" ] && set_resend_count 4
12165
12166 test_118j() {
12167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12168         remote_ost_nodsh && skip "remote OST with nodsh"
12169
12170         reset_async
12171
12172         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12173         set_nodes_failloc "$(osts_nodes)" 0x220
12174
12175         # return -EIO from OST
12176         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12177         RC=$?
12178         set_nodes_failloc "$(osts_nodes)" 0x0
12179         if [[ $RC -eq 0 ]]; then
12180                 error "Must return error due to dropped pages, rc=$RC"
12181         fi
12182
12183         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12184         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12185         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12186         if [[ $LOCKED -ne 0 ]]; then
12187                 error "Locked pages remain in cache, locked=$LOCKED"
12188         fi
12189
12190         # in recoverable error on OST we want resend and stay until it finished
12191         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12192                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12193         fi
12194
12195         rm -f $DIR/$tfile
12196         echo "No pages locked after fsync"
12197
12198         return 0
12199 }
12200 run_test 118j "Simulate unrecoverable OST side error =========="
12201
12202 test_118k()
12203 {
12204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12205         remote_ost_nodsh && skip "remote OSTs with nodsh"
12206
12207         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12208         set_nodes_failloc "$(osts_nodes)" 0x20e
12209         test_mkdir $DIR/$tdir
12210
12211         for ((i=0;i<10;i++)); do
12212                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12213                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12214                 SLEEPPID=$!
12215                 sleep 0.500s
12216                 kill $SLEEPPID
12217                 wait $SLEEPPID
12218         done
12219
12220         set_nodes_failloc "$(osts_nodes)" 0
12221         rm -rf $DIR/$tdir
12222 }
12223 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12224
12225 test_118l() # LU-646
12226 {
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228
12229         test_mkdir $DIR/$tdir
12230         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12231         rm -rf $DIR/$tdir
12232 }
12233 run_test 118l "fsync dir"
12234
12235 test_118m() # LU-3066
12236 {
12237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12238
12239         test_mkdir $DIR/$tdir
12240         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12241         rm -rf $DIR/$tdir
12242 }
12243 run_test 118m "fdatasync dir ========="
12244
12245 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12246
12247 test_118n()
12248 {
12249         local begin
12250         local end
12251
12252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12253         remote_ost_nodsh && skip "remote OSTs with nodsh"
12254
12255         # Sleep to avoid a cached response.
12256         #define OBD_STATFS_CACHE_SECONDS 1
12257         sleep 2
12258
12259         # Inject a 10 second delay in the OST_STATFS handler.
12260         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12261         set_nodes_failloc "$(osts_nodes)" 0x242
12262
12263         begin=$SECONDS
12264         stat --file-system $MOUNT > /dev/null
12265         end=$SECONDS
12266
12267         set_nodes_failloc "$(osts_nodes)" 0
12268
12269         if ((end - begin > 20)); then
12270             error "statfs took $((end - begin)) seconds, expected 10"
12271         fi
12272 }
12273 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12274
12275 test_119a() # bug 11737
12276 {
12277         BSIZE=$((512 * 1024))
12278         directio write $DIR/$tfile 0 1 $BSIZE
12279         # We ask to read two blocks, which is more than a file size.
12280         # directio will indicate an error when requested and actual
12281         # sizes aren't equeal (a normal situation in this case) and
12282         # print actual read amount.
12283         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12284         if [ "$NOB" != "$BSIZE" ]; then
12285                 error "read $NOB bytes instead of $BSIZE"
12286         fi
12287         rm -f $DIR/$tfile
12288 }
12289 run_test 119a "Short directIO read must return actual read amount"
12290
12291 test_119b() # bug 11737
12292 {
12293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12294
12295         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12296         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12297         sync
12298         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12299                 error "direct read failed"
12300         rm -f $DIR/$tfile
12301 }
12302 run_test 119b "Sparse directIO read must return actual read amount"
12303
12304 test_119c() # bug 13099
12305 {
12306         BSIZE=1048576
12307         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12308         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12309         rm -f $DIR/$tfile
12310 }
12311 run_test 119c "Testing for direct read hitting hole"
12312
12313 test_119d() # bug 15950
12314 {
12315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12316
12317         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12318         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12319         BSIZE=1048576
12320         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12321         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12322         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12323         lctl set_param fail_loc=0x40d
12324         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12325         pid_dio=$!
12326         sleep 1
12327         cat $DIR/$tfile > /dev/null &
12328         lctl set_param fail_loc=0
12329         pid_reads=$!
12330         wait $pid_dio
12331         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12332         sleep 2
12333         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12334         error "the read rpcs have not completed in 2s"
12335         rm -f $DIR/$tfile
12336         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12337 }
12338 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12339
12340 test_120a() {
12341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12342         remote_mds_nodsh && skip "remote MDS with nodsh"
12343         test_mkdir -i0 -c1 $DIR/$tdir
12344         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12345                 skip_env "no early lock cancel on server"
12346
12347         lru_resize_disable mdc
12348         lru_resize_disable osc
12349         cancel_lru_locks mdc
12350         # asynchronous object destroy at MDT could cause bl ast to client
12351         cancel_lru_locks osc
12352
12353         stat $DIR/$tdir > /dev/null
12354         can1=$(do_facet mds1 \
12355                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12356                awk '/ldlm_cancel/ {print $2}')
12357         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12358                awk '/ldlm_bl_callback/ {print $2}')
12359         test_mkdir -i0 -c1 $DIR/$tdir/d1
12360         can2=$(do_facet mds1 \
12361                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12362                awk '/ldlm_cancel/ {print $2}')
12363         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12364                awk '/ldlm_bl_callback/ {print $2}')
12365         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12366         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12367         lru_resize_enable mdc
12368         lru_resize_enable osc
12369 }
12370 run_test 120a "Early Lock Cancel: mkdir test"
12371
12372 test_120b() {
12373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12374         remote_mds_nodsh && skip "remote MDS with nodsh"
12375         test_mkdir $DIR/$tdir
12376         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12377                 skip_env "no early lock cancel on server"
12378
12379         lru_resize_disable mdc
12380         lru_resize_disable osc
12381         cancel_lru_locks mdc
12382         stat $DIR/$tdir > /dev/null
12383         can1=$(do_facet $SINGLEMDS \
12384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12385                awk '/ldlm_cancel/ {print $2}')
12386         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12387                awk '/ldlm_bl_callback/ {print $2}')
12388         touch $DIR/$tdir/f1
12389         can2=$(do_facet $SINGLEMDS \
12390                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12391                awk '/ldlm_cancel/ {print $2}')
12392         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12393                awk '/ldlm_bl_callback/ {print $2}')
12394         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12395         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12396         lru_resize_enable mdc
12397         lru_resize_enable osc
12398 }
12399 run_test 120b "Early Lock Cancel: create test"
12400
12401 test_120c() {
12402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12403         remote_mds_nodsh && skip "remote MDS with nodsh"
12404         test_mkdir -i0 -c1 $DIR/$tdir
12405         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12406                 skip "no early lock cancel on server"
12407
12408         lru_resize_disable mdc
12409         lru_resize_disable osc
12410         test_mkdir -i0 -c1 $DIR/$tdir/d1
12411         test_mkdir -i0 -c1 $DIR/$tdir/d2
12412         touch $DIR/$tdir/d1/f1
12413         cancel_lru_locks mdc
12414         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12415         can1=$(do_facet mds1 \
12416                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12417                awk '/ldlm_cancel/ {print $2}')
12418         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12419                awk '/ldlm_bl_callback/ {print $2}')
12420         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12421         can2=$(do_facet mds1 \
12422                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12423                awk '/ldlm_cancel/ {print $2}')
12424         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12425                awk '/ldlm_bl_callback/ {print $2}')
12426         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12427         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12428         lru_resize_enable mdc
12429         lru_resize_enable osc
12430 }
12431 run_test 120c "Early Lock Cancel: link test"
12432
12433 test_120d() {
12434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12435         remote_mds_nodsh && skip "remote MDS with nodsh"
12436         test_mkdir -i0 -c1 $DIR/$tdir
12437         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12438                 skip_env "no early lock cancel on server"
12439
12440         lru_resize_disable mdc
12441         lru_resize_disable osc
12442         touch $DIR/$tdir
12443         cancel_lru_locks mdc
12444         stat $DIR/$tdir > /dev/null
12445         can1=$(do_facet mds1 \
12446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12447                awk '/ldlm_cancel/ {print $2}')
12448         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12449                awk '/ldlm_bl_callback/ {print $2}')
12450         chmod a+x $DIR/$tdir
12451         can2=$(do_facet mds1 \
12452                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12453                awk '/ldlm_cancel/ {print $2}')
12454         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12455                awk '/ldlm_bl_callback/ {print $2}')
12456         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12457         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12458         lru_resize_enable mdc
12459         lru_resize_enable osc
12460 }
12461 run_test 120d "Early Lock Cancel: setattr test"
12462
12463 test_120e() {
12464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12465         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12466                 skip_env "no early lock cancel on server"
12467         remote_mds_nodsh && skip "remote MDS with nodsh"
12468
12469         local dlmtrace_set=false
12470
12471         test_mkdir -i0 -c1 $DIR/$tdir
12472         lru_resize_disable mdc
12473         lru_resize_disable osc
12474         ! $LCTL get_param debug | grep -q dlmtrace &&
12475                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12476         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12477         cancel_lru_locks mdc
12478         cancel_lru_locks osc
12479         dd if=$DIR/$tdir/f1 of=/dev/null
12480         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12481         # XXX client can not do early lock cancel of OST lock
12482         # during unlink (LU-4206), so cancel osc lock now.
12483         sleep 2
12484         cancel_lru_locks osc
12485         can1=$(do_facet mds1 \
12486                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12487                awk '/ldlm_cancel/ {print $2}')
12488         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12489                awk '/ldlm_bl_callback/ {print $2}')
12490         unlink $DIR/$tdir/f1
12491         sleep 5
12492         can2=$(do_facet mds1 \
12493                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12494                awk '/ldlm_cancel/ {print $2}')
12495         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12496                awk '/ldlm_bl_callback/ {print $2}')
12497         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12498                 $LCTL dk $TMP/cancel.debug.txt
12499         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12500                 $LCTL dk $TMP/blocking.debug.txt
12501         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12502         lru_resize_enable mdc
12503         lru_resize_enable osc
12504 }
12505 run_test 120e "Early Lock Cancel: unlink test"
12506
12507 test_120f() {
12508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12509         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12510                 skip_env "no early lock cancel on server"
12511         remote_mds_nodsh && skip "remote MDS with nodsh"
12512
12513         test_mkdir -i0 -c1 $DIR/$tdir
12514         lru_resize_disable mdc
12515         lru_resize_disable osc
12516         test_mkdir -i0 -c1 $DIR/$tdir/d1
12517         test_mkdir -i0 -c1 $DIR/$tdir/d2
12518         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12519         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12520         cancel_lru_locks mdc
12521         cancel_lru_locks osc
12522         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12523         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12524         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12525         # XXX client can not do early lock cancel of OST lock
12526         # during rename (LU-4206), so cancel osc lock now.
12527         sleep 2
12528         cancel_lru_locks osc
12529         can1=$(do_facet mds1 \
12530                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12531                awk '/ldlm_cancel/ {print $2}')
12532         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12533                awk '/ldlm_bl_callback/ {print $2}')
12534         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12535         sleep 5
12536         can2=$(do_facet mds1 \
12537                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12538                awk '/ldlm_cancel/ {print $2}')
12539         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12540                awk '/ldlm_bl_callback/ {print $2}')
12541         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12542         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12543         lru_resize_enable mdc
12544         lru_resize_enable osc
12545 }
12546 run_test 120f "Early Lock Cancel: rename test"
12547
12548 test_120g() {
12549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12550         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12551                 skip_env "no early lock cancel on server"
12552         remote_mds_nodsh && skip "remote MDS with nodsh"
12553
12554         lru_resize_disable mdc
12555         lru_resize_disable osc
12556         count=10000
12557         echo create $count files
12558         test_mkdir $DIR/$tdir
12559         cancel_lru_locks mdc
12560         cancel_lru_locks osc
12561         t0=$(date +%s)
12562
12563         can0=$(do_facet $SINGLEMDS \
12564                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12565                awk '/ldlm_cancel/ {print $2}')
12566         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12567                awk '/ldlm_bl_callback/ {print $2}')
12568         createmany -o $DIR/$tdir/f $count
12569         sync
12570         can1=$(do_facet $SINGLEMDS \
12571                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12572                awk '/ldlm_cancel/ {print $2}')
12573         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12574                awk '/ldlm_bl_callback/ {print $2}')
12575         t1=$(date +%s)
12576         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12577         echo rm $count files
12578         rm -r $DIR/$tdir
12579         sync
12580         can2=$(do_facet $SINGLEMDS \
12581                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12582                awk '/ldlm_cancel/ {print $2}')
12583         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12584                awk '/ldlm_bl_callback/ {print $2}')
12585         t2=$(date +%s)
12586         echo total: $count removes in $((t2-t1))
12587         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12588         sleep 2
12589         # wait for commitment of removal
12590         lru_resize_enable mdc
12591         lru_resize_enable osc
12592 }
12593 run_test 120g "Early Lock Cancel: performance test"
12594
12595 test_121() { #bug #10589
12596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12597
12598         rm -rf $DIR/$tfile
12599         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12600 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12601         lctl set_param fail_loc=0x310
12602         cancel_lru_locks osc > /dev/null
12603         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12604         lctl set_param fail_loc=0
12605         [[ $reads -eq $writes ]] ||
12606                 error "read $reads blocks, must be $writes blocks"
12607 }
12608 run_test 121 "read cancel race ========="
12609
12610 test_123a_base() { # was test 123, statahead(bug 11401)
12611         local lsx="$1"
12612
12613         SLOWOK=0
12614         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12615                 log "testing UP system. Performance may be lower than expected."
12616                 SLOWOK=1
12617         fi
12618
12619         rm -rf $DIR/$tdir
12620         test_mkdir $DIR/$tdir
12621         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12622         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12623         MULT=10
12624         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12625                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12626
12627                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12628                 lctl set_param -n llite.*.statahead_max 0
12629                 lctl get_param llite.*.statahead_max
12630                 cancel_lru_locks mdc
12631                 cancel_lru_locks osc
12632                 stime=$(date +%s)
12633                 time $lsx $DIR/$tdir | wc -l
12634                 etime=$(date +%s)
12635                 delta=$((etime - stime))
12636                 log "$lsx $i files without statahead: $delta sec"
12637                 lctl set_param llite.*.statahead_max=$max
12638
12639                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12640                         grep "statahead wrong:" | awk '{print $3}')
12641                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12642                 cancel_lru_locks mdc
12643                 cancel_lru_locks osc
12644                 stime=$(date +%s)
12645                 time $lsx $DIR/$tdir | wc -l
12646                 etime=$(date +%s)
12647                 delta_sa=$((etime - stime))
12648                 log "$lsx $i files with statahead: $delta_sa sec"
12649                 lctl get_param -n llite.*.statahead_stats
12650                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12651                         grep "statahead wrong:" | awk '{print $3}')
12652
12653                 [[ $swrong -lt $ewrong ]] &&
12654                         log "statahead was stopped, maybe too many locks held!"
12655                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12656
12657                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12658                         max=$(lctl get_param -n llite.*.statahead_max |
12659                                 head -n 1)
12660                         lctl set_param -n llite.*.statahead_max 0
12661                         lctl get_param llite.*.statahead_max
12662                         cancel_lru_locks mdc
12663                         cancel_lru_locks osc
12664                         stime=$(date +%s)
12665                         time $lsx $DIR/$tdir | wc -l
12666                         etime=$(date +%s)
12667                         delta=$((etime - stime))
12668                         log "$lsx $i files again without statahead: $delta sec"
12669                         lctl set_param llite.*.statahead_max=$max
12670                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12671                                 if [  $SLOWOK -eq 0 ]; then
12672                                         error "$lsx $i files is slower with statahead!"
12673                                 else
12674                                         log "$lsx $i files is slower with statahead!"
12675                                 fi
12676                                 break
12677                         fi
12678                 fi
12679
12680                 [ $delta -gt 20 ] && break
12681                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12682                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12683         done
12684         log "$lsx done"
12685
12686         stime=$(date +%s)
12687         rm -r $DIR/$tdir
12688         sync
12689         etime=$(date +%s)
12690         delta=$((etime - stime))
12691         log "rm -r $DIR/$tdir/: $delta seconds"
12692         log "rm done"
12693         lctl get_param -n llite.*.statahead_stats
12694 }
12695
12696 test_123aa() {
12697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12698
12699         test_123a_base "ls -l"
12700 }
12701 run_test 123aa "verify statahead work"
12702
12703 test_123ab() {
12704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12705
12706         statx_supported || skip_env "Test must be statx() syscall supported"
12707
12708         test_123a_base "$STATX -l"
12709 }
12710 run_test 123ab "verify statahead work by using statx"
12711
12712 test_123ac() {
12713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12714
12715         statx_supported || skip_env "Test must be statx() syscall supported"
12716
12717         local rpcs_before
12718         local rpcs_after
12719         local agl_before
12720         local agl_after
12721
12722         cancel_lru_locks $OSC
12723         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12724         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12725                 awk '/agl.total:/ {print $3}')
12726         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12727         test_123a_base "$STATX --cached=always -D"
12728         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12729                 awk '/agl.total:/ {print $3}')
12730         [ $agl_before -eq $agl_after ] ||
12731                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12732         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12733         [ $rpcs_after -eq $rpcs_before ] ||
12734                 error "$STATX should not send glimpse RPCs to $OSC"
12735 }
12736 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12737
12738 test_123b () { # statahead(bug 15027)
12739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12740
12741         test_mkdir $DIR/$tdir
12742         createmany -o $DIR/$tdir/$tfile-%d 1000
12743
12744         cancel_lru_locks mdc
12745         cancel_lru_locks osc
12746
12747 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12748         lctl set_param fail_loc=0x80000803
12749         ls -lR $DIR/$tdir > /dev/null
12750         log "ls done"
12751         lctl set_param fail_loc=0x0
12752         lctl get_param -n llite.*.statahead_stats
12753         rm -r $DIR/$tdir
12754         sync
12755
12756 }
12757 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12758
12759 test_123c() {
12760         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12761
12762         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12763         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12764         touch $DIR/$tdir.1/{1..3}
12765         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12766
12767         remount_client $MOUNT
12768
12769         $MULTIOP $DIR/$tdir.0 Q
12770
12771         # let statahead to complete
12772         ls -l $DIR/$tdir.0 > /dev/null
12773
12774         testid=$(echo $TESTNAME | tr '_' ' ')
12775         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12776                 error "statahead warning" || true
12777 }
12778 run_test 123c "Can not initialize inode warning on DNE statahead"
12779
12780 test_124a() {
12781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12782         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12783                 skip_env "no lru resize on server"
12784
12785         local NR=2000
12786
12787         test_mkdir $DIR/$tdir
12788
12789         log "create $NR files at $DIR/$tdir"
12790         createmany -o $DIR/$tdir/f $NR ||
12791                 error "failed to create $NR files in $DIR/$tdir"
12792
12793         cancel_lru_locks mdc
12794         ls -l $DIR/$tdir > /dev/null
12795
12796         local NSDIR=""
12797         local LRU_SIZE=0
12798         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12799                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12800                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12801                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12802                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12803                         log "NSDIR=$NSDIR"
12804                         log "NS=$(basename $NSDIR)"
12805                         break
12806                 fi
12807         done
12808
12809         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12810                 skip "Not enough cached locks created!"
12811         fi
12812         log "LRU=$LRU_SIZE"
12813
12814         local SLEEP=30
12815
12816         # We know that lru resize allows one client to hold $LIMIT locks
12817         # for 10h. After that locks begin to be killed by client.
12818         local MAX_HRS=10
12819         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12820         log "LIMIT=$LIMIT"
12821         if [ $LIMIT -lt $LRU_SIZE ]; then
12822                 skip "Limit is too small $LIMIT"
12823         fi
12824
12825         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12826         # killing locks. Some time was spent for creating locks. This means
12827         # that up to the moment of sleep finish we must have killed some of
12828         # them (10-100 locks). This depends on how fast ther were created.
12829         # Many of them were touched in almost the same moment and thus will
12830         # be killed in groups.
12831         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12832
12833         # Use $LRU_SIZE_B here to take into account real number of locks
12834         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12835         local LRU_SIZE_B=$LRU_SIZE
12836         log "LVF=$LVF"
12837         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12838         log "OLD_LVF=$OLD_LVF"
12839         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12840
12841         # Let's make sure that we really have some margin. Client checks
12842         # cached locks every 10 sec.
12843         SLEEP=$((SLEEP+20))
12844         log "Sleep ${SLEEP} sec"
12845         local SEC=0
12846         while ((SEC<$SLEEP)); do
12847                 echo -n "..."
12848                 sleep 5
12849                 SEC=$((SEC+5))
12850                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12851                 echo -n "$LRU_SIZE"
12852         done
12853         echo ""
12854         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12855         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12856
12857         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12858                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12859                 unlinkmany $DIR/$tdir/f $NR
12860                 return
12861         }
12862
12863         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12864         log "unlink $NR files at $DIR/$tdir"
12865         unlinkmany $DIR/$tdir/f $NR
12866 }
12867 run_test 124a "lru resize ======================================="
12868
12869 get_max_pool_limit()
12870 {
12871         local limit=$($LCTL get_param \
12872                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12873         local max=0
12874         for l in $limit; do
12875                 if [[ $l -gt $max ]]; then
12876                         max=$l
12877                 fi
12878         done
12879         echo $max
12880 }
12881
12882 test_124b() {
12883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12884         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12885                 skip_env "no lru resize on server"
12886
12887         LIMIT=$(get_max_pool_limit)
12888
12889         NR=$(($(default_lru_size)*20))
12890         if [[ $NR -gt $LIMIT ]]; then
12891                 log "Limit lock number by $LIMIT locks"
12892                 NR=$LIMIT
12893         fi
12894
12895         IFree=$(mdsrate_inodes_available)
12896         if [ $IFree -lt $NR ]; then
12897                 log "Limit lock number by $IFree inodes"
12898                 NR=$IFree
12899         fi
12900
12901         lru_resize_disable mdc
12902         test_mkdir -p $DIR/$tdir/disable_lru_resize
12903
12904         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12905         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12906         cancel_lru_locks mdc
12907         stime=`date +%s`
12908         PID=""
12909         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12910         PID="$PID $!"
12911         sleep 2
12912         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12913         PID="$PID $!"
12914         sleep 2
12915         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12916         PID="$PID $!"
12917         wait $PID
12918         etime=`date +%s`
12919         nolruresize_delta=$((etime-stime))
12920         log "ls -la time: $nolruresize_delta seconds"
12921         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12922         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12923
12924         lru_resize_enable mdc
12925         test_mkdir -p $DIR/$tdir/enable_lru_resize
12926
12927         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12928         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12929         cancel_lru_locks mdc
12930         stime=`date +%s`
12931         PID=""
12932         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12933         PID="$PID $!"
12934         sleep 2
12935         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12936         PID="$PID $!"
12937         sleep 2
12938         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12939         PID="$PID $!"
12940         wait $PID
12941         etime=`date +%s`
12942         lruresize_delta=$((etime-stime))
12943         log "ls -la time: $lruresize_delta seconds"
12944         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12945
12946         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12947                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12948         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12949                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12950         else
12951                 log "lru resize performs the same with no lru resize"
12952         fi
12953         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12954 }
12955 run_test 124b "lru resize (performance test) ======================="
12956
12957 test_124c() {
12958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12959         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12960                 skip_env "no lru resize on server"
12961
12962         # cache ununsed locks on client
12963         local nr=100
12964         cancel_lru_locks mdc
12965         test_mkdir $DIR/$tdir
12966         createmany -o $DIR/$tdir/f $nr ||
12967                 error "failed to create $nr files in $DIR/$tdir"
12968         ls -l $DIR/$tdir > /dev/null
12969
12970         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12971         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12972         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12973         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12974         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12975
12976         # set lru_max_age to 1 sec
12977         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12978         echo "sleep $((recalc_p * 2)) seconds..."
12979         sleep $((recalc_p * 2))
12980
12981         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12982         # restore lru_max_age
12983         $LCTL set_param -n $nsdir.lru_max_age $max_age
12984         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12985         unlinkmany $DIR/$tdir/f $nr
12986 }
12987 run_test 124c "LRUR cancel very aged locks"
12988
12989 test_124d() {
12990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12991         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12992                 skip_env "no lru resize on server"
12993
12994         # cache ununsed locks on client
12995         local nr=100
12996
12997         lru_resize_disable mdc
12998         stack_trap "lru_resize_enable mdc" EXIT
12999
13000         cancel_lru_locks mdc
13001
13002         # asynchronous object destroy at MDT could cause bl ast to client
13003         test_mkdir $DIR/$tdir
13004         createmany -o $DIR/$tdir/f $nr ||
13005                 error "failed to create $nr files in $DIR/$tdir"
13006         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13007
13008         ls -l $DIR/$tdir > /dev/null
13009
13010         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13011         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13012         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13013         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13014
13015         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13016
13017         # set lru_max_age to 1 sec
13018         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13019         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13020
13021         echo "sleep $((recalc_p * 2)) seconds..."
13022         sleep $((recalc_p * 2))
13023
13024         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13025
13026         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13027 }
13028 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13029
13030 test_125() { # 13358
13031         $LCTL get_param -n llite.*.client_type | grep -q local ||
13032                 skip "must run as local client"
13033         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13034                 skip_env "must have acl enabled"
13035         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13036
13037         test_mkdir $DIR/$tdir
13038         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13039         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13040         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13041 }
13042 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13043
13044 test_126() { # bug 12829/13455
13045         $GSS && skip_env "must run as gss disabled"
13046         $LCTL get_param -n llite.*.client_type | grep -q local ||
13047                 skip "must run as local client"
13048         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13049
13050         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13051         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13052         rm -f $DIR/$tfile
13053         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13054 }
13055 run_test 126 "check that the fsgid provided by the client is taken into account"
13056
13057 test_127a() { # bug 15521
13058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13059         local name count samp unit min max sum sumsq
13060
13061         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13062         echo "stats before reset"
13063         $LCTL get_param osc.*.stats
13064         $LCTL set_param osc.*.stats=0
13065         local fsize=$((2048 * 1024))
13066
13067         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13068         cancel_lru_locks osc
13069         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13070
13071         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13072         stack_trap "rm -f $TMP/$tfile.tmp"
13073         while read name count samp unit min max sum sumsq; do
13074                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13075                 [ ! $min ] && error "Missing min value for $name proc entry"
13076                 eval $name=$count || error "Wrong proc format"
13077
13078                 case $name in
13079                 read_bytes|write_bytes)
13080                         [[ "$unit" =~ "bytes" ]] ||
13081                                 error "unit is not 'bytes': $unit"
13082                         (( $min >= 4096 )) || error "min is too small: $min"
13083                         (( $min <= $fsize )) || error "min is too big: $min"
13084                         (( $max >= 4096 )) || error "max is too small: $max"
13085                         (( $max <= $fsize )) || error "max is too big: $max"
13086                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13087                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13088                                 error "sumsquare is too small: $sumsq"
13089                         (( $sumsq <= $fsize * $fsize )) ||
13090                                 error "sumsquare is too big: $sumsq"
13091                         ;;
13092                 ost_read|ost_write)
13093                         [[ "$unit" =~ "usec" ]] ||
13094                                 error "unit is not 'usec': $unit"
13095                         ;;
13096                 *)      ;;
13097                 esac
13098         done < $DIR/$tfile.tmp
13099
13100         #check that we actually got some stats
13101         [ "$read_bytes" ] || error "Missing read_bytes stats"
13102         [ "$write_bytes" ] || error "Missing write_bytes stats"
13103         [ "$read_bytes" != 0 ] || error "no read done"
13104         [ "$write_bytes" != 0 ] || error "no write done"
13105 }
13106 run_test 127a "verify the client stats are sane"
13107
13108 test_127b() { # bug LU-333
13109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13110         local name count samp unit min max sum sumsq
13111
13112         echo "stats before reset"
13113         $LCTL get_param llite.*.stats
13114         $LCTL set_param llite.*.stats=0
13115
13116         # perform 2 reads and writes so MAX is different from SUM.
13117         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13118         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13119         cancel_lru_locks osc
13120         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13121         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13122
13123         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13124         stack_trap "rm -f $TMP/$tfile.tmp"
13125         while read name count samp unit min max sum sumsq; do
13126                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13127                 eval $name=$count || error "Wrong proc format"
13128
13129                 case $name in
13130                 read_bytes|write_bytes)
13131                         [[ "$unit" =~ "bytes" ]] ||
13132                                 error "unit is not 'bytes': $unit"
13133                         (( $count == 2 )) || error "count is not 2: $count"
13134                         (( $min == $PAGE_SIZE )) ||
13135                                 error "min is not $PAGE_SIZE: $min"
13136                         (( $max == $PAGE_SIZE )) ||
13137                                 error "max is not $PAGE_SIZE: $max"
13138                         (( $sum == $PAGE_SIZE * 2 )) ||
13139                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13140                         ;;
13141                 read|write)
13142                         [[ "$unit" =~ "usec" ]] ||
13143                                 error "unit is not 'usec': $unit"
13144                         ;;
13145                 *)      ;;
13146                 esac
13147         done < $TMP/$tfile.tmp
13148
13149         #check that we actually got some stats
13150         [ "$read_bytes" ] || error "Missing read_bytes stats"
13151         [ "$write_bytes" ] || error "Missing write_bytes stats"
13152         [ "$read_bytes" != 0 ] || error "no read done"
13153         [ "$write_bytes" != 0 ] || error "no write done"
13154 }
13155 run_test 127b "verify the llite client stats are sane"
13156
13157 test_127c() { # LU-12394
13158         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13159         local size
13160         local bsize
13161         local reads
13162         local writes
13163         local count
13164
13165         $LCTL set_param llite.*.extents_stats=1
13166         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13167
13168         # Use two stripes so there is enough space in default config
13169         $LFS setstripe -c 2 $DIR/$tfile
13170
13171         # Extent stats start at 0-4K and go in power of two buckets
13172         # LL_HIST_START = 12 --> 2^12 = 4K
13173         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13174         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13175         # small configs
13176         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13177                 do
13178                 # Write and read, 2x each, second time at a non-zero offset
13179                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13180                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13181                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13182                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13183                 rm -f $DIR/$tfile
13184         done
13185
13186         $LCTL get_param llite.*.extents_stats
13187
13188         count=2
13189         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13190                 do
13191                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13192                                 grep -m 1 $bsize)
13193                 reads=$(echo $bucket | awk '{print $5}')
13194                 writes=$(echo $bucket | awk '{print $9}')
13195                 [ "$reads" -eq $count ] ||
13196                         error "$reads reads in < $bsize bucket, expect $count"
13197                 [ "$writes" -eq $count ] ||
13198                         error "$writes writes in < $bsize bucket, expect $count"
13199         done
13200
13201         # Test mmap write and read
13202         $LCTL set_param llite.*.extents_stats=c
13203         size=512
13204         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13205         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13206         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13207
13208         $LCTL get_param llite.*.extents_stats
13209
13210         count=$(((size*1024) / PAGE_SIZE))
13211
13212         bsize=$((2 * PAGE_SIZE / 1024))K
13213
13214         bucket=$($LCTL get_param -n llite.*.extents_stats |
13215                         grep -m 1 $bsize)
13216         reads=$(echo $bucket | awk '{print $5}')
13217         writes=$(echo $bucket | awk '{print $9}')
13218         # mmap writes fault in the page first, creating an additonal read
13219         [ "$reads" -eq $((2 * count)) ] ||
13220                 error "$reads reads in < $bsize bucket, expect $count"
13221         [ "$writes" -eq $count ] ||
13222                 error "$writes writes in < $bsize bucket, expect $count"
13223 }
13224 run_test 127c "test llite extent stats with regular & mmap i/o"
13225
13226 test_128() { # bug 15212
13227         touch $DIR/$tfile
13228         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13229                 find $DIR/$tfile
13230                 find $DIR/$tfile
13231         EOF
13232
13233         result=$(grep error $TMP/$tfile.log)
13234         rm -f $DIR/$tfile $TMP/$tfile.log
13235         [ -z "$result" ] ||
13236                 error "consecutive find's under interactive lfs failed"
13237 }
13238 run_test 128 "interactive lfs for 2 consecutive find's"
13239
13240 set_dir_limits () {
13241         local mntdev
13242         local canondev
13243         local node
13244
13245         local ldproc=/proc/fs/ldiskfs
13246         local facets=$(get_facets MDS)
13247
13248         for facet in ${facets//,/ }; do
13249                 canondev=$(ldiskfs_canon \
13250                            *.$(convert_facet2label $facet).mntdev $facet)
13251                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13252                         ldproc=/sys/fs/ldiskfs
13253                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13254                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13255         done
13256 }
13257
13258 check_mds_dmesg() {
13259         local facets=$(get_facets MDS)
13260         for facet in ${facets//,/ }; do
13261                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13262         done
13263         return 1
13264 }
13265
13266 test_129() {
13267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13268         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13269                 skip "Need MDS version with at least 2.5.56"
13270         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13271                 skip_env "ldiskfs only test"
13272         fi
13273         remote_mds_nodsh && skip "remote MDS with nodsh"
13274
13275         local ENOSPC=28
13276         local has_warning=false
13277
13278         rm -rf $DIR/$tdir
13279         mkdir -p $DIR/$tdir
13280
13281         # block size of mds1
13282         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13283         set_dir_limits $maxsize $((maxsize * 6 / 8))
13284         stack_trap "set_dir_limits 0 0"
13285         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13286         local dirsize=$(stat -c%s "$DIR/$tdir")
13287         local nfiles=0
13288         while (( $dirsize <= $maxsize )); do
13289                 $MCREATE $DIR/$tdir/file_base_$nfiles
13290                 rc=$?
13291                 # check two errors:
13292                 # ENOSPC for ext4 max_dir_size, which has been used since
13293                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13294                 if (( rc == ENOSPC )); then
13295                         set_dir_limits 0 0
13296                         echo "rc=$rc returned as expected after $nfiles files"
13297
13298                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13299                                 error "create failed w/o dir size limit"
13300
13301                         # messages may be rate limited if test is run repeatedly
13302                         check_mds_dmesg '"is approaching max"' ||
13303                                 echo "warning message should be output"
13304                         check_mds_dmesg '"has reached max"' ||
13305                                 echo "reached message should be output"
13306
13307                         dirsize=$(stat -c%s "$DIR/$tdir")
13308
13309                         [[ $dirsize -ge $maxsize ]] && return 0
13310                         error "dirsize $dirsize < $maxsize after $nfiles files"
13311                 elif (( rc != 0 )); then
13312                         break
13313                 fi
13314                 nfiles=$((nfiles + 1))
13315                 dirsize=$(stat -c%s "$DIR/$tdir")
13316         done
13317
13318         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13319 }
13320 run_test 129 "test directory size limit ========================"
13321
13322 OLDIFS="$IFS"
13323 cleanup_130() {
13324         trap 0
13325         IFS="$OLDIFS"
13326 }
13327
13328 test_130a() {
13329         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13330         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13331
13332         trap cleanup_130 EXIT RETURN
13333
13334         local fm_file=$DIR/$tfile
13335         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13336         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13337                 error "dd failed for $fm_file"
13338
13339         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13340         filefrag -ves $fm_file
13341         RC=$?
13342         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13343                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13344         [ $RC != 0 ] && error "filefrag $fm_file failed"
13345
13346         filefrag_op=$(filefrag -ve -k $fm_file |
13347                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13348         lun=$($LFS getstripe -i $fm_file)
13349
13350         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13351         IFS=$'\n'
13352         tot_len=0
13353         for line in $filefrag_op
13354         do
13355                 frag_lun=`echo $line | cut -d: -f5`
13356                 ext_len=`echo $line | cut -d: -f4`
13357                 if (( $frag_lun != $lun )); then
13358                         cleanup_130
13359                         error "FIEMAP on 1-stripe file($fm_file) failed"
13360                         return
13361                 fi
13362                 (( tot_len += ext_len ))
13363         done
13364
13365         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13366                 cleanup_130
13367                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13368                 return
13369         fi
13370
13371         cleanup_130
13372
13373         echo "FIEMAP on single striped file succeeded"
13374 }
13375 run_test 130a "FIEMAP (1-stripe file)"
13376
13377 test_130b() {
13378         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13379
13380         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13381         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13382
13383         trap cleanup_130 EXIT RETURN
13384
13385         local fm_file=$DIR/$tfile
13386         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13387                         error "setstripe on $fm_file"
13388         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13389                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13390
13391         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13392                 error "dd failed on $fm_file"
13393
13394         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13395         filefrag_op=$(filefrag -ve -k $fm_file |
13396                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13397
13398         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13399                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13400
13401         IFS=$'\n'
13402         tot_len=0
13403         num_luns=1
13404         for line in $filefrag_op
13405         do
13406                 frag_lun=$(echo $line | cut -d: -f5 |
13407                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13408                 ext_len=$(echo $line | cut -d: -f4)
13409                 if (( $frag_lun != $last_lun )); then
13410                         if (( tot_len != 1024 )); then
13411                                 cleanup_130
13412                                 error "FIEMAP on $fm_file failed; returned " \
13413                                 "len $tot_len for OST $last_lun instead of 1024"
13414                                 return
13415                         else
13416                                 (( num_luns += 1 ))
13417                                 tot_len=0
13418                         fi
13419                 fi
13420                 (( tot_len += ext_len ))
13421                 last_lun=$frag_lun
13422         done
13423         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13424                 cleanup_130
13425                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13426                         "luns or wrong len for OST $last_lun"
13427                 return
13428         fi
13429
13430         cleanup_130
13431
13432         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13433 }
13434 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13435
13436 test_130c() {
13437         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13438
13439         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13440         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13441
13442         trap cleanup_130 EXIT RETURN
13443
13444         local fm_file=$DIR/$tfile
13445         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13446         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13447                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13448
13449         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13450                         error "dd failed on $fm_file"
13451
13452         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13453         filefrag_op=$(filefrag -ve -k $fm_file |
13454                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13455
13456         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13457                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13458
13459         IFS=$'\n'
13460         tot_len=0
13461         num_luns=1
13462         for line in $filefrag_op
13463         do
13464                 frag_lun=$(echo $line | cut -d: -f5 |
13465                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13466                 ext_len=$(echo $line | cut -d: -f4)
13467                 if (( $frag_lun != $last_lun )); then
13468                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13469                         if (( logical != 512 )); then
13470                                 cleanup_130
13471                                 error "FIEMAP on $fm_file failed; returned " \
13472                                 "logical start for lun $logical instead of 512"
13473                                 return
13474                         fi
13475                         if (( tot_len != 512 )); then
13476                                 cleanup_130
13477                                 error "FIEMAP on $fm_file failed; returned " \
13478                                 "len $tot_len for OST $last_lun instead of 1024"
13479                                 return
13480                         else
13481                                 (( num_luns += 1 ))
13482                                 tot_len=0
13483                         fi
13484                 fi
13485                 (( tot_len += ext_len ))
13486                 last_lun=$frag_lun
13487         done
13488         if (( num_luns != 2 || tot_len != 512 )); then
13489                 cleanup_130
13490                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13491                         "luns or wrong len for OST $last_lun"
13492                 return
13493         fi
13494
13495         cleanup_130
13496
13497         echo "FIEMAP on 2-stripe file with hole succeeded"
13498 }
13499 run_test 130c "FIEMAP (2-stripe file with hole)"
13500
13501 test_130d() {
13502         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13503
13504         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13505         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13506
13507         trap cleanup_130 EXIT RETURN
13508
13509         local fm_file=$DIR/$tfile
13510         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13511                         error "setstripe on $fm_file"
13512         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13513                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13514
13515         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13516         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13517                 error "dd failed on $fm_file"
13518
13519         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13520         filefrag_op=$(filefrag -ve -k $fm_file |
13521                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13522
13523         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13524                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13525
13526         IFS=$'\n'
13527         tot_len=0
13528         num_luns=1
13529         for line in $filefrag_op
13530         do
13531                 frag_lun=$(echo $line | cut -d: -f5 |
13532                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13533                 ext_len=$(echo $line | cut -d: -f4)
13534                 if (( $frag_lun != $last_lun )); then
13535                         if (( tot_len != 1024 )); then
13536                                 cleanup_130
13537                                 error "FIEMAP on $fm_file failed; returned " \
13538                                 "len $tot_len for OST $last_lun instead of 1024"
13539                                 return
13540                         else
13541                                 (( num_luns += 1 ))
13542                                 tot_len=0
13543                         fi
13544                 fi
13545                 (( tot_len += ext_len ))
13546                 last_lun=$frag_lun
13547         done
13548         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13549                 cleanup_130
13550                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13551                         "luns or wrong len for OST $last_lun"
13552                 return
13553         fi
13554
13555         cleanup_130
13556
13557         echo "FIEMAP on N-stripe file succeeded"
13558 }
13559 run_test 130d "FIEMAP (N-stripe file)"
13560
13561 test_130e() {
13562         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13563
13564         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13565         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13566
13567         trap cleanup_130 EXIT RETURN
13568
13569         local fm_file=$DIR/$tfile
13570         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13571
13572         NUM_BLKS=512
13573         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13574         for ((i = 0; i < $NUM_BLKS; i++)); do
13575                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13576                         conv=notrunc > /dev/null 2>&1
13577         done
13578
13579         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13580         filefrag_op=$(filefrag -ve -k $fm_file |
13581                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13582
13583         last_lun=$(echo $filefrag_op | cut -d: -f5)
13584
13585         IFS=$'\n'
13586         tot_len=0
13587         num_luns=1
13588         for line in $filefrag_op; do
13589                 frag_lun=$(echo $line | cut -d: -f5)
13590                 ext_len=$(echo $line | cut -d: -f4)
13591                 if [[ "$frag_lun" != "$last_lun" ]]; then
13592                         if (( tot_len != $EXPECTED_LEN )); then
13593                                 cleanup_130
13594                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13595                         else
13596                                 (( num_luns += 1 ))
13597                                 tot_len=0
13598                         fi
13599                 fi
13600                 (( tot_len += ext_len ))
13601                 last_lun=$frag_lun
13602         done
13603         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13604                 cleanup_130
13605                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13606         fi
13607
13608         echo "FIEMAP with continuation calls succeeded"
13609 }
13610 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13611
13612 test_130f() {
13613         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13614         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13615
13616         local fm_file=$DIR/$tfile
13617         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13618                 error "multiop create with lov_delay_create on $fm_file"
13619
13620         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13621         filefrag_extents=$(filefrag -vek $fm_file |
13622                            awk '/extents? found/ { print $2 }')
13623         if [[ "$filefrag_extents" != "0" ]]; then
13624                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13625         fi
13626
13627         rm -f $fm_file
13628 }
13629 run_test 130f "FIEMAP (unstriped file)"
13630
13631 test_130g() {
13632         local file=$DIR/$tfile
13633         local nr=$((OSTCOUNT * 100))
13634
13635         $LFS setstripe -C $nr $file ||
13636                 error "failed to setstripe -C $nr $file"
13637
13638         dd if=/dev/zero of=$file count=$nr bs=1M
13639         sync
13640         nr=$($LFS getstripe -c $file)
13641
13642         local extents=$(filefrag -v $file |
13643                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13644
13645         echo "filefrag list $extents extents in file with stripecount $nr"
13646         if (( extents < nr )); then
13647                 $LFS getstripe $file
13648                 filefrag -v $file
13649                 error "filefrag printed $extents < $nr extents"
13650         fi
13651
13652         rm -f $file
13653 }
13654 run_test 130g "FIEMAP (overstripe file)"
13655
13656 # Test for writev/readv
13657 test_131a() {
13658         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13659                 error "writev test failed"
13660         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13661                 error "readv failed"
13662         rm -f $DIR/$tfile
13663 }
13664 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13665
13666 test_131b() {
13667         local fsize=$((524288 + 1048576 + 1572864))
13668         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13669                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13670                         error "append writev test failed"
13671
13672         ((fsize += 1572864 + 1048576))
13673         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13674                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13675                         error "append writev test failed"
13676         rm -f $DIR/$tfile
13677 }
13678 run_test 131b "test append writev"
13679
13680 test_131c() {
13681         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13682         error "NOT PASS"
13683 }
13684 run_test 131c "test read/write on file w/o objects"
13685
13686 test_131d() {
13687         rwv -f $DIR/$tfile -w -n 1 1572864
13688         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13689         if [ "$NOB" != 1572864 ]; then
13690                 error "Short read filed: read $NOB bytes instead of 1572864"
13691         fi
13692         rm -f $DIR/$tfile
13693 }
13694 run_test 131d "test short read"
13695
13696 test_131e() {
13697         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13698         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13699         error "read hitting hole failed"
13700         rm -f $DIR/$tfile
13701 }
13702 run_test 131e "test read hitting hole"
13703
13704 check_stats() {
13705         local facet=$1
13706         local op=$2
13707         local want=${3:-0}
13708         local res
13709
13710         case $facet in
13711         mds*) res=$(do_facet $facet \
13712                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13713                  ;;
13714         ost*) res=$(do_facet $facet \
13715                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13716                  ;;
13717         *) error "Wrong facet '$facet'" ;;
13718         esac
13719         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13720         # if the argument $3 is zero, it means any stat increment is ok.
13721         if [[ $want -gt 0 ]]; then
13722                 local count=$(echo $res | awk '{ print $2 }')
13723                 [[ $count -ne $want ]] &&
13724                         error "The $op counter on $facet is $count, not $want"
13725         fi
13726 }
13727
13728 test_133a() {
13729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13730         remote_ost_nodsh && skip "remote OST with nodsh"
13731         remote_mds_nodsh && skip "remote MDS with nodsh"
13732         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13733                 skip_env "MDS doesn't support rename stats"
13734
13735         local testdir=$DIR/${tdir}/stats_testdir
13736
13737         mkdir -p $DIR/${tdir}
13738
13739         # clear stats.
13740         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13741         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13742
13743         # verify mdt stats first.
13744         mkdir ${testdir} || error "mkdir failed"
13745         check_stats $SINGLEMDS "mkdir" 1
13746         touch ${testdir}/${tfile} || error "touch failed"
13747         check_stats $SINGLEMDS "open" 1
13748         check_stats $SINGLEMDS "close" 1
13749         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13750                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13751                 check_stats $SINGLEMDS "mknod" 2
13752         }
13753         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13754         check_stats $SINGLEMDS "unlink" 1
13755         rm -f ${testdir}/${tfile} || error "file remove failed"
13756         check_stats $SINGLEMDS "unlink" 2
13757
13758         # remove working dir and check mdt stats again.
13759         rmdir ${testdir} || error "rmdir failed"
13760         check_stats $SINGLEMDS "rmdir" 1
13761
13762         local testdir1=$DIR/${tdir}/stats_testdir1
13763         mkdir -p ${testdir}
13764         mkdir -p ${testdir1}
13765         touch ${testdir1}/test1
13766         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13767         check_stats $SINGLEMDS "crossdir_rename" 1
13768
13769         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13770         check_stats $SINGLEMDS "samedir_rename" 1
13771
13772         rm -rf $DIR/${tdir}
13773 }
13774 run_test 133a "Verifying MDT stats ========================================"
13775
13776 test_133b() {
13777         local res
13778
13779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13780         remote_ost_nodsh && skip "remote OST with nodsh"
13781         remote_mds_nodsh && skip "remote MDS with nodsh"
13782
13783         local testdir=$DIR/${tdir}/stats_testdir
13784
13785         mkdir -p ${testdir} || error "mkdir failed"
13786         touch ${testdir}/${tfile} || error "touch failed"
13787         cancel_lru_locks mdc
13788
13789         # clear stats.
13790         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13791         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13792
13793         # extra mdt stats verification.
13794         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13795         check_stats $SINGLEMDS "setattr" 1
13796         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13797         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13798         then            # LU-1740
13799                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13800                 check_stats $SINGLEMDS "getattr" 1
13801         fi
13802         rm -rf $DIR/${tdir}
13803
13804         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13805         # so the check below is not reliable
13806         [ $MDSCOUNT -eq 1 ] || return 0
13807
13808         # Sleep to avoid a cached response.
13809         #define OBD_STATFS_CACHE_SECONDS 1
13810         sleep 2
13811         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13812         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13813         $LFS df || error "lfs failed"
13814         check_stats $SINGLEMDS "statfs" 1
13815
13816         # check aggregated statfs (LU-10018)
13817         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13818                 return 0
13819         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13820                 return 0
13821         sleep 2
13822         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13823         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13824         df $DIR
13825         check_stats $SINGLEMDS "statfs" 1
13826
13827         # We want to check that the client didn't send OST_STATFS to
13828         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13829         # extra care is needed here.
13830         if remote_mds; then
13831                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13832                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13833
13834                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13835                 [ "$res" ] && error "OST got STATFS"
13836         fi
13837
13838         return 0
13839 }
13840 run_test 133b "Verifying extra MDT stats =================================="
13841
13842 test_133c() {
13843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13844         remote_ost_nodsh && skip "remote OST with nodsh"
13845         remote_mds_nodsh && skip "remote MDS with nodsh"
13846
13847         local testdir=$DIR/$tdir/stats_testdir
13848
13849         test_mkdir -p $testdir
13850
13851         # verify obdfilter stats.
13852         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13853         sync
13854         cancel_lru_locks osc
13855         wait_delete_completed
13856
13857         # clear stats.
13858         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13859         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13860
13861         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13862                 error "dd failed"
13863         sync
13864         cancel_lru_locks osc
13865         check_stats ost1 "write" 1
13866
13867         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13868         check_stats ost1 "read" 1
13869
13870         > $testdir/$tfile || error "truncate failed"
13871         check_stats ost1 "punch" 1
13872
13873         rm -f $testdir/$tfile || error "file remove failed"
13874         wait_delete_completed
13875         check_stats ost1 "destroy" 1
13876
13877         rm -rf $DIR/$tdir
13878 }
13879 run_test 133c "Verifying OST stats ========================================"
13880
13881 order_2() {
13882         local value=$1
13883         local orig=$value
13884         local order=1
13885
13886         while [ $value -ge 2 ]; do
13887                 order=$((order*2))
13888                 value=$((value/2))
13889         done
13890
13891         if [ $orig -gt $order ]; then
13892                 order=$((order*2))
13893         fi
13894         echo $order
13895 }
13896
13897 size_in_KMGT() {
13898     local value=$1
13899     local size=('K' 'M' 'G' 'T');
13900     local i=0
13901     local size_string=$value
13902
13903     while [ $value -ge 1024 ]; do
13904         if [ $i -gt 3 ]; then
13905             #T is the biggest unit we get here, if that is bigger,
13906             #just return XXXT
13907             size_string=${value}T
13908             break
13909         fi
13910         value=$((value >> 10))
13911         if [ $value -lt 1024 ]; then
13912             size_string=${value}${size[$i]}
13913             break
13914         fi
13915         i=$((i + 1))
13916     done
13917
13918     echo $size_string
13919 }
13920
13921 get_rename_size() {
13922         local size=$1
13923         local context=${2:-.}
13924         local sample=$(do_facet $SINGLEMDS $LCTL \
13925                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13926                 grep -A1 $context |
13927                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13928         echo $sample
13929 }
13930
13931 test_133d() {
13932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13933         remote_ost_nodsh && skip "remote OST with nodsh"
13934         remote_mds_nodsh && skip "remote MDS with nodsh"
13935         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13936                 skip_env "MDS doesn't support rename stats"
13937
13938         local testdir1=$DIR/${tdir}/stats_testdir1
13939         local testdir2=$DIR/${tdir}/stats_testdir2
13940         mkdir -p $DIR/${tdir}
13941
13942         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13943
13944         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13945         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13946
13947         createmany -o $testdir1/test 512 || error "createmany failed"
13948
13949         # check samedir rename size
13950         mv ${testdir1}/test0 ${testdir1}/test_0
13951
13952         local testdir1_size=$(ls -l $DIR/${tdir} |
13953                 awk '/stats_testdir1/ {print $5}')
13954         local testdir2_size=$(ls -l $DIR/${tdir} |
13955                 awk '/stats_testdir2/ {print $5}')
13956
13957         testdir1_size=$(order_2 $testdir1_size)
13958         testdir2_size=$(order_2 $testdir2_size)
13959
13960         testdir1_size=$(size_in_KMGT $testdir1_size)
13961         testdir2_size=$(size_in_KMGT $testdir2_size)
13962
13963         echo "source rename dir size: ${testdir1_size}"
13964         echo "target rename dir size: ${testdir2_size}"
13965
13966         local cmd="do_facet $SINGLEMDS $LCTL "
13967         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13968
13969         eval $cmd || error "$cmd failed"
13970         local samedir=$($cmd | grep 'same_dir')
13971         local same_sample=$(get_rename_size $testdir1_size)
13972         [ -z "$samedir" ] && error "samedir_rename_size count error"
13973         [[ $same_sample -eq 1 ]] ||
13974                 error "samedir_rename_size error $same_sample"
13975         echo "Check same dir rename stats success"
13976
13977         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13978
13979         # check crossdir rename size
13980         mv ${testdir1}/test_0 ${testdir2}/test_0
13981
13982         testdir1_size=$(ls -l $DIR/${tdir} |
13983                 awk '/stats_testdir1/ {print $5}')
13984         testdir2_size=$(ls -l $DIR/${tdir} |
13985                 awk '/stats_testdir2/ {print $5}')
13986
13987         testdir1_size=$(order_2 $testdir1_size)
13988         testdir2_size=$(order_2 $testdir2_size)
13989
13990         testdir1_size=$(size_in_KMGT $testdir1_size)
13991         testdir2_size=$(size_in_KMGT $testdir2_size)
13992
13993         echo "source rename dir size: ${testdir1_size}"
13994         echo "target rename dir size: ${testdir2_size}"
13995
13996         eval $cmd || error "$cmd failed"
13997         local crossdir=$($cmd | grep 'crossdir')
13998         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13999         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14000         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14001         [[ $src_sample -eq 1 ]] ||
14002                 error "crossdir_rename_size error $src_sample"
14003         [[ $tgt_sample -eq 1 ]] ||
14004                 error "crossdir_rename_size error $tgt_sample"
14005         echo "Check cross dir rename stats success"
14006         rm -rf $DIR/${tdir}
14007 }
14008 run_test 133d "Verifying rename_stats ========================================"
14009
14010 test_133e() {
14011         remote_mds_nodsh && skip "remote MDS with nodsh"
14012         remote_ost_nodsh && skip "remote OST with nodsh"
14013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14014
14015         local testdir=$DIR/${tdir}/stats_testdir
14016         local ctr f0 f1 bs=32768 count=42 sum
14017
14018         mkdir -p ${testdir} || error "mkdir failed"
14019
14020         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14021
14022         for ctr in {write,read}_bytes; do
14023                 sync
14024                 cancel_lru_locks osc
14025
14026                 do_facet ost1 $LCTL set_param -n \
14027                         "obdfilter.*.exports.clear=clear"
14028
14029                 if [ $ctr = write_bytes ]; then
14030                         f0=/dev/zero
14031                         f1=${testdir}/${tfile}
14032                 else
14033                         f0=${testdir}/${tfile}
14034                         f1=/dev/null
14035                 fi
14036
14037                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14038                         error "dd failed"
14039                 sync
14040                 cancel_lru_locks osc
14041
14042                 sum=$(do_facet ost1 $LCTL get_param \
14043                         "obdfilter.*.exports.*.stats" |
14044                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14045                                 $1 == ctr { sum += $7 }
14046                                 END { printf("%0.0f", sum) }')
14047
14048                 if ((sum != bs * count)); then
14049                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14050                 fi
14051         done
14052
14053         rm -rf $DIR/${tdir}
14054 }
14055 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14056
14057 test_133f() {
14058         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14059                 skip "too old lustre for get_param -R ($facet_ver)"
14060
14061         # verifying readability.
14062         $LCTL get_param -R '*' &> /dev/null
14063
14064         # Verifing writability with badarea_io.
14065         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14066         local skipped_params='force_lbug|changelog_mask|daemon_file'
14067         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14068                 egrep -v "$skipped_params" |
14069                 xargs -n 1 find $proc_dirs -name |
14070                 xargs -n 1 badarea_io ||
14071                 error "client badarea_io failed"
14072
14073         # remount the FS in case writes/reads /proc break the FS
14074         cleanup || error "failed to unmount"
14075         setup || error "failed to setup"
14076 }
14077 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14078
14079 test_133g() {
14080         remote_mds_nodsh && skip "remote MDS with nodsh"
14081         remote_ost_nodsh && skip "remote OST with nodsh"
14082
14083         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14084         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14085         local facet
14086         for facet in mds1 ost1; do
14087                 local facet_ver=$(lustre_version_code $facet)
14088                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14089                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14090                 else
14091                         log "$facet: too old lustre for get_param -R"
14092                 fi
14093                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14094                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14095                                 tr -d = | egrep -v $skipped_params |
14096                                 xargs -n 1 find $proc_dirs -name |
14097                                 xargs -n 1 badarea_io" ||
14098                                         error "$facet badarea_io failed"
14099                 else
14100                         skip_noexit "$facet: too old lustre for get_param -R"
14101                 fi
14102         done
14103
14104         # remount the FS in case writes/reads /proc break the FS
14105         cleanup || error "failed to unmount"
14106         setup || error "failed to setup"
14107 }
14108 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14109
14110 test_133h() {
14111         remote_mds_nodsh && skip "remote MDS with nodsh"
14112         remote_ost_nodsh && skip "remote OST with nodsh"
14113         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14114                 skip "Need MDS version at least 2.9.54"
14115
14116         local facet
14117         for facet in client mds1 ost1; do
14118                 # Get the list of files that are missing the terminating newline
14119                 local plist=$(do_facet $facet
14120                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14121                 local ent
14122                 for ent in $plist; do
14123                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14124                                 awk -v FS='\v' -v RS='\v\v' \
14125                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14126                                         print FILENAME}'" 2>/dev/null)
14127                         [ -z $missing ] || {
14128                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14129                                 error "file does not end with newline: $facet-$ent"
14130                         }
14131                 done
14132         done
14133 }
14134 run_test 133h "Proc files should end with newlines"
14135
14136 test_134a() {
14137         remote_mds_nodsh && skip "remote MDS with nodsh"
14138         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14139                 skip "Need MDS version at least 2.7.54"
14140
14141         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14142         cancel_lru_locks mdc
14143
14144         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14145         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14146         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14147
14148         local nr=1000
14149         createmany -o $DIR/$tdir/f $nr ||
14150                 error "failed to create $nr files in $DIR/$tdir"
14151         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14152
14153         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14154         do_facet mds1 $LCTL set_param fail_loc=0x327
14155         do_facet mds1 $LCTL set_param fail_val=500
14156         touch $DIR/$tdir/m
14157
14158         echo "sleep 10 seconds ..."
14159         sleep 10
14160         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14161
14162         do_facet mds1 $LCTL set_param fail_loc=0
14163         do_facet mds1 $LCTL set_param fail_val=0
14164         [ $lck_cnt -lt $unused ] ||
14165                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14166
14167         rm $DIR/$tdir/m
14168         unlinkmany $DIR/$tdir/f $nr
14169 }
14170 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14171
14172 test_134b() {
14173         remote_mds_nodsh && skip "remote MDS with nodsh"
14174         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14175                 skip "Need MDS version at least 2.7.54"
14176
14177         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14178         cancel_lru_locks mdc
14179
14180         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14181                         ldlm.lock_reclaim_threshold_mb)
14182         # disable reclaim temporarily
14183         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14184
14185         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14186         do_facet mds1 $LCTL set_param fail_loc=0x328
14187         do_facet mds1 $LCTL set_param fail_val=500
14188
14189         $LCTL set_param debug=+trace
14190
14191         local nr=600
14192         createmany -o $DIR/$tdir/f $nr &
14193         local create_pid=$!
14194
14195         echo "Sleep $TIMEOUT seconds ..."
14196         sleep $TIMEOUT
14197         if ! ps -p $create_pid  > /dev/null 2>&1; then
14198                 do_facet mds1 $LCTL set_param fail_loc=0
14199                 do_facet mds1 $LCTL set_param fail_val=0
14200                 do_facet mds1 $LCTL set_param \
14201                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14202                 error "createmany finished incorrectly!"
14203         fi
14204         do_facet mds1 $LCTL set_param fail_loc=0
14205         do_facet mds1 $LCTL set_param fail_val=0
14206         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14207         wait $create_pid || return 1
14208
14209         unlinkmany $DIR/$tdir/f $nr
14210 }
14211 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14212
14213 test_135() {
14214         remote_mds_nodsh && skip "remote MDS with nodsh"
14215         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14216                 skip "Need MDS version at least 2.13.50"
14217         local fname
14218
14219         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14220
14221 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14222         #set only one record at plain llog
14223         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14224
14225         #fill already existed plain llog each 64767
14226         #wrapping whole catalog
14227         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14228
14229         createmany -o $DIR/$tdir/$tfile_ 64700
14230         for (( i = 0; i < 64700; i = i + 2 ))
14231         do
14232                 rm $DIR/$tdir/$tfile_$i &
14233                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14234                 local pid=$!
14235                 wait $pid
14236         done
14237
14238         #waiting osp synchronization
14239         wait_delete_completed
14240 }
14241 run_test 135 "Race catalog processing"
14242
14243 test_136() {
14244         remote_mds_nodsh && skip "remote MDS with nodsh"
14245         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14246                 skip "Need MDS version at least 2.13.50"
14247         local fname
14248
14249         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14250         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14251         #set only one record at plain llog
14252 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14254
14255         #fill already existed 2 plain llogs each 64767
14256         #wrapping whole catalog
14257         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14258         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14259         wait_delete_completed
14260
14261         createmany -o $DIR/$tdir/$tfile_ 10
14262         sleep 25
14263
14264         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14265         for (( i = 0; i < 10; i = i + 3 ))
14266         do
14267                 rm $DIR/$tdir/$tfile_$i &
14268                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14269                 local pid=$!
14270                 wait $pid
14271                 sleep 7
14272                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14273         done
14274
14275         #waiting osp synchronization
14276         wait_delete_completed
14277 }
14278 run_test 136 "Race catalog processing 2"
14279
14280 test_140() { #bug-17379
14281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14282
14283         test_mkdir $DIR/$tdir
14284         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14285         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14286
14287         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14288         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14289         local i=0
14290         while i=$((i + 1)); do
14291                 test_mkdir $i
14292                 cd $i || error "Changing to $i"
14293                 ln -s ../stat stat || error "Creating stat symlink"
14294                 # Read the symlink until ELOOP present,
14295                 # not LBUGing the system is considered success,
14296                 # we didn't overrun the stack.
14297                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14298                 if [ $ret -ne 0 ]; then
14299                         if [ $ret -eq 40 ]; then
14300                                 break  # -ELOOP
14301                         else
14302                                 error "Open stat symlink"
14303                                         return
14304                         fi
14305                 fi
14306         done
14307         i=$((i - 1))
14308         echo "The symlink depth = $i"
14309         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14310                 error "Invalid symlink depth"
14311
14312         # Test recursive symlink
14313         ln -s symlink_self symlink_self
14314         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14315         echo "open symlink_self returns $ret"
14316         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14317 }
14318 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14319
14320 test_150a() {
14321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14322
14323         local TF="$TMP/$tfile"
14324
14325         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14326         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14327         cp $TF $DIR/$tfile
14328         cancel_lru_locks $OSC
14329         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14330         remount_client $MOUNT
14331         df -P $MOUNT
14332         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14333
14334         $TRUNCATE $TF 6000
14335         $TRUNCATE $DIR/$tfile 6000
14336         cancel_lru_locks $OSC
14337         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14338
14339         echo "12345" >>$TF
14340         echo "12345" >>$DIR/$tfile
14341         cancel_lru_locks $OSC
14342         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14343
14344         echo "12345" >>$TF
14345         echo "12345" >>$DIR/$tfile
14346         cancel_lru_locks $OSC
14347         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14348 }
14349 run_test 150a "truncate/append tests"
14350
14351 test_150b() {
14352         check_set_fallocate_or_skip
14353
14354         touch $DIR/$tfile
14355         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14356         check_fallocate $DIR/$tfile || error "fallocate failed"
14357 }
14358 run_test 150b "Verify fallocate (prealloc) functionality"
14359
14360 test_150bb() {
14361         check_set_fallocate_or_skip
14362
14363         touch $DIR/$tfile
14364         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14365         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14366         > $DIR/$tfile
14367         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14368         # precomputed md5sum for 20MB of zeroes
14369         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14370         local sum=($(md5sum $DIR/$tfile))
14371
14372         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14373
14374         check_set_fallocate 1
14375
14376         > $DIR/$tfile
14377         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14378         sum=($(md5sum $DIR/$tfile))
14379
14380         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14381 }
14382 run_test 150bb "Verify fallocate modes both zero space"
14383
14384 test_150c() {
14385         check_set_fallocate_or_skip
14386         local striping="-c2"
14387
14388         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14389         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14390         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14391         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14392         local want=$((OSTCOUNT * 1048576))
14393
14394         # Must allocate all requested space, not more than 5% extra
14395         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14396                 error "bytes $bytes is not $want"
14397
14398         rm -f $DIR/$tfile
14399
14400         echo "verify fallocate on PFL file"
14401
14402         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14403
14404         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14405                 error "Create $DIR/$tfile failed"
14406         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14407                         error "fallocate failed"
14408         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14409         want=$((512 * 1048576))
14410
14411         # Must allocate all requested space, not more than 5% extra
14412         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14413                 error "bytes $bytes is not $want"
14414 }
14415 run_test 150c "Verify fallocate Size and Blocks"
14416
14417 test_150d() {
14418         check_set_fallocate_or_skip
14419         local striping="-c2"
14420
14421         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14422
14423         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14424         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14425                 error "setstripe failed"
14426         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14427         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14428         local want=$((OSTCOUNT * 1048576))
14429
14430         # Must allocate all requested space, not more than 5% extra
14431         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14432                 error "bytes $bytes is not $want"
14433 }
14434 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14435
14436 test_150e() {
14437         check_set_fallocate_or_skip
14438
14439         echo "df before:"
14440         $LFS df
14441         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14442         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14443                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14444
14445         # Find OST with Minimum Size
14446         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14447                        sort -un | head -1)
14448
14449         # Get 100MB per OST of the available space to reduce run time
14450         # else 60% of the available space if we are running SLOW tests
14451         if [ $SLOW == "no" ]; then
14452                 local space=$((1024 * 100 * OSTCOUNT))
14453         else
14454                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14455         fi
14456
14457         fallocate -l${space}k $DIR/$tfile ||
14458                 error "fallocate ${space}k $DIR/$tfile failed"
14459         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14460
14461         # get size immediately after fallocate. This should be correctly
14462         # updated
14463         local size=$(stat -c '%s' $DIR/$tfile)
14464         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14465
14466         # Sleep for a while for statfs to get updated. And not pull from cache.
14467         sleep 2
14468
14469         echo "df after fallocate:"
14470         $LFS df
14471
14472         (( size / 1024 == space )) || error "size $size != requested $space"
14473         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14474                 error "used $used < space $space"
14475
14476         rm $DIR/$tfile || error "rm failed"
14477         sync
14478         wait_delete_completed
14479
14480         echo "df after unlink:"
14481         $LFS df
14482 }
14483 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14484
14485 test_150f() {
14486         local size
14487         local blocks
14488         local want_size_before=20480 # in bytes
14489         local want_blocks_before=40 # 512 sized blocks
14490         local want_blocks_after=24  # 512 sized blocks
14491         local length=$(((want_blocks_before - want_blocks_after) * 512))
14492
14493         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14494                 skip "need at least 2.14.0 for fallocate punch"
14495
14496         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14497                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14498         fi
14499
14500         check_set_fallocate_or_skip
14501         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14502
14503         [[ "x$DOM" == "xyes" ]] &&
14504                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14505
14506         echo "Verify fallocate punch: Range within the file range"
14507         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14508                 error "dd failed for bs 4096 and count 5"
14509
14510         # Call fallocate with punch range which is within the file range
14511         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14512                 error "fallocate failed: offset 4096 and length $length"
14513         # client must see changes immediately after fallocate
14514         size=$(stat -c '%s' $DIR/$tfile)
14515         blocks=$(stat -c '%b' $DIR/$tfile)
14516
14517         # Verify punch worked.
14518         (( blocks == want_blocks_after )) ||
14519                 error "punch failed: blocks $blocks != $want_blocks_after"
14520
14521         (( size == want_size_before )) ||
14522                 error "punch failed: size $size != $want_size_before"
14523
14524         # Verify there is hole in file
14525         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14526         # precomputed md5sum
14527         local expect="4a9a834a2db02452929c0a348273b4aa"
14528
14529         cksum=($(md5sum $DIR/$tfile))
14530         [[ "${cksum[0]}" == "$expect" ]] ||
14531                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14532
14533         # Start second sub-case for fallocate punch.
14534         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14535         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14536                 error "dd failed for bs 4096 and count 5"
14537
14538         # Punch range less than block size will have no change in block count
14539         want_blocks_after=40  # 512 sized blocks
14540
14541         # Punch overlaps two blocks and less than blocksize
14542         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14543                 error "fallocate failed: offset 4000 length 3000"
14544         size=$(stat -c '%s' $DIR/$tfile)
14545         blocks=$(stat -c '%b' $DIR/$tfile)
14546
14547         # Verify punch worked.
14548         (( blocks == want_blocks_after )) ||
14549                 error "punch failed: blocks $blocks != $want_blocks_after"
14550
14551         (( size == want_size_before )) ||
14552                 error "punch failed: size $size != $want_size_before"
14553
14554         # Verify if range is really zero'ed out. We expect Zeros.
14555         # precomputed md5sum
14556         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14557         cksum=($(md5sum $DIR/$tfile))
14558         [[ "${cksum[0]}" == "$expect" ]] ||
14559                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14560 }
14561 run_test 150f "Verify fallocate punch functionality"
14562
14563 test_150g() {
14564         local space
14565         local size
14566         local blocks
14567         local blocks_after
14568         local size_after
14569         local BS=4096 # Block size in bytes
14570
14571         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14572                 skip "need at least 2.14.0 for fallocate punch"
14573
14574         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14575                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14576         fi
14577
14578         check_set_fallocate_or_skip
14579         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14580
14581         if [[ "x$DOM" == "xyes" ]]; then
14582                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14583                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14584         else
14585                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14586                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14587         fi
14588
14589         # Get 100MB per OST of the available space to reduce run time
14590         # else 60% of the available space if we are running SLOW tests
14591         if [ $SLOW == "no" ]; then
14592                 space=$((1024 * 100 * OSTCOUNT))
14593         else
14594                 # Find OST with Minimum Size
14595                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14596                         sort -un | head -1)
14597                 echo "min size OST: $space"
14598                 space=$(((space * 60)/100 * OSTCOUNT))
14599         fi
14600         # space in 1k units, round to 4k blocks
14601         local blkcount=$((space * 1024 / $BS))
14602
14603         echo "Verify fallocate punch: Very large Range"
14604         fallocate -l${space}k $DIR/$tfile ||
14605                 error "fallocate ${space}k $DIR/$tfile failed"
14606         # write 1M at the end, start and in the middle
14607         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14608                 error "dd failed: bs $BS count 256"
14609         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14610                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14611         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14612                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14613
14614         # Gather stats.
14615         size=$(stat -c '%s' $DIR/$tfile)
14616
14617         # gather punch length.
14618         local punch_size=$((size - (BS * 2)))
14619
14620         echo "punch_size = $punch_size"
14621         echo "size - punch_size: $((size - punch_size))"
14622         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14623
14624         # Call fallocate to punch all except 2 blocks. We leave the
14625         # first and the last block
14626         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14627         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14628                 error "fallocate failed: offset $BS length $punch_size"
14629
14630         size_after=$(stat -c '%s' $DIR/$tfile)
14631         blocks_after=$(stat -c '%b' $DIR/$tfile)
14632
14633         # Verify punch worked.
14634         # Size should be kept
14635         (( size == size_after )) ||
14636                 error "punch failed: size $size != $size_after"
14637
14638         # two 4k data blocks to remain plus possible 1 extra extent block
14639         (( blocks_after <= ((BS / 512) * 3) )) ||
14640                 error "too many blocks remains: $blocks_after"
14641
14642         # Verify that file has hole between the first and the last blocks
14643         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14644         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14645
14646         echo "Hole at [$hole_start, $hole_end)"
14647         (( hole_start == BS )) ||
14648                 error "no hole at offset $BS after punch"
14649
14650         (( hole_end == BS + punch_size )) ||
14651                 error "data at offset $hole_end < $((BS + punch_size))"
14652 }
14653 run_test 150g "Verify fallocate punch on large range"
14654
14655 #LU-2902 roc_hit was not able to read all values from lproc
14656 function roc_hit_init() {
14657         local list=$(comma_list $(osts_nodes))
14658         local dir=$DIR/$tdir-check
14659         local file=$dir/$tfile
14660         local BEFORE
14661         local AFTER
14662         local idx
14663
14664         test_mkdir $dir
14665         #use setstripe to do a write to every ost
14666         for i in $(seq 0 $((OSTCOUNT-1))); do
14667                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14668                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14669                 idx=$(printf %04x $i)
14670                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14671                         awk '$1 == "cache_access" {sum += $7}
14672                                 END { printf("%0.0f", sum) }')
14673
14674                 cancel_lru_locks osc
14675                 cat $file >/dev/null
14676
14677                 AFTER=$(get_osd_param $list *OST*$idx stats |
14678                         awk '$1 == "cache_access" {sum += $7}
14679                                 END { printf("%0.0f", sum) }')
14680
14681                 echo BEFORE:$BEFORE AFTER:$AFTER
14682                 if ! let "AFTER - BEFORE == 4"; then
14683                         rm -rf $dir
14684                         error "roc_hit is not safe to use"
14685                 fi
14686                 rm $file
14687         done
14688
14689         rm -rf $dir
14690 }
14691
14692 function roc_hit() {
14693         local list=$(comma_list $(osts_nodes))
14694         echo $(get_osd_param $list '' stats |
14695                 awk '$1 == "cache_hit" {sum += $7}
14696                         END { printf("%0.0f", sum) }')
14697 }
14698
14699 function set_cache() {
14700         local on=1
14701
14702         if [ "$2" == "off" ]; then
14703                 on=0;
14704         fi
14705         local list=$(comma_list $(osts_nodes))
14706         set_osd_param $list '' $1_cache_enable $on
14707
14708         cancel_lru_locks osc
14709 }
14710
14711 test_151() {
14712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14713         remote_ost_nodsh && skip "remote OST with nodsh"
14714
14715         local CPAGES=3
14716         local list=$(comma_list $(osts_nodes))
14717
14718         # check whether obdfilter is cache capable at all
14719         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14720                 skip "not cache-capable obdfilter"
14721         fi
14722
14723         # check cache is enabled on all obdfilters
14724         if get_osd_param $list '' read_cache_enable | grep 0; then
14725                 skip "oss cache is disabled"
14726         fi
14727
14728         set_osd_param $list '' writethrough_cache_enable 1
14729
14730         # check write cache is enabled on all obdfilters
14731         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14732                 skip "oss write cache is NOT enabled"
14733         fi
14734
14735         roc_hit_init
14736
14737         #define OBD_FAIL_OBD_NO_LRU  0x609
14738         do_nodes $list $LCTL set_param fail_loc=0x609
14739
14740         # pages should be in the case right after write
14741         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14742                 error "dd failed"
14743
14744         local BEFORE=$(roc_hit)
14745         cancel_lru_locks osc
14746         cat $DIR/$tfile >/dev/null
14747         local AFTER=$(roc_hit)
14748
14749         do_nodes $list $LCTL set_param fail_loc=0
14750
14751         if ! let "AFTER - BEFORE == CPAGES"; then
14752                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14753         fi
14754
14755         cancel_lru_locks osc
14756         # invalidates OST cache
14757         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14758         set_osd_param $list '' read_cache_enable 0
14759         cat $DIR/$tfile >/dev/null
14760
14761         # now data shouldn't be found in the cache
14762         BEFORE=$(roc_hit)
14763         cancel_lru_locks osc
14764         cat $DIR/$tfile >/dev/null
14765         AFTER=$(roc_hit)
14766         if let "AFTER - BEFORE != 0"; then
14767                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14768         fi
14769
14770         set_osd_param $list '' read_cache_enable 1
14771         rm -f $DIR/$tfile
14772 }
14773 run_test 151 "test cache on oss and controls ==============================="
14774
14775 test_152() {
14776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14777
14778         local TF="$TMP/$tfile"
14779
14780         # simulate ENOMEM during write
14781 #define OBD_FAIL_OST_NOMEM      0x226
14782         lctl set_param fail_loc=0x80000226
14783         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14784         cp $TF $DIR/$tfile
14785         sync || error "sync failed"
14786         lctl set_param fail_loc=0
14787
14788         # discard client's cache
14789         cancel_lru_locks osc
14790
14791         # simulate ENOMEM during read
14792         lctl set_param fail_loc=0x80000226
14793         cmp $TF $DIR/$tfile || error "cmp failed"
14794         lctl set_param fail_loc=0
14795
14796         rm -f $TF
14797 }
14798 run_test 152 "test read/write with enomem ============================"
14799
14800 test_153() {
14801         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14802 }
14803 run_test 153 "test if fdatasync does not crash ======================="
14804
14805 dot_lustre_fid_permission_check() {
14806         local fid=$1
14807         local ffid=$MOUNT/.lustre/fid/$fid
14808         local test_dir=$2
14809
14810         echo "stat fid $fid"
14811         stat $ffid > /dev/null || error "stat $ffid failed."
14812         echo "touch fid $fid"
14813         touch $ffid || error "touch $ffid failed."
14814         echo "write to fid $fid"
14815         cat /etc/hosts > $ffid || error "write $ffid failed."
14816         echo "read fid $fid"
14817         diff /etc/hosts $ffid || error "read $ffid failed."
14818         echo "append write to fid $fid"
14819         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14820         echo "rename fid $fid"
14821         mv $ffid $test_dir/$tfile.1 &&
14822                 error "rename $ffid to $tfile.1 should fail."
14823         touch $test_dir/$tfile.1
14824         mv $test_dir/$tfile.1 $ffid &&
14825                 error "rename $tfile.1 to $ffid should fail."
14826         rm -f $test_dir/$tfile.1
14827         echo "truncate fid $fid"
14828         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14829         echo "link fid $fid"
14830         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14831         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14832                 echo "setfacl fid $fid"
14833                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14834                 echo "getfacl fid $fid"
14835                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14836         fi
14837         echo "unlink fid $fid"
14838         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14839         echo "mknod fid $fid"
14840         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14841
14842         fid=[0xf00000400:0x1:0x0]
14843         ffid=$MOUNT/.lustre/fid/$fid
14844
14845         echo "stat non-exist fid $fid"
14846         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14847         echo "write to non-exist fid $fid"
14848         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14849         echo "link new fid $fid"
14850         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14851
14852         mkdir -p $test_dir/$tdir
14853         touch $test_dir/$tdir/$tfile
14854         fid=$($LFS path2fid $test_dir/$tdir)
14855         rc=$?
14856         [ $rc -ne 0 ] &&
14857                 error "error: could not get fid for $test_dir/$dir/$tfile."
14858
14859         ffid=$MOUNT/.lustre/fid/$fid
14860
14861         echo "ls $fid"
14862         ls $ffid > /dev/null || error "ls $ffid failed."
14863         echo "touch $fid/$tfile.1"
14864         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14865
14866         echo "touch $MOUNT/.lustre/fid/$tfile"
14867         touch $MOUNT/.lustre/fid/$tfile && \
14868                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14869
14870         echo "setxattr to $MOUNT/.lustre/fid"
14871         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14872
14873         echo "listxattr for $MOUNT/.lustre/fid"
14874         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14875
14876         echo "delxattr from $MOUNT/.lustre/fid"
14877         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14878
14879         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14880         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14881                 error "touch invalid fid should fail."
14882
14883         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14884         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14885                 error "touch non-normal fid should fail."
14886
14887         echo "rename $tdir to $MOUNT/.lustre/fid"
14888         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14889                 error "rename to $MOUNT/.lustre/fid should fail."
14890
14891         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14892         then            # LU-3547
14893                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14894                 local new_obf_mode=777
14895
14896                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14897                 chmod $new_obf_mode $DIR/.lustre/fid ||
14898                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14899
14900                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14901                 [ $obf_mode -eq $new_obf_mode ] ||
14902                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14903
14904                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14905                 chmod $old_obf_mode $DIR/.lustre/fid ||
14906                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14907         fi
14908
14909         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14910         fid=$($LFS path2fid $test_dir/$tfile-2)
14911
14912         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14913         then # LU-5424
14914                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14915                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14916                         error "create lov data thru .lustre failed"
14917         fi
14918         echo "cp /etc/passwd $test_dir/$tfile-2"
14919         cp /etc/passwd $test_dir/$tfile-2 ||
14920                 error "copy to $test_dir/$tfile-2 failed."
14921         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14922         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14923                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14924
14925         rm -rf $test_dir/tfile.lnk
14926         rm -rf $test_dir/$tfile-2
14927 }
14928
14929 test_154A() {
14930         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14931                 skip "Need MDS version at least 2.4.1"
14932
14933         local tf=$DIR/$tfile
14934         touch $tf
14935
14936         local fid=$($LFS path2fid $tf)
14937         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14938
14939         # check that we get the same pathname back
14940         local rootpath
14941         local found
14942         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14943                 echo "$rootpath $fid"
14944                 found=$($LFS fid2path $rootpath "$fid")
14945                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14946                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14947         done
14948
14949         # check wrong root path format
14950         rootpath=$MOUNT"_wrong"
14951         found=$($LFS fid2path $rootpath "$fid")
14952         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14953 }
14954 run_test 154A "lfs path2fid and fid2path basic checks"
14955
14956 test_154B() {
14957         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14958                 skip "Need MDS version at least 2.4.1"
14959
14960         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14961         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14962         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14963         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14964
14965         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14966         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14967
14968         # check that we get the same pathname
14969         echo "PFID: $PFID, name: $name"
14970         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14971         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14972         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14973                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14974
14975         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14976 }
14977 run_test 154B "verify the ll_decode_linkea tool"
14978
14979 test_154a() {
14980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14981         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14982         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14983                 skip "Need MDS version at least 2.2.51"
14984         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14985
14986         cp /etc/hosts $DIR/$tfile
14987
14988         fid=$($LFS path2fid $DIR/$tfile)
14989         rc=$?
14990         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14991
14992         dot_lustre_fid_permission_check "$fid" $DIR ||
14993                 error "dot lustre permission check $fid failed"
14994
14995         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14996
14997         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14998
14999         touch $MOUNT/.lustre/file &&
15000                 error "creation is not allowed under .lustre"
15001
15002         mkdir $MOUNT/.lustre/dir &&
15003                 error "mkdir is not allowed under .lustre"
15004
15005         rm -rf $DIR/$tfile
15006 }
15007 run_test 154a "Open-by-FID"
15008
15009 test_154b() {
15010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15011         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15012         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15013         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15014                 skip "Need MDS version at least 2.2.51"
15015
15016         local remote_dir=$DIR/$tdir/remote_dir
15017         local MDTIDX=1
15018         local rc=0
15019
15020         mkdir -p $DIR/$tdir
15021         $LFS mkdir -i $MDTIDX $remote_dir ||
15022                 error "create remote directory failed"
15023
15024         cp /etc/hosts $remote_dir/$tfile
15025
15026         fid=$($LFS path2fid $remote_dir/$tfile)
15027         rc=$?
15028         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15029
15030         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15031                 error "dot lustre permission check $fid failed"
15032         rm -rf $DIR/$tdir
15033 }
15034 run_test 154b "Open-by-FID for remote directory"
15035
15036 test_154c() {
15037         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15038                 skip "Need MDS version at least 2.4.1"
15039
15040         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15041         local FID1=$($LFS path2fid $DIR/$tfile.1)
15042         local FID2=$($LFS path2fid $DIR/$tfile.2)
15043         local FID3=$($LFS path2fid $DIR/$tfile.3)
15044
15045         local N=1
15046         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15047                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15048                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15049                 local want=FID$N
15050                 [ "$FID" = "${!want}" ] ||
15051                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15052                 N=$((N + 1))
15053         done
15054
15055         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15056         do
15057                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15058                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15059                 N=$((N + 1))
15060         done
15061 }
15062 run_test 154c "lfs path2fid and fid2path multiple arguments"
15063
15064 test_154d() {
15065         remote_mds_nodsh && skip "remote MDS with nodsh"
15066         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15067                 skip "Need MDS version at least 2.5.53"
15068
15069         if remote_mds; then
15070                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15071         else
15072                 nid="0@lo"
15073         fi
15074         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15075         local fd
15076         local cmd
15077
15078         rm -f $DIR/$tfile
15079         touch $DIR/$tfile
15080
15081         local fid=$($LFS path2fid $DIR/$tfile)
15082         # Open the file
15083         fd=$(free_fd)
15084         cmd="exec $fd<$DIR/$tfile"
15085         eval $cmd
15086         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15087         echo "$fid_list" | grep "$fid"
15088         rc=$?
15089
15090         cmd="exec $fd>/dev/null"
15091         eval $cmd
15092         if [ $rc -ne 0 ]; then
15093                 error "FID $fid not found in open files list $fid_list"
15094         fi
15095 }
15096 run_test 154d "Verify open file fid"
15097
15098 test_154e()
15099 {
15100         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15101                 skip "Need MDS version at least 2.6.50"
15102
15103         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15104                 error ".lustre returned by readdir"
15105         fi
15106 }
15107 run_test 154e ".lustre is not returned by readdir"
15108
15109 test_154f() {
15110         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15111
15112         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15113         mkdir_on_mdt0 $DIR/$tdir
15114         # test dirs inherit from its stripe
15115         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15116         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15117         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15118         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15119         touch $DIR/f
15120
15121         # get fid of parents
15122         local FID0=$($LFS path2fid $DIR/$tdir)
15123         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15124         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15125         local FID3=$($LFS path2fid $DIR)
15126
15127         # check that path2fid --parents returns expected <parent_fid>/name
15128         # 1) test for a directory (single parent)
15129         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15130         [ "$parent" == "$FID0/foo1" ] ||
15131                 error "expected parent: $FID0/foo1, got: $parent"
15132
15133         # 2) test for a file with nlink > 1 (multiple parents)
15134         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15135         echo "$parent" | grep -F "$FID1/$tfile" ||
15136                 error "$FID1/$tfile not returned in parent list"
15137         echo "$parent" | grep -F "$FID2/link" ||
15138                 error "$FID2/link not returned in parent list"
15139
15140         # 3) get parent by fid
15141         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15142         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15143         echo "$parent" | grep -F "$FID1/$tfile" ||
15144                 error "$FID1/$tfile not returned in parent list (by fid)"
15145         echo "$parent" | grep -F "$FID2/link" ||
15146                 error "$FID2/link not returned in parent list (by fid)"
15147
15148         # 4) test for entry in root directory
15149         parent=$($LFS path2fid --parents $DIR/f)
15150         echo "$parent" | grep -F "$FID3/f" ||
15151                 error "$FID3/f not returned in parent list"
15152
15153         # 5) test it on root directory
15154         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15155                 error "$MOUNT should not have parents"
15156
15157         # enable xattr caching and check that linkea is correctly updated
15158         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15159         save_lustre_params client "llite.*.xattr_cache" > $save
15160         lctl set_param llite.*.xattr_cache 1
15161
15162         # 6.1) linkea update on rename
15163         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15164
15165         # get parents by fid
15166         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15167         # foo1 should no longer be returned in parent list
15168         echo "$parent" | grep -F "$FID1" &&
15169                 error "$FID1 should no longer be in parent list"
15170         # the new path should appear
15171         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15172                 error "$FID2/$tfile.moved is not in parent list"
15173
15174         # 6.2) linkea update on unlink
15175         rm -f $DIR/$tdir/foo2/link
15176         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15177         # foo2/link should no longer be returned in parent list
15178         echo "$parent" | grep -F "$FID2/link" &&
15179                 error "$FID2/link should no longer be in parent list"
15180         true
15181
15182         rm -f $DIR/f
15183         restore_lustre_params < $save
15184         rm -f $save
15185 }
15186 run_test 154f "get parent fids by reading link ea"
15187
15188 test_154g()
15189 {
15190         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15191         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15192            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15193                 skip "Need MDS version at least 2.6.92"
15194
15195         mkdir_on_mdt0 $DIR/$tdir
15196         llapi_fid_test -d $DIR/$tdir
15197 }
15198 run_test 154g "various llapi FID tests"
15199
15200 test_155_small_load() {
15201     local temp=$TMP/$tfile
15202     local file=$DIR/$tfile
15203
15204     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15205         error "dd of=$temp bs=6096 count=1 failed"
15206     cp $temp $file
15207     cancel_lru_locks $OSC
15208     cmp $temp $file || error "$temp $file differ"
15209
15210     $TRUNCATE $temp 6000
15211     $TRUNCATE $file 6000
15212     cmp $temp $file || error "$temp $file differ (truncate1)"
15213
15214     echo "12345" >>$temp
15215     echo "12345" >>$file
15216     cmp $temp $file || error "$temp $file differ (append1)"
15217
15218     echo "12345" >>$temp
15219     echo "12345" >>$file
15220     cmp $temp $file || error "$temp $file differ (append2)"
15221
15222     rm -f $temp $file
15223     true
15224 }
15225
15226 test_155_big_load() {
15227         remote_ost_nodsh && skip "remote OST with nodsh"
15228
15229         local temp=$TMP/$tfile
15230         local file=$DIR/$tfile
15231
15232         free_min_max
15233         local cache_size=$(do_facet ost$((MAXI+1)) \
15234                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15235         local large_file_size=$((cache_size * 2))
15236
15237         echo "OSS cache size: $cache_size KB"
15238         echo "Large file size: $large_file_size KB"
15239
15240         [ $MAXV -le $large_file_size ] &&
15241                 skip_env "max available OST size needs > $large_file_size KB"
15242
15243         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15244
15245         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15246                 error "dd of=$temp bs=$large_file_size count=1k failed"
15247         cp $temp $file
15248         ls -lh $temp $file
15249         cancel_lru_locks osc
15250         cmp $temp $file || error "$temp $file differ"
15251
15252         rm -f $temp $file
15253         true
15254 }
15255
15256 save_writethrough() {
15257         local facets=$(get_facets OST)
15258
15259         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15260 }
15261
15262 test_155a() {
15263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15264
15265         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15266
15267         save_writethrough $p
15268
15269         set_cache read on
15270         set_cache writethrough on
15271         test_155_small_load
15272         restore_lustre_params < $p
15273         rm -f $p
15274 }
15275 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15276
15277 test_155b() {
15278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15279
15280         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15281
15282         save_writethrough $p
15283
15284         set_cache read on
15285         set_cache writethrough off
15286         test_155_small_load
15287         restore_lustre_params < $p
15288         rm -f $p
15289 }
15290 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15291
15292 test_155c() {
15293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15294
15295         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15296
15297         save_writethrough $p
15298
15299         set_cache read off
15300         set_cache writethrough on
15301         test_155_small_load
15302         restore_lustre_params < $p
15303         rm -f $p
15304 }
15305 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15306
15307 test_155d() {
15308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15309
15310         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15311
15312         save_writethrough $p
15313
15314         set_cache read off
15315         set_cache writethrough off
15316         test_155_small_load
15317         restore_lustre_params < $p
15318         rm -f $p
15319 }
15320 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15321
15322 test_155e() {
15323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15324
15325         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15326
15327         save_writethrough $p
15328
15329         set_cache read on
15330         set_cache writethrough on
15331         test_155_big_load
15332         restore_lustre_params < $p
15333         rm -f $p
15334 }
15335 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15336
15337 test_155f() {
15338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15339
15340         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15341
15342         save_writethrough $p
15343
15344         set_cache read on
15345         set_cache writethrough off
15346         test_155_big_load
15347         restore_lustre_params < $p
15348         rm -f $p
15349 }
15350 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15351
15352 test_155g() {
15353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15354
15355         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15356
15357         save_writethrough $p
15358
15359         set_cache read off
15360         set_cache writethrough on
15361         test_155_big_load
15362         restore_lustre_params < $p
15363         rm -f $p
15364 }
15365 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15366
15367 test_155h() {
15368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15369
15370         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15371
15372         save_writethrough $p
15373
15374         set_cache read off
15375         set_cache writethrough off
15376         test_155_big_load
15377         restore_lustre_params < $p
15378         rm -f $p
15379 }
15380 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15381
15382 test_156() {
15383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15384         remote_ost_nodsh && skip "remote OST with nodsh"
15385         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15386                 skip "stats not implemented on old servers"
15387         [ "$ost1_FSTYPE" = "zfs" ] &&
15388                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15389
15390         local CPAGES=3
15391         local BEFORE
15392         local AFTER
15393         local file="$DIR/$tfile"
15394         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15395
15396         save_writethrough $p
15397         roc_hit_init
15398
15399         log "Turn on read and write cache"
15400         set_cache read on
15401         set_cache writethrough on
15402
15403         log "Write data and read it back."
15404         log "Read should be satisfied from the cache."
15405         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15406         BEFORE=$(roc_hit)
15407         cancel_lru_locks osc
15408         cat $file >/dev/null
15409         AFTER=$(roc_hit)
15410         if ! let "AFTER - BEFORE == CPAGES"; then
15411                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15412         else
15413                 log "cache hits: before: $BEFORE, after: $AFTER"
15414         fi
15415
15416         log "Read again; it should be satisfied from the cache."
15417         BEFORE=$AFTER
15418         cancel_lru_locks osc
15419         cat $file >/dev/null
15420         AFTER=$(roc_hit)
15421         if ! let "AFTER - BEFORE == CPAGES"; then
15422                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15423         else
15424                 log "cache hits:: before: $BEFORE, after: $AFTER"
15425         fi
15426
15427         log "Turn off the read cache and turn on the write cache"
15428         set_cache read off
15429         set_cache writethrough on
15430
15431         log "Read again; it should be satisfied from the cache."
15432         BEFORE=$(roc_hit)
15433         cancel_lru_locks osc
15434         cat $file >/dev/null
15435         AFTER=$(roc_hit)
15436         if ! let "AFTER - BEFORE == CPAGES"; then
15437                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15438         else
15439                 log "cache hits:: before: $BEFORE, after: $AFTER"
15440         fi
15441
15442         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15443                 # > 2.12.56 uses pagecache if cached
15444                 log "Read again; it should not be satisfied from the cache."
15445                 BEFORE=$AFTER
15446                 cancel_lru_locks osc
15447                 cat $file >/dev/null
15448                 AFTER=$(roc_hit)
15449                 if ! let "AFTER - BEFORE == 0"; then
15450                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15451                 else
15452                         log "cache hits:: before: $BEFORE, after: $AFTER"
15453                 fi
15454         fi
15455
15456         log "Write data and read it back."
15457         log "Read should be satisfied from the cache."
15458         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15459         BEFORE=$(roc_hit)
15460         cancel_lru_locks osc
15461         cat $file >/dev/null
15462         AFTER=$(roc_hit)
15463         if ! let "AFTER - BEFORE == CPAGES"; then
15464                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15465         else
15466                 log "cache hits:: before: $BEFORE, after: $AFTER"
15467         fi
15468
15469         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15470                 # > 2.12.56 uses pagecache if cached
15471                 log "Read again; it should not be satisfied from the cache."
15472                 BEFORE=$AFTER
15473                 cancel_lru_locks osc
15474                 cat $file >/dev/null
15475                 AFTER=$(roc_hit)
15476                 if ! let "AFTER - BEFORE == 0"; then
15477                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15478                 else
15479                         log "cache hits:: before: $BEFORE, after: $AFTER"
15480                 fi
15481         fi
15482
15483         log "Turn off read and write cache"
15484         set_cache read off
15485         set_cache writethrough off
15486
15487         log "Write data and read it back"
15488         log "It should not be satisfied from the cache."
15489         rm -f $file
15490         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15491         cancel_lru_locks osc
15492         BEFORE=$(roc_hit)
15493         cat $file >/dev/null
15494         AFTER=$(roc_hit)
15495         if ! let "AFTER - BEFORE == 0"; then
15496                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15497         else
15498                 log "cache hits:: before: $BEFORE, after: $AFTER"
15499         fi
15500
15501         log "Turn on the read cache and turn off the write cache"
15502         set_cache read on
15503         set_cache writethrough off
15504
15505         log "Write data and read it back"
15506         log "It should not be satisfied from the cache."
15507         rm -f $file
15508         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15509         BEFORE=$(roc_hit)
15510         cancel_lru_locks osc
15511         cat $file >/dev/null
15512         AFTER=$(roc_hit)
15513         if ! let "AFTER - BEFORE == 0"; then
15514                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15515         else
15516                 log "cache hits:: before: $BEFORE, after: $AFTER"
15517         fi
15518
15519         log "Read again; it should be satisfied from the cache."
15520         BEFORE=$(roc_hit)
15521         cancel_lru_locks osc
15522         cat $file >/dev/null
15523         AFTER=$(roc_hit)
15524         if ! let "AFTER - BEFORE == CPAGES"; then
15525                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15526         else
15527                 log "cache hits:: before: $BEFORE, after: $AFTER"
15528         fi
15529
15530         restore_lustre_params < $p
15531         rm -f $p $file
15532 }
15533 run_test 156 "Verification of tunables"
15534
15535 test_160a() {
15536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15537         remote_mds_nodsh && skip "remote MDS with nodsh"
15538         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15539                 skip "Need MDS version at least 2.2.0"
15540
15541         changelog_register || error "changelog_register failed"
15542         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15543         changelog_users $SINGLEMDS | grep -q $cl_user ||
15544                 error "User $cl_user not found in changelog_users"
15545
15546         mkdir_on_mdt0 $DIR/$tdir
15547
15548         # change something
15549         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15550         changelog_clear 0 || error "changelog_clear failed"
15551         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15552         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15553         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15554         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15555         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15556         rm $DIR/$tdir/pics/desktop.jpg
15557
15558         echo "verifying changelog mask"
15559         changelog_chmask "-MKDIR"
15560         changelog_chmask "-CLOSE"
15561
15562         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15563         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15564
15565         changelog_chmask "+MKDIR"
15566         changelog_chmask "+CLOSE"
15567
15568         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15569         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15570
15571         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15572         CLOSES=$(changelog_dump | grep -c "CLOSE")
15573         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15574         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15575
15576         # verify contents
15577         echo "verifying target fid"
15578         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15579         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15580         [ "$fidc" == "$fidf" ] ||
15581                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15582         echo "verifying parent fid"
15583         # The FID returned from the Changelog may be the directory shard on
15584         # a different MDT, and not the FID returned by path2fid on the parent.
15585         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15586         # since this is what will matter when recreating this file in the tree.
15587         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15588         local pathp=$($LFS fid2path $MOUNT "$fidp")
15589         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15590                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15591
15592         echo "getting records for $cl_user"
15593         changelog_users $SINGLEMDS
15594         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15595         local nclr=3
15596         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15597                 error "changelog_clear failed"
15598         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15599         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15600         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15601                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15602
15603         local min0_rec=$(changelog_users $SINGLEMDS |
15604                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15605         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15606                           awk '{ print $1; exit; }')
15607
15608         changelog_dump | tail -n 5
15609         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15610         [ $first_rec == $((min0_rec + 1)) ] ||
15611                 error "first index should be $min0_rec + 1 not $first_rec"
15612
15613         # LU-3446 changelog index reset on MDT restart
15614         local cur_rec1=$(changelog_users $SINGLEMDS |
15615                          awk '/^current.index:/ { print $NF }')
15616         changelog_clear 0 ||
15617                 error "clear all changelog records for $cl_user failed"
15618         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15619         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15620                 error "Fail to start $SINGLEMDS"
15621         local cur_rec2=$(changelog_users $SINGLEMDS |
15622                          awk '/^current.index:/ { print $NF }')
15623         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15624         [ $cur_rec1 == $cur_rec2 ] ||
15625                 error "current index should be $cur_rec1 not $cur_rec2"
15626
15627         echo "verifying users from this test are deregistered"
15628         changelog_deregister || error "changelog_deregister failed"
15629         changelog_users $SINGLEMDS | grep -q $cl_user &&
15630                 error "User '$cl_user' still in changelog_users"
15631
15632         # lctl get_param -n mdd.*.changelog_users
15633         # current_index: 144
15634         # ID    index (idle seconds)
15635         # cl3   144   (2) mask=<list>
15636         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15637                 # this is the normal case where all users were deregistered
15638                 # make sure no new records are added when no users are present
15639                 local last_rec1=$(changelog_users $SINGLEMDS |
15640                                   awk '/^current.index:/ { print $NF }')
15641                 touch $DIR/$tdir/chloe
15642                 local last_rec2=$(changelog_users $SINGLEMDS |
15643                                   awk '/^current.index:/ { print $NF }')
15644                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15645                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15646         else
15647                 # any changelog users must be leftovers from a previous test
15648                 changelog_users $SINGLEMDS
15649                 echo "other changelog users; can't verify off"
15650         fi
15651 }
15652 run_test 160a "changelog sanity"
15653
15654 test_160b() { # LU-3587
15655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15656         remote_mds_nodsh && skip "remote MDS with nodsh"
15657         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15658                 skip "Need MDS version at least 2.2.0"
15659
15660         changelog_register || error "changelog_register failed"
15661         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15662         changelog_users $SINGLEMDS | grep -q $cl_user ||
15663                 error "User '$cl_user' not found in changelog_users"
15664
15665         local longname1=$(str_repeat a 255)
15666         local longname2=$(str_repeat b 255)
15667
15668         cd $DIR
15669         echo "creating very long named file"
15670         touch $longname1 || error "create of '$longname1' failed"
15671         echo "renaming very long named file"
15672         mv $longname1 $longname2
15673
15674         changelog_dump | grep RENME | tail -n 5
15675         rm -f $longname2
15676 }
15677 run_test 160b "Verify that very long rename doesn't crash in changelog"
15678
15679 test_160c() {
15680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15681         remote_mds_nodsh && skip "remote MDS with nodsh"
15682
15683         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15684                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15685                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15686                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15687
15688         local rc=0
15689
15690         # Registration step
15691         changelog_register || error "changelog_register failed"
15692
15693         rm -rf $DIR/$tdir
15694         mkdir -p $DIR/$tdir
15695         $MCREATE $DIR/$tdir/foo_160c
15696         changelog_chmask "-TRUNC"
15697         $TRUNCATE $DIR/$tdir/foo_160c 200
15698         changelog_chmask "+TRUNC"
15699         $TRUNCATE $DIR/$tdir/foo_160c 199
15700         changelog_dump | tail -n 5
15701         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15702         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15703 }
15704 run_test 160c "verify that changelog log catch the truncate event"
15705
15706 test_160d() {
15707         remote_mds_nodsh && skip "remote MDS with nodsh"
15708         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15710         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15711                 skip "Need MDS version at least 2.7.60"
15712
15713         # Registration step
15714         changelog_register || error "changelog_register failed"
15715
15716         mkdir -p $DIR/$tdir/migrate_dir
15717         changelog_clear 0 || error "changelog_clear failed"
15718
15719         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15720         changelog_dump | tail -n 5
15721         local migrates=$(changelog_dump | grep -c "MIGRT")
15722         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15723 }
15724 run_test 160d "verify that changelog log catch the migrate event"
15725
15726 test_160e() {
15727         remote_mds_nodsh && skip "remote MDS with nodsh"
15728
15729         # Create a user
15730         changelog_register || error "changelog_register failed"
15731
15732         local MDT0=$(facet_svc $SINGLEMDS)
15733         local rc
15734
15735         # No user (expect fail)
15736         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15737         rc=$?
15738         if [ $rc -eq 0 ]; then
15739                 error "Should fail without user"
15740         elif [ $rc -ne 4 ]; then
15741                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15742         fi
15743
15744         # Delete a future user (expect fail)
15745         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15746         rc=$?
15747         if [ $rc -eq 0 ]; then
15748                 error "Deleted non-existant user cl77"
15749         elif [ $rc -ne 2 ]; then
15750                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15751         fi
15752
15753         # Clear to a bad index (1 billion should be safe)
15754         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15755         rc=$?
15756
15757         if [ $rc -eq 0 ]; then
15758                 error "Successfully cleared to invalid CL index"
15759         elif [ $rc -ne 22 ]; then
15760                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15761         fi
15762 }
15763 run_test 160e "changelog negative testing (should return errors)"
15764
15765 test_160f() {
15766         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15767         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15768                 skip "Need MDS version at least 2.10.56"
15769
15770         local mdts=$(comma_list $(mdts_nodes))
15771
15772         # Create a user
15773         changelog_register || error "first changelog_register failed"
15774         changelog_register || error "second changelog_register failed"
15775         local cl_users
15776         declare -A cl_user1
15777         declare -A cl_user2
15778         local user_rec1
15779         local user_rec2
15780         local i
15781
15782         # generate some changelog records to accumulate on each MDT
15783         # use all_char because created files should be evenly distributed
15784         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15785                 error "test_mkdir $tdir failed"
15786         log "$(date +%s): creating first files"
15787         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15788                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15789                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15790         done
15791
15792         # check changelogs have been generated
15793         local start=$SECONDS
15794         local idle_time=$((MDSCOUNT * 5 + 5))
15795         local nbcl=$(changelog_dump | wc -l)
15796         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15797
15798         for param in "changelog_max_idle_time=$idle_time" \
15799                      "changelog_gc=1" \
15800                      "changelog_min_gc_interval=2" \
15801                      "changelog_min_free_cat_entries=3"; do
15802                 local MDT0=$(facet_svc $SINGLEMDS)
15803                 local var="${param%=*}"
15804                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15805
15806                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15807                 do_nodes $mdts $LCTL set_param mdd.*.$param
15808         done
15809
15810         # force cl_user2 to be idle (1st part), but also cancel the
15811         # cl_user1 records so that it is not evicted later in the test.
15812         local sleep1=$((idle_time / 2))
15813         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15814         sleep $sleep1
15815
15816         # simulate changelog catalog almost full
15817         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15818         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15819
15820         for i in $(seq $MDSCOUNT); do
15821                 cl_users=(${CL_USERS[mds$i]})
15822                 cl_user1[mds$i]="${cl_users[0]}"
15823                 cl_user2[mds$i]="${cl_users[1]}"
15824
15825                 [ -n "${cl_user1[mds$i]}" ] ||
15826                         error "mds$i: no user registered"
15827                 [ -n "${cl_user2[mds$i]}" ] ||
15828                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15829
15830                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15831                 [ -n "$user_rec1" ] ||
15832                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15833                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15834                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15835                 [ -n "$user_rec2" ] ||
15836                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15837                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15838                      "$user_rec1 + 2 == $user_rec2"
15839                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15840                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15841                               "$user_rec1 + 2, but is $user_rec2"
15842                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15843                 [ -n "$user_rec2" ] ||
15844                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15845                 [ $user_rec1 == $user_rec2 ] ||
15846                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15847                               "$user_rec1, but is $user_rec2"
15848         done
15849
15850         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15851         local sleep2=$((idle_time - (SECONDS - start) + 1))
15852         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15853         sleep $sleep2
15854
15855         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15856         # cl_user1 should be OK because it recently processed records.
15857         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15858         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15859                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15860                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15861         done
15862
15863         # ensure gc thread is done
15864         for i in $(mdts_nodes); do
15865                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15866                         error "$i: GC-thread not done"
15867         done
15868
15869         local first_rec
15870         for (( i = 1; i <= MDSCOUNT; i++ )); do
15871                 # check cl_user1 still registered
15872                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15873                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15874                 # check cl_user2 unregistered
15875                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15876                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15877
15878                 # check changelogs are present and starting at $user_rec1 + 1
15879                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15880                 [ -n "$user_rec1" ] ||
15881                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15882                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15883                             awk '{ print $1; exit; }')
15884
15885                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15886                 [ $((user_rec1 + 1)) == $first_rec ] ||
15887                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15888         done
15889 }
15890 run_test 160f "changelog garbage collect (timestamped users)"
15891
15892 test_160g() {
15893         remote_mds_nodsh && skip "remote MDS with nodsh"
15894         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15895                 skip "Need MDS version at least 2.10.56"
15896
15897         local mdts=$(comma_list $(mdts_nodes))
15898
15899         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15900         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15901
15902         # Create a user
15903         changelog_register || error "first changelog_register failed"
15904         changelog_register || error "second changelog_register failed"
15905         local cl_users
15906         declare -A cl_user1
15907         declare -A cl_user2
15908         local user_rec1
15909         local user_rec2
15910         local i
15911
15912         # generate some changelog records to accumulate on each MDT
15913         # use all_char because created files should be evenly distributed
15914         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15915                 error "test_mkdir $tdir failed"
15916         for ((i = 0; i < MDSCOUNT; i++)); do
15917                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15918                         error "create $DIR/$tdir/d$i.1 failed"
15919         done
15920
15921         # check changelogs have been generated
15922         local nbcl=$(changelog_dump | wc -l)
15923         (( $nbcl > 0 )) || error "no changelogs found"
15924
15925         # reduce the max_idle_indexes value to make sure we exceed it
15926         for param in "changelog_max_idle_indexes=1" \
15927                      "changelog_gc=1" \
15928                      "changelog_min_gc_interval=2" \
15929                      "changelog_min_free_cat_entries=3"; do
15930                 local MDT0=$(facet_svc $SINGLEMDS)
15931                 local var="${param%=*}"
15932                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15933
15934                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15935                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15936                         error "unable to set mdd.*.$param"
15937         done
15938
15939         # simulate changelog catalog almost full
15940         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15941         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15942
15943         local start=$SECONDS
15944         for i in $(seq $MDSCOUNT); do
15945                 cl_users=(${CL_USERS[mds$i]})
15946                 cl_user1[mds$i]="${cl_users[0]}"
15947                 cl_user2[mds$i]="${cl_users[1]}"
15948
15949                 [ -n "${cl_user1[mds$i]}" ] ||
15950                         error "mds$i: no user registered"
15951                 [ -n "${cl_user2[mds$i]}" ] ||
15952                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15953
15954                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15955                 [ -n "$user_rec1" ] ||
15956                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15957                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15958                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15959                 [ -n "$user_rec2" ] ||
15960                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15961                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15962                      "$user_rec1 + 2 == $user_rec2"
15963                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15964                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15965                               "$user_rec1 + 2, but is $user_rec2"
15966                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15967                 [ -n "$user_rec2" ] ||
15968                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15969                 [ $user_rec1 == $user_rec2 ] ||
15970                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15971                               "$user_rec1, but is $user_rec2"
15972         done
15973
15974         # ensure we are past the previous changelog_min_gc_interval set above
15975         local sleep2=$((start + 2 - SECONDS))
15976         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15977
15978         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15979         # cl_user1 should be OK because it recently processed records.
15980         for ((i = 0; i < MDSCOUNT; i++)); do
15981                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15982                         error "create $DIR/$tdir/d$i.3 failed"
15983         done
15984
15985         # ensure gc thread is done
15986         for i in $(mdts_nodes); do
15987                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15988                         error "$i: GC-thread not done"
15989         done
15990
15991         local first_rec
15992         for (( i = 1; i <= MDSCOUNT; i++ )); do
15993                 # check cl_user1 still registered
15994                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15995                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15996                 # check cl_user2 unregistered
15997                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15998                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15999
16000                 # check changelogs are present and starting at $user_rec1 + 1
16001                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16002                 [ -n "$user_rec1" ] ||
16003                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16004                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16005                             awk '{ print $1; exit; }')
16006
16007                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16008                 [ $((user_rec1 + 1)) == $first_rec ] ||
16009                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16010         done
16011 }
16012 run_test 160g "changelog garbage collect (old users)"
16013
16014 test_160h() {
16015         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16016         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16017                 skip "Need MDS version at least 2.10.56"
16018
16019         local mdts=$(comma_list $(mdts_nodes))
16020
16021         # Create a user
16022         changelog_register || error "first changelog_register failed"
16023         changelog_register || error "second changelog_register failed"
16024         local cl_users
16025         declare -A cl_user1
16026         declare -A cl_user2
16027         local user_rec1
16028         local user_rec2
16029         local i
16030
16031         # generate some changelog records to accumulate on each MDT
16032         # use all_char because created files should be evenly distributed
16033         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16034                 error "test_mkdir $tdir failed"
16035         for ((i = 0; i < MDSCOUNT; i++)); do
16036                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16037                         error "create $DIR/$tdir/d$i.1 failed"
16038         done
16039
16040         # check changelogs have been generated
16041         local nbcl=$(changelog_dump | wc -l)
16042         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16043
16044         for param in "changelog_max_idle_time=10" \
16045                      "changelog_gc=1" \
16046                      "changelog_min_gc_interval=2"; do
16047                 local MDT0=$(facet_svc $SINGLEMDS)
16048                 local var="${param%=*}"
16049                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16050
16051                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16052                 do_nodes $mdts $LCTL set_param mdd.*.$param
16053         done
16054
16055         # force cl_user2 to be idle (1st part)
16056         sleep 9
16057
16058         for i in $(seq $MDSCOUNT); do
16059                 cl_users=(${CL_USERS[mds$i]})
16060                 cl_user1[mds$i]="${cl_users[0]}"
16061                 cl_user2[mds$i]="${cl_users[1]}"
16062
16063                 [ -n "${cl_user1[mds$i]}" ] ||
16064                         error "mds$i: no user registered"
16065                 [ -n "${cl_user2[mds$i]}" ] ||
16066                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16067
16068                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16069                 [ -n "$user_rec1" ] ||
16070                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16071                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16072                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16073                 [ -n "$user_rec2" ] ||
16074                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16075                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16076                      "$user_rec1 + 2 == $user_rec2"
16077                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16078                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16079                               "$user_rec1 + 2, but is $user_rec2"
16080                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16081                 [ -n "$user_rec2" ] ||
16082                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16083                 [ $user_rec1 == $user_rec2 ] ||
16084                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16085                               "$user_rec1, but is $user_rec2"
16086         done
16087
16088         # force cl_user2 to be idle (2nd part) and to reach
16089         # changelog_max_idle_time
16090         sleep 2
16091
16092         # force each GC-thread start and block then
16093         # one per MDT/MDD, set fail_val accordingly
16094         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16095         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16096
16097         # generate more changelogs to trigger fail_loc
16098         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16099                 error "create $DIR/$tdir/${tfile}bis failed"
16100
16101         # stop MDT to stop GC-thread, should be done in back-ground as it will
16102         # block waiting for the thread to be released and exit
16103         declare -A stop_pids
16104         for i in $(seq $MDSCOUNT); do
16105                 stop mds$i &
16106                 stop_pids[mds$i]=$!
16107         done
16108
16109         for i in $(mdts_nodes); do
16110                 local facet
16111                 local nb=0
16112                 local facets=$(facets_up_on_host $i)
16113
16114                 for facet in ${facets//,/ }; do
16115                         if [[ $facet == mds* ]]; then
16116                                 nb=$((nb + 1))
16117                         fi
16118                 done
16119                 # ensure each MDS's gc threads are still present and all in "R"
16120                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16121                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16122                         error "$i: expected $nb GC-thread"
16123                 wait_update $i \
16124                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16125                         "R" 20 ||
16126                         error "$i: GC-thread not found in R-state"
16127                 # check umounts of each MDT on MDS have reached kthread_stop()
16128                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16129                         error "$i: expected $nb umount"
16130                 wait_update $i \
16131                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16132                         error "$i: umount not found in D-state"
16133         done
16134
16135         # release all GC-threads
16136         do_nodes $mdts $LCTL set_param fail_loc=0
16137
16138         # wait for MDT stop to complete
16139         for i in $(seq $MDSCOUNT); do
16140                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16141         done
16142
16143         # XXX
16144         # may try to check if any orphan changelog records are present
16145         # via ldiskfs/zfs and llog_reader...
16146
16147         # re-start/mount MDTs
16148         for i in $(seq $MDSCOUNT); do
16149                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16150                         error "Fail to start mds$i"
16151         done
16152
16153         local first_rec
16154         for i in $(seq $MDSCOUNT); do
16155                 # check cl_user1 still registered
16156                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16157                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16158                 # check cl_user2 unregistered
16159                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16160                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16161
16162                 # check changelogs are present and starting at $user_rec1 + 1
16163                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16164                 [ -n "$user_rec1" ] ||
16165                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16166                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16167                             awk '{ print $1; exit; }')
16168
16169                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16170                 [ $((user_rec1 + 1)) == $first_rec ] ||
16171                         error "mds$i: first index should be $user_rec1 + 1, " \
16172                               "but is $first_rec"
16173         done
16174 }
16175 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16176               "during mount"
16177
16178 test_160i() {
16179
16180         local mdts=$(comma_list $(mdts_nodes))
16181
16182         changelog_register || error "first changelog_register failed"
16183
16184         # generate some changelog records to accumulate on each MDT
16185         # use all_char because created files should be evenly distributed
16186         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16187                 error "test_mkdir $tdir failed"
16188         for ((i = 0; i < MDSCOUNT; i++)); do
16189                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16190                         error "create $DIR/$tdir/d$i.1 failed"
16191         done
16192
16193         # check changelogs have been generated
16194         local nbcl=$(changelog_dump | wc -l)
16195         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16196
16197         # simulate race between register and unregister
16198         # XXX as fail_loc is set per-MDS, with DNE configs the race
16199         # simulation will only occur for one MDT per MDS and for the
16200         # others the normal race scenario will take place
16201         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16202         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16203         do_nodes $mdts $LCTL set_param fail_val=1
16204
16205         # unregister 1st user
16206         changelog_deregister &
16207         local pid1=$!
16208         # wait some time for deregister work to reach race rdv
16209         sleep 2
16210         # register 2nd user
16211         changelog_register || error "2nd user register failed"
16212
16213         wait $pid1 || error "1st user deregister failed"
16214
16215         local i
16216         local last_rec
16217         declare -A LAST_REC
16218         for i in $(seq $MDSCOUNT); do
16219                 if changelog_users mds$i | grep "^cl"; then
16220                         # make sure new records are added with one user present
16221                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16222                                           awk '/^current.index:/ { print $NF }')
16223                 else
16224                         error "mds$i has no user registered"
16225                 fi
16226         done
16227
16228         # generate more changelog records to accumulate on each MDT
16229         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16230                 error "create $DIR/$tdir/${tfile}bis failed"
16231
16232         for i in $(seq $MDSCOUNT); do
16233                 last_rec=$(changelog_users $SINGLEMDS |
16234                            awk '/^current.index:/ { print $NF }')
16235                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16236                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16237                         error "changelogs are off on mds$i"
16238         done
16239 }
16240 run_test 160i "changelog user register/unregister race"
16241
16242 test_160j() {
16243         remote_mds_nodsh && skip "remote MDS with nodsh"
16244         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16245                 skip "Need MDS version at least 2.12.56"
16246
16247         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16248         stack_trap "umount $MOUNT2" EXIT
16249
16250         changelog_register || error "first changelog_register failed"
16251         stack_trap "changelog_deregister" EXIT
16252
16253         # generate some changelog
16254         # use all_char because created files should be evenly distributed
16255         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16256                 error "mkdir $tdir failed"
16257         for ((i = 0; i < MDSCOUNT; i++)); do
16258                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16259                         error "create $DIR/$tdir/d$i.1 failed"
16260         done
16261
16262         # open the changelog device
16263         exec 3>/dev/changelog-$FSNAME-MDT0000
16264         stack_trap "exec 3>&-" EXIT
16265         exec 4</dev/changelog-$FSNAME-MDT0000
16266         stack_trap "exec 4<&-" EXIT
16267
16268         # umount the first lustre mount
16269         umount $MOUNT
16270         stack_trap "mount_client $MOUNT" EXIT
16271
16272         # read changelog, which may or may not fail, but should not crash
16273         cat <&4 >/dev/null
16274
16275         # clear changelog
16276         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16277         changelog_users $SINGLEMDS | grep -q $cl_user ||
16278                 error "User $cl_user not found in changelog_users"
16279
16280         printf 'clear:'$cl_user':0' >&3
16281 }
16282 run_test 160j "client can be umounted while its chanangelog is being used"
16283
16284 test_160k() {
16285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16286         remote_mds_nodsh && skip "remote MDS with nodsh"
16287
16288         mkdir -p $DIR/$tdir/1/1
16289
16290         changelog_register || error "changelog_register failed"
16291         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16292
16293         changelog_users $SINGLEMDS | grep -q $cl_user ||
16294                 error "User '$cl_user' not found in changelog_users"
16295 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16296         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16297         rmdir $DIR/$tdir/1/1 & sleep 1
16298         mkdir $DIR/$tdir/2
16299         touch $DIR/$tdir/2/2
16300         rm -rf $DIR/$tdir/2
16301
16302         wait
16303         sleep 4
16304
16305         changelog_dump | grep rmdir || error "rmdir not recorded"
16306 }
16307 run_test 160k "Verify that changelog records are not lost"
16308
16309 # Verifies that a file passed as a parameter has recently had an operation
16310 # performed on it that has generated an MTIME changelog which contains the
16311 # correct parent FID. As files might reside on a different MDT from the
16312 # parent directory in DNE configurations, the FIDs are translated to paths
16313 # before being compared, which should be identical
16314 compare_mtime_changelog() {
16315         local file="${1}"
16316         local mdtidx
16317         local mtime
16318         local cl_fid
16319         local pdir
16320         local dir
16321
16322         mdtidx=$($LFS getstripe --mdt-index $file)
16323         mdtidx=$(printf "%04x" $mdtidx)
16324
16325         # Obtain the parent FID from the MTIME changelog
16326         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16327         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16328
16329         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16330         [ -z "$cl_fid" ] && error "parent FID not present"
16331
16332         # Verify that the path for the parent FID is the same as the path for
16333         # the test directory
16334         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16335
16336         dir=$(dirname $1)
16337
16338         [[ "${pdir%/}" == "$dir" ]] ||
16339                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16340 }
16341
16342 test_160l() {
16343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16344
16345         remote_mds_nodsh && skip "remote MDS with nodsh"
16346         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16347                 skip "Need MDS version at least 2.13.55"
16348
16349         local cl_user
16350
16351         changelog_register || error "changelog_register failed"
16352         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16353
16354         changelog_users $SINGLEMDS | grep -q $cl_user ||
16355                 error "User '$cl_user' not found in changelog_users"
16356
16357         # Clear some types so that MTIME changelogs are generated
16358         changelog_chmask "-CREAT"
16359         changelog_chmask "-CLOSE"
16360
16361         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16362
16363         # Test CL_MTIME during setattr
16364         touch $DIR/$tdir/$tfile
16365         compare_mtime_changelog $DIR/$tdir/$tfile
16366
16367         # Test CL_MTIME during close
16368         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16369         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16370 }
16371 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16372
16373 test_160m() {
16374         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16375         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16376                 skip "Need MDS version at least 2.14.51"
16377         local cl_users
16378         local cl_user1
16379         local cl_user2
16380         local pid1
16381
16382         # Create a user
16383         changelog_register || error "first changelog_register failed"
16384         changelog_register || error "second changelog_register failed"
16385
16386         cl_users=(${CL_USERS[mds1]})
16387         cl_user1="${cl_users[0]}"
16388         cl_user2="${cl_users[1]}"
16389         # generate some changelog records to accumulate on MDT0
16390         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16391         createmany -m $DIR/$tdir/$tfile 50 ||
16392                 error "create $DIR/$tdir/$tfile failed"
16393         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16394         rm -f $DIR/$tdir
16395
16396         # check changelogs have been generated
16397         local nbcl=$(changelog_dump | wc -l)
16398         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16399
16400 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16401         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16402
16403         __changelog_clear mds1 $cl_user1 +10
16404         __changelog_clear mds1 $cl_user2 0 &
16405         pid1=$!
16406         sleep 2
16407         __changelog_clear mds1 $cl_user1 0 ||
16408                 error "fail to cancel record for $cl_user1"
16409         wait $pid1
16410         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16411 }
16412 run_test 160m "Changelog clear race"
16413
16414 test_160n() {
16415         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16416         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16417                 skip "Need MDS version at least 2.14.51"
16418         local cl_users
16419         local cl_user1
16420         local cl_user2
16421         local pid1
16422         local first_rec
16423         local last_rec=0
16424
16425         # Create a user
16426         changelog_register || error "first changelog_register failed"
16427
16428         cl_users=(${CL_USERS[mds1]})
16429         cl_user1="${cl_users[0]}"
16430
16431         # generate some changelog records to accumulate on MDT0
16432         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16433         first_rec=$(changelog_users $SINGLEMDS |
16434                         awk '/^current.index:/ { print $NF }')
16435         while (( last_rec < (( first_rec + 65000)) )); do
16436                 createmany -m $DIR/$tdir/$tfile 10000 ||
16437                         error "create $DIR/$tdir/$tfile failed"
16438
16439                 for i in $(seq 0 10000); do
16440                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16441                                 > /dev/null
16442                 done
16443
16444                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16445                         error "unlinkmany failed unlink"
16446                 last_rec=$(changelog_users $SINGLEMDS |
16447                         awk '/^current.index:/ { print $NF }')
16448                 echo last record $last_rec
16449                 (( last_rec == 0 )) && error "no changelog found"
16450         done
16451
16452 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16453         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16454
16455         __changelog_clear mds1 $cl_user1 0 &
16456         pid1=$!
16457         sleep 2
16458         __changelog_clear mds1 $cl_user1 0 ||
16459                 error "fail to cancel record for $cl_user1"
16460         wait $pid1
16461         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16462 }
16463 run_test 160n "Changelog destroy race"
16464
16465 test_160o() {
16466         local mdt="$(facet_svc $SINGLEMDS)"
16467
16468         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16469         remote_mds_nodsh && skip "remote MDS with nodsh"
16470         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16471                 skip "Need MDS version at least 2.14.52"
16472
16473         changelog_register --user test_160o -m unlnk+close+open ||
16474                 error "changelog_register failed"
16475
16476         do_facet $SINGLEMDS $LCTL --device $mdt \
16477                                 changelog_register -u "Tt3_-#" &&
16478                 error "bad symbols in name should fail"
16479
16480         do_facet $SINGLEMDS $LCTL --device $mdt \
16481                                 changelog_register -u test_160o &&
16482                 error "the same name registration should fail"
16483
16484         do_facet $SINGLEMDS $LCTL --device $mdt \
16485                         changelog_register -u test_160toolongname &&
16486                 error "too long name registration should fail"
16487
16488         changelog_chmask "MARK+HSM"
16489         lctl get_param mdd.*.changelog*mask
16490         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16491         changelog_users $SINGLEMDS | grep -q $cl_user ||
16492                 error "User $cl_user not found in changelog_users"
16493         #verify username
16494         echo $cl_user | grep -q test_160o ||
16495                 error "User $cl_user has no specific name 'test160o'"
16496
16497         # change something
16498         changelog_clear 0 || error "changelog_clear failed"
16499         # generate some changelog records to accumulate on MDT0
16500         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16501         touch $DIR/$tdir/$tfile                 # open 1
16502
16503         OPENS=$(changelog_dump | grep -c "OPEN")
16504         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16505
16506         # must be no MKDIR it wasn't set as user mask
16507         MKDIR=$(changelog_dump | grep -c "MKDIR")
16508         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16509
16510         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16511                                 mdd.$mdt.changelog_current_mask -n)
16512         # register maskless user
16513         changelog_register || error "changelog_register failed"
16514         # effective mask should be not changed because it is not minimal
16515         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16516                                 mdd.$mdt.changelog_current_mask -n)
16517         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16518         # set server mask to minimal value
16519         changelog_chmask "MARK"
16520         # check effective mask again, should be treated as DEFMASK now
16521         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16522                                 mdd.$mdt.changelog_current_mask -n)
16523         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16524
16525         do_facet $SINGLEMDS $LCTL --device $mdt \
16526                                 changelog_deregister -u test_160o ||
16527                 error "cannot deregister by name"
16528 }
16529 run_test 160o "changelog user name and mask"
16530
16531 test_160p() {
16532         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16533         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16534                 skip "Need MDS version at least 2.14.51"
16535         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16536         local cl_users
16537         local cl_user1
16538         local entry_count
16539
16540         # Create a user
16541         changelog_register || error "first changelog_register failed"
16542
16543         cl_users=(${CL_USERS[mds1]})
16544         cl_user1="${cl_users[0]}"
16545
16546         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16547         createmany -m $DIR/$tdir/$tfile 50 ||
16548                 error "create $DIR/$tdir/$tfile failed"
16549         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16550         rm -rf $DIR/$tdir
16551
16552         # check changelogs have been generated
16553         entry_count=$(changelog_dump | wc -l)
16554         ((entry_count != 0)) || error "no changelog entries found"
16555
16556         # remove changelog_users and check that orphan entries are removed
16557         stop mds1
16558         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16559         start mds1 || error "cannot start mdt"
16560         entry_count=$(changelog_dump | wc -l)
16561         ((entry_count == 0)) ||
16562                 error "found $entry_count changelog entries, expected none"
16563 }
16564 run_test 160p "Changelog orphan cleanup with no users"
16565
16566 test_160q() {
16567         local mdt="$(facet_svc $SINGLEMDS)"
16568         local clu
16569
16570         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16571         remote_mds_nodsh && skip "remote MDS with nodsh"
16572         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16573                 skip "Need MDS version at least 2.14.54"
16574
16575         # set server mask to minimal value like server init does
16576         changelog_chmask "MARK"
16577         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16578                 error "changelog_register failed"
16579         # check effective mask again, should be treated as DEFMASK now
16580         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16581                                 mdd.$mdt.changelog_current_mask -n)
16582         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16583                 error "changelog_deregister failed"
16584         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16585 }
16586 run_test 160q "changelog effective mask is DEFMASK if not set"
16587
16588 test_161a() {
16589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16590
16591         test_mkdir -c1 $DIR/$tdir
16592         cp /etc/hosts $DIR/$tdir/$tfile
16593         test_mkdir -c1 $DIR/$tdir/foo1
16594         test_mkdir -c1 $DIR/$tdir/foo2
16595         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16596         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16597         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16598         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16599         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16600         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16601                 $LFS fid2path $DIR $FID
16602                 error "bad link ea"
16603         fi
16604         # middle
16605         rm $DIR/$tdir/foo2/zachary
16606         # last
16607         rm $DIR/$tdir/foo2/thor
16608         # first
16609         rm $DIR/$tdir/$tfile
16610         # rename
16611         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16612         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16613                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16614         rm $DIR/$tdir/foo2/maggie
16615
16616         # overflow the EA
16617         local longname=$tfile.avg_len_is_thirty_two_
16618         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16619                 error_noexit 'failed to unlink many hardlinks'" EXIT
16620         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16621                 error "failed to hardlink many files"
16622         links=$($LFS fid2path $DIR $FID | wc -l)
16623         echo -n "${links}/1000 links in link EA"
16624         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16625 }
16626 run_test 161a "link ea sanity"
16627
16628 test_161b() {
16629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16630         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16631
16632         local MDTIDX=1
16633         local remote_dir=$DIR/$tdir/remote_dir
16634
16635         mkdir -p $DIR/$tdir
16636         $LFS mkdir -i $MDTIDX $remote_dir ||
16637                 error "create remote directory failed"
16638
16639         cp /etc/hosts $remote_dir/$tfile
16640         mkdir -p $remote_dir/foo1
16641         mkdir -p $remote_dir/foo2
16642         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16643         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16644         ln $remote_dir/$tfile $remote_dir/foo1/luna
16645         ln $remote_dir/$tfile $remote_dir/foo2/thor
16646
16647         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16648                      tr -d ']')
16649         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16650                 $LFS fid2path $DIR $FID
16651                 error "bad link ea"
16652         fi
16653         # middle
16654         rm $remote_dir/foo2/zachary
16655         # last
16656         rm $remote_dir/foo2/thor
16657         # first
16658         rm $remote_dir/$tfile
16659         # rename
16660         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16661         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16662         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16663                 $LFS fid2path $DIR $FID
16664                 error "bad link rename"
16665         fi
16666         rm $remote_dir/foo2/maggie
16667
16668         # overflow the EA
16669         local longname=filename_avg_len_is_thirty_two_
16670         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16671                 error "failed to hardlink many files"
16672         links=$($LFS fid2path $DIR $FID | wc -l)
16673         echo -n "${links}/1000 links in link EA"
16674         [[ ${links} -gt 60 ]] ||
16675                 error "expected at least 60 links in link EA"
16676         unlinkmany $remote_dir/foo2/$longname 1000 ||
16677         error "failed to unlink many hardlinks"
16678 }
16679 run_test 161b "link ea sanity under remote directory"
16680
16681 test_161c() {
16682         remote_mds_nodsh && skip "remote MDS with nodsh"
16683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16684         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16685                 skip "Need MDS version at least 2.1.5"
16686
16687         # define CLF_RENAME_LAST 0x0001
16688         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16689         changelog_register || error "changelog_register failed"
16690
16691         rm -rf $DIR/$tdir
16692         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16693         touch $DIR/$tdir/foo_161c
16694         touch $DIR/$tdir/bar_161c
16695         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16696         changelog_dump | grep RENME | tail -n 5
16697         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16698         changelog_clear 0 || error "changelog_clear failed"
16699         if [ x$flags != "x0x1" ]; then
16700                 error "flag $flags is not 0x1"
16701         fi
16702
16703         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16704         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16705         touch $DIR/$tdir/foo_161c
16706         touch $DIR/$tdir/bar_161c
16707         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16708         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16709         changelog_dump | grep RENME | tail -n 5
16710         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16711         changelog_clear 0 || error "changelog_clear failed"
16712         if [ x$flags != "x0x0" ]; then
16713                 error "flag $flags is not 0x0"
16714         fi
16715         echo "rename overwrite a target having nlink > 1," \
16716                 "changelog record has flags of $flags"
16717
16718         # rename doesn't overwrite a target (changelog flag 0x0)
16719         touch $DIR/$tdir/foo_161c
16720         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16721         changelog_dump | grep RENME | tail -n 5
16722         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16723         changelog_clear 0 || error "changelog_clear failed"
16724         if [ x$flags != "x0x0" ]; then
16725                 error "flag $flags is not 0x0"
16726         fi
16727         echo "rename doesn't overwrite a target," \
16728                 "changelog record has flags of $flags"
16729
16730         # define CLF_UNLINK_LAST 0x0001
16731         # unlink a file having nlink = 1 (changelog flag 0x1)
16732         rm -f $DIR/$tdir/foo2_161c
16733         changelog_dump | grep UNLNK | tail -n 5
16734         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16735         changelog_clear 0 || error "changelog_clear failed"
16736         if [ x$flags != "x0x1" ]; then
16737                 error "flag $flags is not 0x1"
16738         fi
16739         echo "unlink a file having nlink = 1," \
16740                 "changelog record has flags of $flags"
16741
16742         # unlink a file having nlink > 1 (changelog flag 0x0)
16743         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16744         rm -f $DIR/$tdir/foobar_161c
16745         changelog_dump | grep UNLNK | tail -n 5
16746         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16747         changelog_clear 0 || error "changelog_clear failed"
16748         if [ x$flags != "x0x0" ]; then
16749                 error "flag $flags is not 0x0"
16750         fi
16751         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16752 }
16753 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16754
16755 test_161d() {
16756         remote_mds_nodsh && skip "remote MDS with nodsh"
16757         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16758
16759         local pid
16760         local fid
16761
16762         changelog_register || error "changelog_register failed"
16763
16764         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16765         # interfer with $MOUNT/.lustre/fid/ access
16766         mkdir $DIR/$tdir
16767         [[ $? -eq 0 ]] || error "mkdir failed"
16768
16769         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16770         $LCTL set_param fail_loc=0x8000140c
16771         # 5s pause
16772         $LCTL set_param fail_val=5
16773
16774         # create file
16775         echo foofoo > $DIR/$tdir/$tfile &
16776         pid=$!
16777
16778         # wait for create to be delayed
16779         sleep 2
16780
16781         ps -p $pid
16782         [[ $? -eq 0 ]] || error "create should be blocked"
16783
16784         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16785         stack_trap "rm -f $tempfile"
16786         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16787         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16788         # some delay may occur during ChangeLog publishing and file read just
16789         # above, that could allow file write to happen finally
16790         [[ -s $tempfile ]] && echo "file should be empty"
16791
16792         $LCTL set_param fail_loc=0
16793
16794         wait $pid
16795         [[ $? -eq 0 ]] || error "create failed"
16796 }
16797 run_test 161d "create with concurrent .lustre/fid access"
16798
16799 check_path() {
16800         local expected="$1"
16801         shift
16802         local fid="$2"
16803
16804         local path
16805         path=$($LFS fid2path "$@")
16806         local rc=$?
16807
16808         if [ $rc -ne 0 ]; then
16809                 error "path looked up of '$expected' failed: rc=$rc"
16810         elif [ "$path" != "$expected" ]; then
16811                 error "path looked up '$path' instead of '$expected'"
16812         else
16813                 echo "FID '$fid' resolves to path '$path' as expected"
16814         fi
16815 }
16816
16817 test_162a() { # was test_162
16818         test_mkdir -p -c1 $DIR/$tdir/d2
16819         touch $DIR/$tdir/d2/$tfile
16820         touch $DIR/$tdir/d2/x1
16821         touch $DIR/$tdir/d2/x2
16822         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16823         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16824         # regular file
16825         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16826         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16827
16828         # softlink
16829         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16830         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16831         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16832
16833         # softlink to wrong file
16834         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16835         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16836         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16837
16838         # hardlink
16839         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16840         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16841         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16842         # fid2path dir/fsname should both work
16843         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16844         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16845
16846         # hardlink count: check that there are 2 links
16847         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16848         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16849
16850         # hardlink indexing: remove the first link
16851         rm $DIR/$tdir/d2/p/q/r/hlink
16852         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16853 }
16854 run_test 162a "path lookup sanity"
16855
16856 test_162b() {
16857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16859
16860         mkdir $DIR/$tdir
16861         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16862                                 error "create striped dir failed"
16863
16864         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16865                                         tail -n 1 | awk '{print $2}')
16866         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16867
16868         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16869         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16870
16871         # regular file
16872         for ((i=0;i<5;i++)); do
16873                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16874                         error "get fid for f$i failed"
16875                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16876
16877                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16878                         error "get fid for d$i failed"
16879                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16880         done
16881
16882         return 0
16883 }
16884 run_test 162b "striped directory path lookup sanity"
16885
16886 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16887 test_162c() {
16888         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16889                 skip "Need MDS version at least 2.7.51"
16890
16891         local lpath=$tdir.local
16892         local rpath=$tdir.remote
16893
16894         test_mkdir $DIR/$lpath
16895         test_mkdir $DIR/$rpath
16896
16897         for ((i = 0; i <= 101; i++)); do
16898                 lpath="$lpath/$i"
16899                 mkdir $DIR/$lpath
16900                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16901                         error "get fid for local directory $DIR/$lpath failed"
16902                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16903
16904                 rpath="$rpath/$i"
16905                 test_mkdir $DIR/$rpath
16906                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16907                         error "get fid for remote directory $DIR/$rpath failed"
16908                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16909         done
16910
16911         return 0
16912 }
16913 run_test 162c "fid2path works with paths 100 or more directories deep"
16914
16915 oalr_event_count() {
16916         local event="${1}"
16917         local trace="${2}"
16918
16919         awk -v name="${FSNAME}-OST0000" \
16920             -v event="${event}" \
16921             '$1 == "TRACE" && $2 == event && $3 == name' \
16922             "${trace}" |
16923         wc -l
16924 }
16925
16926 oalr_expect_event_count() {
16927         local event="${1}"
16928         local trace="${2}"
16929         local expect="${3}"
16930         local count
16931
16932         count=$(oalr_event_count "${event}" "${trace}")
16933         if ((count == expect)); then
16934                 return 0
16935         fi
16936
16937         error_noexit "${event} event count was '${count}', expected ${expect}"
16938         cat "${trace}" >&2
16939         exit 1
16940 }
16941
16942 cleanup_165() {
16943         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16944         stop ost1
16945         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16946 }
16947
16948 setup_165() {
16949         sync # Flush previous IOs so we can count log entries.
16950         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16951         stack_trap cleanup_165 EXIT
16952 }
16953
16954 test_165a() {
16955         local trace="/tmp/${tfile}.trace"
16956         local rc
16957         local count
16958
16959         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16960                 skip "OFD access log unsupported"
16961
16962         setup_165
16963         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16964         sleep 5
16965
16966         do_facet ost1 ofd_access_log_reader --list
16967         stop ost1
16968
16969         do_facet ost1 killall -TERM ofd_access_log_reader
16970         wait
16971         rc=$?
16972
16973         if ((rc != 0)); then
16974                 error "ofd_access_log_reader exited with rc = '${rc}'"
16975         fi
16976
16977         # Parse trace file for discovery events:
16978         oalr_expect_event_count alr_log_add "${trace}" 1
16979         oalr_expect_event_count alr_log_eof "${trace}" 1
16980         oalr_expect_event_count alr_log_free "${trace}" 1
16981 }
16982 run_test 165a "ofd access log discovery"
16983
16984 test_165b() {
16985         local trace="/tmp/${tfile}.trace"
16986         local file="${DIR}/${tfile}"
16987         local pfid1
16988         local pfid2
16989         local -a entry
16990         local rc
16991         local count
16992         local size
16993         local flags
16994
16995         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16996                 skip "OFD access log unsupported"
16997
16998         setup_165
16999         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17000         sleep 5
17001
17002         do_facet ost1 ofd_access_log_reader --list
17003
17004         lfs setstripe -c 1 -i 0 "${file}"
17005         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17006                 error "cannot create '${file}'"
17007
17008         sleep 5
17009         do_facet ost1 killall -TERM ofd_access_log_reader
17010         wait
17011         rc=$?
17012
17013         if ((rc != 0)); then
17014                 error "ofd_access_log_reader exited with rc = '${rc}'"
17015         fi
17016
17017         oalr_expect_event_count alr_log_entry "${trace}" 1
17018
17019         pfid1=$($LFS path2fid "${file}")
17020
17021         # 1     2             3   4    5     6   7    8    9     10
17022         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17023         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17024
17025         echo "entry = '${entry[*]}'" >&2
17026
17027         pfid2=${entry[4]}
17028         if [[ "${pfid1}" != "${pfid2}" ]]; then
17029                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17030         fi
17031
17032         size=${entry[8]}
17033         if ((size != 1048576)); then
17034                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17035         fi
17036
17037         flags=${entry[10]}
17038         if [[ "${flags}" != "w" ]]; then
17039                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17040         fi
17041
17042         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17043         sleep 5
17044
17045         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17046                 error "cannot read '${file}'"
17047         sleep 5
17048
17049         do_facet ost1 killall -TERM ofd_access_log_reader
17050         wait
17051         rc=$?
17052
17053         if ((rc != 0)); then
17054                 error "ofd_access_log_reader exited with rc = '${rc}'"
17055         fi
17056
17057         oalr_expect_event_count alr_log_entry "${trace}" 1
17058
17059         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17060         echo "entry = '${entry[*]}'" >&2
17061
17062         pfid2=${entry[4]}
17063         if [[ "${pfid1}" != "${pfid2}" ]]; then
17064                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17065         fi
17066
17067         size=${entry[8]}
17068         if ((size != 524288)); then
17069                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17070         fi
17071
17072         flags=${entry[10]}
17073         if [[ "${flags}" != "r" ]]; then
17074                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17075         fi
17076 }
17077 run_test 165b "ofd access log entries are produced and consumed"
17078
17079 test_165c() {
17080         local trace="/tmp/${tfile}.trace"
17081         local file="${DIR}/${tdir}/${tfile}"
17082
17083         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17084                 skip "OFD access log unsupported"
17085
17086         test_mkdir "${DIR}/${tdir}"
17087
17088         setup_165
17089         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17090         sleep 5
17091
17092         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17093
17094         # 4096 / 64 = 64. Create twice as many entries.
17095         for ((i = 0; i < 128; i++)); do
17096                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17097                         error "cannot create file"
17098         done
17099
17100         sync
17101
17102         do_facet ost1 killall -TERM ofd_access_log_reader
17103         wait
17104         rc=$?
17105         if ((rc != 0)); then
17106                 error "ofd_access_log_reader exited with rc = '${rc}'"
17107         fi
17108
17109         unlinkmany  "${file}-%d" 128
17110 }
17111 run_test 165c "full ofd access logs do not block IOs"
17112
17113 oal_get_read_count() {
17114         local stats="$1"
17115
17116         # STATS lustre-OST0001 alr_read_count 1
17117
17118         do_facet ost1 cat "${stats}" |
17119         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17120              END { print count; }'
17121 }
17122
17123 oal_expect_read_count() {
17124         local stats="$1"
17125         local count
17126         local expect="$2"
17127
17128         # Ask ofd_access_log_reader to write stats.
17129         do_facet ost1 killall -USR1 ofd_access_log_reader
17130
17131         # Allow some time for things to happen.
17132         sleep 1
17133
17134         count=$(oal_get_read_count "${stats}")
17135         if ((count == expect)); then
17136                 return 0
17137         fi
17138
17139         error_noexit "bad read count, got ${count}, expected ${expect}"
17140         do_facet ost1 cat "${stats}" >&2
17141         exit 1
17142 }
17143
17144 test_165d() {
17145         local stats="/tmp/${tfile}.stats"
17146         local file="${DIR}/${tdir}/${tfile}"
17147         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17148
17149         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17150                 skip "OFD access log unsupported"
17151
17152         test_mkdir "${DIR}/${tdir}"
17153
17154         setup_165
17155         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17156         sleep 5
17157
17158         lfs setstripe -c 1 -i 0 "${file}"
17159
17160         do_facet ost1 lctl set_param "${param}=rw"
17161         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17162                 error "cannot create '${file}'"
17163         oal_expect_read_count "${stats}" 1
17164
17165         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17166                 error "cannot read '${file}'"
17167         oal_expect_read_count "${stats}" 2
17168
17169         do_facet ost1 lctl set_param "${param}=r"
17170         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17171                 error "cannot create '${file}'"
17172         oal_expect_read_count "${stats}" 2
17173
17174         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17175                 error "cannot read '${file}'"
17176         oal_expect_read_count "${stats}" 3
17177
17178         do_facet ost1 lctl set_param "${param}=w"
17179         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17180                 error "cannot create '${file}'"
17181         oal_expect_read_count "${stats}" 4
17182
17183         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17184                 error "cannot read '${file}'"
17185         oal_expect_read_count "${stats}" 4
17186
17187         do_facet ost1 lctl set_param "${param}=0"
17188         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17189                 error "cannot create '${file}'"
17190         oal_expect_read_count "${stats}" 4
17191
17192         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17193                 error "cannot read '${file}'"
17194         oal_expect_read_count "${stats}" 4
17195
17196         do_facet ost1 killall -TERM ofd_access_log_reader
17197         wait
17198         rc=$?
17199         if ((rc != 0)); then
17200                 error "ofd_access_log_reader exited with rc = '${rc}'"
17201         fi
17202 }
17203 run_test 165d "ofd_access_log mask works"
17204
17205 test_165e() {
17206         local stats="/tmp/${tfile}.stats"
17207         local file0="${DIR}/${tdir}-0/${tfile}"
17208         local file1="${DIR}/${tdir}-1/${tfile}"
17209
17210         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17211                 skip "OFD access log unsupported"
17212
17213         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17214
17215         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17216         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17217
17218         lfs setstripe -c 1 -i 0 "${file0}"
17219         lfs setstripe -c 1 -i 0 "${file1}"
17220
17221         setup_165
17222         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17223         sleep 5
17224
17225         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17226                 error "cannot create '${file0}'"
17227         sync
17228         oal_expect_read_count "${stats}" 0
17229
17230         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17231                 error "cannot create '${file1}'"
17232         sync
17233         oal_expect_read_count "${stats}" 1
17234
17235         do_facet ost1 killall -TERM ofd_access_log_reader
17236         wait
17237         rc=$?
17238         if ((rc != 0)); then
17239                 error "ofd_access_log_reader exited with rc = '${rc}'"
17240         fi
17241 }
17242 run_test 165e "ofd_access_log MDT index filter works"
17243
17244 test_165f() {
17245         local trace="/tmp/${tfile}.trace"
17246         local rc
17247         local count
17248
17249         setup_165
17250         do_facet ost1 timeout 60 ofd_access_log_reader \
17251                 --exit-on-close --debug=- --trace=- > "${trace}" &
17252         sleep 5
17253         stop ost1
17254
17255         wait
17256         rc=$?
17257
17258         if ((rc != 0)); then
17259                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17260                 cat "${trace}"
17261                 exit 1
17262         fi
17263 }
17264 run_test 165f "ofd_access_log_reader --exit-on-close works"
17265
17266 test_169() {
17267         # do directio so as not to populate the page cache
17268         log "creating a 10 Mb file"
17269         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17270                 error "multiop failed while creating a file"
17271         log "starting reads"
17272         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17273         log "truncating the file"
17274         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17275                 error "multiop failed while truncating the file"
17276         log "killing dd"
17277         kill %+ || true # reads might have finished
17278         echo "wait until dd is finished"
17279         wait
17280         log "removing the temporary file"
17281         rm -rf $DIR/$tfile || error "tmp file removal failed"
17282 }
17283 run_test 169 "parallel read and truncate should not deadlock"
17284
17285 test_170() {
17286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17287
17288         $LCTL clear     # bug 18514
17289         $LCTL debug_daemon start $TMP/${tfile}_log_good
17290         touch $DIR/$tfile
17291         $LCTL debug_daemon stop
17292         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17293                 error "sed failed to read log_good"
17294
17295         $LCTL debug_daemon start $TMP/${tfile}_log_good
17296         rm -rf $DIR/$tfile
17297         $LCTL debug_daemon stop
17298
17299         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17300                error "lctl df log_bad failed"
17301
17302         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17303         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17304
17305         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17306         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17307
17308         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17309                 error "bad_line good_line1 good_line2 are empty"
17310
17311         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17312         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17313         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17314
17315         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17316         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17317         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17318
17319         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17320                 error "bad_line_new good_line_new are empty"
17321
17322         local expected_good=$((good_line1 + good_line2*2))
17323
17324         rm -f $TMP/${tfile}*
17325         # LU-231, short malformed line may not be counted into bad lines
17326         if [ $bad_line -ne $bad_line_new ] &&
17327                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17328                 error "expected $bad_line bad lines, but got $bad_line_new"
17329                 return 1
17330         fi
17331
17332         if [ $expected_good -ne $good_line_new ]; then
17333                 error "expected $expected_good good lines, but got $good_line_new"
17334                 return 2
17335         fi
17336         true
17337 }
17338 run_test 170 "test lctl df to handle corrupted log ====================="
17339
17340 test_171() { # bug20592
17341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17342
17343         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17344         $LCTL set_param fail_loc=0x50e
17345         $LCTL set_param fail_val=3000
17346         multiop_bg_pause $DIR/$tfile O_s || true
17347         local MULTIPID=$!
17348         kill -USR1 $MULTIPID
17349         # cause log dump
17350         sleep 3
17351         wait $MULTIPID
17352         if dmesg | grep "recursive fault"; then
17353                 error "caught a recursive fault"
17354         fi
17355         $LCTL set_param fail_loc=0
17356         true
17357 }
17358 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17359
17360 # it would be good to share it with obdfilter-survey/iokit-libecho code
17361 setup_obdecho_osc () {
17362         local rc=0
17363         local ost_nid=$1
17364         local obdfilter_name=$2
17365         echo "Creating new osc for $obdfilter_name on $ost_nid"
17366         # make sure we can find loopback nid
17367         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17368
17369         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17370                            ${obdfilter_name}_osc_UUID || rc=2; }
17371         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17372                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17373         return $rc
17374 }
17375
17376 cleanup_obdecho_osc () {
17377         local obdfilter_name=$1
17378         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17379         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17380         return 0
17381 }
17382
17383 obdecho_test() {
17384         local OBD=$1
17385         local node=$2
17386         local pages=${3:-64}
17387         local rc=0
17388         local id
17389
17390         local count=10
17391         local obd_size=$(get_obd_size $node $OBD)
17392         local page_size=$(get_page_size $node)
17393         if [[ -n "$obd_size" ]]; then
17394                 local new_count=$((obd_size / (pages * page_size / 1024)))
17395                 [[ $new_count -ge $count ]] || count=$new_count
17396         fi
17397
17398         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17399         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17400                            rc=2; }
17401         if [ $rc -eq 0 ]; then
17402             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17403             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17404         fi
17405         echo "New object id is $id"
17406         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17407                            rc=4; }
17408         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17409                            "test_brw $count w v $pages $id" || rc=4; }
17410         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17411                            rc=4; }
17412         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17413                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17414         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17415                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17416         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17417         return $rc
17418 }
17419
17420 test_180a() {
17421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17422
17423         if ! [ -d /sys/fs/lustre/echo_client ] &&
17424            ! module_loaded obdecho; then
17425                 load_module obdecho/obdecho &&
17426                         stack_trap "rmmod obdecho" EXIT ||
17427                         error "unable to load obdecho on client"
17428         fi
17429
17430         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17431         local host=$($LCTL get_param -n osc.$osc.import |
17432                      awk '/current_connection:/ { print $2 }' )
17433         local target=$($LCTL get_param -n osc.$osc.import |
17434                        awk '/target:/ { print $2 }' )
17435         target=${target%_UUID}
17436
17437         if [ -n "$target" ]; then
17438                 setup_obdecho_osc $host $target &&
17439                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17440                         { error "obdecho setup failed with $?"; return; }
17441
17442                 obdecho_test ${target}_osc client ||
17443                         error "obdecho_test failed on ${target}_osc"
17444         else
17445                 $LCTL get_param osc.$osc.import
17446                 error "there is no osc.$osc.import target"
17447         fi
17448 }
17449 run_test 180a "test obdecho on osc"
17450
17451 test_180b() {
17452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17453         remote_ost_nodsh && skip "remote OST with nodsh"
17454
17455         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17456                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17457                 error "failed to load module obdecho"
17458
17459         local target=$(do_facet ost1 $LCTL dl |
17460                        awk '/obdfilter/ { print $4; exit; }')
17461
17462         if [ -n "$target" ]; then
17463                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17464         else
17465                 do_facet ost1 $LCTL dl
17466                 error "there is no obdfilter target on ost1"
17467         fi
17468 }
17469 run_test 180b "test obdecho directly on obdfilter"
17470
17471 test_180c() { # LU-2598
17472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17473         remote_ost_nodsh && skip "remote OST with nodsh"
17474         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17475                 skip "Need MDS version at least 2.4.0"
17476
17477         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17478                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17479                 error "failed to load module obdecho"
17480
17481         local target=$(do_facet ost1 $LCTL dl |
17482                        awk '/obdfilter/ { print $4; exit; }')
17483
17484         if [ -n "$target" ]; then
17485                 local pages=16384 # 64MB bulk I/O RPC size
17486
17487                 obdecho_test "$target" ost1 "$pages" ||
17488                         error "obdecho_test with pages=$pages failed with $?"
17489         else
17490                 do_facet ost1 $LCTL dl
17491                 error "there is no obdfilter target on ost1"
17492         fi
17493 }
17494 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17495
17496 test_181() { # bug 22177
17497         test_mkdir $DIR/$tdir
17498         # create enough files to index the directory
17499         createmany -o $DIR/$tdir/foobar 4000
17500         # print attributes for debug purpose
17501         lsattr -d .
17502         # open dir
17503         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17504         MULTIPID=$!
17505         # remove the files & current working dir
17506         unlinkmany $DIR/$tdir/foobar 4000
17507         rmdir $DIR/$tdir
17508         kill -USR1 $MULTIPID
17509         wait $MULTIPID
17510         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17511         return 0
17512 }
17513 run_test 181 "Test open-unlinked dir ========================"
17514
17515 test_182() {
17516         local fcount=1000
17517         local tcount=10
17518
17519         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17520
17521         $LCTL set_param mdc.*.rpc_stats=clear
17522
17523         for (( i = 0; i < $tcount; i++ )) ; do
17524                 mkdir $DIR/$tdir/$i
17525         done
17526
17527         for (( i = 0; i < $tcount; i++ )) ; do
17528                 createmany -o $DIR/$tdir/$i/f- $fcount &
17529         done
17530         wait
17531
17532         for (( i = 0; i < $tcount; i++ )) ; do
17533                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17534         done
17535         wait
17536
17537         $LCTL get_param mdc.*.rpc_stats
17538
17539         rm -rf $DIR/$tdir
17540 }
17541 run_test 182 "Test parallel modify metadata operations ================"
17542
17543 test_183() { # LU-2275
17544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17545         remote_mds_nodsh && skip "remote MDS with nodsh"
17546         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17547                 skip "Need MDS version at least 2.3.56"
17548
17549         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17550         echo aaa > $DIR/$tdir/$tfile
17551
17552 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17553         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17554
17555         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17556         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17557
17558         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17559
17560         # Flush negative dentry cache
17561         touch $DIR/$tdir/$tfile
17562
17563         # We are not checking for any leaked references here, they'll
17564         # become evident next time we do cleanup with module unload.
17565         rm -rf $DIR/$tdir
17566 }
17567 run_test 183 "No crash or request leak in case of strange dispositions ========"
17568
17569 # test suite 184 is for LU-2016, LU-2017
17570 test_184a() {
17571         check_swap_layouts_support
17572
17573         dir0=$DIR/$tdir/$testnum
17574         test_mkdir -p -c1 $dir0
17575         ref1=/etc/passwd
17576         ref2=/etc/group
17577         file1=$dir0/f1
17578         file2=$dir0/f2
17579         $LFS setstripe -c1 $file1
17580         cp $ref1 $file1
17581         $LFS setstripe -c2 $file2
17582         cp $ref2 $file2
17583         gen1=$($LFS getstripe -g $file1)
17584         gen2=$($LFS getstripe -g $file2)
17585
17586         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17587         gen=$($LFS getstripe -g $file1)
17588         [[ $gen1 != $gen ]] ||
17589                 "Layout generation on $file1 does not change"
17590         gen=$($LFS getstripe -g $file2)
17591         [[ $gen2 != $gen ]] ||
17592                 "Layout generation on $file2 does not change"
17593
17594         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17595         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17596
17597         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17598 }
17599 run_test 184a "Basic layout swap"
17600
17601 test_184b() {
17602         check_swap_layouts_support
17603
17604         dir0=$DIR/$tdir/$testnum
17605         mkdir -p $dir0 || error "creating dir $dir0"
17606         file1=$dir0/f1
17607         file2=$dir0/f2
17608         file3=$dir0/f3
17609         dir1=$dir0/d1
17610         dir2=$dir0/d2
17611         mkdir $dir1 $dir2
17612         $LFS setstripe -c1 $file1
17613         $LFS setstripe -c2 $file2
17614         $LFS setstripe -c1 $file3
17615         chown $RUNAS_ID $file3
17616         gen1=$($LFS getstripe -g $file1)
17617         gen2=$($LFS getstripe -g $file2)
17618
17619         $LFS swap_layouts $dir1 $dir2 &&
17620                 error "swap of directories layouts should fail"
17621         $LFS swap_layouts $dir1 $file1 &&
17622                 error "swap of directory and file layouts should fail"
17623         $RUNAS $LFS swap_layouts $file1 $file2 &&
17624                 error "swap of file we cannot write should fail"
17625         $LFS swap_layouts $file1 $file3 &&
17626                 error "swap of file with different owner should fail"
17627         /bin/true # to clear error code
17628 }
17629 run_test 184b "Forbidden layout swap (will generate errors)"
17630
17631 test_184c() {
17632         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17633         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17634         check_swap_layouts_support
17635         check_swap_layout_no_dom $DIR
17636
17637         local dir0=$DIR/$tdir/$testnum
17638         mkdir -p $dir0 || error "creating dir $dir0"
17639
17640         local ref1=$dir0/ref1
17641         local ref2=$dir0/ref2
17642         local file1=$dir0/file1
17643         local file2=$dir0/file2
17644         # create a file large enough for the concurrent test
17645         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17646         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17647         echo "ref file size: ref1($(stat -c %s $ref1))," \
17648              "ref2($(stat -c %s $ref2))"
17649
17650         cp $ref2 $file2
17651         dd if=$ref1 of=$file1 bs=16k &
17652         local DD_PID=$!
17653
17654         # Make sure dd starts to copy file, but wait at most 5 seconds
17655         local loops=0
17656         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17657
17658         $LFS swap_layouts $file1 $file2
17659         local rc=$?
17660         wait $DD_PID
17661         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17662         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17663
17664         # how many bytes copied before swapping layout
17665         local copied=$(stat -c %s $file2)
17666         local remaining=$(stat -c %s $ref1)
17667         remaining=$((remaining - copied))
17668         echo "Copied $copied bytes before swapping layout..."
17669
17670         cmp -n $copied $file1 $ref2 | grep differ &&
17671                 error "Content mismatch [0, $copied) of ref2 and file1"
17672         cmp -n $copied $file2 $ref1 ||
17673                 error "Content mismatch [0, $copied) of ref1 and file2"
17674         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17675                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17676
17677         # clean up
17678         rm -f $ref1 $ref2 $file1 $file2
17679 }
17680 run_test 184c "Concurrent write and layout swap"
17681
17682 test_184d() {
17683         check_swap_layouts_support
17684         check_swap_layout_no_dom $DIR
17685         [ -z "$(which getfattr 2>/dev/null)" ] &&
17686                 skip_env "no getfattr command"
17687
17688         local file1=$DIR/$tdir/$tfile-1
17689         local file2=$DIR/$tdir/$tfile-2
17690         local file3=$DIR/$tdir/$tfile-3
17691         local lovea1
17692         local lovea2
17693
17694         mkdir -p $DIR/$tdir
17695         touch $file1 || error "create $file1 failed"
17696         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17697                 error "create $file2 failed"
17698         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17699                 error "create $file3 failed"
17700         lovea1=$(get_layout_param $file1)
17701
17702         $LFS swap_layouts $file2 $file3 ||
17703                 error "swap $file2 $file3 layouts failed"
17704         $LFS swap_layouts $file1 $file2 ||
17705                 error "swap $file1 $file2 layouts failed"
17706
17707         lovea2=$(get_layout_param $file2)
17708         echo "$lovea1"
17709         echo "$lovea2"
17710         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17711
17712         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17713         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17714 }
17715 run_test 184d "allow stripeless layouts swap"
17716
17717 test_184e() {
17718         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17719                 skip "Need MDS version at least 2.6.94"
17720         check_swap_layouts_support
17721         check_swap_layout_no_dom $DIR
17722         [ -z "$(which getfattr 2>/dev/null)" ] &&
17723                 skip_env "no getfattr command"
17724
17725         local file1=$DIR/$tdir/$tfile-1
17726         local file2=$DIR/$tdir/$tfile-2
17727         local file3=$DIR/$tdir/$tfile-3
17728         local lovea
17729
17730         mkdir -p $DIR/$tdir
17731         touch $file1 || error "create $file1 failed"
17732         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17733                 error "create $file2 failed"
17734         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17735                 error "create $file3 failed"
17736
17737         $LFS swap_layouts $file1 $file2 ||
17738                 error "swap $file1 $file2 layouts failed"
17739
17740         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17741         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17742
17743         echo 123 > $file1 || error "Should be able to write into $file1"
17744
17745         $LFS swap_layouts $file1 $file3 ||
17746                 error "swap $file1 $file3 layouts failed"
17747
17748         echo 123 > $file1 || error "Should be able to write into $file1"
17749
17750         rm -rf $file1 $file2 $file3
17751 }
17752 run_test 184e "Recreate layout after stripeless layout swaps"
17753
17754 test_184f() {
17755         # Create a file with name longer than sizeof(struct stat) ==
17756         # 144 to see if we can get chars from the file name to appear
17757         # in the returned striping. Note that 'f' == 0x66.
17758         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17759
17760         mkdir -p $DIR/$tdir
17761         mcreate $DIR/$tdir/$file
17762         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17763                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17764         fi
17765 }
17766 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17767
17768 test_185() { # LU-2441
17769         # LU-3553 - no volatile file support in old servers
17770         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17771                 skip "Need MDS version at least 2.3.60"
17772
17773         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17774         touch $DIR/$tdir/spoo
17775         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17776         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17777                 error "cannot create/write a volatile file"
17778         [ "$FILESET" == "" ] &&
17779         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17780                 error "FID is still valid after close"
17781
17782         multiop_bg_pause $DIR/$tdir vVw4096_c
17783         local multi_pid=$!
17784
17785         local OLD_IFS=$IFS
17786         IFS=":"
17787         local fidv=($fid)
17788         IFS=$OLD_IFS
17789         # assume that the next FID for this client is sequential, since stdout
17790         # is unfortunately eaten by multiop_bg_pause
17791         local n=$((${fidv[1]} + 1))
17792         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17793         if [ "$FILESET" == "" ]; then
17794                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17795                         error "FID is missing before close"
17796         fi
17797         kill -USR1 $multi_pid
17798         # 1 second delay, so if mtime change we will see it
17799         sleep 1
17800         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17801         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17802 }
17803 run_test 185 "Volatile file support"
17804
17805 function create_check_volatile() {
17806         local idx=$1
17807         local tgt
17808
17809         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17810         local PID=$!
17811         sleep 1
17812         local FID=$(cat /tmp/${tfile}.fid)
17813         [ "$FID" == "" ] && error "can't get FID for volatile"
17814         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17815         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17816         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17817         kill -USR1 $PID
17818         wait
17819         sleep 1
17820         cancel_lru_locks mdc # flush opencache
17821         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17822         return 0
17823 }
17824
17825 test_185a(){
17826         # LU-12516 - volatile creation via .lustre
17827         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17828                 skip "Need MDS version at least 2.3.55"
17829
17830         create_check_volatile 0
17831         [ $MDSCOUNT -lt 2 ] && return 0
17832
17833         # DNE case
17834         create_check_volatile 1
17835
17836         return 0
17837 }
17838 run_test 185a "Volatile file creation in .lustre/fid/"
17839
17840 test_187a() {
17841         remote_mds_nodsh && skip "remote MDS with nodsh"
17842         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17843                 skip "Need MDS version at least 2.3.0"
17844
17845         local dir0=$DIR/$tdir/$testnum
17846         mkdir -p $dir0 || error "creating dir $dir0"
17847
17848         local file=$dir0/file1
17849         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17850         local dv1=$($LFS data_version $file)
17851         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17852         local dv2=$($LFS data_version $file)
17853         [[ $dv1 != $dv2 ]] ||
17854                 error "data version did not change on write $dv1 == $dv2"
17855
17856         # clean up
17857         rm -f $file1
17858 }
17859 run_test 187a "Test data version change"
17860
17861 test_187b() {
17862         remote_mds_nodsh && skip "remote MDS with nodsh"
17863         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17864                 skip "Need MDS version at least 2.3.0"
17865
17866         local dir0=$DIR/$tdir/$testnum
17867         mkdir -p $dir0 || error "creating dir $dir0"
17868
17869         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17870         [[ ${DV[0]} != ${DV[1]} ]] ||
17871                 error "data version did not change on write"\
17872                       " ${DV[0]} == ${DV[1]}"
17873
17874         # clean up
17875         rm -f $file1
17876 }
17877 run_test 187b "Test data version change on volatile file"
17878
17879 test_200() {
17880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17881         remote_mgs_nodsh && skip "remote MGS with nodsh"
17882         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17883
17884         local POOL=${POOL:-cea1}
17885         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17886         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17887         # Pool OST targets
17888         local first_ost=0
17889         local last_ost=$(($OSTCOUNT - 1))
17890         local ost_step=2
17891         local ost_list=$(seq $first_ost $ost_step $last_ost)
17892         local ost_range="$first_ost $last_ost $ost_step"
17893         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17894         local file_dir=$POOL_ROOT/file_tst
17895         local subdir=$test_path/subdir
17896         local rc=0
17897
17898         while : ; do
17899                 # former test_200a test_200b
17900                 pool_add $POOL                          || { rc=$? ; break; }
17901                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17902                 # former test_200c test_200d
17903                 mkdir -p $test_path
17904                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17905                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17906                 mkdir -p $subdir
17907                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17908                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17909                                                         || { rc=$? ; break; }
17910                 # former test_200e test_200f
17911                 local files=$((OSTCOUNT*3))
17912                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17913                                                         || { rc=$? ; break; }
17914                 pool_create_files $POOL $file_dir $files "$ost_list" \
17915                                                         || { rc=$? ; break; }
17916                 # former test_200g test_200h
17917                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17918                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17919
17920                 # former test_201a test_201b test_201c
17921                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17922
17923                 local f=$test_path/$tfile
17924                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17925                 pool_remove $POOL $f                    || { rc=$? ; break; }
17926                 break
17927         done
17928
17929         destroy_test_pools
17930
17931         return $rc
17932 }
17933 run_test 200 "OST pools"
17934
17935 # usage: default_attr <count | size | offset>
17936 default_attr() {
17937         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17938 }
17939
17940 # usage: check_default_stripe_attr
17941 check_default_stripe_attr() {
17942         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17943         case $1 in
17944         --stripe-count|-c)
17945                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17946         --stripe-size|-S)
17947                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17948         --stripe-index|-i)
17949                 EXPECTED=-1;;
17950         *)
17951                 error "unknown getstripe attr '$1'"
17952         esac
17953
17954         [ $ACTUAL == $EXPECTED ] ||
17955                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17956 }
17957
17958 test_204a() {
17959         test_mkdir $DIR/$tdir
17960         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17961
17962         check_default_stripe_attr --stripe-count
17963         check_default_stripe_attr --stripe-size
17964         check_default_stripe_attr --stripe-index
17965 }
17966 run_test 204a "Print default stripe attributes"
17967
17968 test_204b() {
17969         test_mkdir $DIR/$tdir
17970         $LFS setstripe --stripe-count 1 $DIR/$tdir
17971
17972         check_default_stripe_attr --stripe-size
17973         check_default_stripe_attr --stripe-index
17974 }
17975 run_test 204b "Print default stripe size and offset"
17976
17977 test_204c() {
17978         test_mkdir $DIR/$tdir
17979         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17980
17981         check_default_stripe_attr --stripe-count
17982         check_default_stripe_attr --stripe-index
17983 }
17984 run_test 204c "Print default stripe count and offset"
17985
17986 test_204d() {
17987         test_mkdir $DIR/$tdir
17988         $LFS setstripe --stripe-index 0 $DIR/$tdir
17989
17990         check_default_stripe_attr --stripe-count
17991         check_default_stripe_attr --stripe-size
17992 }
17993 run_test 204d "Print default stripe count and size"
17994
17995 test_204e() {
17996         test_mkdir $DIR/$tdir
17997         $LFS setstripe -d $DIR/$tdir
17998
17999         check_default_stripe_attr --stripe-count --raw
18000         check_default_stripe_attr --stripe-size --raw
18001         check_default_stripe_attr --stripe-index --raw
18002 }
18003 run_test 204e "Print raw stripe attributes"
18004
18005 test_204f() {
18006         test_mkdir $DIR/$tdir
18007         $LFS setstripe --stripe-count 1 $DIR/$tdir
18008
18009         check_default_stripe_attr --stripe-size --raw
18010         check_default_stripe_attr --stripe-index --raw
18011 }
18012 run_test 204f "Print raw stripe size and offset"
18013
18014 test_204g() {
18015         test_mkdir $DIR/$tdir
18016         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18017
18018         check_default_stripe_attr --stripe-count --raw
18019         check_default_stripe_attr --stripe-index --raw
18020 }
18021 run_test 204g "Print raw stripe count and offset"
18022
18023 test_204h() {
18024         test_mkdir $DIR/$tdir
18025         $LFS setstripe --stripe-index 0 $DIR/$tdir
18026
18027         check_default_stripe_attr --stripe-count --raw
18028         check_default_stripe_attr --stripe-size --raw
18029 }
18030 run_test 204h "Print raw stripe count and size"
18031
18032 # Figure out which job scheduler is being used, if any,
18033 # or use a fake one
18034 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18035         JOBENV=SLURM_JOB_ID
18036 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18037         JOBENV=LSB_JOBID
18038 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18039         JOBENV=PBS_JOBID
18040 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18041         JOBENV=LOADL_STEP_ID
18042 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18043         JOBENV=JOB_ID
18044 else
18045         $LCTL list_param jobid_name > /dev/null 2>&1
18046         if [ $? -eq 0 ]; then
18047                 JOBENV=nodelocal
18048         else
18049                 JOBENV=FAKE_JOBID
18050         fi
18051 fi
18052 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18053
18054 verify_jobstats() {
18055         local cmd=($1)
18056         shift
18057         local facets="$@"
18058
18059 # we don't really need to clear the stats for this test to work, since each
18060 # command has a unique jobid, but it makes debugging easier if needed.
18061 #       for facet in $facets; do
18062 #               local dev=$(convert_facet2label $facet)
18063 #               # clear old jobstats
18064 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18065 #       done
18066
18067         # use a new JobID for each test, or we might see an old one
18068         [ "$JOBENV" = "FAKE_JOBID" ] &&
18069                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18070
18071         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18072
18073         [ "$JOBENV" = "nodelocal" ] && {
18074                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18075                 $LCTL set_param jobid_name=$FAKE_JOBID
18076                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18077         }
18078
18079         log "Test: ${cmd[*]}"
18080         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18081
18082         if [ $JOBENV = "FAKE_JOBID" ]; then
18083                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18084         else
18085                 ${cmd[*]}
18086         fi
18087
18088         # all files are created on OST0000
18089         for facet in $facets; do
18090                 local stats="*.$(convert_facet2label $facet).job_stats"
18091
18092                 # strip out libtool wrappers for in-tree executables
18093                 if [ $(do_facet $facet lctl get_param $stats |
18094                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18095                         do_facet $facet lctl get_param $stats
18096                         error "No jobstats for $JOBVAL found on $facet::$stats"
18097                 fi
18098         done
18099 }
18100
18101 jobstats_set() {
18102         local new_jobenv=$1
18103
18104         set_persistent_param_and_check client "jobid_var" \
18105                 "$FSNAME.sys.jobid_var" $new_jobenv
18106 }
18107
18108 test_205a() { # Job stats
18109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18110         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18111                 skip "Need MDS version with at least 2.7.1"
18112         remote_mgs_nodsh && skip "remote MGS with nodsh"
18113         remote_mds_nodsh && skip "remote MDS with nodsh"
18114         remote_ost_nodsh && skip "remote OST with nodsh"
18115         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18116                 skip "Server doesn't support jobstats"
18117         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18118
18119         local old_jobenv=$($LCTL get_param -n jobid_var)
18120         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18121
18122         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18123                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18124         else
18125                 stack_trap "do_facet mgs $PERM_CMD \
18126                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18127         fi
18128         changelog_register
18129
18130         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18131                                 mdt.*.job_cleanup_interval | head -n 1)
18132         local new_interval=5
18133         do_facet $SINGLEMDS \
18134                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18135         stack_trap "do_facet $SINGLEMDS \
18136                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18137         local start=$SECONDS
18138
18139         local cmd
18140         # mkdir
18141         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18142         verify_jobstats "$cmd" "$SINGLEMDS"
18143         # rmdir
18144         cmd="rmdir $DIR/$tdir"
18145         verify_jobstats "$cmd" "$SINGLEMDS"
18146         # mkdir on secondary MDT
18147         if [ $MDSCOUNT -gt 1 ]; then
18148                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18149                 verify_jobstats "$cmd" "mds2"
18150         fi
18151         # mknod
18152         cmd="mknod $DIR/$tfile c 1 3"
18153         verify_jobstats "$cmd" "$SINGLEMDS"
18154         # unlink
18155         cmd="rm -f $DIR/$tfile"
18156         verify_jobstats "$cmd" "$SINGLEMDS"
18157         # create all files on OST0000 so verify_jobstats can find OST stats
18158         # open & close
18159         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18160         verify_jobstats "$cmd" "$SINGLEMDS"
18161         # setattr
18162         cmd="touch $DIR/$tfile"
18163         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18164         # write
18165         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18166         verify_jobstats "$cmd" "ost1"
18167         # read
18168         cancel_lru_locks osc
18169         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18170         verify_jobstats "$cmd" "ost1"
18171         # truncate
18172         cmd="$TRUNCATE $DIR/$tfile 0"
18173         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18174         # rename
18175         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18176         verify_jobstats "$cmd" "$SINGLEMDS"
18177         # jobstats expiry - sleep until old stats should be expired
18178         local left=$((new_interval + 5 - (SECONDS - start)))
18179         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18180                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18181                         "0" $left
18182         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18183         verify_jobstats "$cmd" "$SINGLEMDS"
18184         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18185             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18186
18187         # Ensure that jobid are present in changelog (if supported by MDS)
18188         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18189                 changelog_dump | tail -10
18190                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18191                 [ $jobids -eq 9 ] ||
18192                         error "Wrong changelog jobid count $jobids != 9"
18193
18194                 # LU-5862
18195                 JOBENV="disable"
18196                 jobstats_set $JOBENV
18197                 touch $DIR/$tfile
18198                 changelog_dump | grep $tfile
18199                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18200                 [ $jobids -eq 0 ] ||
18201                         error "Unexpected jobids when jobid_var=$JOBENV"
18202         fi
18203
18204         # test '%j' access to environment variable - if supported
18205         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18206                 JOBENV="JOBCOMPLEX"
18207                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18208
18209                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18210         fi
18211
18212         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18213                 JOBENV="JOBCOMPLEX"
18214                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18215
18216                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18217         fi
18218
18219         # test '%j' access to per-session jobid - if supported
18220         if lctl list_param jobid_this_session > /dev/null 2>&1
18221         then
18222                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18223                 lctl set_param jobid_this_session=$USER
18224
18225                 JOBENV="JOBCOMPLEX"
18226                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18227
18228                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18229         fi
18230 }
18231 run_test 205a "Verify job stats"
18232
18233 # LU-13117, LU-13597
18234 test_205b() {
18235         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18236                 skip "Need MDS version at least 2.13.54.91"
18237
18238         job_stats="mdt.*.job_stats"
18239         $LCTL set_param $job_stats=clear
18240         # Setting jobid_var to USER might not be supported
18241         $LCTL set_param jobid_var=USER || true
18242         $LCTL set_param jobid_name="%e.%u"
18243         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18244         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18245                 grep "job_id:.*foolish" &&
18246                         error "Unexpected jobid found"
18247         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18248                 grep "open:.*min.*max.*sum" ||
18249                         error "wrong job_stats format found"
18250 }
18251 run_test 205b "Verify job stats jobid and output format"
18252
18253 # LU-13733
18254 test_205c() {
18255         $LCTL set_param llite.*.stats=0
18256         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18257         $LCTL get_param llite.*.stats
18258         $LCTL get_param llite.*.stats | grep \
18259                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18260                         error "wrong client stats format found"
18261 }
18262 run_test 205c "Verify client stats format"
18263
18264 # LU-1480, LU-1773 and LU-1657
18265 test_206() {
18266         mkdir -p $DIR/$tdir
18267         $LFS setstripe -c -1 $DIR/$tdir
18268 #define OBD_FAIL_LOV_INIT 0x1403
18269         $LCTL set_param fail_loc=0xa0001403
18270         $LCTL set_param fail_val=1
18271         touch $DIR/$tdir/$tfile || true
18272 }
18273 run_test 206 "fail lov_init_raid0() doesn't lbug"
18274
18275 test_207a() {
18276         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18277         local fsz=`stat -c %s $DIR/$tfile`
18278         cancel_lru_locks mdc
18279
18280         # do not return layout in getattr intent
18281 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18282         $LCTL set_param fail_loc=0x170
18283         local sz=`stat -c %s $DIR/$tfile`
18284
18285         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18286
18287         rm -rf $DIR/$tfile
18288 }
18289 run_test 207a "can refresh layout at glimpse"
18290
18291 test_207b() {
18292         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18293         local cksum=`md5sum $DIR/$tfile`
18294         local fsz=`stat -c %s $DIR/$tfile`
18295         cancel_lru_locks mdc
18296         cancel_lru_locks osc
18297
18298         # do not return layout in getattr intent
18299 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18300         $LCTL set_param fail_loc=0x171
18301
18302         # it will refresh layout after the file is opened but before read issues
18303         echo checksum is "$cksum"
18304         echo "$cksum" |md5sum -c --quiet || error "file differs"
18305
18306         rm -rf $DIR/$tfile
18307 }
18308 run_test 207b "can refresh layout at open"
18309
18310 test_208() {
18311         # FIXME: in this test suite, only RD lease is used. This is okay
18312         # for now as only exclusive open is supported. After generic lease
18313         # is done, this test suite should be revised. - Jinshan
18314
18315         remote_mds_nodsh && skip "remote MDS with nodsh"
18316         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18317                 skip "Need MDS version at least 2.4.52"
18318
18319         echo "==== test 1: verify get lease work"
18320         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18321
18322         echo "==== test 2: verify lease can be broken by upcoming open"
18323         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18324         local PID=$!
18325         sleep 1
18326
18327         $MULTIOP $DIR/$tfile oO_RDWR:c
18328         kill -USR1 $PID && wait $PID || error "break lease error"
18329
18330         echo "==== test 3: verify lease can't be granted if an open already exists"
18331         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18332         local PID=$!
18333         sleep 1
18334
18335         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18336         kill -USR1 $PID && wait $PID || error "open file error"
18337
18338         echo "==== test 4: lease can sustain over recovery"
18339         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18340         PID=$!
18341         sleep 1
18342
18343         fail mds1
18344
18345         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18346
18347         echo "==== test 5: lease broken can't be regained by replay"
18348         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18349         PID=$!
18350         sleep 1
18351
18352         # open file to break lease and then recovery
18353         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18354         fail mds1
18355
18356         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18357
18358         rm -f $DIR/$tfile
18359 }
18360 run_test 208 "Exclusive open"
18361
18362 test_209() {
18363         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18364                 skip_env "must have disp_stripe"
18365
18366         touch $DIR/$tfile
18367         sync; sleep 5; sync;
18368
18369         echo 3 > /proc/sys/vm/drop_caches
18370         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18371                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18372         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18373
18374         # open/close 500 times
18375         for i in $(seq 500); do
18376                 cat $DIR/$tfile
18377         done
18378
18379         echo 3 > /proc/sys/vm/drop_caches
18380         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18381                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18382         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18383
18384         echo "before: $req_before, after: $req_after"
18385         [ $((req_after - req_before)) -ge 300 ] &&
18386                 error "open/close requests are not freed"
18387         return 0
18388 }
18389 run_test 209 "read-only open/close requests should be freed promptly"
18390
18391 test_210() {
18392         local pid
18393
18394         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18395         pid=$!
18396         sleep 1
18397
18398         $LFS getstripe $DIR/$tfile
18399         kill -USR1 $pid
18400         wait $pid || error "multiop failed"
18401
18402         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18403         pid=$!
18404         sleep 1
18405
18406         $LFS getstripe $DIR/$tfile
18407         kill -USR1 $pid
18408         wait $pid || error "multiop failed"
18409 }
18410 run_test 210 "lfs getstripe does not break leases"
18411
18412 test_212() {
18413         size=`date +%s`
18414         size=$((size % 8192 + 1))
18415         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18416         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18417         rm -f $DIR/f212 $DIR/f212.xyz
18418 }
18419 run_test 212 "Sendfile test ============================================"
18420
18421 test_213() {
18422         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18423         cancel_lru_locks osc
18424         lctl set_param fail_loc=0x8000040f
18425         # generate a read lock
18426         cat $DIR/$tfile > /dev/null
18427         # write to the file, it will try to cancel the above read lock.
18428         cat /etc/hosts >> $DIR/$tfile
18429 }
18430 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18431
18432 test_214() { # for bug 20133
18433         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18434         for (( i=0; i < 340; i++ )) ; do
18435                 touch $DIR/$tdir/d214c/a$i
18436         done
18437
18438         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18439         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18440         ls $DIR/d214c || error "ls $DIR/d214c failed"
18441         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18442         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18443 }
18444 run_test 214 "hash-indexed directory test - bug 20133"
18445
18446 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18447 create_lnet_proc_files() {
18448         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18449 }
18450
18451 # counterpart of create_lnet_proc_files
18452 remove_lnet_proc_files() {
18453         rm -f $TMP/lnet_$1.sys
18454 }
18455
18456 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18457 # 3rd arg as regexp for body
18458 check_lnet_proc_stats() {
18459         local l=$(cat "$TMP/lnet_$1" |wc -l)
18460         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18461
18462         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18463 }
18464
18465 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18466 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18467 # optional and can be regexp for 2nd line (lnet.routes case)
18468 check_lnet_proc_entry() {
18469         local blp=2          # blp stands for 'position of 1st line of body'
18470         [ -z "$5" ] || blp=3 # lnet.routes case
18471
18472         local l=$(cat "$TMP/lnet_$1" |wc -l)
18473         # subtracting one from $blp because the body can be empty
18474         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18475
18476         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18477                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18478
18479         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18480                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18481
18482         # bail out if any unexpected line happened
18483         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18484         [ "$?" != 0 ] || error "$2 misformatted"
18485 }
18486
18487 test_215() { # for bugs 18102, 21079, 21517
18488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18489
18490         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18491         local P='[1-9][0-9]*'           # positive numeric
18492         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18493         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18494         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18495         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18496
18497         local L1 # regexp for 1st line
18498         local L2 # regexp for 2nd line (optional)
18499         local BR # regexp for the rest (body)
18500
18501         # lnet.stats should look as 11 space-separated non-negative numerics
18502         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18503         create_lnet_proc_files "stats"
18504         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18505         remove_lnet_proc_files "stats"
18506
18507         # lnet.routes should look like this:
18508         # Routing disabled/enabled
18509         # net hops priority state router
18510         # where net is a string like tcp0, hops > 0, priority >= 0,
18511         # state is up/down,
18512         # router is a string like 192.168.1.1@tcp2
18513         L1="^Routing (disabled|enabled)$"
18514         L2="^net +hops +priority +state +router$"
18515         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18516         create_lnet_proc_files "routes"
18517         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18518         remove_lnet_proc_files "routes"
18519
18520         # lnet.routers should look like this:
18521         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18522         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18523         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18524         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18525         L1="^ref +rtr_ref +alive +router$"
18526         BR="^$P +$P +(up|down) +$NID$"
18527         create_lnet_proc_files "routers"
18528         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18529         remove_lnet_proc_files "routers"
18530
18531         # lnet.peers should look like this:
18532         # nid refs state last max rtr min tx min queue
18533         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18534         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18535         # numeric (0 or >0 or <0), queue >= 0.
18536         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18537         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18538         create_lnet_proc_files "peers"
18539         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18540         remove_lnet_proc_files "peers"
18541
18542         # lnet.buffers  should look like this:
18543         # pages count credits min
18544         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18545         L1="^pages +count +credits +min$"
18546         BR="^ +$N +$N +$I +$I$"
18547         create_lnet_proc_files "buffers"
18548         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18549         remove_lnet_proc_files "buffers"
18550
18551         # lnet.nis should look like this:
18552         # nid status alive refs peer rtr max tx min
18553         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18554         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18555         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18556         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18557         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18558         create_lnet_proc_files "nis"
18559         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18560         remove_lnet_proc_files "nis"
18561
18562         # can we successfully write to lnet.stats?
18563         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18564 }
18565 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18566
18567 test_216() { # bug 20317
18568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18569         remote_ost_nodsh && skip "remote OST with nodsh"
18570
18571         local node
18572         local facets=$(get_facets OST)
18573         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18574
18575         save_lustre_params client "osc.*.contention_seconds" > $p
18576         save_lustre_params $facets \
18577                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18578         save_lustre_params $facets \
18579                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18580         save_lustre_params $facets \
18581                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18582         clear_stats osc.*.osc_stats
18583
18584         # agressive lockless i/o settings
18585         do_nodes $(comma_list $(osts_nodes)) \
18586                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18587                         ldlm.namespaces.filter-*.contended_locks=0 \
18588                         ldlm.namespaces.filter-*.contention_seconds=60"
18589         lctl set_param -n osc.*.contention_seconds=60
18590
18591         $DIRECTIO write $DIR/$tfile 0 10 4096
18592         $CHECKSTAT -s 40960 $DIR/$tfile
18593
18594         # disable lockless i/o
18595         do_nodes $(comma_list $(osts_nodes)) \
18596                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18597                         ldlm.namespaces.filter-*.contended_locks=32 \
18598                         ldlm.namespaces.filter-*.contention_seconds=0"
18599         lctl set_param -n osc.*.contention_seconds=0
18600         clear_stats osc.*.osc_stats
18601
18602         dd if=/dev/zero of=$DIR/$tfile count=0
18603         $CHECKSTAT -s 0 $DIR/$tfile
18604
18605         restore_lustre_params <$p
18606         rm -f $p
18607         rm $DIR/$tfile
18608 }
18609 run_test 216 "check lockless direct write updates file size and kms correctly"
18610
18611 test_217() { # bug 22430
18612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18613
18614         local node
18615         local nid
18616
18617         for node in $(nodes_list); do
18618                 nid=$(host_nids_address $node $NETTYPE)
18619                 if [[ $nid = *-* ]] ; then
18620                         echo "lctl ping $(h2nettype $nid)"
18621                         lctl ping $(h2nettype $nid)
18622                 else
18623                         echo "skipping $node (no hyphen detected)"
18624                 fi
18625         done
18626 }
18627 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18628
18629 test_218() {
18630        # do directio so as not to populate the page cache
18631        log "creating a 10 Mb file"
18632        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18633        log "starting reads"
18634        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18635        log "truncating the file"
18636        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18637        log "killing dd"
18638        kill %+ || true # reads might have finished
18639        echo "wait until dd is finished"
18640        wait
18641        log "removing the temporary file"
18642        rm -rf $DIR/$tfile || error "tmp file removal failed"
18643 }
18644 run_test 218 "parallel read and truncate should not deadlock"
18645
18646 test_219() {
18647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18648
18649         # write one partial page
18650         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18651         # set no grant so vvp_io_commit_write will do sync write
18652         $LCTL set_param fail_loc=0x411
18653         # write a full page at the end of file
18654         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18655
18656         $LCTL set_param fail_loc=0
18657         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18658         $LCTL set_param fail_loc=0x411
18659         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18660
18661         # LU-4201
18662         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18663         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18664 }
18665 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18666
18667 test_220() { #LU-325
18668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18669         remote_ost_nodsh && skip "remote OST with nodsh"
18670         remote_mds_nodsh && skip "remote MDS with nodsh"
18671         remote_mgs_nodsh && skip "remote MGS with nodsh"
18672
18673         local OSTIDX=0
18674
18675         # create on MDT0000 so the last_id and next_id are correct
18676         mkdir_on_mdt0 $DIR/$tdir
18677         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18678         OST=${OST%_UUID}
18679
18680         # on the mdt's osc
18681         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18682         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18683                         osp.$mdtosc_proc1.prealloc_last_id)
18684         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18685                         osp.$mdtosc_proc1.prealloc_next_id)
18686
18687         $LFS df -i
18688
18689         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18690         #define OBD_FAIL_OST_ENOINO              0x229
18691         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18692         create_pool $FSNAME.$TESTNAME || return 1
18693         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18694
18695         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18696
18697         MDSOBJS=$((last_id - next_id))
18698         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18699
18700         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18701         echo "OST still has $count kbytes free"
18702
18703         echo "create $MDSOBJS files @next_id..."
18704         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18705
18706         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18707                         osp.$mdtosc_proc1.prealloc_last_id)
18708         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18709                         osp.$mdtosc_proc1.prealloc_next_id)
18710
18711         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18712         $LFS df -i
18713
18714         echo "cleanup..."
18715
18716         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18717         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18718
18719         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18720                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18721         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18722                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18723         echo "unlink $MDSOBJS files @$next_id..."
18724         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18725 }
18726 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18727
18728 test_221() {
18729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18730
18731         dd if=`which date` of=$MOUNT/date oflag=sync
18732         chmod +x $MOUNT/date
18733
18734         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18735         $LCTL set_param fail_loc=0x80001401
18736
18737         $MOUNT/date > /dev/null
18738         rm -f $MOUNT/date
18739 }
18740 run_test 221 "make sure fault and truncate race to not cause OOM"
18741
18742 test_222a () {
18743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18744
18745         rm -rf $DIR/$tdir
18746         test_mkdir $DIR/$tdir
18747         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18748         createmany -o $DIR/$tdir/$tfile 10
18749         cancel_lru_locks mdc
18750         cancel_lru_locks osc
18751         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18752         $LCTL set_param fail_loc=0x31a
18753         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18754         $LCTL set_param fail_loc=0
18755         rm -r $DIR/$tdir
18756 }
18757 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18758
18759 test_222b () {
18760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18761
18762         rm -rf $DIR/$tdir
18763         test_mkdir $DIR/$tdir
18764         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18765         createmany -o $DIR/$tdir/$tfile 10
18766         cancel_lru_locks mdc
18767         cancel_lru_locks osc
18768         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18769         $LCTL set_param fail_loc=0x31a
18770         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18771         $LCTL set_param fail_loc=0
18772 }
18773 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18774
18775 test_223 () {
18776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18777
18778         rm -rf $DIR/$tdir
18779         test_mkdir $DIR/$tdir
18780         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18781         createmany -o $DIR/$tdir/$tfile 10
18782         cancel_lru_locks mdc
18783         cancel_lru_locks osc
18784         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18785         $LCTL set_param fail_loc=0x31b
18786         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18787         $LCTL set_param fail_loc=0
18788         rm -r $DIR/$tdir
18789 }
18790 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18791
18792 test_224a() { # LU-1039, MRP-303
18793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18794
18795         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18796         $LCTL set_param fail_loc=0x508
18797         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18798         $LCTL set_param fail_loc=0
18799         df $DIR
18800 }
18801 run_test 224a "Don't panic on bulk IO failure"
18802
18803 test_224b() { # LU-1039, MRP-303
18804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18805
18806         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18807         cancel_lru_locks osc
18808         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18809         $LCTL set_param fail_loc=0x515
18810         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18811         $LCTL set_param fail_loc=0
18812         df $DIR
18813 }
18814 run_test 224b "Don't panic on bulk IO failure"
18815
18816 test_224c() { # LU-6441
18817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18818         remote_mds_nodsh && skip "remote MDS with nodsh"
18819
18820         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18821         save_writethrough $p
18822         set_cache writethrough on
18823
18824         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18825         local at_max=$($LCTL get_param -n at_max)
18826         local timeout=$($LCTL get_param -n timeout)
18827         local test_at="at_max"
18828         local param_at="$FSNAME.sys.at_max"
18829         local test_timeout="timeout"
18830         local param_timeout="$FSNAME.sys.timeout"
18831
18832         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18833
18834         set_persistent_param_and_check client "$test_at" "$param_at" 0
18835         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18836
18837         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18838         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18839         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18840         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18841         sync
18842         do_facet ost1 "$LCTL set_param fail_loc=0"
18843
18844         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18845         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18846                 $timeout
18847
18848         $LCTL set_param -n $pages_per_rpc
18849         restore_lustre_params < $p
18850         rm -f $p
18851 }
18852 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18853
18854 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18855 test_225a () {
18856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18857         if [ -z ${MDSSURVEY} ]; then
18858                 skip_env "mds-survey not found"
18859         fi
18860         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18861                 skip "Need MDS version at least 2.2.51"
18862
18863         local mds=$(facet_host $SINGLEMDS)
18864         local target=$(do_nodes $mds 'lctl dl' |
18865                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18866
18867         local cmd1="file_count=1000 thrhi=4"
18868         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18869         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18870         local cmd="$cmd1 $cmd2 $cmd3"
18871
18872         rm -f ${TMP}/mds_survey*
18873         echo + $cmd
18874         eval $cmd || error "mds-survey with zero-stripe failed"
18875         cat ${TMP}/mds_survey*
18876         rm -f ${TMP}/mds_survey*
18877 }
18878 run_test 225a "Metadata survey sanity with zero-stripe"
18879
18880 test_225b () {
18881         if [ -z ${MDSSURVEY} ]; then
18882                 skip_env "mds-survey not found"
18883         fi
18884         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18885                 skip "Need MDS version at least 2.2.51"
18886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18887         remote_mds_nodsh && skip "remote MDS with nodsh"
18888         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18889                 skip_env "Need to mount OST to test"
18890         fi
18891
18892         local mds=$(facet_host $SINGLEMDS)
18893         local target=$(do_nodes $mds 'lctl dl' |
18894                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18895
18896         local cmd1="file_count=1000 thrhi=4"
18897         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18898         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18899         local cmd="$cmd1 $cmd2 $cmd3"
18900
18901         rm -f ${TMP}/mds_survey*
18902         echo + $cmd
18903         eval $cmd || error "mds-survey with stripe_count failed"
18904         cat ${TMP}/mds_survey*
18905         rm -f ${TMP}/mds_survey*
18906 }
18907 run_test 225b "Metadata survey sanity with stripe_count = 1"
18908
18909 mcreate_path2fid () {
18910         local mode=$1
18911         local major=$2
18912         local minor=$3
18913         local name=$4
18914         local desc=$5
18915         local path=$DIR/$tdir/$name
18916         local fid
18917         local rc
18918         local fid_path
18919
18920         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18921                 error "cannot create $desc"
18922
18923         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18924         rc=$?
18925         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18926
18927         fid_path=$($LFS fid2path $MOUNT $fid)
18928         rc=$?
18929         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18930
18931         [ "$path" == "$fid_path" ] ||
18932                 error "fid2path returned $fid_path, expected $path"
18933
18934         echo "pass with $path and $fid"
18935 }
18936
18937 test_226a () {
18938         rm -rf $DIR/$tdir
18939         mkdir -p $DIR/$tdir
18940
18941         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18942         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18943         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18944         mcreate_path2fid 0040666 0 0 dir "directory"
18945         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18946         mcreate_path2fid 0100666 0 0 file "regular file"
18947         mcreate_path2fid 0120666 0 0 link "symbolic link"
18948         mcreate_path2fid 0140666 0 0 sock "socket"
18949 }
18950 run_test 226a "call path2fid and fid2path on files of all type"
18951
18952 test_226b () {
18953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18954
18955         local MDTIDX=1
18956
18957         rm -rf $DIR/$tdir
18958         mkdir -p $DIR/$tdir
18959         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18960                 error "create remote directory failed"
18961         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18962         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18963                                 "character special file (null)"
18964         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18965                                 "character special file (no device)"
18966         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18967         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18968                                 "block special file (loop)"
18969         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18970         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18971         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18972 }
18973 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18974
18975 test_226c () {
18976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18977         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18978                 skip "Need MDS version at least 2.13.55"
18979
18980         local submnt=/mnt/submnt
18981         local srcfile=/etc/passwd
18982         local dstfile=$submnt/passwd
18983         local path
18984         local fid
18985
18986         rm -rf $DIR/$tdir
18987         rm -rf $submnt
18988         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18989                 error "create remote directory failed"
18990         mkdir -p $submnt || error "create $submnt failed"
18991         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18992                 error "mount $submnt failed"
18993         stack_trap "umount $submnt" EXIT
18994
18995         cp $srcfile $dstfile
18996         fid=$($LFS path2fid $dstfile)
18997         path=$($LFS fid2path $submnt "$fid")
18998         [ "$path" = "$dstfile" ] ||
18999                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19000 }
19001 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19002
19003 # LU-1299 Executing or running ldd on a truncated executable does not
19004 # cause an out-of-memory condition.
19005 test_227() {
19006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19007         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19008
19009         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19010         chmod +x $MOUNT/date
19011
19012         $MOUNT/date > /dev/null
19013         ldd $MOUNT/date > /dev/null
19014         rm -f $MOUNT/date
19015 }
19016 run_test 227 "running truncated executable does not cause OOM"
19017
19018 # LU-1512 try to reuse idle OI blocks
19019 test_228a() {
19020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19021         remote_mds_nodsh && skip "remote MDS with nodsh"
19022         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19023
19024         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19025         local myDIR=$DIR/$tdir
19026
19027         mkdir -p $myDIR
19028         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19029         $LCTL set_param fail_loc=0x80001002
19030         createmany -o $myDIR/t- 10000
19031         $LCTL set_param fail_loc=0
19032         # The guard is current the largest FID holder
19033         touch $myDIR/guard
19034         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19035                     tr -d '[')
19036         local IDX=$(($SEQ % 64))
19037
19038         do_facet $SINGLEMDS sync
19039         # Make sure journal flushed.
19040         sleep 6
19041         local blk1=$(do_facet $SINGLEMDS \
19042                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19043                      grep Blockcount | awk '{print $4}')
19044
19045         # Remove old files, some OI blocks will become idle.
19046         unlinkmany $myDIR/t- 10000
19047         # Create new files, idle OI blocks should be reused.
19048         createmany -o $myDIR/t- 2000
19049         do_facet $SINGLEMDS sync
19050         # Make sure journal flushed.
19051         sleep 6
19052         local blk2=$(do_facet $SINGLEMDS \
19053                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19054                      grep Blockcount | awk '{print $4}')
19055
19056         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19057 }
19058 run_test 228a "try to reuse idle OI blocks"
19059
19060 test_228b() {
19061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19062         remote_mds_nodsh && skip "remote MDS with nodsh"
19063         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19064
19065         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19066         local myDIR=$DIR/$tdir
19067
19068         mkdir -p $myDIR
19069         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19070         $LCTL set_param fail_loc=0x80001002
19071         createmany -o $myDIR/t- 10000
19072         $LCTL set_param fail_loc=0
19073         # The guard is current the largest FID holder
19074         touch $myDIR/guard
19075         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19076                     tr -d '[')
19077         local IDX=$(($SEQ % 64))
19078
19079         do_facet $SINGLEMDS sync
19080         # Make sure journal flushed.
19081         sleep 6
19082         local blk1=$(do_facet $SINGLEMDS \
19083                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19084                      grep Blockcount | awk '{print $4}')
19085
19086         # Remove old files, some OI blocks will become idle.
19087         unlinkmany $myDIR/t- 10000
19088
19089         # stop the MDT
19090         stop $SINGLEMDS || error "Fail to stop MDT."
19091         # remount the MDT
19092         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19093
19094         df $MOUNT || error "Fail to df."
19095         # Create new files, idle OI blocks should be reused.
19096         createmany -o $myDIR/t- 2000
19097         do_facet $SINGLEMDS sync
19098         # Make sure journal flushed.
19099         sleep 6
19100         local blk2=$(do_facet $SINGLEMDS \
19101                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19102                      grep Blockcount | awk '{print $4}')
19103
19104         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19105 }
19106 run_test 228b "idle OI blocks can be reused after MDT restart"
19107
19108 #LU-1881
19109 test_228c() {
19110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19111         remote_mds_nodsh && skip "remote MDS with nodsh"
19112         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19113
19114         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19115         local myDIR=$DIR/$tdir
19116
19117         mkdir -p $myDIR
19118         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19119         $LCTL set_param fail_loc=0x80001002
19120         # 20000 files can guarantee there are index nodes in the OI file
19121         createmany -o $myDIR/t- 20000
19122         $LCTL set_param fail_loc=0
19123         # The guard is current the largest FID holder
19124         touch $myDIR/guard
19125         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19126                     tr -d '[')
19127         local IDX=$(($SEQ % 64))
19128
19129         do_facet $SINGLEMDS sync
19130         # Make sure journal flushed.
19131         sleep 6
19132         local blk1=$(do_facet $SINGLEMDS \
19133                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19134                      grep Blockcount | awk '{print $4}')
19135
19136         # Remove old files, some OI blocks will become idle.
19137         unlinkmany $myDIR/t- 20000
19138         rm -f $myDIR/guard
19139         # The OI file should become empty now
19140
19141         # Create new files, idle OI blocks should be reused.
19142         createmany -o $myDIR/t- 2000
19143         do_facet $SINGLEMDS sync
19144         # Make sure journal flushed.
19145         sleep 6
19146         local blk2=$(do_facet $SINGLEMDS \
19147                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19148                      grep Blockcount | awk '{print $4}')
19149
19150         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19151 }
19152 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19153
19154 test_229() { # LU-2482, LU-3448
19155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19156         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19157         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19158                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19159
19160         rm -f $DIR/$tfile
19161
19162         # Create a file with a released layout and stripe count 2.
19163         $MULTIOP $DIR/$tfile H2c ||
19164                 error "failed to create file with released layout"
19165
19166         $LFS getstripe -v $DIR/$tfile
19167
19168         local pattern=$($LFS getstripe -L $DIR/$tfile)
19169         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19170
19171         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19172                 error "getstripe"
19173         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19174         stat $DIR/$tfile || error "failed to stat released file"
19175
19176         chown $RUNAS_ID $DIR/$tfile ||
19177                 error "chown $RUNAS_ID $DIR/$tfile failed"
19178
19179         chgrp $RUNAS_ID $DIR/$tfile ||
19180                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19181
19182         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19183         rm $DIR/$tfile || error "failed to remove released file"
19184 }
19185 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19186
19187 test_230a() {
19188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19190         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19191                 skip "Need MDS version at least 2.11.52"
19192
19193         local MDTIDX=1
19194
19195         test_mkdir $DIR/$tdir
19196         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19197         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19198         [ $mdt_idx -ne 0 ] &&
19199                 error "create local directory on wrong MDT $mdt_idx"
19200
19201         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19202                         error "create remote directory failed"
19203         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19204         [ $mdt_idx -ne $MDTIDX ] &&
19205                 error "create remote directory on wrong MDT $mdt_idx"
19206
19207         createmany -o $DIR/$tdir/test_230/t- 10 ||
19208                 error "create files on remote directory failed"
19209         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19210         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19211         rm -r $DIR/$tdir || error "unlink remote directory failed"
19212 }
19213 run_test 230a "Create remote directory and files under the remote directory"
19214
19215 test_230b() {
19216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19217         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19218         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19219                 skip "Need MDS version at least 2.11.52"
19220
19221         local MDTIDX=1
19222         local mdt_index
19223         local i
19224         local file
19225         local pid
19226         local stripe_count
19227         local migrate_dir=$DIR/$tdir/migrate_dir
19228         local other_dir=$DIR/$tdir/other_dir
19229
19230         test_mkdir $DIR/$tdir
19231         test_mkdir -i0 -c1 $migrate_dir
19232         test_mkdir -i0 -c1 $other_dir
19233         for ((i=0; i<10; i++)); do
19234                 mkdir -p $migrate_dir/dir_${i}
19235                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19236                         error "create files under remote dir failed $i"
19237         done
19238
19239         cp /etc/passwd $migrate_dir/$tfile
19240         cp /etc/passwd $other_dir/$tfile
19241         chattr +SAD $migrate_dir
19242         chattr +SAD $migrate_dir/$tfile
19243
19244         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19245         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19246         local old_dir_mode=$(stat -c%f $migrate_dir)
19247         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19248
19249         mkdir -p $migrate_dir/dir_default_stripe2
19250         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19251         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19252
19253         mkdir -p $other_dir
19254         ln $migrate_dir/$tfile $other_dir/luna
19255         ln $migrate_dir/$tfile $migrate_dir/sofia
19256         ln $other_dir/$tfile $migrate_dir/david
19257         ln -s $migrate_dir/$tfile $other_dir/zachary
19258         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19259         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19260
19261         local len
19262         local lnktgt
19263
19264         # inline symlink
19265         for len in 58 59 60; do
19266                 lnktgt=$(str_repeat 'l' $len)
19267                 touch $migrate_dir/$lnktgt
19268                 ln -s $lnktgt $migrate_dir/${len}char_ln
19269         done
19270
19271         # PATH_MAX
19272         for len in 4094 4095; do
19273                 lnktgt=$(str_repeat 'l' $len)
19274                 ln -s $lnktgt $migrate_dir/${len}char_ln
19275         done
19276
19277         # NAME_MAX
19278         for len in 254 255; do
19279                 touch $migrate_dir/$(str_repeat 'l' $len)
19280         done
19281
19282         $LFS migrate -m $MDTIDX $migrate_dir ||
19283                 error "fails on migrating remote dir to MDT1"
19284
19285         echo "migratate to MDT1, then checking.."
19286         for ((i = 0; i < 10; i++)); do
19287                 for file in $(find $migrate_dir/dir_${i}); do
19288                         mdt_index=$($LFS getstripe -m $file)
19289                         # broken symlink getstripe will fail
19290                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19291                                 error "$file is not on MDT${MDTIDX}"
19292                 done
19293         done
19294
19295         # the multiple link file should still in MDT0
19296         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19297         [ $mdt_index == 0 ] ||
19298                 error "$file is not on MDT${MDTIDX}"
19299
19300         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19301         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19302                 error " expect $old_dir_flag get $new_dir_flag"
19303
19304         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19305         [ "$old_file_flag" = "$new_file_flag" ] ||
19306                 error " expect $old_file_flag get $new_file_flag"
19307
19308         local new_dir_mode=$(stat -c%f $migrate_dir)
19309         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19310                 error "expect mode $old_dir_mode get $new_dir_mode"
19311
19312         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19313         [ "$old_file_mode" = "$new_file_mode" ] ||
19314                 error "expect mode $old_file_mode get $new_file_mode"
19315
19316         diff /etc/passwd $migrate_dir/$tfile ||
19317                 error "$tfile different after migration"
19318
19319         diff /etc/passwd $other_dir/luna ||
19320                 error "luna different after migration"
19321
19322         diff /etc/passwd $migrate_dir/sofia ||
19323                 error "sofia different after migration"
19324
19325         diff /etc/passwd $migrate_dir/david ||
19326                 error "david different after migration"
19327
19328         diff /etc/passwd $other_dir/zachary ||
19329                 error "zachary different after migration"
19330
19331         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19332                 error "${tfile}_ln different after migration"
19333
19334         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19335                 error "${tfile}_ln_other different after migration"
19336
19337         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19338         [ $stripe_count = 2 ] ||
19339                 error "dir strpe_count $d != 2 after migration."
19340
19341         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19342         [ $stripe_count = 2 ] ||
19343                 error "file strpe_count $d != 2 after migration."
19344
19345         #migrate back to MDT0
19346         MDTIDX=0
19347
19348         $LFS migrate -m $MDTIDX $migrate_dir ||
19349                 error "fails on migrating remote dir to MDT0"
19350
19351         echo "migrate back to MDT0, checking.."
19352         for file in $(find $migrate_dir); do
19353                 mdt_index=$($LFS getstripe -m $file)
19354                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19355                         error "$file is not on MDT${MDTIDX}"
19356         done
19357
19358         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19359         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19360                 error " expect $old_dir_flag get $new_dir_flag"
19361
19362         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19363         [ "$old_file_flag" = "$new_file_flag" ] ||
19364                 error " expect $old_file_flag get $new_file_flag"
19365
19366         local new_dir_mode=$(stat -c%f $migrate_dir)
19367         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19368                 error "expect mode $old_dir_mode get $new_dir_mode"
19369
19370         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19371         [ "$old_file_mode" = "$new_file_mode" ] ||
19372                 error "expect mode $old_file_mode get $new_file_mode"
19373
19374         diff /etc/passwd ${migrate_dir}/$tfile ||
19375                 error "$tfile different after migration"
19376
19377         diff /etc/passwd ${other_dir}/luna ||
19378                 error "luna different after migration"
19379
19380         diff /etc/passwd ${migrate_dir}/sofia ||
19381                 error "sofia different after migration"
19382
19383         diff /etc/passwd ${other_dir}/zachary ||
19384                 error "zachary different after migration"
19385
19386         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19387                 error "${tfile}_ln different after migration"
19388
19389         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19390                 error "${tfile}_ln_other different after migration"
19391
19392         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19393         [ $stripe_count = 2 ] ||
19394                 error "dir strpe_count $d != 2 after migration."
19395
19396         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19397         [ $stripe_count = 2 ] ||
19398                 error "file strpe_count $d != 2 after migration."
19399
19400         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19401 }
19402 run_test 230b "migrate directory"
19403
19404 test_230c() {
19405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19406         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19407         remote_mds_nodsh && skip "remote MDS with nodsh"
19408         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19409                 skip "Need MDS version at least 2.11.52"
19410
19411         local MDTIDX=1
19412         local total=3
19413         local mdt_index
19414         local file
19415         local migrate_dir=$DIR/$tdir/migrate_dir
19416
19417         #If migrating directory fails in the middle, all entries of
19418         #the directory is still accessiable.
19419         test_mkdir $DIR/$tdir
19420         test_mkdir -i0 -c1 $migrate_dir
19421         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19422         stat $migrate_dir
19423         createmany -o $migrate_dir/f $total ||
19424                 error "create files under ${migrate_dir} failed"
19425
19426         # fail after migrating top dir, and this will fail only once, so the
19427         # first sub file migration will fail (currently f3), others succeed.
19428         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19429         do_facet mds1 lctl set_param fail_loc=0x1801
19430         local t=$(ls $migrate_dir | wc -l)
19431         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19432                 error "migrate should fail"
19433         local u=$(ls $migrate_dir | wc -l)
19434         [ "$u" == "$t" ] || error "$u != $t during migration"
19435
19436         # add new dir/file should succeed
19437         mkdir $migrate_dir/dir ||
19438                 error "mkdir failed under migrating directory"
19439         touch $migrate_dir/file ||
19440                 error "create file failed under migrating directory"
19441
19442         # add file with existing name should fail
19443         for file in $migrate_dir/f*; do
19444                 stat $file > /dev/null || error "stat $file failed"
19445                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19446                         error "open(O_CREAT|O_EXCL) $file should fail"
19447                 $MULTIOP $file m && error "create $file should fail"
19448                 touch $DIR/$tdir/remote_dir/$tfile ||
19449                         error "touch $tfile failed"
19450                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19451                         error "link $file should fail"
19452                 mdt_index=$($LFS getstripe -m $file)
19453                 if [ $mdt_index == 0 ]; then
19454                         # file failed to migrate is not allowed to rename to
19455                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19456                                 error "rename to $file should fail"
19457                 else
19458                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19459                                 error "rename to $file failed"
19460                 fi
19461                 echo hello >> $file || error "write $file failed"
19462         done
19463
19464         # resume migration with different options should fail
19465         $LFS migrate -m 0 $migrate_dir &&
19466                 error "migrate -m 0 $migrate_dir should fail"
19467
19468         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19469                 error "migrate -c 2 $migrate_dir should fail"
19470
19471         # resume migration should succeed
19472         $LFS migrate -m $MDTIDX $migrate_dir ||
19473                 error "migrate $migrate_dir failed"
19474
19475         echo "Finish migration, then checking.."
19476         for file in $(find $migrate_dir); do
19477                 mdt_index=$($LFS getstripe -m $file)
19478                 [ $mdt_index == $MDTIDX ] ||
19479                         error "$file is not on MDT${MDTIDX}"
19480         done
19481
19482         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19483 }
19484 run_test 230c "check directory accessiblity if migration failed"
19485
19486 test_230d() {
19487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19488         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19489         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19490                 skip "Need MDS version at least 2.11.52"
19491         # LU-11235
19492         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19493
19494         local migrate_dir=$DIR/$tdir/migrate_dir
19495         local old_index
19496         local new_index
19497         local old_count
19498         local new_count
19499         local new_hash
19500         local mdt_index
19501         local i
19502         local j
19503
19504         old_index=$((RANDOM % MDSCOUNT))
19505         old_count=$((MDSCOUNT - old_index))
19506         new_index=$((RANDOM % MDSCOUNT))
19507         new_count=$((MDSCOUNT - new_index))
19508         new_hash=1 # for all_char
19509
19510         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19511         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19512
19513         test_mkdir $DIR/$tdir
19514         test_mkdir -i $old_index -c $old_count $migrate_dir
19515
19516         for ((i=0; i<100; i++)); do
19517                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19518                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19519                         error "create files under remote dir failed $i"
19520         done
19521
19522         echo -n "Migrate from MDT$old_index "
19523         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19524         echo -n "to MDT$new_index"
19525         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19526         echo
19527
19528         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19529         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19530                 error "migrate remote dir error"
19531
19532         echo "Finish migration, then checking.."
19533         for file in $(find $migrate_dir); do
19534                 mdt_index=$($LFS getstripe -m $file)
19535                 if [ $mdt_index -lt $new_index ] ||
19536                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19537                         error "$file is on MDT$mdt_index"
19538                 fi
19539         done
19540
19541         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19542 }
19543 run_test 230d "check migrate big directory"
19544
19545 test_230e() {
19546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19547         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19548         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19549                 skip "Need MDS version at least 2.11.52"
19550
19551         local i
19552         local j
19553         local a_fid
19554         local b_fid
19555
19556         mkdir_on_mdt0 $DIR/$tdir
19557         mkdir $DIR/$tdir/migrate_dir
19558         mkdir $DIR/$tdir/other_dir
19559         touch $DIR/$tdir/migrate_dir/a
19560         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19561         ls $DIR/$tdir/other_dir
19562
19563         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19564                 error "migrate dir fails"
19565
19566         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19567         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19568
19569         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19570         [ $mdt_index == 0 ] || error "a is not on MDT0"
19571
19572         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19573                 error "migrate dir fails"
19574
19575         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19576         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19577
19578         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19579         [ $mdt_index == 1 ] || error "a is not on MDT1"
19580
19581         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19582         [ $mdt_index == 1 ] || error "b is not on MDT1"
19583
19584         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19585         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19586
19587         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19588
19589         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19590 }
19591 run_test 230e "migrate mulitple local link files"
19592
19593 test_230f() {
19594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19595         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19596         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19597                 skip "Need MDS version at least 2.11.52"
19598
19599         local a_fid
19600         local ln_fid
19601
19602         mkdir -p $DIR/$tdir
19603         mkdir $DIR/$tdir/migrate_dir
19604         $LFS mkdir -i1 $DIR/$tdir/other_dir
19605         touch $DIR/$tdir/migrate_dir/a
19606         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19607         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19608         ls $DIR/$tdir/other_dir
19609
19610         # a should be migrated to MDT1, since no other links on MDT0
19611         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19612                 error "#1 migrate dir fails"
19613         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19614         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19615         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19616         [ $mdt_index == 1 ] || error "a is not on MDT1"
19617
19618         # a should stay on MDT1, because it is a mulitple link file
19619         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19620                 error "#2 migrate dir fails"
19621         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19622         [ $mdt_index == 1 ] || error "a is not on MDT1"
19623
19624         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19625                 error "#3 migrate dir fails"
19626
19627         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19628         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19629         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19630
19631         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19632         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19633
19634         # a should be migrated to MDT0, since no other links on MDT1
19635         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19636                 error "#4 migrate dir fails"
19637         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19638         [ $mdt_index == 0 ] || error "a is not on MDT0"
19639
19640         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19641 }
19642 run_test 230f "migrate mulitple remote link files"
19643
19644 test_230g() {
19645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19646         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19647         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19648                 skip "Need MDS version at least 2.11.52"
19649
19650         mkdir -p $DIR/$tdir/migrate_dir
19651
19652         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19653                 error "migrating dir to non-exist MDT succeeds"
19654         true
19655 }
19656 run_test 230g "migrate dir to non-exist MDT"
19657
19658 test_230h() {
19659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19660         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19661         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19662                 skip "Need MDS version at least 2.11.52"
19663
19664         local mdt_index
19665
19666         mkdir -p $DIR/$tdir/migrate_dir
19667
19668         $LFS migrate -m1 $DIR &&
19669                 error "migrating mountpoint1 should fail"
19670
19671         $LFS migrate -m1 $DIR/$tdir/.. &&
19672                 error "migrating mountpoint2 should fail"
19673
19674         # same as mv
19675         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19676                 error "migrating $tdir/migrate_dir/.. should fail"
19677
19678         true
19679 }
19680 run_test 230h "migrate .. and root"
19681
19682 test_230i() {
19683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19685         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19686                 skip "Need MDS version at least 2.11.52"
19687
19688         mkdir -p $DIR/$tdir/migrate_dir
19689
19690         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19691                 error "migration fails with a tailing slash"
19692
19693         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19694                 error "migration fails with two tailing slashes"
19695 }
19696 run_test 230i "lfs migrate -m tolerates trailing slashes"
19697
19698 test_230j() {
19699         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19700         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19701                 skip "Need MDS version at least 2.11.52"
19702
19703         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19704         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19705                 error "create $tfile failed"
19706         cat /etc/passwd > $DIR/$tdir/$tfile
19707
19708         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19709
19710         cmp /etc/passwd $DIR/$tdir/$tfile ||
19711                 error "DoM file mismatch after migration"
19712 }
19713 run_test 230j "DoM file data not changed after dir migration"
19714
19715 test_230k() {
19716         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19717         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19718                 skip "Need MDS version at least 2.11.56"
19719
19720         local total=20
19721         local files_on_starting_mdt=0
19722
19723         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19724         $LFS getdirstripe $DIR/$tdir
19725         for i in $(seq $total); do
19726                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19727                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19728                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19729         done
19730
19731         echo "$files_on_starting_mdt files on MDT0"
19732
19733         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19734         $LFS getdirstripe $DIR/$tdir
19735
19736         files_on_starting_mdt=0
19737         for i in $(seq $total); do
19738                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19739                         error "file $tfile.$i mismatch after migration"
19740                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19741                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19742         done
19743
19744         echo "$files_on_starting_mdt files on MDT1 after migration"
19745         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19746
19747         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19748         $LFS getdirstripe $DIR/$tdir
19749
19750         files_on_starting_mdt=0
19751         for i in $(seq $total); do
19752                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19753                         error "file $tfile.$i mismatch after 2nd migration"
19754                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19755                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19756         done
19757
19758         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19759         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19760
19761         true
19762 }
19763 run_test 230k "file data not changed after dir migration"
19764
19765 test_230l() {
19766         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19767         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19768                 skip "Need MDS version at least 2.11.56"
19769
19770         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19771         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19772                 error "create files under remote dir failed $i"
19773         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19774 }
19775 run_test 230l "readdir between MDTs won't crash"
19776
19777 test_230m() {
19778         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19779         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19780                 skip "Need MDS version at least 2.11.56"
19781
19782         local MDTIDX=1
19783         local mig_dir=$DIR/$tdir/migrate_dir
19784         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19785         local shortstr="b"
19786         local val
19787
19788         echo "Creating files and dirs with xattrs"
19789         test_mkdir $DIR/$tdir
19790         test_mkdir -i0 -c1 $mig_dir
19791         mkdir $mig_dir/dir
19792         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19793                 error "cannot set xattr attr1 on dir"
19794         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19795                 error "cannot set xattr attr2 on dir"
19796         touch $mig_dir/dir/f0
19797         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19798                 error "cannot set xattr attr1 on file"
19799         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19800                 error "cannot set xattr attr2 on file"
19801         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19802         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19803         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19804         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19805         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19806         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19807         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19808         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19809         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19810
19811         echo "Migrating to MDT1"
19812         $LFS migrate -m $MDTIDX $mig_dir ||
19813                 error "fails on migrating dir to MDT1"
19814
19815         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19816         echo "Checking xattrs"
19817         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19818         [ "$val" = $longstr ] ||
19819                 error "expecting xattr1 $longstr on dir, found $val"
19820         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19821         [ "$val" = $shortstr ] ||
19822                 error "expecting xattr2 $shortstr on dir, found $val"
19823         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19824         [ "$val" = $longstr ] ||
19825                 error "expecting xattr1 $longstr on file, found $val"
19826         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19827         [ "$val" = $shortstr ] ||
19828                 error "expecting xattr2 $shortstr on file, found $val"
19829 }
19830 run_test 230m "xattrs not changed after dir migration"
19831
19832 test_230n() {
19833         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19834         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19835                 skip "Need MDS version at least 2.13.53"
19836
19837         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19838         cat /etc/hosts > $DIR/$tdir/$tfile
19839         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19840         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19841
19842         cmp /etc/hosts $DIR/$tdir/$tfile ||
19843                 error "File data mismatch after migration"
19844 }
19845 run_test 230n "Dir migration with mirrored file"
19846
19847 test_230o() {
19848         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19849         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19850                 skip "Need MDS version at least 2.13.52"
19851
19852         local mdts=$(comma_list $(mdts_nodes))
19853         local timeout=100
19854         local restripe_status
19855         local delta
19856         local i
19857
19858         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19859
19860         # in case "crush" hash type is not set
19861         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19862
19863         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19864                            mdt.*MDT0000.enable_dir_restripe)
19865         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19866         stack_trap "do_nodes $mdts $LCTL set_param \
19867                     mdt.*.enable_dir_restripe=$restripe_status"
19868
19869         mkdir $DIR/$tdir
19870         createmany -m $DIR/$tdir/f 100 ||
19871                 error "create files under remote dir failed $i"
19872         createmany -d $DIR/$tdir/d 100 ||
19873                 error "create dirs under remote dir failed $i"
19874
19875         for i in $(seq 2 $MDSCOUNT); do
19876                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19877                 $LFS setdirstripe -c $i $DIR/$tdir ||
19878                         error "split -c $i $tdir failed"
19879                 wait_update $HOSTNAME \
19880                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19881                         error "dir split not finished"
19882                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19883                         awk '/migrate/ {sum += $2} END { print sum }')
19884                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19885                 # delta is around total_files/stripe_count
19886                 (( $delta < 200 / (i - 1) + 4 )) ||
19887                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19888         done
19889 }
19890 run_test 230o "dir split"
19891
19892 test_230p() {
19893         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19894         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19895                 skip "Need MDS version at least 2.13.52"
19896
19897         local mdts=$(comma_list $(mdts_nodes))
19898         local timeout=100
19899         local restripe_status
19900         local delta
19901         local c
19902
19903         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19904
19905         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19906
19907         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19908                            mdt.*MDT0000.enable_dir_restripe)
19909         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19910         stack_trap "do_nodes $mdts $LCTL set_param \
19911                     mdt.*.enable_dir_restripe=$restripe_status"
19912
19913         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19914         createmany -m $DIR/$tdir/f 100 ||
19915                 error "create files under remote dir failed"
19916         createmany -d $DIR/$tdir/d 100 ||
19917                 error "create dirs under remote dir failed"
19918
19919         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19920                 local mdt_hash="crush"
19921
19922                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19923                 $LFS setdirstripe -c $c $DIR/$tdir ||
19924                         error "split -c $c $tdir failed"
19925                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19926                         mdt_hash="$mdt_hash,fixed"
19927                 elif [ $c -eq 1 ]; then
19928                         mdt_hash="none"
19929                 fi
19930                 wait_update $HOSTNAME \
19931                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19932                         error "dir merge not finished"
19933                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19934                         awk '/migrate/ {sum += $2} END { print sum }')
19935                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19936                 # delta is around total_files/stripe_count
19937                 (( delta < 200 / c + 4 )) ||
19938                         error "$delta files migrated >= $((200 / c + 4))"
19939         done
19940 }
19941 run_test 230p "dir merge"
19942
19943 test_230q() {
19944         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19945         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19946                 skip "Need MDS version at least 2.13.52"
19947
19948         local mdts=$(comma_list $(mdts_nodes))
19949         local saved_threshold=$(do_facet mds1 \
19950                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19951         local saved_delta=$(do_facet mds1 \
19952                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19953         local threshold=100
19954         local delta=2
19955         local total=0
19956         local stripe_count=0
19957         local stripe_index
19958         local nr_files
19959         local create
19960
19961         # test with fewer files on ZFS
19962         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19963
19964         stack_trap "do_nodes $mdts $LCTL set_param \
19965                     mdt.*.dir_split_count=$saved_threshold"
19966         stack_trap "do_nodes $mdts $LCTL set_param \
19967                     mdt.*.dir_split_delta=$saved_delta"
19968         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19969         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19970         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19971         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19972         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19973         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19974
19975         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19976         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19977
19978         create=$((threshold * 3 / 2))
19979         while [ $stripe_count -lt $MDSCOUNT ]; do
19980                 createmany -m $DIR/$tdir/f $total $create ||
19981                         error "create sub files failed"
19982                 stat $DIR/$tdir > /dev/null
19983                 total=$((total + create))
19984                 stripe_count=$((stripe_count + delta))
19985                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19986
19987                 wait_update $HOSTNAME \
19988                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19989                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19990
19991                 wait_update $HOSTNAME \
19992                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19993                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19994
19995                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19996                 echo "$nr_files/$total files on MDT$stripe_index after split"
19997                 # allow 10% margin of imbalance with crush hash
19998                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19999                         error "$nr_files files on MDT$stripe_index after split"
20000
20001                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20002                 [ $nr_files -eq $total ] ||
20003                         error "total sub files $nr_files != $total"
20004         done
20005
20006         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20007
20008         echo "fixed layout directory won't auto split"
20009         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20010         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20011                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20012         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20013                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20014 }
20015 run_test 230q "dir auto split"
20016
20017 test_230r() {
20018         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20019         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20020         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20021                 skip "Need MDS version at least 2.13.54"
20022
20023         # maximum amount of local locks:
20024         # parent striped dir - 2 locks
20025         # new stripe in parent to migrate to - 1 lock
20026         # source and target - 2 locks
20027         # Total 5 locks for regular file
20028         mkdir -p $DIR/$tdir
20029         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20030         touch $DIR/$tdir/dir1/eee
20031
20032         # create 4 hardlink for 4 more locks
20033         # Total: 9 locks > RS_MAX_LOCKS (8)
20034         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20035         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20036         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20037         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20038         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20039         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20040         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20041         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20042
20043         cancel_lru_locks mdc
20044
20045         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20046                 error "migrate dir fails"
20047
20048         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20049 }
20050 run_test 230r "migrate with too many local locks"
20051
20052 test_230s() {
20053         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20054                 skip "Need MDS version at least 2.13.57"
20055
20056         local mdts=$(comma_list $(mdts_nodes))
20057         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20058                                 mdt.*MDT0000.enable_dir_restripe)
20059
20060         stack_trap "do_nodes $mdts $LCTL set_param \
20061                     mdt.*.enable_dir_restripe=$restripe_status"
20062
20063         local st
20064         for st in 0 1; do
20065                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20066                 test_mkdir $DIR/$tdir
20067                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20068                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20069                 rmdir $DIR/$tdir
20070         done
20071 }
20072 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20073
20074 test_230t()
20075 {
20076         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20077         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20078                 skip "Need MDS version at least 2.14.50"
20079
20080         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20081         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20082         $LFS project -p 1 -s $DIR/$tdir ||
20083                 error "set $tdir project id failed"
20084         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20085                 error "set subdir project id failed"
20086         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20087 }
20088 run_test 230t "migrate directory with project ID set"
20089
20090 test_231a()
20091 {
20092         # For simplicity this test assumes that max_pages_per_rpc
20093         # is the same across all OSCs
20094         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20095         local bulk_size=$((max_pages * PAGE_SIZE))
20096         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20097                                        head -n 1)
20098
20099         mkdir -p $DIR/$tdir
20100         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20101                 error "failed to set stripe with -S ${brw_size}M option"
20102
20103         # clear the OSC stats
20104         $LCTL set_param osc.*.stats=0 &>/dev/null
20105         stop_writeback
20106
20107         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20108         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20109                 oflag=direct &>/dev/null || error "dd failed"
20110
20111         sync; sleep 1; sync # just to be safe
20112         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20113         if [ x$nrpcs != "x1" ]; then
20114                 $LCTL get_param osc.*.stats
20115                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20116         fi
20117
20118         start_writeback
20119         # Drop the OSC cache, otherwise we will read from it
20120         cancel_lru_locks osc
20121
20122         # clear the OSC stats
20123         $LCTL set_param osc.*.stats=0 &>/dev/null
20124
20125         # Client reads $bulk_size.
20126         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20127                 iflag=direct &>/dev/null || error "dd failed"
20128
20129         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20130         if [ x$nrpcs != "x1" ]; then
20131                 $LCTL get_param osc.*.stats
20132                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20133         fi
20134 }
20135 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20136
20137 test_231b() {
20138         mkdir -p $DIR/$tdir
20139         local i
20140         for i in {0..1023}; do
20141                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20142                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20143                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20144         done
20145         sync
20146 }
20147 run_test 231b "must not assert on fully utilized OST request buffer"
20148
20149 test_232a() {
20150         mkdir -p $DIR/$tdir
20151         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20152
20153         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20154         do_facet ost1 $LCTL set_param fail_loc=0x31c
20155
20156         # ignore dd failure
20157         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20158
20159         do_facet ost1 $LCTL set_param fail_loc=0
20160         umount_client $MOUNT || error "umount failed"
20161         mount_client $MOUNT || error "mount failed"
20162         stop ost1 || error "cannot stop ost1"
20163         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20164 }
20165 run_test 232a "failed lock should not block umount"
20166
20167 test_232b() {
20168         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20169                 skip "Need MDS version at least 2.10.58"
20170
20171         mkdir -p $DIR/$tdir
20172         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20173         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20174         sync
20175         cancel_lru_locks osc
20176
20177         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20178         do_facet ost1 $LCTL set_param fail_loc=0x31c
20179
20180         # ignore failure
20181         $LFS data_version $DIR/$tdir/$tfile || true
20182
20183         do_facet ost1 $LCTL set_param fail_loc=0
20184         umount_client $MOUNT || error "umount failed"
20185         mount_client $MOUNT || error "mount failed"
20186         stop ost1 || error "cannot stop ost1"
20187         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20188 }
20189 run_test 232b "failed data version lock should not block umount"
20190
20191 test_233a() {
20192         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20193                 skip "Need MDS version at least 2.3.64"
20194         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20195
20196         local fid=$($LFS path2fid $MOUNT)
20197
20198         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20199                 error "cannot access $MOUNT using its FID '$fid'"
20200 }
20201 run_test 233a "checking that OBF of the FS root succeeds"
20202
20203 test_233b() {
20204         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20205                 skip "Need MDS version at least 2.5.90"
20206         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20207
20208         local fid=$($LFS path2fid $MOUNT/.lustre)
20209
20210         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20211                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20212
20213         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20214         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20215                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20216 }
20217 run_test 233b "checking that OBF of the FS .lustre succeeds"
20218
20219 test_234() {
20220         local p="$TMP/sanityN-$TESTNAME.parameters"
20221         save_lustre_params client "llite.*.xattr_cache" > $p
20222         lctl set_param llite.*.xattr_cache 1 ||
20223                 skip_env "xattr cache is not supported"
20224
20225         mkdir -p $DIR/$tdir || error "mkdir failed"
20226         touch $DIR/$tdir/$tfile || error "touch failed"
20227         # OBD_FAIL_LLITE_XATTR_ENOMEM
20228         $LCTL set_param fail_loc=0x1405
20229         getfattr -n user.attr $DIR/$tdir/$tfile &&
20230                 error "getfattr should have failed with ENOMEM"
20231         $LCTL set_param fail_loc=0x0
20232         rm -rf $DIR/$tdir
20233
20234         restore_lustre_params < $p
20235         rm -f $p
20236 }
20237 run_test 234 "xattr cache should not crash on ENOMEM"
20238
20239 test_235() {
20240         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20241                 skip "Need MDS version at least 2.4.52"
20242
20243         flock_deadlock $DIR/$tfile
20244         local RC=$?
20245         case $RC in
20246                 0)
20247                 ;;
20248                 124) error "process hangs on a deadlock"
20249                 ;;
20250                 *) error "error executing flock_deadlock $DIR/$tfile"
20251                 ;;
20252         esac
20253 }
20254 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20255
20256 #LU-2935
20257 test_236() {
20258         check_swap_layouts_support
20259
20260         local ref1=/etc/passwd
20261         local ref2=/etc/group
20262         local file1=$DIR/$tdir/f1
20263         local file2=$DIR/$tdir/f2
20264
20265         test_mkdir -c1 $DIR/$tdir
20266         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20267         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20268         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20269         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20270         local fd=$(free_fd)
20271         local cmd="exec $fd<>$file2"
20272         eval $cmd
20273         rm $file2
20274         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20275                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20276         cmd="exec $fd>&-"
20277         eval $cmd
20278         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20279
20280         #cleanup
20281         rm -rf $DIR/$tdir
20282 }
20283 run_test 236 "Layout swap on open unlinked file"
20284
20285 # LU-4659 linkea consistency
20286 test_238() {
20287         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20288                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20289                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20290                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20291
20292         touch $DIR/$tfile
20293         ln $DIR/$tfile $DIR/$tfile.lnk
20294         touch $DIR/$tfile.new
20295         mv $DIR/$tfile.new $DIR/$tfile
20296         local fid1=$($LFS path2fid $DIR/$tfile)
20297         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20298         local path1=$($LFS fid2path $FSNAME "$fid1")
20299         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20300         local path2=$($LFS fid2path $FSNAME "$fid2")
20301         [ $tfile.lnk == $path2 ] ||
20302                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20303         rm -f $DIR/$tfile*
20304 }
20305 run_test 238 "Verify linkea consistency"
20306
20307 test_239A() { # was test_239
20308         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20309                 skip "Need MDS version at least 2.5.60"
20310
20311         local list=$(comma_list $(mdts_nodes))
20312
20313         mkdir -p $DIR/$tdir
20314         createmany -o $DIR/$tdir/f- 5000
20315         unlinkmany $DIR/$tdir/f- 5000
20316         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20317                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20318         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20319                         osp.*MDT*.sync_in_flight" | calc_sum)
20320         [ "$changes" -eq 0 ] || error "$changes not synced"
20321 }
20322 run_test 239A "osp_sync test"
20323
20324 test_239a() { #LU-5297
20325         remote_mds_nodsh && skip "remote MDS with nodsh"
20326
20327         touch $DIR/$tfile
20328         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20329         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20330         chgrp $RUNAS_GID $DIR/$tfile
20331         wait_delete_completed
20332 }
20333 run_test 239a "process invalid osp sync record correctly"
20334
20335 test_239b() { #LU-5297
20336         remote_mds_nodsh && skip "remote MDS with nodsh"
20337
20338         touch $DIR/$tfile1
20339         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20340         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20341         chgrp $RUNAS_GID $DIR/$tfile1
20342         wait_delete_completed
20343         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20344         touch $DIR/$tfile2
20345         chgrp $RUNAS_GID $DIR/$tfile2
20346         wait_delete_completed
20347 }
20348 run_test 239b "process osp sync record with ENOMEM error correctly"
20349
20350 test_240() {
20351         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20352         remote_mds_nodsh && skip "remote MDS with nodsh"
20353
20354         mkdir -p $DIR/$tdir
20355
20356         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20357                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20358         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20359                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20360
20361         umount_client $MOUNT || error "umount failed"
20362         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20363         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20364         mount_client $MOUNT || error "failed to mount client"
20365
20366         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20367         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20368 }
20369 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20370
20371 test_241_bio() {
20372         local count=$1
20373         local bsize=$2
20374
20375         for LOOP in $(seq $count); do
20376                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20377                 cancel_lru_locks $OSC || true
20378         done
20379 }
20380
20381 test_241_dio() {
20382         local count=$1
20383         local bsize=$2
20384
20385         for LOOP in $(seq $1); do
20386                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20387                         2>/dev/null
20388         done
20389 }
20390
20391 test_241a() { # was test_241
20392         local bsize=$PAGE_SIZE
20393
20394         (( bsize < 40960 )) && bsize=40960
20395         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20396         ls -la $DIR/$tfile
20397         cancel_lru_locks $OSC
20398         test_241_bio 1000 $bsize &
20399         PID=$!
20400         test_241_dio 1000 $bsize
20401         wait $PID
20402 }
20403 run_test 241a "bio vs dio"
20404
20405 test_241b() {
20406         local bsize=$PAGE_SIZE
20407
20408         (( bsize < 40960 )) && bsize=40960
20409         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20410         ls -la $DIR/$tfile
20411         test_241_dio 1000 $bsize &
20412         PID=$!
20413         test_241_dio 1000 $bsize
20414         wait $PID
20415 }
20416 run_test 241b "dio vs dio"
20417
20418 test_242() {
20419         remote_mds_nodsh && skip "remote MDS with nodsh"
20420
20421         mkdir_on_mdt0 $DIR/$tdir
20422         touch $DIR/$tdir/$tfile
20423
20424         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20425         do_facet mds1 lctl set_param fail_loc=0x105
20426         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20427
20428         do_facet mds1 lctl set_param fail_loc=0
20429         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20430 }
20431 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20432
20433 test_243()
20434 {
20435         test_mkdir $DIR/$tdir
20436         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20437 }
20438 run_test 243 "various group lock tests"
20439
20440 test_244a()
20441 {
20442         test_mkdir $DIR/$tdir
20443         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20444         sendfile_grouplock $DIR/$tdir/$tfile || \
20445                 error "sendfile+grouplock failed"
20446         rm -rf $DIR/$tdir
20447 }
20448 run_test 244a "sendfile with group lock tests"
20449
20450 test_244b()
20451 {
20452         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20453
20454         local threads=50
20455         local size=$((1024*1024))
20456
20457         test_mkdir $DIR/$tdir
20458         for i in $(seq 1 $threads); do
20459                 local file=$DIR/$tdir/file_$((i / 10))
20460                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20461                 local pids[$i]=$!
20462         done
20463         for i in $(seq 1 $threads); do
20464                 wait ${pids[$i]}
20465         done
20466 }
20467 run_test 244b "multi-threaded write with group lock"
20468
20469 test_245() {
20470         local flagname="multi_mod_rpcs"
20471         local connect_data_name="max_mod_rpcs"
20472         local out
20473
20474         # check if multiple modify RPCs flag is set
20475         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20476                 grep "connect_flags:")
20477         echo "$out"
20478
20479         echo "$out" | grep -qw $flagname
20480         if [ $? -ne 0 ]; then
20481                 echo "connect flag $flagname is not set"
20482                 return
20483         fi
20484
20485         # check if multiple modify RPCs data is set
20486         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20487         echo "$out"
20488
20489         echo "$out" | grep -qw $connect_data_name ||
20490                 error "import should have connect data $connect_data_name"
20491 }
20492 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20493
20494 cleanup_247() {
20495         local submount=$1
20496
20497         trap 0
20498         umount_client $submount
20499         rmdir $submount
20500 }
20501
20502 test_247a() {
20503         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20504                 grep -q subtree ||
20505                 skip_env "Fileset feature is not supported"
20506
20507         local submount=${MOUNT}_$tdir
20508
20509         mkdir $MOUNT/$tdir
20510         mkdir -p $submount || error "mkdir $submount failed"
20511         FILESET="$FILESET/$tdir" mount_client $submount ||
20512                 error "mount $submount failed"
20513         trap "cleanup_247 $submount" EXIT
20514         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20515         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20516                 error "read $MOUNT/$tdir/$tfile failed"
20517         cleanup_247 $submount
20518 }
20519 run_test 247a "mount subdir as fileset"
20520
20521 test_247b() {
20522         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20523                 skip_env "Fileset feature is not supported"
20524
20525         local submount=${MOUNT}_$tdir
20526
20527         rm -rf $MOUNT/$tdir
20528         mkdir -p $submount || error "mkdir $submount failed"
20529         SKIP_FILESET=1
20530         FILESET="$FILESET/$tdir" mount_client $submount &&
20531                 error "mount $submount should fail"
20532         rmdir $submount
20533 }
20534 run_test 247b "mount subdir that dose not exist"
20535
20536 test_247c() {
20537         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20538                 skip_env "Fileset feature is not supported"
20539
20540         local submount=${MOUNT}_$tdir
20541
20542         mkdir -p $MOUNT/$tdir/dir1
20543         mkdir -p $submount || error "mkdir $submount failed"
20544         trap "cleanup_247 $submount" EXIT
20545         FILESET="$FILESET/$tdir" mount_client $submount ||
20546                 error "mount $submount failed"
20547         local fid=$($LFS path2fid $MOUNT/)
20548         $LFS fid2path $submount $fid && error "fid2path should fail"
20549         cleanup_247 $submount
20550 }
20551 run_test 247c "running fid2path outside subdirectory root"
20552
20553 test_247d() {
20554         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20555                 skip "Fileset feature is not supported"
20556
20557         local submount=${MOUNT}_$tdir
20558
20559         mkdir -p $MOUNT/$tdir/dir1
20560         mkdir -p $submount || error "mkdir $submount failed"
20561         FILESET="$FILESET/$tdir" mount_client $submount ||
20562                 error "mount $submount failed"
20563         trap "cleanup_247 $submount" EXIT
20564
20565         local td=$submount/dir1
20566         local fid=$($LFS path2fid $td)
20567         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20568
20569         # check that we get the same pathname back
20570         local rootpath
20571         local found
20572         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20573                 echo "$rootpath $fid"
20574                 found=$($LFS fid2path $rootpath "$fid")
20575                 [ -n "found" ] || error "fid2path should succeed"
20576                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20577         done
20578         # check wrong root path format
20579         rootpath=$submount"_wrong"
20580         found=$($LFS fid2path $rootpath "$fid")
20581         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20582
20583         cleanup_247 $submount
20584 }
20585 run_test 247d "running fid2path inside subdirectory root"
20586
20587 # LU-8037
20588 test_247e() {
20589         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20590                 grep -q subtree ||
20591                 skip "Fileset feature is not supported"
20592
20593         local submount=${MOUNT}_$tdir
20594
20595         mkdir $MOUNT/$tdir
20596         mkdir -p $submount || error "mkdir $submount failed"
20597         FILESET="$FILESET/.." mount_client $submount &&
20598                 error "mount $submount should fail"
20599         rmdir $submount
20600 }
20601 run_test 247e "mount .. as fileset"
20602
20603 test_247f() {
20604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20605         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20606                 skip "Need at least version 2.13.52"
20607         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20608                 skip "Need at least version 2.14.50"
20609         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20610                 grep -q subtree ||
20611                 skip "Fileset feature is not supported"
20612
20613         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20614         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20615                 error "mkdir remote failed"
20616         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20617                 error "mkdir remote/subdir failed"
20618         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20619                 error "mkdir striped failed"
20620         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20621
20622         local submount=${MOUNT}_$tdir
20623
20624         mkdir -p $submount || error "mkdir $submount failed"
20625         stack_trap "rmdir $submount"
20626
20627         local dir
20628         local stat
20629         local fileset=$FILESET
20630         local mdts=$(comma_list $(mdts_nodes))
20631
20632         stat=$(do_facet mds1 $LCTL get_param -n \
20633                 mdt.*MDT0000.enable_remote_subdir_mount)
20634         stack_trap "do_nodes $mdts $LCTL set_param \
20635                 mdt.*.enable_remote_subdir_mount=$stat"
20636
20637         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20638         stack_trap "umount_client $submount"
20639         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20640                 error "mount remote dir $dir should fail"
20641
20642         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20643                 $tdir/striped/. ; do
20644                 FILESET="$fileset/$dir" mount_client $submount ||
20645                         error "mount $dir failed"
20646                 umount_client $submount
20647         done
20648
20649         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20650         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20651                 error "mount $tdir/remote failed"
20652 }
20653 run_test 247f "mount striped or remote directory as fileset"
20654
20655 test_247g() {
20656         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20657         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20658                 skip "Need at least version 2.14.50"
20659
20660         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20661                 error "mkdir $tdir failed"
20662         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20663
20664         local submount=${MOUNT}_$tdir
20665
20666         mkdir -p $submount || error "mkdir $submount failed"
20667         stack_trap "rmdir $submount"
20668
20669         FILESET="$fileset/$tdir" mount_client $submount ||
20670                 error "mount $dir failed"
20671         stack_trap "umount $submount"
20672
20673         local mdts=$(comma_list $(mdts_nodes))
20674
20675         local nrpcs
20676
20677         stat $submount > /dev/null
20678         cancel_lru_locks $MDC
20679         stat $submount > /dev/null
20680         stat $submount/$tfile > /dev/null
20681         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20682         stat $submount/$tfile > /dev/null
20683         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20684                 awk '/getattr/ {sum += $2} END {print sum}')
20685
20686         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20687 }
20688 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20689
20690 test_248a() {
20691         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20692         [ -z "$fast_read_sav" ] && skip "no fast read support"
20693
20694         # create a large file for fast read verification
20695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20696
20697         # make sure the file is created correctly
20698         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20699                 { rm -f $DIR/$tfile; skip "file creation error"; }
20700
20701         echo "Test 1: verify that fast read is 4 times faster on cache read"
20702
20703         # small read with fast read enabled
20704         $LCTL set_param -n llite.*.fast_read=1
20705         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20706                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20707                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20708         # small read with fast read disabled
20709         $LCTL set_param -n llite.*.fast_read=0
20710         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20711                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20712                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20713
20714         # verify that fast read is 4 times faster for cache read
20715         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20716                 error_not_in_vm "fast read was not 4 times faster: " \
20717                            "$t_fast vs $t_slow"
20718
20719         echo "Test 2: verify the performance between big and small read"
20720         $LCTL set_param -n llite.*.fast_read=1
20721
20722         # 1k non-cache read
20723         cancel_lru_locks osc
20724         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20725                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20726                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20727
20728         # 1M non-cache read
20729         cancel_lru_locks osc
20730         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20731                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20732                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20733
20734         # verify that big IO is not 4 times faster than small IO
20735         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20736                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20737
20738         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20739         rm -f $DIR/$tfile
20740 }
20741 run_test 248a "fast read verification"
20742
20743 test_248b() {
20744         # Default short_io_bytes=16384, try both smaller and larger sizes.
20745         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20746         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20747         echo "bs=53248 count=113 normal buffered write"
20748         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20749                 error "dd of initial data file failed"
20750         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20751
20752         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20753         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20754                 error "dd with sync normal writes failed"
20755         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20756
20757         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20758         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20759                 error "dd with sync small writes failed"
20760         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20761
20762         cancel_lru_locks osc
20763
20764         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20765         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20766         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20767         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20768                 iflag=direct || error "dd with O_DIRECT small read failed"
20769         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20770         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20771                 error "compare $TMP/$tfile.1 failed"
20772
20773         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20774         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20775
20776         # just to see what the maximum tunable value is, and test parsing
20777         echo "test invalid parameter 2MB"
20778         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20779                 error "too-large short_io_bytes allowed"
20780         echo "test maximum parameter 512KB"
20781         # if we can set a larger short_io_bytes, run test regardless of version
20782         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20783                 # older clients may not allow setting it this large, that's OK
20784                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20785                         skip "Need at least client version 2.13.50"
20786                 error "medium short_io_bytes failed"
20787         fi
20788         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20789         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20790
20791         echo "test large parameter 64KB"
20792         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20793         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20794
20795         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20796         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20797                 error "dd with sync large writes failed"
20798         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20799
20800         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20801         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20802         num=$((113 * 4096 / PAGE_SIZE))
20803         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20804         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20805                 error "dd with O_DIRECT large writes failed"
20806         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20807                 error "compare $DIR/$tfile.3 failed"
20808
20809         cancel_lru_locks osc
20810
20811         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20812         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20813                 error "dd with O_DIRECT large read failed"
20814         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20815                 error "compare $TMP/$tfile.2 failed"
20816
20817         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20818         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20819                 error "dd with O_DIRECT large read failed"
20820         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20821                 error "compare $TMP/$tfile.3 failed"
20822 }
20823 run_test 248b "test short_io read and write for both small and large sizes"
20824
20825 test_249() { # LU-7890
20826         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20827                 skip "Need at least version 2.8.54"
20828
20829         rm -f $DIR/$tfile
20830         $LFS setstripe -c 1 $DIR/$tfile
20831         # Offset 2T == 4k * 512M
20832         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20833                 error "dd to 2T offset failed"
20834 }
20835 run_test 249 "Write above 2T file size"
20836
20837 test_250() {
20838         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20839          && skip "no 16TB file size limit on ZFS"
20840
20841         $LFS setstripe -c 1 $DIR/$tfile
20842         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20843         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20844         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20845         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20846                 conv=notrunc,fsync && error "append succeeded"
20847         return 0
20848 }
20849 run_test 250 "Write above 16T limit"
20850
20851 test_251() {
20852         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20853
20854         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20855         #Skip once - writing the first stripe will succeed
20856         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20857         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20858                 error "short write happened"
20859
20860         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20861         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20862                 error "short read happened"
20863
20864         rm -f $DIR/$tfile
20865 }
20866 run_test 251 "Handling short read and write correctly"
20867
20868 test_252() {
20869         remote_mds_nodsh && skip "remote MDS with nodsh"
20870         remote_ost_nodsh && skip "remote OST with nodsh"
20871         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20872                 skip_env "ldiskfs only test"
20873         fi
20874
20875         local tgt
20876         local dev
20877         local out
20878         local uuid
20879         local num
20880         local gen
20881
20882         # check lr_reader on OST0000
20883         tgt=ost1
20884         dev=$(facet_device $tgt)
20885         out=$(do_facet $tgt $LR_READER $dev)
20886         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20887         echo "$out"
20888         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20889         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20890                 error "Invalid uuid returned by $LR_READER on target $tgt"
20891         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20892
20893         # check lr_reader -c on MDT0000
20894         tgt=mds1
20895         dev=$(facet_device $tgt)
20896         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20897                 skip "$LR_READER does not support additional options"
20898         fi
20899         out=$(do_facet $tgt $LR_READER -c $dev)
20900         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20901         echo "$out"
20902         num=$(echo "$out" | grep -c "mdtlov")
20903         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20904                 error "Invalid number of mdtlov clients returned by $LR_READER"
20905         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20906
20907         # check lr_reader -cr on MDT0000
20908         out=$(do_facet $tgt $LR_READER -cr $dev)
20909         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20910         echo "$out"
20911         echo "$out" | grep -q "^reply_data:$" ||
20912                 error "$LR_READER should have returned 'reply_data' section"
20913         num=$(echo "$out" | grep -c "client_generation")
20914         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20915 }
20916 run_test 252 "check lr_reader tool"
20917
20918 test_253() {
20919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20920         remote_mds_nodsh && skip "remote MDS with nodsh"
20921         remote_mgs_nodsh && skip "remote MGS with nodsh"
20922
20923         local ostidx=0
20924         local rc=0
20925         local ost_name=$(ostname_from_index $ostidx)
20926
20927         # on the mdt's osc
20928         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20929         do_facet $SINGLEMDS $LCTL get_param -n \
20930                 osp.$mdtosc_proc1.reserved_mb_high ||
20931                 skip  "remote MDS does not support reserved_mb_high"
20932
20933         rm -rf $DIR/$tdir
20934         wait_mds_ost_sync
20935         wait_delete_completed
20936         mkdir $DIR/$tdir
20937
20938         pool_add $TESTNAME || error "Pool creation failed"
20939         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20940
20941         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20942                 error "Setstripe failed"
20943
20944         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20945
20946         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20947                     grep "watermarks")
20948         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20949
20950         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20951                         osp.$mdtosc_proc1.prealloc_status)
20952         echo "prealloc_status $oa_status"
20953
20954         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20955                 error "File creation should fail"
20956
20957         #object allocation was stopped, but we still able to append files
20958         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20959                 oflag=append || error "Append failed"
20960
20961         rm -f $DIR/$tdir/$tfile.0
20962
20963         # For this test, we want to delete the files we created to go out of
20964         # space but leave the watermark, so we remain nearly out of space
20965         ost_watermarks_enospc_delete_files $tfile $ostidx
20966
20967         wait_delete_completed
20968
20969         sleep_maxage
20970
20971         for i in $(seq 10 12); do
20972                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20973                         2>/dev/null || error "File creation failed after rm"
20974         done
20975
20976         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20977                         osp.$mdtosc_proc1.prealloc_status)
20978         echo "prealloc_status $oa_status"
20979
20980         if (( oa_status != 0 )); then
20981                 error "Object allocation still disable after rm"
20982         fi
20983 }
20984 run_test 253 "Check object allocation limit"
20985
20986 test_254() {
20987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20988         remote_mds_nodsh && skip "remote MDS with nodsh"
20989         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20990                 skip "MDS does not support changelog_size"
20991
20992         local cl_user
20993         local MDT0=$(facet_svc $SINGLEMDS)
20994
20995         changelog_register || error "changelog_register failed"
20996
20997         changelog_clear 0 || error "changelog_clear failed"
20998
20999         local size1=$(do_facet $SINGLEMDS \
21000                       $LCTL get_param -n mdd.$MDT0.changelog_size)
21001         echo "Changelog size $size1"
21002
21003         rm -rf $DIR/$tdir
21004         $LFS mkdir -i 0 $DIR/$tdir
21005         # change something
21006         mkdir -p $DIR/$tdir/pics/2008/zachy
21007         touch $DIR/$tdir/pics/2008/zachy/timestamp
21008         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21009         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21010         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21011         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21012         rm $DIR/$tdir/pics/desktop.jpg
21013
21014         local size2=$(do_facet $SINGLEMDS \
21015                       $LCTL get_param -n mdd.$MDT0.changelog_size)
21016         echo "Changelog size after work $size2"
21017
21018         (( $size2 > $size1 )) ||
21019                 error "new Changelog size=$size2 less than old size=$size1"
21020 }
21021 run_test 254 "Check changelog size"
21022
21023 ladvise_no_type()
21024 {
21025         local type=$1
21026         local file=$2
21027
21028         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21029                 awk -F: '{print $2}' | grep $type > /dev/null
21030         if [ $? -ne 0 ]; then
21031                 return 0
21032         fi
21033         return 1
21034 }
21035
21036 ladvise_no_ioctl()
21037 {
21038         local file=$1
21039
21040         lfs ladvise -a willread $file > /dev/null 2>&1
21041         if [ $? -eq 0 ]; then
21042                 return 1
21043         fi
21044
21045         lfs ladvise -a willread $file 2>&1 |
21046                 grep "Inappropriate ioctl for device" > /dev/null
21047         if [ $? -eq 0 ]; then
21048                 return 0
21049         fi
21050         return 1
21051 }
21052
21053 percent() {
21054         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21055 }
21056
21057 # run a random read IO workload
21058 # usage: random_read_iops <filename> <filesize> <iosize>
21059 random_read_iops() {
21060         local file=$1
21061         local fsize=$2
21062         local iosize=${3:-4096}
21063
21064         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21065                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21066 }
21067
21068 drop_file_oss_cache() {
21069         local file="$1"
21070         local nodes="$2"
21071
21072         $LFS ladvise -a dontneed $file 2>/dev/null ||
21073                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21074 }
21075
21076 ladvise_willread_performance()
21077 {
21078         local repeat=10
21079         local average_origin=0
21080         local average_cache=0
21081         local average_ladvise=0
21082
21083         for ((i = 1; i <= $repeat; i++)); do
21084                 echo "Iter $i/$repeat: reading without willread hint"
21085                 cancel_lru_locks osc
21086                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21087                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21088                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21089                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21090
21091                 cancel_lru_locks osc
21092                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21093                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21094                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21095
21096                 cancel_lru_locks osc
21097                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21098                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21099                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21100                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21101                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21102         done
21103         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21104         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21105         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21106
21107         speedup_cache=$(percent $average_cache $average_origin)
21108         speedup_ladvise=$(percent $average_ladvise $average_origin)
21109
21110         echo "Average uncached read: $average_origin"
21111         echo "Average speedup with OSS cached read: " \
21112                 "$average_cache = +$speedup_cache%"
21113         echo "Average speedup with ladvise willread: " \
21114                 "$average_ladvise = +$speedup_ladvise%"
21115
21116         local lowest_speedup=20
21117         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21118                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21119                         "got $average_cache%. Skipping ladvise willread check."
21120                 return 0
21121         fi
21122
21123         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21124         # it is still good to run until then to exercise 'ladvise willread'
21125         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21126                 [ "$ost1_FSTYPE" = "zfs" ] &&
21127                 echo "osd-zfs does not support dontneed or drop_caches" &&
21128                 return 0
21129
21130         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21131         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21132                 error_not_in_vm "Speedup with willread is less than " \
21133                         "$lowest_speedup%, got $average_ladvise%"
21134 }
21135
21136 test_255a() {
21137         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21138                 skip "lustre < 2.8.54 does not support ladvise "
21139         remote_ost_nodsh && skip "remote OST with nodsh"
21140
21141         stack_trap "rm -f $DIR/$tfile"
21142         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21143
21144         ladvise_no_type willread $DIR/$tfile &&
21145                 skip "willread ladvise is not supported"
21146
21147         ladvise_no_ioctl $DIR/$tfile &&
21148                 skip "ladvise ioctl is not supported"
21149
21150         local size_mb=100
21151         local size=$((size_mb * 1048576))
21152         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21153                 error "dd to $DIR/$tfile failed"
21154
21155         lfs ladvise -a willread $DIR/$tfile ||
21156                 error "Ladvise failed with no range argument"
21157
21158         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21159                 error "Ladvise failed with no -l or -e argument"
21160
21161         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21162                 error "Ladvise failed with only -e argument"
21163
21164         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21165                 error "Ladvise failed with only -l argument"
21166
21167         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21168                 error "End offset should not be smaller than start offset"
21169
21170         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21171                 error "End offset should not be equal to start offset"
21172
21173         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21174                 error "Ladvise failed with overflowing -s argument"
21175
21176         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21177                 error "Ladvise failed with overflowing -e argument"
21178
21179         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21180                 error "Ladvise failed with overflowing -l argument"
21181
21182         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21183                 error "Ladvise succeeded with conflicting -l and -e arguments"
21184
21185         echo "Synchronous ladvise should wait"
21186         local delay=4
21187 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21188         do_nodes $(comma_list $(osts_nodes)) \
21189                 $LCTL set_param fail_val=$delay fail_loc=0x237
21190
21191         local start_ts=$SECONDS
21192         lfs ladvise -a willread $DIR/$tfile ||
21193                 error "Ladvise failed with no range argument"
21194         local end_ts=$SECONDS
21195         local inteval_ts=$((end_ts - start_ts))
21196
21197         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21198                 error "Synchronous advice didn't wait reply"
21199         fi
21200
21201         echo "Asynchronous ladvise shouldn't wait"
21202         local start_ts=$SECONDS
21203         lfs ladvise -a willread -b $DIR/$tfile ||
21204                 error "Ladvise failed with no range argument"
21205         local end_ts=$SECONDS
21206         local inteval_ts=$((end_ts - start_ts))
21207
21208         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21209                 error "Asynchronous advice blocked"
21210         fi
21211
21212         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21213         ladvise_willread_performance
21214 }
21215 run_test 255a "check 'lfs ladvise -a willread'"
21216
21217 facet_meminfo() {
21218         local facet=$1
21219         local info=$2
21220
21221         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21222 }
21223
21224 test_255b() {
21225         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21226                 skip "lustre < 2.8.54 does not support ladvise "
21227         remote_ost_nodsh && skip "remote OST with nodsh"
21228
21229         stack_trap "rm -f $DIR/$tfile"
21230         lfs setstripe -c 1 -i 0 $DIR/$tfile
21231
21232         ladvise_no_type dontneed $DIR/$tfile &&
21233                 skip "dontneed ladvise is not supported"
21234
21235         ladvise_no_ioctl $DIR/$tfile &&
21236                 skip "ladvise ioctl is not supported"
21237
21238         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21239                 [ "$ost1_FSTYPE" = "zfs" ] &&
21240                 skip "zfs-osd does not support 'ladvise dontneed'"
21241
21242         local size_mb=100
21243         local size=$((size_mb * 1048576))
21244         # In order to prevent disturbance of other processes, only check 3/4
21245         # of the memory usage
21246         local kibibytes=$((size_mb * 1024 * 3 / 4))
21247
21248         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21249                 error "dd to $DIR/$tfile failed"
21250
21251         #force write to complete before dropping OST cache & checking memory
21252         sync
21253
21254         local total=$(facet_meminfo ost1 MemTotal)
21255         echo "Total memory: $total KiB"
21256
21257         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21258         local before_read=$(facet_meminfo ost1 Cached)
21259         echo "Cache used before read: $before_read KiB"
21260
21261         lfs ladvise -a willread $DIR/$tfile ||
21262                 error "Ladvise willread failed"
21263         local after_read=$(facet_meminfo ost1 Cached)
21264         echo "Cache used after read: $after_read KiB"
21265
21266         lfs ladvise -a dontneed $DIR/$tfile ||
21267                 error "Ladvise dontneed again failed"
21268         local no_read=$(facet_meminfo ost1 Cached)
21269         echo "Cache used after dontneed ladvise: $no_read KiB"
21270
21271         if [ $total -lt $((before_read + kibibytes)) ]; then
21272                 echo "Memory is too small, abort checking"
21273                 return 0
21274         fi
21275
21276         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21277                 error "Ladvise willread should use more memory" \
21278                         "than $kibibytes KiB"
21279         fi
21280
21281         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21282                 error "Ladvise dontneed should release more memory" \
21283                         "than $kibibytes KiB"
21284         fi
21285 }
21286 run_test 255b "check 'lfs ladvise -a dontneed'"
21287
21288 test_255c() {
21289         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21290                 skip "lustre < 2.10.50 does not support lockahead"
21291
21292         local ost1_imp=$(get_osc_import_name client ost1)
21293         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21294                          cut -d'.' -f2)
21295         local count
21296         local new_count
21297         local difference
21298         local i
21299         local rc
21300
21301         test_mkdir -p $DIR/$tdir
21302         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21303
21304         #test 10 returns only success/failure
21305         i=10
21306         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21307         rc=$?
21308         if [ $rc -eq 255 ]; then
21309                 error "Ladvise test${i} failed, ${rc}"
21310         fi
21311
21312         #test 11 counts lock enqueue requests, all others count new locks
21313         i=11
21314         count=$(do_facet ost1 \
21315                 $LCTL get_param -n ost.OSS.ost.stats)
21316         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21317
21318         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21319         rc=$?
21320         if [ $rc -eq 255 ]; then
21321                 error "Ladvise test${i} failed, ${rc}"
21322         fi
21323
21324         new_count=$(do_facet ost1 \
21325                 $LCTL get_param -n ost.OSS.ost.stats)
21326         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21327                    awk '{ print $2 }')
21328
21329         difference="$((new_count - count))"
21330         if [ $difference -ne $rc ]; then
21331                 error "Ladvise test${i}, bad enqueue count, returned " \
21332                       "${rc}, actual ${difference}"
21333         fi
21334
21335         for i in $(seq 12 21); do
21336                 # If we do not do this, we run the risk of having too many
21337                 # locks and starting lock cancellation while we are checking
21338                 # lock counts.
21339                 cancel_lru_locks osc
21340
21341                 count=$($LCTL get_param -n \
21342                        ldlm.namespaces.$imp_name.lock_unused_count)
21343
21344                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21345                 rc=$?
21346                 if [ $rc -eq 255 ]; then
21347                         error "Ladvise test ${i} failed, ${rc}"
21348                 fi
21349
21350                 new_count=$($LCTL get_param -n \
21351                        ldlm.namespaces.$imp_name.lock_unused_count)
21352                 difference="$((new_count - count))"
21353
21354                 # Test 15 output is divided by 100 to map down to valid return
21355                 if [ $i -eq 15 ]; then
21356                         rc="$((rc * 100))"
21357                 fi
21358
21359                 if [ $difference -ne $rc ]; then
21360                         error "Ladvise test ${i}, bad lock count, returned " \
21361                               "${rc}, actual ${difference}"
21362                 fi
21363         done
21364
21365         #test 22 returns only success/failure
21366         i=22
21367         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21368         rc=$?
21369         if [ $rc -eq 255 ]; then
21370                 error "Ladvise test${i} failed, ${rc}"
21371         fi
21372 }
21373 run_test 255c "suite of ladvise lockahead tests"
21374
21375 test_256() {
21376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21377         remote_mds_nodsh && skip "remote MDS with nodsh"
21378         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21379         changelog_users $SINGLEMDS | grep "^cl" &&
21380                 skip "active changelog user"
21381
21382         local cl_user
21383         local cat_sl
21384         local mdt_dev
21385
21386         mdt_dev=$(mdsdevname 1)
21387         echo $mdt_dev
21388
21389         changelog_register || error "changelog_register failed"
21390
21391         rm -rf $DIR/$tdir
21392         mkdir_on_mdt0 $DIR/$tdir
21393
21394         changelog_clear 0 || error "changelog_clear failed"
21395
21396         # change something
21397         touch $DIR/$tdir/{1..10}
21398
21399         # stop the MDT
21400         stop $SINGLEMDS || error "Fail to stop MDT"
21401
21402         # remount the MDT
21403
21404         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21405
21406         #after mount new plainllog is used
21407         touch $DIR/$tdir/{11..19}
21408         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21409         stack_trap "rm -f $tmpfile"
21410         cat_sl=$(do_facet $SINGLEMDS "sync; \
21411                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21412                  llog_reader $tmpfile | grep -c type=1064553b")
21413         do_facet $SINGLEMDS llog_reader $tmpfile
21414
21415         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21416
21417         changelog_clear 0 || error "changelog_clear failed"
21418
21419         cat_sl=$(do_facet $SINGLEMDS "sync; \
21420                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21421                  llog_reader $tmpfile | grep -c type=1064553b")
21422
21423         if (( cat_sl == 2 )); then
21424                 error "Empty plain llog was not deleted from changelog catalog"
21425         elif (( cat_sl != 1 )); then
21426                 error "Active plain llog shouldn't be deleted from catalog"
21427         fi
21428 }
21429 run_test 256 "Check llog delete for empty and not full state"
21430
21431 test_257() {
21432         remote_mds_nodsh && skip "remote MDS with nodsh"
21433         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21434                 skip "Need MDS version at least 2.8.55"
21435
21436         test_mkdir $DIR/$tdir
21437
21438         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21439                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21440         stat $DIR/$tdir
21441
21442 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21443         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21444         local facet=mds$((mdtidx + 1))
21445         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21446         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21447
21448         stop $facet || error "stop MDS failed"
21449         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21450                 error "start MDS fail"
21451         wait_recovery_complete $facet
21452 }
21453 run_test 257 "xattr locks are not lost"
21454
21455 # Verify we take the i_mutex when security requires it
21456 test_258a() {
21457 #define OBD_FAIL_IMUTEX_SEC 0x141c
21458         $LCTL set_param fail_loc=0x141c
21459         touch $DIR/$tfile
21460         chmod u+s $DIR/$tfile
21461         chmod a+rwx $DIR/$tfile
21462         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21463         RC=$?
21464         if [ $RC -ne 0 ]; then
21465                 error "error, failed to take i_mutex, rc=$?"
21466         fi
21467         rm -f $DIR/$tfile
21468 }
21469 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21470
21471 # Verify we do NOT take the i_mutex in the normal case
21472 test_258b() {
21473 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21474         $LCTL set_param fail_loc=0x141d
21475         touch $DIR/$tfile
21476         chmod a+rwx $DIR
21477         chmod a+rw $DIR/$tfile
21478         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21479         RC=$?
21480         if [ $RC -ne 0 ]; then
21481                 error "error, took i_mutex unnecessarily, rc=$?"
21482         fi
21483         rm -f $DIR/$tfile
21484
21485 }
21486 run_test 258b "verify i_mutex security behavior"
21487
21488 test_259() {
21489         local file=$DIR/$tfile
21490         local before
21491         local after
21492
21493         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21494
21495         stack_trap "rm -f $file" EXIT
21496
21497         wait_delete_completed
21498         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21499         echo "before: $before"
21500
21501         $LFS setstripe -i 0 -c 1 $file
21502         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21503         sync_all_data
21504         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21505         echo "after write: $after"
21506
21507 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21508         do_facet ost1 $LCTL set_param fail_loc=0x2301
21509         $TRUNCATE $file 0
21510         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21511         echo "after truncate: $after"
21512
21513         stop ost1
21514         do_facet ost1 $LCTL set_param fail_loc=0
21515         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21516         sleep 2
21517         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21518         echo "after restart: $after"
21519         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21520                 error "missing truncate?"
21521
21522         return 0
21523 }
21524 run_test 259 "crash at delayed truncate"
21525
21526 test_260() {
21527 #define OBD_FAIL_MDC_CLOSE               0x806
21528         $LCTL set_param fail_loc=0x80000806
21529         touch $DIR/$tfile
21530
21531 }
21532 run_test 260 "Check mdc_close fail"
21533
21534 ### Data-on-MDT sanity tests ###
21535 test_270a() {
21536         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21537                 skip "Need MDS version at least 2.10.55 for DoM"
21538
21539         # create DoM file
21540         local dom=$DIR/$tdir/dom_file
21541         local tmp=$DIR/$tdir/tmp_file
21542
21543         mkdir_on_mdt0 $DIR/$tdir
21544
21545         # basic checks for DoM component creation
21546         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21547                 error "Can set MDT layout to non-first entry"
21548
21549         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21550                 error "Can define multiple entries as MDT layout"
21551
21552         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21553
21554         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21555         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21556         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21557
21558         local mdtidx=$($LFS getstripe -m $dom)
21559         local mdtname=MDT$(printf %04x $mdtidx)
21560         local facet=mds$((mdtidx + 1))
21561         local space_check=1
21562
21563         # Skip free space checks with ZFS
21564         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21565
21566         # write
21567         sync
21568         local size_tmp=$((65536 * 3))
21569         local mdtfree1=$(do_facet $facet \
21570                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21571
21572         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21573         # check also direct IO along write
21574         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21575         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21576         sync
21577         cmp $tmp $dom || error "file data is different"
21578         [ $(stat -c%s $dom) == $size_tmp ] ||
21579                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21580         if [ $space_check == 1 ]; then
21581                 local mdtfree2=$(do_facet $facet \
21582                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21583
21584                 # increase in usage from by $size_tmp
21585                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21586                         error "MDT free space wrong after write: " \
21587                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21588         fi
21589
21590         # truncate
21591         local size_dom=10000
21592
21593         $TRUNCATE $dom $size_dom
21594         [ $(stat -c%s $dom) == $size_dom ] ||
21595                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21596         if [ $space_check == 1 ]; then
21597                 mdtfree1=$(do_facet $facet \
21598                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21599                 # decrease in usage from $size_tmp to new $size_dom
21600                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21601                   $(((size_tmp - size_dom) / 1024)) ] ||
21602                         error "MDT free space is wrong after truncate: " \
21603                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21604         fi
21605
21606         # append
21607         cat $tmp >> $dom
21608         sync
21609         size_dom=$((size_dom + size_tmp))
21610         [ $(stat -c%s $dom) == $size_dom ] ||
21611                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21612         if [ $space_check == 1 ]; then
21613                 mdtfree2=$(do_facet $facet \
21614                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21615                 # increase in usage by $size_tmp from previous
21616                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21617                         error "MDT free space is wrong after append: " \
21618                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21619         fi
21620
21621         # delete
21622         rm $dom
21623         if [ $space_check == 1 ]; then
21624                 mdtfree1=$(do_facet $facet \
21625                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21626                 # decrease in usage by $size_dom from previous
21627                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21628                         error "MDT free space is wrong after removal: " \
21629                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21630         fi
21631
21632         # combined striping
21633         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21634                 error "Can't create DoM + OST striping"
21635
21636         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21637         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21638         # check also direct IO along write
21639         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21640         sync
21641         cmp $tmp $dom || error "file data is different"
21642         [ $(stat -c%s $dom) == $size_tmp ] ||
21643                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21644         rm $dom $tmp
21645
21646         return 0
21647 }
21648 run_test 270a "DoM: basic functionality tests"
21649
21650 test_270b() {
21651         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21652                 skip "Need MDS version at least 2.10.55"
21653
21654         local dom=$DIR/$tdir/dom_file
21655         local max_size=1048576
21656
21657         mkdir -p $DIR/$tdir
21658         $LFS setstripe -E $max_size -L mdt $dom
21659
21660         # truncate over the limit
21661         $TRUNCATE $dom $(($max_size + 1)) &&
21662                 error "successful truncate over the maximum size"
21663         # write over the limit
21664         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21665                 error "successful write over the maximum size"
21666         # append over the limit
21667         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21668         echo "12345" >> $dom && error "successful append over the maximum size"
21669         rm $dom
21670
21671         return 0
21672 }
21673 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21674
21675 test_270c() {
21676         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21677                 skip "Need MDS version at least 2.10.55"
21678
21679         mkdir -p $DIR/$tdir
21680         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21681
21682         # check files inherit DoM EA
21683         touch $DIR/$tdir/first
21684         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21685                 error "bad pattern"
21686         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21687                 error "bad stripe count"
21688         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21689                 error "bad stripe size"
21690
21691         # check directory inherits DoM EA and uses it as default
21692         mkdir $DIR/$tdir/subdir
21693         touch $DIR/$tdir/subdir/second
21694         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21695                 error "bad pattern in sub-directory"
21696         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21697                 error "bad stripe count in sub-directory"
21698         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21699                 error "bad stripe size in sub-directory"
21700         return 0
21701 }
21702 run_test 270c "DoM: DoM EA inheritance tests"
21703
21704 test_270d() {
21705         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21706                 skip "Need MDS version at least 2.10.55"
21707
21708         mkdir -p $DIR/$tdir
21709         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21710
21711         # inherit default DoM striping
21712         mkdir $DIR/$tdir/subdir
21713         touch $DIR/$tdir/subdir/f1
21714
21715         # change default directory striping
21716         $LFS setstripe -c 1 $DIR/$tdir/subdir
21717         touch $DIR/$tdir/subdir/f2
21718         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21719                 error "wrong default striping in file 2"
21720         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21721                 error "bad pattern in file 2"
21722         return 0
21723 }
21724 run_test 270d "DoM: change striping from DoM to RAID0"
21725
21726 test_270e() {
21727         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21728                 skip "Need MDS version at least 2.10.55"
21729
21730         mkdir -p $DIR/$tdir/dom
21731         mkdir -p $DIR/$tdir/norm
21732         DOMFILES=20
21733         NORMFILES=10
21734         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21735         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21736
21737         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21738         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21739
21740         # find DoM files by layout
21741         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21742         [ $NUM -eq  $DOMFILES ] ||
21743                 error "lfs find -L: found $NUM, expected $DOMFILES"
21744         echo "Test 1: lfs find 20 DOM files by layout: OK"
21745
21746         # there should be 1 dir with default DOM striping
21747         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21748         [ $NUM -eq  1 ] ||
21749                 error "lfs find -L: found $NUM, expected 1 dir"
21750         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21751
21752         # find DoM files by stripe size
21753         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21754         [ $NUM -eq  $DOMFILES ] ||
21755                 error "lfs find -S: found $NUM, expected $DOMFILES"
21756         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21757
21758         # find files by stripe offset except DoM files
21759         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21760         [ $NUM -eq  $NORMFILES ] ||
21761                 error "lfs find -i: found $NUM, expected $NORMFILES"
21762         echo "Test 5: lfs find no DOM files by stripe index: OK"
21763         return 0
21764 }
21765 run_test 270e "DoM: lfs find with DoM files test"
21766
21767 test_270f() {
21768         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21769                 skip "Need MDS version at least 2.10.55"
21770
21771         local mdtname=${FSNAME}-MDT0000-mdtlov
21772         local dom=$DIR/$tdir/dom_file
21773         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21774                                                 lod.$mdtname.dom_stripesize)
21775         local dom_limit=131072
21776
21777         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21778         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21779                                                 lod.$mdtname.dom_stripesize)
21780         [ ${dom_limit} -eq ${dom_current} ] ||
21781                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21782
21783         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21784         $LFS setstripe -d $DIR/$tdir
21785         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21786                 error "Can't set directory default striping"
21787
21788         # exceed maximum stripe size
21789         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21790                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21791         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21792                 error "Able to create DoM component size more than LOD limit"
21793
21794         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21795         dom_current=$(do_facet mds1 $LCTL get_param -n \
21796                                                 lod.$mdtname.dom_stripesize)
21797         [ 0 -eq ${dom_current} ] ||
21798                 error "Can't set zero DoM stripe limit"
21799         rm $dom
21800
21801         # attempt to create DoM file on server with disabled DoM should
21802         # remove DoM entry from layout and be succeed
21803         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21804                 error "Can't create DoM file (DoM is disabled)"
21805         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21806                 error "File has DoM component while DoM is disabled"
21807         rm $dom
21808
21809         # attempt to create DoM file with only DoM stripe should return error
21810         $LFS setstripe -E $dom_limit -L mdt $dom &&
21811                 error "Able to create DoM-only file while DoM is disabled"
21812
21813         # too low values to be aligned with smallest stripe size 64K
21814         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21815         dom_current=$(do_facet mds1 $LCTL get_param -n \
21816                                                 lod.$mdtname.dom_stripesize)
21817         [ 30000 -eq ${dom_current} ] &&
21818                 error "Can set too small DoM stripe limit"
21819
21820         # 64K is a minimal stripe size in Lustre, expect limit of that size
21821         [ 65536 -eq ${dom_current} ] ||
21822                 error "Limit is not set to 64K but ${dom_current}"
21823
21824         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21825         dom_current=$(do_facet mds1 $LCTL get_param -n \
21826                                                 lod.$mdtname.dom_stripesize)
21827         echo $dom_current
21828         [ 2147483648 -eq ${dom_current} ] &&
21829                 error "Can set too large DoM stripe limit"
21830
21831         do_facet mds1 $LCTL set_param -n \
21832                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21833         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21834                 error "Can't create DoM component size after limit change"
21835         do_facet mds1 $LCTL set_param -n \
21836                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21837         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21838                 error "Can't create DoM file after limit decrease"
21839         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21840                 error "Can create big DoM component after limit decrease"
21841         touch ${dom}_def ||
21842                 error "Can't create file with old default layout"
21843
21844         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21845         return 0
21846 }
21847 run_test 270f "DoM: maximum DoM stripe size checks"
21848
21849 test_270g() {
21850         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21851                 skip "Need MDS version at least 2.13.52"
21852         local dom=$DIR/$tdir/$tfile
21853
21854         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21855         local lodname=${FSNAME}-MDT0000-mdtlov
21856
21857         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21858         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21859         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21860         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21861
21862         local dom_limit=1024
21863         local dom_threshold="50%"
21864
21865         $LFS setstripe -d $DIR/$tdir
21866         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21867                 error "Can't set directory default striping"
21868
21869         do_facet mds1 $LCTL set_param -n \
21870                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21871         # set 0 threshold and create DOM file to change tunable stripesize
21872         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21873         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21874                 error "Failed to create $dom file"
21875         # now tunable dom_cur_stripesize should reach maximum
21876         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21877                                         lod.${lodname}.dom_stripesize_cur_kb)
21878         [[ $dom_current == $dom_limit ]] ||
21879                 error "Current DOM stripesize is not maximum"
21880         rm $dom
21881
21882         # set threshold for further tests
21883         do_facet mds1 $LCTL set_param -n \
21884                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21885         echo "DOM threshold is $dom_threshold free space"
21886         local dom_def
21887         local dom_set
21888         # Spoof bfree to exceed threshold
21889         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21890         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21891         for spfree in 40 20 0 15 30 55; do
21892                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21893                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21894                         error "Failed to create $dom file"
21895                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21896                                         lod.${lodname}.dom_stripesize_cur_kb)
21897                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21898                 [[ $dom_def != $dom_current ]] ||
21899                         error "Default stripe size was not changed"
21900                 if [[ $spfree > 0 ]] ; then
21901                         dom_set=$($LFS getstripe -S $dom)
21902                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21903                                 error "DOM component size is still old"
21904                 else
21905                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21906                                 error "DoM component is set with no free space"
21907                 fi
21908                 rm $dom
21909                 dom_current=$dom_def
21910         done
21911 }
21912 run_test 270g "DoM: default DoM stripe size depends on free space"
21913
21914 test_270h() {
21915         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21916                 skip "Need MDS version at least 2.13.53"
21917
21918         local mdtname=${FSNAME}-MDT0000-mdtlov
21919         local dom=$DIR/$tdir/$tfile
21920         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21921
21922         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21923         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21924
21925         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21926         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21927                 error "can't create OST file"
21928         # mirrored file with DOM entry in the second mirror
21929         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21930                 error "can't create mirror with DoM component"
21931
21932         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21933
21934         # DOM component in the middle and has other enries in the same mirror,
21935         # should succeed but lost DoM component
21936         $LFS setstripe --copy=${dom}_1 $dom ||
21937                 error "Can't create file from OST|DOM mirror layout"
21938         # check new file has no DoM layout after all
21939         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21940                 error "File has DoM component while DoM is disabled"
21941 }
21942 run_test 270h "DoM: DoM stripe removal when disabled on server"
21943
21944 test_271a() {
21945         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21946                 skip "Need MDS version at least 2.10.55"
21947
21948         local dom=$DIR/$tdir/dom
21949
21950         mkdir -p $DIR/$tdir
21951
21952         $LFS setstripe -E 1024K -L mdt $dom
21953
21954         lctl set_param -n mdc.*.stats=clear
21955         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21956         cat $dom > /dev/null
21957         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21958         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21959         ls $dom
21960         rm -f $dom
21961 }
21962 run_test 271a "DoM: data is cached for read after write"
21963
21964 test_271b() {
21965         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21966                 skip "Need MDS version at least 2.10.55"
21967
21968         local dom=$DIR/$tdir/dom
21969
21970         mkdir -p $DIR/$tdir
21971
21972         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21973
21974         lctl set_param -n mdc.*.stats=clear
21975         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21976         cancel_lru_locks mdc
21977         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21978         # second stat to check size is cached on client
21979         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21980         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21981         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21982         rm -f $dom
21983 }
21984 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21985
21986 test_271ba() {
21987         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21988                 skip "Need MDS version at least 2.10.55"
21989
21990         local dom=$DIR/$tdir/dom
21991
21992         mkdir -p $DIR/$tdir
21993
21994         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21995
21996         lctl set_param -n mdc.*.stats=clear
21997         lctl set_param -n osc.*.stats=clear
21998         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21999         cancel_lru_locks mdc
22000         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22001         # second stat to check size is cached on client
22002         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22003         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22004         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22005         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22006         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22007         rm -f $dom
22008 }
22009 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22010
22011
22012 get_mdc_stats() {
22013         local mdtidx=$1
22014         local param=$2
22015         local mdt=MDT$(printf %04x $mdtidx)
22016
22017         if [ -z $param ]; then
22018                 lctl get_param -n mdc.*$mdt*.stats
22019         else
22020                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22021         fi
22022 }
22023
22024 test_271c() {
22025         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22026                 skip "Need MDS version at least 2.10.55"
22027
22028         local dom=$DIR/$tdir/dom
22029
22030         mkdir -p $DIR/$tdir
22031
22032         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22033
22034         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22035         local facet=mds$((mdtidx + 1))
22036
22037         cancel_lru_locks mdc
22038         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22039         createmany -o $dom 1000
22040         lctl set_param -n mdc.*.stats=clear
22041         smalliomany -w $dom 1000 200
22042         get_mdc_stats $mdtidx
22043         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22044         # Each file has 1 open, 1 IO enqueues, total 2000
22045         # but now we have also +1 getxattr for security.capability, total 3000
22046         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22047         unlinkmany $dom 1000
22048
22049         cancel_lru_locks mdc
22050         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22051         createmany -o $dom 1000
22052         lctl set_param -n mdc.*.stats=clear
22053         smalliomany -w $dom 1000 200
22054         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22055         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22056         # for OPEN and IO lock.
22057         [ $((enq - enq_2)) -ge 1000 ] ||
22058                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22059         unlinkmany $dom 1000
22060         return 0
22061 }
22062 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22063
22064 cleanup_271def_tests() {
22065         trap 0
22066         rm -f $1
22067 }
22068
22069 test_271d() {
22070         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22071                 skip "Need MDS version at least 2.10.57"
22072
22073         local dom=$DIR/$tdir/dom
22074         local tmp=$TMP/$tfile
22075         trap "cleanup_271def_tests $tmp" EXIT
22076
22077         mkdir -p $DIR/$tdir
22078
22079         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22080
22081         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22082
22083         cancel_lru_locks mdc
22084         dd if=/dev/urandom of=$tmp bs=1000 count=1
22085         dd if=$tmp of=$dom bs=1000 count=1
22086         cancel_lru_locks mdc
22087
22088         cat /etc/hosts >> $tmp
22089         lctl set_param -n mdc.*.stats=clear
22090
22091         # append data to the same file it should update local page
22092         echo "Append to the same page"
22093         cat /etc/hosts >> $dom
22094         local num=$(get_mdc_stats $mdtidx ost_read)
22095         local ra=$(get_mdc_stats $mdtidx req_active)
22096         local rw=$(get_mdc_stats $mdtidx req_waittime)
22097
22098         [ -z $num ] || error "$num READ RPC occured"
22099         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22100         echo "... DONE"
22101
22102         # compare content
22103         cmp $tmp $dom || error "file miscompare"
22104
22105         cancel_lru_locks mdc
22106         lctl set_param -n mdc.*.stats=clear
22107
22108         echo "Open and read file"
22109         cat $dom > /dev/null
22110         local num=$(get_mdc_stats $mdtidx ost_read)
22111         local ra=$(get_mdc_stats $mdtidx req_active)
22112         local rw=$(get_mdc_stats $mdtidx req_waittime)
22113
22114         [ -z $num ] || error "$num READ RPC occured"
22115         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22116         echo "... DONE"
22117
22118         # compare content
22119         cmp $tmp $dom || error "file miscompare"
22120
22121         return 0
22122 }
22123 run_test 271d "DoM: read on open (1K file in reply buffer)"
22124
22125 test_271f() {
22126         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22127                 skip "Need MDS version at least 2.10.57"
22128
22129         local dom=$DIR/$tdir/dom
22130         local tmp=$TMP/$tfile
22131         trap "cleanup_271def_tests $tmp" EXIT
22132
22133         mkdir -p $DIR/$tdir
22134
22135         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22136
22137         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22138
22139         cancel_lru_locks mdc
22140         dd if=/dev/urandom of=$tmp bs=265000 count=1
22141         dd if=$tmp of=$dom bs=265000 count=1
22142         cancel_lru_locks mdc
22143         cat /etc/hosts >> $tmp
22144         lctl set_param -n mdc.*.stats=clear
22145
22146         echo "Append to the same page"
22147         cat /etc/hosts >> $dom
22148         local num=$(get_mdc_stats $mdtidx ost_read)
22149         local ra=$(get_mdc_stats $mdtidx req_active)
22150         local rw=$(get_mdc_stats $mdtidx req_waittime)
22151
22152         [ -z $num ] || error "$num READ RPC occured"
22153         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22154         echo "... DONE"
22155
22156         # compare content
22157         cmp $tmp $dom || error "file miscompare"
22158
22159         cancel_lru_locks mdc
22160         lctl set_param -n mdc.*.stats=clear
22161
22162         echo "Open and read file"
22163         cat $dom > /dev/null
22164         local num=$(get_mdc_stats $mdtidx ost_read)
22165         local ra=$(get_mdc_stats $mdtidx req_active)
22166         local rw=$(get_mdc_stats $mdtidx req_waittime)
22167
22168         [ -z $num ] && num=0
22169         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22170         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22171         echo "... DONE"
22172
22173         # compare content
22174         cmp $tmp $dom || error "file miscompare"
22175
22176         return 0
22177 }
22178 run_test 271f "DoM: read on open (200K file and read tail)"
22179
22180 test_271g() {
22181         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22182                 skip "Skipping due to old client or server version"
22183
22184         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22185         # to get layout
22186         $CHECKSTAT -t file $DIR1/$tfile
22187
22188         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22189         MULTIOP_PID=$!
22190         sleep 1
22191         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22192         $LCTL set_param fail_loc=0x80000314
22193         rm $DIR1/$tfile || error "Unlink fails"
22194         RC=$?
22195         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22196         [ $RC -eq 0 ] || error "Failed write to stale object"
22197 }
22198 run_test 271g "Discard DoM data vs client flush race"
22199
22200 test_272a() {
22201         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22202                 skip "Need MDS version at least 2.11.50"
22203
22204         local dom=$DIR/$tdir/dom
22205         mkdir -p $DIR/$tdir
22206
22207         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22208         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22209                 error "failed to write data into $dom"
22210         local old_md5=$(md5sum $dom)
22211
22212         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22213                 error "failed to migrate to the same DoM component"
22214
22215         local new_md5=$(md5sum $dom)
22216
22217         [ "$old_md5" == "$new_md5" ] ||
22218                 error "md5sum differ: $old_md5, $new_md5"
22219
22220         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22221                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22222 }
22223 run_test 272a "DoM migration: new layout with the same DOM component"
22224
22225 test_272b() {
22226         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22227                 skip "Need MDS version at least 2.11.50"
22228
22229         local dom=$DIR/$tdir/dom
22230         mkdir -p $DIR/$tdir
22231         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22232
22233         local mdtidx=$($LFS getstripe -m $dom)
22234         local mdtname=MDT$(printf %04x $mdtidx)
22235         local facet=mds$((mdtidx + 1))
22236
22237         local mdtfree1=$(do_facet $facet \
22238                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22239         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22240                 error "failed to write data into $dom"
22241         local old_md5=$(md5sum $dom)
22242         cancel_lru_locks mdc
22243         local mdtfree1=$(do_facet $facet \
22244                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22245
22246         $LFS migrate -c2 $dom ||
22247                 error "failed to migrate to the new composite layout"
22248         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22249                 error "MDT stripe was not removed"
22250
22251         cancel_lru_locks mdc
22252         local new_md5=$(md5sum $dom)
22253         [ "$old_md5" == "$new_md5" ] ||
22254                 error "$old_md5 != $new_md5"
22255
22256         # Skip free space checks with ZFS
22257         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22258                 local mdtfree2=$(do_facet $facet \
22259                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22260                 [ $mdtfree2 -gt $mdtfree1 ] ||
22261                         error "MDT space is not freed after migration"
22262         fi
22263         return 0
22264 }
22265 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22266
22267 test_272c() {
22268         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22269                 skip "Need MDS version at least 2.11.50"
22270
22271         local dom=$DIR/$tdir/$tfile
22272         mkdir -p $DIR/$tdir
22273         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22274
22275         local mdtidx=$($LFS getstripe -m $dom)
22276         local mdtname=MDT$(printf %04x $mdtidx)
22277         local facet=mds$((mdtidx + 1))
22278
22279         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22280                 error "failed to write data into $dom"
22281         local old_md5=$(md5sum $dom)
22282         cancel_lru_locks mdc
22283         local mdtfree1=$(do_facet $facet \
22284                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22285
22286         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22287                 error "failed to migrate to the new composite layout"
22288         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22289                 error "MDT stripe was not removed"
22290
22291         cancel_lru_locks mdc
22292         local new_md5=$(md5sum $dom)
22293         [ "$old_md5" == "$new_md5" ] ||
22294                 error "$old_md5 != $new_md5"
22295
22296         # Skip free space checks with ZFS
22297         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22298                 local mdtfree2=$(do_facet $facet \
22299                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22300                 [ $mdtfree2 -gt $mdtfree1 ] ||
22301                         error "MDS space is not freed after migration"
22302         fi
22303         return 0
22304 }
22305 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22306
22307 test_272d() {
22308         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22309                 skip "Need MDS version at least 2.12.55"
22310
22311         local dom=$DIR/$tdir/$tfile
22312         mkdir -p $DIR/$tdir
22313         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22314
22315         local mdtidx=$($LFS getstripe -m $dom)
22316         local mdtname=MDT$(printf %04x $mdtidx)
22317         local facet=mds$((mdtidx + 1))
22318
22319         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22320                 error "failed to write data into $dom"
22321         local old_md5=$(md5sum $dom)
22322         cancel_lru_locks mdc
22323         local mdtfree1=$(do_facet $facet \
22324                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22325
22326         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22327                 error "failed mirroring to the new composite layout"
22328         $LFS mirror resync $dom ||
22329                 error "failed mirror resync"
22330         $LFS mirror split --mirror-id 1 -d $dom ||
22331                 error "failed mirror split"
22332
22333         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22334                 error "MDT stripe was not removed"
22335
22336         cancel_lru_locks mdc
22337         local new_md5=$(md5sum $dom)
22338         [ "$old_md5" == "$new_md5" ] ||
22339                 error "$old_md5 != $new_md5"
22340
22341         # Skip free space checks with ZFS
22342         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22343                 local mdtfree2=$(do_facet $facet \
22344                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22345                 [ $mdtfree2 -gt $mdtfree1 ] ||
22346                         error "MDS space is not freed after DOM mirror deletion"
22347         fi
22348         return 0
22349 }
22350 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22351
22352 test_272e() {
22353         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22354                 skip "Need MDS version at least 2.12.55"
22355
22356         local dom=$DIR/$tdir/$tfile
22357         mkdir -p $DIR/$tdir
22358         $LFS setstripe -c 2 $dom
22359
22360         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22361                 error "failed to write data into $dom"
22362         local old_md5=$(md5sum $dom)
22363         cancel_lru_locks mdc
22364
22365         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22366                 error "failed mirroring to the DOM layout"
22367         $LFS mirror resync $dom ||
22368                 error "failed mirror resync"
22369         $LFS mirror split --mirror-id 1 -d $dom ||
22370                 error "failed mirror split"
22371
22372         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22373                 error "MDT stripe was not removed"
22374
22375         cancel_lru_locks mdc
22376         local new_md5=$(md5sum $dom)
22377         [ "$old_md5" == "$new_md5" ] ||
22378                 error "$old_md5 != $new_md5"
22379
22380         return 0
22381 }
22382 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22383
22384 test_272f() {
22385         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22386                 skip "Need MDS version at least 2.12.55"
22387
22388         local dom=$DIR/$tdir/$tfile
22389         mkdir -p $DIR/$tdir
22390         $LFS setstripe -c 2 $dom
22391
22392         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22393                 error "failed to write data into $dom"
22394         local old_md5=$(md5sum $dom)
22395         cancel_lru_locks mdc
22396
22397         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22398                 error "failed migrating to the DOM file"
22399
22400         cancel_lru_locks mdc
22401         local new_md5=$(md5sum $dom)
22402         [ "$old_md5" != "$new_md5" ] &&
22403                 error "$old_md5 != $new_md5"
22404
22405         return 0
22406 }
22407 run_test 272f "DoM migration: OST-striped file to DOM file"
22408
22409 test_273a() {
22410         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22411                 skip "Need MDS version at least 2.11.50"
22412
22413         # Layout swap cannot be done if either file has DOM component,
22414         # this will never be supported, migration should be used instead
22415
22416         local dom=$DIR/$tdir/$tfile
22417         mkdir -p $DIR/$tdir
22418
22419         $LFS setstripe -c2 ${dom}_plain
22420         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22421         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22422                 error "can swap layout with DoM component"
22423         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22424                 error "can swap layout with DoM component"
22425
22426         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22427         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22428                 error "can swap layout with DoM component"
22429         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22430                 error "can swap layout with DoM component"
22431         return 0
22432 }
22433 run_test 273a "DoM: layout swapping should fail with DOM"
22434
22435 test_273b() {
22436         mkdir -p $DIR/$tdir
22437         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22438
22439 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22440         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22441
22442         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22443 }
22444 run_test 273b "DoM: race writeback and object destroy"
22445
22446 test_275() {
22447         remote_ost_nodsh && skip "remote OST with nodsh"
22448         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22449                 skip "Need OST version >= 2.10.57"
22450
22451         local file=$DIR/$tfile
22452         local oss
22453
22454         oss=$(comma_list $(osts_nodes))
22455
22456         dd if=/dev/urandom of=$file bs=1M count=2 ||
22457                 error "failed to create a file"
22458         cancel_lru_locks osc
22459
22460         #lock 1
22461         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22462                 error "failed to read a file"
22463
22464 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22465         $LCTL set_param fail_loc=0x8000031f
22466
22467         cancel_lru_locks osc &
22468         sleep 1
22469
22470 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22471         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22472         #IO takes another lock, but matches the PENDING one
22473         #and places it to the IO RPC
22474         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22475                 error "failed to read a file with PENDING lock"
22476 }
22477 run_test 275 "Read on a canceled duplicate lock"
22478
22479 test_276() {
22480         remote_ost_nodsh && skip "remote OST with nodsh"
22481         local pid
22482
22483         do_facet ost1 "(while true; do \
22484                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22485                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22486         pid=$!
22487
22488         for LOOP in $(seq 20); do
22489                 stop ost1
22490                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22491         done
22492         kill -9 $pid
22493         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22494                 rm $TMP/sanity_276_pid"
22495 }
22496 run_test 276 "Race between mount and obd_statfs"
22497
22498 test_277() {
22499         $LCTL set_param ldlm.namespaces.*.lru_size=0
22500         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22501         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22502                         grep ^used_mb | awk '{print $2}')
22503         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22504         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22505                 oflag=direct conv=notrunc
22506         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22507                         grep ^used_mb | awk '{print $2}')
22508         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22509 }
22510 run_test 277 "Direct IO shall drop page cache"
22511
22512 test_278() {
22513         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22514         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22515         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22516                 skip "needs the same host for mdt1 mdt2" && return
22517
22518         local pid1
22519         local pid2
22520
22521 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22522         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22523         stop mds2 &
22524         pid2=$!
22525
22526         stop mds1
22527
22528         echo "Starting MDTs"
22529         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22530         wait $pid2
22531 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22532 #will return NULL
22533         do_facet mds2 $LCTL set_param fail_loc=0
22534
22535         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22536         wait_recovery_complete mds2
22537 }
22538 run_test 278 "Race starting MDS between MDTs stop/start"
22539
22540 test_280() {
22541         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22542                 skip "Need MGS version at least 2.13.52"
22543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22544         combined_mgs_mds || skip "needs combined MGS/MDT"
22545
22546         umount_client $MOUNT
22547 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22548         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22549
22550         mount_client $MOUNT &
22551         sleep 1
22552         stop mgs || error "stop mgs failed"
22553         #for a race mgs would crash
22554         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22555         # make sure we unmount client before remounting
22556         wait
22557         umount_client $MOUNT
22558         mount_client $MOUNT || error "mount client failed"
22559 }
22560 run_test 280 "Race between MGS umount and client llog processing"
22561
22562 cleanup_test_300() {
22563         trap 0
22564         umask $SAVE_UMASK
22565 }
22566 test_striped_dir() {
22567         local mdt_index=$1
22568         local stripe_count
22569         local stripe_index
22570
22571         mkdir -p $DIR/$tdir
22572
22573         SAVE_UMASK=$(umask)
22574         trap cleanup_test_300 RETURN EXIT
22575
22576         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22577                                                 $DIR/$tdir/striped_dir ||
22578                 error "set striped dir error"
22579
22580         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22581         [ "$mode" = "755" ] || error "expect 755 got $mode"
22582
22583         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22584                 error "getdirstripe failed"
22585         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22586         if [ "$stripe_count" != "2" ]; then
22587                 error "1:stripe_count is $stripe_count, expect 2"
22588         fi
22589         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22590         if [ "$stripe_count" != "2" ]; then
22591                 error "2:stripe_count is $stripe_count, expect 2"
22592         fi
22593
22594         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22595         if [ "$stripe_index" != "$mdt_index" ]; then
22596                 error "stripe_index is $stripe_index, expect $mdt_index"
22597         fi
22598
22599         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22600                 error "nlink error after create striped dir"
22601
22602         mkdir $DIR/$tdir/striped_dir/a
22603         mkdir $DIR/$tdir/striped_dir/b
22604
22605         stat $DIR/$tdir/striped_dir/a ||
22606                 error "create dir under striped dir failed"
22607         stat $DIR/$tdir/striped_dir/b ||
22608                 error "create dir under striped dir failed"
22609
22610         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22611                 error "nlink error after mkdir"
22612
22613         rmdir $DIR/$tdir/striped_dir/a
22614         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22615                 error "nlink error after rmdir"
22616
22617         rmdir $DIR/$tdir/striped_dir/b
22618         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22619                 error "nlink error after rmdir"
22620
22621         chattr +i $DIR/$tdir/striped_dir
22622         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22623                 error "immutable flags not working under striped dir!"
22624         chattr -i $DIR/$tdir/striped_dir
22625
22626         rmdir $DIR/$tdir/striped_dir ||
22627                 error "rmdir striped dir error"
22628
22629         cleanup_test_300
22630
22631         true
22632 }
22633
22634 test_300a() {
22635         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22636                 skip "skipped for lustre < 2.7.0"
22637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22638         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22639
22640         test_striped_dir 0 || error "failed on striped dir on MDT0"
22641         test_striped_dir 1 || error "failed on striped dir on MDT0"
22642 }
22643 run_test 300a "basic striped dir sanity test"
22644
22645 test_300b() {
22646         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22647                 skip "skipped for lustre < 2.7.0"
22648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22649         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22650
22651         local i
22652         local mtime1
22653         local mtime2
22654         local mtime3
22655
22656         test_mkdir $DIR/$tdir || error "mkdir fail"
22657         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22658                 error "set striped dir error"
22659         for i in {0..9}; do
22660                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22661                 sleep 1
22662                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22663                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22664                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22665                 sleep 1
22666                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22667                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22668                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22669         done
22670         true
22671 }
22672 run_test 300b "check ctime/mtime for striped dir"
22673
22674 test_300c() {
22675         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22676                 skip "skipped for lustre < 2.7.0"
22677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22678         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22679
22680         local file_count
22681
22682         mkdir_on_mdt0 $DIR/$tdir
22683         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22684                 error "set striped dir error"
22685
22686         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22687                 error "chown striped dir failed"
22688
22689         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22690                 error "create 5k files failed"
22691
22692         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22693
22694         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22695
22696         rm -rf $DIR/$tdir
22697 }
22698 run_test 300c "chown && check ls under striped directory"
22699
22700 test_300d() {
22701         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22702                 skip "skipped for lustre < 2.7.0"
22703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22705
22706         local stripe_count
22707         local file
22708
22709         mkdir -p $DIR/$tdir
22710         $LFS setstripe -c 2 $DIR/$tdir
22711
22712         #local striped directory
22713         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22714                 error "set striped dir error"
22715         #look at the directories for debug purposes
22716         ls -l $DIR/$tdir
22717         $LFS getdirstripe $DIR/$tdir
22718         ls -l $DIR/$tdir/striped_dir
22719         $LFS getdirstripe $DIR/$tdir/striped_dir
22720         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22721                 error "create 10 files failed"
22722
22723         #remote striped directory
22724         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22725                 error "set striped dir error"
22726         #look at the directories for debug purposes
22727         ls -l $DIR/$tdir
22728         $LFS getdirstripe $DIR/$tdir
22729         ls -l $DIR/$tdir/remote_striped_dir
22730         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22731         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22732                 error "create 10 files failed"
22733
22734         for file in $(find $DIR/$tdir); do
22735                 stripe_count=$($LFS getstripe -c $file)
22736                 [ $stripe_count -eq 2 ] ||
22737                         error "wrong stripe $stripe_count for $file"
22738         done
22739
22740         rm -rf $DIR/$tdir
22741 }
22742 run_test 300d "check default stripe under striped directory"
22743
22744 test_300e() {
22745         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22746                 skip "Need MDS version at least 2.7.55"
22747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22748         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22749
22750         local stripe_count
22751         local file
22752
22753         mkdir -p $DIR/$tdir
22754
22755         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22756                 error "set striped dir error"
22757
22758         touch $DIR/$tdir/striped_dir/a
22759         touch $DIR/$tdir/striped_dir/b
22760         touch $DIR/$tdir/striped_dir/c
22761
22762         mkdir $DIR/$tdir/striped_dir/dir_a
22763         mkdir $DIR/$tdir/striped_dir/dir_b
22764         mkdir $DIR/$tdir/striped_dir/dir_c
22765
22766         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22767                 error "set striped adir under striped dir error"
22768
22769         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22770                 error "set striped bdir under striped dir error"
22771
22772         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22773                 error "set striped cdir under striped dir error"
22774
22775         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22776                 error "rename dir under striped dir fails"
22777
22778         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22779                 error "rename dir under different stripes fails"
22780
22781         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22782                 error "rename file under striped dir should succeed"
22783
22784         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22785                 error "rename dir under striped dir should succeed"
22786
22787         rm -rf $DIR/$tdir
22788 }
22789 run_test 300e "check rename under striped directory"
22790
22791 test_300f() {
22792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22793         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22794         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22795                 skip "Need MDS version at least 2.7.55"
22796
22797         local stripe_count
22798         local file
22799
22800         rm -rf $DIR/$tdir
22801         mkdir -p $DIR/$tdir
22802
22803         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22804                 error "set striped dir error"
22805
22806         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22807                 error "set striped dir error"
22808
22809         touch $DIR/$tdir/striped_dir/a
22810         mkdir $DIR/$tdir/striped_dir/dir_a
22811         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22812                 error "create striped dir under striped dir fails"
22813
22814         touch $DIR/$tdir/striped_dir1/b
22815         mkdir $DIR/$tdir/striped_dir1/dir_b
22816         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22817                 error "create striped dir under striped dir fails"
22818
22819         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22820                 error "rename dir under different striped dir should fail"
22821
22822         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22823                 error "rename striped dir under diff striped dir should fail"
22824
22825         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22826                 error "rename file under diff striped dirs fails"
22827
22828         rm -rf $DIR/$tdir
22829 }
22830 run_test 300f "check rename cross striped directory"
22831
22832 test_300_check_default_striped_dir()
22833 {
22834         local dirname=$1
22835         local default_count=$2
22836         local default_index=$3
22837         local stripe_count
22838         local stripe_index
22839         local dir_stripe_index
22840         local dir
22841
22842         echo "checking $dirname $default_count $default_index"
22843         $LFS setdirstripe -D -c $default_count -i $default_index \
22844                                 -H all_char $DIR/$tdir/$dirname ||
22845                 error "set default stripe on striped dir error"
22846         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22847         [ $stripe_count -eq $default_count ] ||
22848                 error "expect $default_count get $stripe_count for $dirname"
22849
22850         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22851         [ $stripe_index -eq $default_index ] ||
22852                 error "expect $default_index get $stripe_index for $dirname"
22853
22854         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22855                                                 error "create dirs failed"
22856
22857         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22858         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22859         for dir in $(find $DIR/$tdir/$dirname/*); do
22860                 stripe_count=$($LFS getdirstripe -c $dir)
22861                 (( $stripe_count == $default_count )) ||
22862                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22863                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22864                 error "stripe count $default_count != $stripe_count for $dir"
22865
22866                 stripe_index=$($LFS getdirstripe -i $dir)
22867                 [ $default_index -eq -1 ] ||
22868                         [ $stripe_index -eq $default_index ] ||
22869                         error "$stripe_index != $default_index for $dir"
22870
22871                 #check default stripe
22872                 stripe_count=$($LFS getdirstripe -D -c $dir)
22873                 [ $stripe_count -eq $default_count ] ||
22874                 error "default count $default_count != $stripe_count for $dir"
22875
22876                 stripe_index=$($LFS getdirstripe -D -i $dir)
22877                 [ $stripe_index -eq $default_index ] ||
22878                 error "default index $default_index != $stripe_index for $dir"
22879         done
22880         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22881 }
22882
22883 test_300g() {
22884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22885         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22886                 skip "Need MDS version at least 2.7.55"
22887
22888         local dir
22889         local stripe_count
22890         local stripe_index
22891
22892         mkdir_on_mdt0 $DIR/$tdir
22893         mkdir $DIR/$tdir/normal_dir
22894
22895         #Checking when client cache stripe index
22896         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22897         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22898                 error "create striped_dir failed"
22899
22900         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22901                 error "create dir0 fails"
22902         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22903         [ $stripe_index -eq 0 ] ||
22904                 error "dir0 expect index 0 got $stripe_index"
22905
22906         mkdir $DIR/$tdir/striped_dir/dir1 ||
22907                 error "create dir1 fails"
22908         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22909         [ $stripe_index -eq 1 ] ||
22910                 error "dir1 expect index 1 got $stripe_index"
22911
22912         #check default stripe count/stripe index
22913         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22914         test_300_check_default_striped_dir normal_dir 1 0
22915         test_300_check_default_striped_dir normal_dir -1 1
22916         test_300_check_default_striped_dir normal_dir 2 -1
22917
22918         #delete default stripe information
22919         echo "delete default stripeEA"
22920         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22921                 error "set default stripe on striped dir error"
22922
22923         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22924         for dir in $(find $DIR/$tdir/normal_dir/*); do
22925                 stripe_count=$($LFS getdirstripe -c $dir)
22926                 [ $stripe_count -eq 0 ] ||
22927                         error "expect 1 get $stripe_count for $dir"
22928         done
22929 }
22930 run_test 300g "check default striped directory for normal directory"
22931
22932 test_300h() {
22933         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22934         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22935                 skip "Need MDS version at least 2.7.55"
22936
22937         local dir
22938         local stripe_count
22939
22940         mkdir $DIR/$tdir
22941         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22942                 error "set striped dir error"
22943
22944         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22945         test_300_check_default_striped_dir striped_dir 1 0
22946         test_300_check_default_striped_dir striped_dir -1 1
22947         test_300_check_default_striped_dir striped_dir 2 -1
22948
22949         #delete default stripe information
22950         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22951                 error "set default stripe on striped dir error"
22952
22953         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22954         for dir in $(find $DIR/$tdir/striped_dir/*); do
22955                 stripe_count=$($LFS getdirstripe -c $dir)
22956                 [ $stripe_count -eq 0 ] ||
22957                         error "expect 1 get $stripe_count for $dir"
22958         done
22959 }
22960 run_test 300h "check default striped directory for striped directory"
22961
22962 test_300i() {
22963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22964         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22965         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22966                 skip "Need MDS version at least 2.7.55"
22967
22968         local stripe_count
22969         local file
22970
22971         mkdir $DIR/$tdir
22972
22973         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22974                 error "set striped dir error"
22975
22976         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22977                 error "create files under striped dir failed"
22978
22979         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22980                 error "set striped hashdir error"
22981
22982         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22983                 error "create dir0 under hash dir failed"
22984         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22985                 error "create dir1 under hash dir failed"
22986         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22987                 error "create dir2 under hash dir failed"
22988
22989         # unfortunately, we need to umount to clear dir layout cache for now
22990         # once we fully implement dir layout, we can drop this
22991         umount_client $MOUNT || error "umount failed"
22992         mount_client $MOUNT || error "mount failed"
22993
22994         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22995         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22996         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22997
22998         #set the stripe to be unknown hash type
22999         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23000         $LCTL set_param fail_loc=0x1901
23001         for ((i = 0; i < 10; i++)); do
23002                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23003                         error "stat f-$i failed"
23004                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23005         done
23006
23007         touch $DIR/$tdir/striped_dir/f0 &&
23008                 error "create under striped dir with unknown hash should fail"
23009
23010         $LCTL set_param fail_loc=0
23011
23012         umount_client $MOUNT || error "umount failed"
23013         mount_client $MOUNT || error "mount failed"
23014
23015         return 0
23016 }
23017 run_test 300i "client handle unknown hash type striped directory"
23018
23019 test_300j() {
23020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23022         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23023                 skip "Need MDS version at least 2.7.55"
23024
23025         local stripe_count
23026         local file
23027
23028         mkdir $DIR/$tdir
23029
23030         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23031         $LCTL set_param fail_loc=0x1702
23032         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23033                 error "set striped dir error"
23034
23035         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23036                 error "create files under striped dir failed"
23037
23038         $LCTL set_param fail_loc=0
23039
23040         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23041
23042         return 0
23043 }
23044 run_test 300j "test large update record"
23045
23046 test_300k() {
23047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23049         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23050                 skip "Need MDS version at least 2.7.55"
23051
23052         # this test needs a huge transaction
23053         local kb
23054         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23055              osd*.$FSNAME-MDT0000.kbytestotal")
23056         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23057
23058         local stripe_count
23059         local file
23060
23061         mkdir $DIR/$tdir
23062
23063         #define OBD_FAIL_LARGE_STRIPE   0x1703
23064         $LCTL set_param fail_loc=0x1703
23065         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23066                 error "set striped dir error"
23067         $LCTL set_param fail_loc=0
23068
23069         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23070                 error "getstripeddir fails"
23071         rm -rf $DIR/$tdir/striped_dir ||
23072                 error "unlink striped dir fails"
23073
23074         return 0
23075 }
23076 run_test 300k "test large striped directory"
23077
23078 test_300l() {
23079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23080         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23081         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23082                 skip "Need MDS version at least 2.7.55"
23083
23084         local stripe_index
23085
23086         test_mkdir -p $DIR/$tdir/striped_dir
23087         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23088                         error "chown $RUNAS_ID failed"
23089         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23090                 error "set default striped dir failed"
23091
23092         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23093         $LCTL set_param fail_loc=0x80000158
23094         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23095
23096         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23097         [ $stripe_index -eq 1 ] ||
23098                 error "expect 1 get $stripe_index for $dir"
23099 }
23100 run_test 300l "non-root user to create dir under striped dir with stale layout"
23101
23102 test_300m() {
23103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23104         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23105         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23106                 skip "Need MDS version at least 2.7.55"
23107
23108         mkdir -p $DIR/$tdir/striped_dir
23109         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23110                 error "set default stripes dir error"
23111
23112         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23113
23114         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23115         [ $stripe_count -eq 0 ] ||
23116                         error "expect 0 get $stripe_count for a"
23117
23118         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23119                 error "set default stripes dir error"
23120
23121         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23122
23123         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23124         [ $stripe_count -eq 0 ] ||
23125                         error "expect 0 get $stripe_count for b"
23126
23127         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23128                 error "set default stripes dir error"
23129
23130         mkdir $DIR/$tdir/striped_dir/c &&
23131                 error "default stripe_index is invalid, mkdir c should fails"
23132
23133         rm -rf $DIR/$tdir || error "rmdir fails"
23134 }
23135 run_test 300m "setstriped directory on single MDT FS"
23136
23137 cleanup_300n() {
23138         local list=$(comma_list $(mdts_nodes))
23139
23140         trap 0
23141         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23142 }
23143
23144 test_300n() {
23145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23146         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23147         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23148                 skip "Need MDS version at least 2.7.55"
23149         remote_mds_nodsh && skip "remote MDS with nodsh"
23150
23151         local stripe_index
23152         local list=$(comma_list $(mdts_nodes))
23153
23154         trap cleanup_300n RETURN EXIT
23155         mkdir -p $DIR/$tdir
23156         chmod 777 $DIR/$tdir
23157         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23158                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23159                 error "create striped dir succeeds with gid=0"
23160
23161         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23162         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23163                 error "create striped dir fails with gid=-1"
23164
23165         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23166         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23167                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23168                 error "set default striped dir succeeds with gid=0"
23169
23170
23171         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23172         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23173                 error "set default striped dir fails with gid=-1"
23174
23175
23176         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23177         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23178                                         error "create test_dir fails"
23179         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23180                                         error "create test_dir1 fails"
23181         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23182                                         error "create test_dir2 fails"
23183         cleanup_300n
23184 }
23185 run_test 300n "non-root user to create dir under striped dir with default EA"
23186
23187 test_300o() {
23188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23189         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23190         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23191                 skip "Need MDS version at least 2.7.55"
23192
23193         local numfree1
23194         local numfree2
23195
23196         mkdir -p $DIR/$tdir
23197
23198         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23199         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23200         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23201                 skip "not enough free inodes $numfree1 $numfree2"
23202         fi
23203
23204         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23205         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23206         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23207                 skip "not enough free space $numfree1 $numfree2"
23208         fi
23209
23210         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23211                 error "setdirstripe fails"
23212
23213         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23214                 error "create dirs fails"
23215
23216         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23217         ls $DIR/$tdir/striped_dir > /dev/null ||
23218                 error "ls striped dir fails"
23219         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23220                 error "unlink big striped dir fails"
23221 }
23222 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23223
23224 test_300p() {
23225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23226         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23227         remote_mds_nodsh && skip "remote MDS with nodsh"
23228
23229         mkdir_on_mdt0 $DIR/$tdir
23230
23231         #define OBD_FAIL_OUT_ENOSPC     0x1704
23232         do_facet mds2 lctl set_param fail_loc=0x80001704
23233         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23234                  && error "create striped directory should fail"
23235
23236         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23237
23238         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23239         true
23240 }
23241 run_test 300p "create striped directory without space"
23242
23243 test_300q() {
23244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23245         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23246
23247         local fd=$(free_fd)
23248         local cmd="exec $fd<$tdir"
23249         cd $DIR
23250         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23251         eval $cmd
23252         cmd="exec $fd<&-"
23253         trap "eval $cmd" EXIT
23254         cd $tdir || error "cd $tdir fails"
23255         rmdir  ../$tdir || error "rmdir $tdir fails"
23256         mkdir local_dir && error "create dir succeeds"
23257         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23258         eval $cmd
23259         return 0
23260 }
23261 run_test 300q "create remote directory under orphan directory"
23262
23263 test_300r() {
23264         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23265                 skip "Need MDS version at least 2.7.55" && return
23266         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23267
23268         mkdir $DIR/$tdir
23269
23270         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23271                 error "set striped dir error"
23272
23273         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23274                 error "getstripeddir fails"
23275
23276         local stripe_count
23277         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23278                       awk '/lmv_stripe_count:/ { print $2 }')
23279
23280         [ $MDSCOUNT -ne $stripe_count ] &&
23281                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23282
23283         rm -rf $DIR/$tdir/striped_dir ||
23284                 error "unlink striped dir fails"
23285 }
23286 run_test 300r "test -1 striped directory"
23287
23288 test_300s_helper() {
23289         local count=$1
23290
23291         local stripe_dir=$DIR/$tdir/striped_dir.$count
23292
23293         $LFS mkdir -c $count $stripe_dir ||
23294                 error "lfs mkdir -c error"
23295
23296         $LFS getdirstripe $stripe_dir ||
23297                 error "lfs getdirstripe fails"
23298
23299         local stripe_count
23300         stripe_count=$($LFS getdirstripe $stripe_dir |
23301                       awk '/lmv_stripe_count:/ { print $2 }')
23302
23303         [ $count -ne $stripe_count ] &&
23304                 error_noexit "bad stripe count $stripe_count expected $count"
23305
23306         local dupe_stripes
23307         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23308                 awk '/0x/ {count[$1] += 1}; END {
23309                         for (idx in count) {
23310                                 if (count[idx]>1) {
23311                                         print "index " idx " count " count[idx]
23312                                 }
23313                         }
23314                 }')
23315
23316         if [[ -n "$dupe_stripes" ]] ; then
23317                 lfs getdirstripe $stripe_dir
23318                 error_noexit "Dupe MDT above: $dupe_stripes "
23319         fi
23320
23321         rm -rf $stripe_dir ||
23322                 error_noexit "unlink $stripe_dir fails"
23323 }
23324
23325 test_300s() {
23326         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23327                 skip "Need MDS version at least 2.7.55" && return
23328         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23329
23330         mkdir $DIR/$tdir
23331         for count in $(seq 2 $MDSCOUNT); do
23332                 test_300s_helper $count
23333         done
23334 }
23335 run_test 300s "test lfs mkdir -c without -i"
23336
23337
23338 prepare_remote_file() {
23339         mkdir $DIR/$tdir/src_dir ||
23340                 error "create remote source failed"
23341
23342         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23343                  error "cp to remote source failed"
23344         touch $DIR/$tdir/src_dir/a
23345
23346         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23347                 error "create remote target dir failed"
23348
23349         touch $DIR/$tdir/tgt_dir/b
23350
23351         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23352                 error "rename dir cross MDT failed!"
23353
23354         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23355                 error "src_child still exists after rename"
23356
23357         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23358                 error "missing file(a) after rename"
23359
23360         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23361                 error "diff after rename"
23362 }
23363
23364 test_310a() {
23365         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23367
23368         local remote_file=$DIR/$tdir/tgt_dir/b
23369
23370         mkdir -p $DIR/$tdir
23371
23372         prepare_remote_file || error "prepare remote file failed"
23373
23374         #open-unlink file
23375         $OPENUNLINK $remote_file $remote_file ||
23376                 error "openunlink $remote_file failed"
23377         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23378 }
23379 run_test 310a "open unlink remote file"
23380
23381 test_310b() {
23382         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23384
23385         local remote_file=$DIR/$tdir/tgt_dir/b
23386
23387         mkdir -p $DIR/$tdir
23388
23389         prepare_remote_file || error "prepare remote file failed"
23390
23391         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23392         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23393         $CHECKSTAT -t file $remote_file || error "check file failed"
23394 }
23395 run_test 310b "unlink remote file with multiple links while open"
23396
23397 test_310c() {
23398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23399         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23400
23401         local remote_file=$DIR/$tdir/tgt_dir/b
23402
23403         mkdir -p $DIR/$tdir
23404
23405         prepare_remote_file || error "prepare remote file failed"
23406
23407         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23408         multiop_bg_pause $remote_file O_uc ||
23409                         error "mulitop failed for remote file"
23410         MULTIPID=$!
23411         $MULTIOP $DIR/$tfile Ouc
23412         kill -USR1 $MULTIPID
23413         wait $MULTIPID
23414 }
23415 run_test 310c "open-unlink remote file with multiple links"
23416
23417 #LU-4825
23418 test_311() {
23419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23420         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23421         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23422                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23423         remote_mds_nodsh && skip "remote MDS with nodsh"
23424
23425         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23426         local mdts=$(comma_list $(mdts_nodes))
23427
23428         mkdir -p $DIR/$tdir
23429         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23430         createmany -o $DIR/$tdir/$tfile. 1000
23431
23432         # statfs data is not real time, let's just calculate it
23433         old_iused=$((old_iused + 1000))
23434
23435         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23436                         osp.*OST0000*MDT0000.create_count")
23437         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23438                                 osp.*OST0000*MDT0000.max_create_count")
23439         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23440
23441         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23442         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23443         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23444
23445         unlinkmany $DIR/$tdir/$tfile. 1000
23446
23447         do_nodes $mdts "$LCTL set_param -n \
23448                         osp.*OST0000*.max_create_count=$max_count"
23449         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23450                 do_nodes $mdts "$LCTL set_param -n \
23451                                 osp.*OST0000*.create_count=$count"
23452         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23453                         grep "=0" && error "create_count is zero"
23454
23455         local new_iused
23456         for i in $(seq 120); do
23457                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23458                 # system may be too busy to destroy all objs in time, use
23459                 # a somewhat small value to not fail autotest
23460                 [ $((old_iused - new_iused)) -gt 400 ] && break
23461                 sleep 1
23462         done
23463
23464         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23465         [ $((old_iused - new_iused)) -gt 400 ] ||
23466                 error "objs not destroyed after unlink"
23467 }
23468 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23469
23470 zfs_oid_to_objid()
23471 {
23472         local ost=$1
23473         local objid=$2
23474
23475         local vdevdir=$(dirname $(facet_vdevice $ost))
23476         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23477         local zfs_zapid=$(do_facet $ost $cmd |
23478                           grep -w "/O/0/d$((objid%32))" -C 5 |
23479                           awk '/Object/{getline; print $1}')
23480         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23481                           awk "/$objid = /"'{printf $3}')
23482
23483         echo $zfs_objid
23484 }
23485
23486 zfs_object_blksz() {
23487         local ost=$1
23488         local objid=$2
23489
23490         local vdevdir=$(dirname $(facet_vdevice $ost))
23491         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23492         local blksz=$(do_facet $ost $cmd $objid |
23493                       awk '/dblk/{getline; printf $4}')
23494
23495         case "${blksz: -1}" in
23496                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23497                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23498                 *) ;;
23499         esac
23500
23501         echo $blksz
23502 }
23503
23504 test_312() { # LU-4856
23505         remote_ost_nodsh && skip "remote OST with nodsh"
23506         [ "$ost1_FSTYPE" = "zfs" ] ||
23507                 skip_env "the test only applies to zfs"
23508
23509         local max_blksz=$(do_facet ost1 \
23510                           $ZFS get -p recordsize $(facet_device ost1) |
23511                           awk '!/VALUE/{print $3}')
23512
23513         # to make life a little bit easier
23514         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23515         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23516
23517         local tf=$DIR/$tdir/$tfile
23518         touch $tf
23519         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23520
23521         # Get ZFS object id
23522         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23523         # block size change by sequential overwrite
23524         local bs
23525
23526         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23527                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23528
23529                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23530                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23531         done
23532         rm -f $tf
23533
23534         # block size change by sequential append write
23535         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23536         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23537         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23538         local count
23539
23540         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23541                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23542                         oflag=sync conv=notrunc
23543
23544                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23545                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23546                         error "blksz error, actual $blksz, " \
23547                                 "expected: 2 * $count * $PAGE_SIZE"
23548         done
23549         rm -f $tf
23550
23551         # random write
23552         touch $tf
23553         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23554         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23555
23556         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23557         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23558         [ $blksz -eq $PAGE_SIZE ] ||
23559                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23560
23561         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23562         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23563         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23564
23565         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23566         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23567         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23568 }
23569 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23570
23571 test_313() {
23572         remote_ost_nodsh && skip "remote OST with nodsh"
23573
23574         local file=$DIR/$tfile
23575
23576         rm -f $file
23577         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23578
23579         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23580         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23581         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23582                 error "write should failed"
23583         do_facet ost1 "$LCTL set_param fail_loc=0"
23584         rm -f $file
23585 }
23586 run_test 313 "io should fail after last_rcvd update fail"
23587
23588 test_314() {
23589         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23590
23591         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23592         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23593         rm -f $DIR/$tfile
23594         wait_delete_completed
23595         do_facet ost1 "$LCTL set_param fail_loc=0"
23596 }
23597 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23598
23599 test_315() { # LU-618
23600         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23601
23602         local file=$DIR/$tfile
23603         rm -f $file
23604
23605         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23606                 error "multiop file write failed"
23607         $MULTIOP $file oO_RDONLY:r4063232_c &
23608         PID=$!
23609
23610         sleep 2
23611
23612         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23613         kill -USR1 $PID
23614
23615         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23616         rm -f $file
23617 }
23618 run_test 315 "read should be accounted"
23619
23620 test_316() {
23621         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23622         large_xattr_enabled || skip_env "ea_inode feature disabled"
23623
23624         rm -rf $DIR/$tdir/d
23625         mkdir -p $DIR/$tdir/d
23626         chown nobody $DIR/$tdir/d
23627         touch $DIR/$tdir/d/file
23628
23629         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23630 }
23631 run_test 316 "lfs mv"
23632
23633 test_317() {
23634         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23635                 skip "Need MDS version at least 2.11.53"
23636         if [ "$ost1_FSTYPE" == "zfs" ]; then
23637                 skip "LU-10370: no implementation for ZFS"
23638         fi
23639
23640         local trunc_sz
23641         local grant_blk_size
23642
23643         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23644                         awk '/grant_block_size:/ { print $2; exit; }')
23645         #
23646         # Create File of size 5M. Truncate it to below size's and verify
23647         # blocks count.
23648         #
23649         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23650                 error "Create file $DIR/$tfile failed"
23651         stack_trap "rm -f $DIR/$tfile" EXIT
23652
23653         for trunc_sz in 2097152 4097 4000 509 0; do
23654                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23655                         error "truncate $tfile to $trunc_sz failed"
23656                 local sz=$(stat --format=%s $DIR/$tfile)
23657                 local blk=$(stat --format=%b $DIR/$tfile)
23658                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23659                                      grant_blk_size) * 8))
23660
23661                 if [[ $blk -ne $trunc_blk ]]; then
23662                         $(which stat) $DIR/$tfile
23663                         error "Expected Block $trunc_blk got $blk for $tfile"
23664                 fi
23665
23666                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23667                         error "Expected Size $trunc_sz got $sz for $tfile"
23668         done
23669
23670         #
23671         # sparse file test
23672         # Create file with a hole and write actual two blocks. Block count
23673         # must be 16.
23674         #
23675         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23676                 conv=fsync || error "Create file : $DIR/$tfile"
23677
23678         # Calculate the final truncate size.
23679         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23680
23681         #
23682         # truncate to size $trunc_sz bytes. Strip the last block
23683         # The block count must drop to 8
23684         #
23685         $TRUNCATE $DIR/$tfile $trunc_sz ||
23686                 error "truncate $tfile to $trunc_sz failed"
23687
23688         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23689         sz=$(stat --format=%s $DIR/$tfile)
23690         blk=$(stat --format=%b $DIR/$tfile)
23691
23692         if [[ $blk -ne $trunc_bsz ]]; then
23693                 $(which stat) $DIR/$tfile
23694                 error "Expected Block $trunc_bsz got $blk for $tfile"
23695         fi
23696
23697         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23698                 error "Expected Size $trunc_sz got $sz for $tfile"
23699 }
23700 run_test 317 "Verify blocks get correctly update after truncate"
23701
23702 test_318() {
23703         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23704         local old_max_active=$($LCTL get_param -n \
23705                             ${llite_name}.max_read_ahead_async_active \
23706                             2>/dev/null)
23707
23708         $LCTL set_param llite.*.max_read_ahead_async_active=256
23709         local max_active=$($LCTL get_param -n \
23710                            ${llite_name}.max_read_ahead_async_active \
23711                            2>/dev/null)
23712         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23713
23714         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23715                 error "set max_read_ahead_async_active should succeed"
23716
23717         $LCTL set_param llite.*.max_read_ahead_async_active=512
23718         max_active=$($LCTL get_param -n \
23719                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23720         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23721
23722         # restore @max_active
23723         [ $old_max_active -ne 0 ] && $LCTL set_param \
23724                 llite.*.max_read_ahead_async_active=$old_max_active
23725
23726         local old_threshold=$($LCTL get_param -n \
23727                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23728         local max_per_file_mb=$($LCTL get_param -n \
23729                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23730
23731         local invalid=$(($max_per_file_mb + 1))
23732         $LCTL set_param \
23733                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23734                         && error "set $invalid should fail"
23735
23736         local valid=$(($invalid - 1))
23737         $LCTL set_param \
23738                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23739                         error "set $valid should succeed"
23740         local threshold=$($LCTL get_param -n \
23741                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23742         [ $threshold -eq $valid ] || error \
23743                 "expect threshold $valid got $threshold"
23744         $LCTL set_param \
23745                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23746 }
23747 run_test 318 "Verify async readahead tunables"
23748
23749 test_319() {
23750         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23751
23752         local before=$(date +%s)
23753         local evict
23754         local mdir=$DIR/$tdir
23755         local file=$mdir/xxx
23756
23757         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23758         touch $file
23759
23760 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23761         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23762         $LFS mv -m1 $file &
23763
23764         sleep 1
23765         dd if=$file of=/dev/null
23766         wait
23767         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23768           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23769
23770         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23771 }
23772 run_test 319 "lost lease lock on migrate error"
23773
23774 test_398a() { # LU-4198
23775         local ost1_imp=$(get_osc_import_name client ost1)
23776         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23777                          cut -d'.' -f2)
23778
23779         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23780         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23781
23782         # request a new lock on client
23783         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23784
23785         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23786         local lock_count=$($LCTL get_param -n \
23787                            ldlm.namespaces.$imp_name.lru_size)
23788         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23789
23790         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23791
23792         # no lock cached, should use lockless IO and not enqueue new lock
23793         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23794         lock_count=$($LCTL get_param -n \
23795                      ldlm.namespaces.$imp_name.lru_size)
23796         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23797 }
23798 run_test 398a "direct IO should cancel lock otherwise lockless"
23799
23800 test_398b() { # LU-4198
23801         which fio || skip_env "no fio installed"
23802         $LFS setstripe -c -1 $DIR/$tfile
23803
23804         local size=12
23805         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23806
23807         local njobs=4
23808         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23809         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23810                 --numjobs=$njobs --fallocate=none \
23811                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23812                 --filename=$DIR/$tfile &
23813         bg_pid=$!
23814
23815         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23816         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23817                 --numjobs=$njobs --fallocate=none \
23818                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23819                 --filename=$DIR/$tfile || true
23820         wait $bg_pid
23821
23822         rm -f $DIR/$tfile
23823 }
23824 run_test 398b "DIO and buffer IO race"
23825
23826 test_398c() { # LU-4198
23827         local ost1_imp=$(get_osc_import_name client ost1)
23828         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23829                          cut -d'.' -f2)
23830
23831         which fio || skip_env "no fio installed"
23832
23833         saved_debug=$($LCTL get_param -n debug)
23834         $LCTL set_param debug=0
23835
23836         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23837         ((size /= 1024)) # by megabytes
23838         ((size /= 2)) # write half of the OST at most
23839         [ $size -gt 40 ] && size=40 #reduce test time anyway
23840
23841         $LFS setstripe -c 1 $DIR/$tfile
23842
23843         # it seems like ldiskfs reserves more space than necessary if the
23844         # writing blocks are not mapped, so it extends the file firstly
23845         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23846         cancel_lru_locks osc
23847
23848         # clear and verify rpc_stats later
23849         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23850
23851         local njobs=4
23852         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23853         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23854                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23855                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23856                 --filename=$DIR/$tfile
23857         [ $? -eq 0 ] || error "fio write error"
23858
23859         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23860                 error "Locks were requested while doing AIO"
23861
23862         # get the percentage of 1-page I/O
23863         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23864                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23865                 awk '{print $7}')
23866         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23867
23868         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23869         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23870                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23871                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23872                 --filename=$DIR/$tfile
23873         [ $? -eq 0 ] || error "fio mixed read write error"
23874
23875         echo "AIO with large block size ${size}M"
23876         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23877                 --numjobs=1 --fallocate=none --ioengine=libaio \
23878                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23879                 --filename=$DIR/$tfile
23880         [ $? -eq 0 ] || error "fio large block size failed"
23881
23882         rm -f $DIR/$tfile
23883         $LCTL set_param debug="$saved_debug"
23884 }
23885 run_test 398c "run fio to test AIO"
23886
23887 test_398d() { #  LU-13846
23888         which aiocp || skip_env "no aiocp installed"
23889         local aio_file=$DIR/$tfile.aio
23890
23891         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23892
23893         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23894         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23895         stack_trap "rm -f $DIR/$tfile $aio_file"
23896
23897         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23898
23899         # make sure we don't crash and fail properly
23900         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23901                 error "aio not aligned with PAGE SIZE should fail"
23902
23903         rm -f $DIR/$tfile $aio_file
23904 }
23905 run_test 398d "run aiocp to verify block size > stripe size"
23906
23907 test_398e() {
23908         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23909         touch $DIR/$tfile.new
23910         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23911 }
23912 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23913
23914 test_398f() { #  LU-14687
23915         which aiocp || skip_env "no aiocp installed"
23916         local aio_file=$DIR/$tfile.aio
23917
23918         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23919
23920         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23921         stack_trap "rm -f $DIR/$tfile $aio_file"
23922
23923         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23924         $LCTL set_param fail_loc=0x1418
23925         # make sure we don't crash and fail properly
23926         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23927                 error "aio with page allocation failure succeeded"
23928         $LCTL set_param fail_loc=0
23929         diff $DIR/$tfile $aio_file
23930         [[ $? != 0 ]] || error "no diff after failed aiocp"
23931 }
23932 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23933
23934 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23935 # stripe and i/o size must be > stripe size
23936 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23937 # single RPC in flight.  This test shows async DIO submission is working by
23938 # showing multiple RPCs in flight.
23939 test_398g() { #  LU-13798
23940         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23941
23942         # We need to do some i/o first to acquire enough grant to put our RPCs
23943         # in flight; otherwise a new connection may not have enough grant
23944         # available
23945         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23946                 error "parallel dio failed"
23947         stack_trap "rm -f $DIR/$tfile"
23948
23949         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23950         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23951         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23952         stack_trap "$LCTL set_param -n $pages_per_rpc"
23953
23954         # Recreate file so it's empty
23955         rm -f $DIR/$tfile
23956         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23957         #Pause rpc completion to guarantee we see multiple rpcs in flight
23958         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23959         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23960         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23961
23962         # Clear rpc stats
23963         $LCTL set_param osc.*.rpc_stats=c
23964
23965         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23966                 error "parallel dio failed"
23967         stack_trap "rm -f $DIR/$tfile"
23968
23969         $LCTL get_param osc.*-OST0000-*.rpc_stats
23970         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23971                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23972                 grep "8:" | awk '{print $8}')
23973         # We look at the "8 rpcs in flight" field, and verify A) it is present
23974         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23975         # as expected for an 8M DIO to a file with 1M stripes.
23976         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23977
23978         # Verify turning off parallel dio works as expected
23979         # Clear rpc stats
23980         $LCTL set_param osc.*.rpc_stats=c
23981         $LCTL set_param llite.*.parallel_dio=0
23982         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23983
23984         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23985                 error "dio with parallel dio disabled failed"
23986
23987         # Ideally, we would see only one RPC in flight here, but there is an
23988         # unavoidable race between i/o completion and RPC in flight counting,
23989         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23990         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23991         # So instead we just verify it's always < 8.
23992         $LCTL get_param osc.*-OST0000-*.rpc_stats
23993         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23994                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23995                 grep '^$' -B1 | grep . | awk '{print $1}')
23996         [ $ret != "8:" ] ||
23997                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23998 }
23999 run_test 398g "verify parallel dio async RPC submission"
24000
24001 test_398h() { #  LU-13798
24002         local dio_file=$DIR/$tfile.dio
24003
24004         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24005
24006         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24007         stack_trap "rm -f $DIR/$tfile $dio_file"
24008
24009         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24010                 error "parallel dio failed"
24011         diff $DIR/$tfile $dio_file
24012         [[ $? == 0 ]] || error "file diff after aiocp"
24013 }
24014 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24015
24016 test_398i() { #  LU-13798
24017         local dio_file=$DIR/$tfile.dio
24018
24019         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24020
24021         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24022         stack_trap "rm -f $DIR/$tfile $dio_file"
24023
24024         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24025         $LCTL set_param fail_loc=0x1418
24026         # make sure we don't crash and fail properly
24027         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24028                 error "parallel dio page allocation failure succeeded"
24029         diff $DIR/$tfile $dio_file
24030         [[ $? != 0 ]] || error "no diff after failed aiocp"
24031 }
24032 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24033
24034 test_398j() { #  LU-13798
24035         # Stripe size > RPC size but less than i/o size tests split across
24036         # stripes and RPCs for individual i/o op
24037         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24038
24039         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24040         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24041         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24042         stack_trap "$LCTL set_param -n $pages_per_rpc"
24043
24044         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24045                 error "parallel dio write failed"
24046         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24047
24048         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24049                 error "parallel dio read failed"
24050         diff $DIR/$tfile $DIR/$tfile.2
24051         [[ $? == 0 ]] || error "file diff after parallel dio read"
24052 }
24053 run_test 398j "test parallel dio where stripe size > rpc_size"
24054
24055 test_398k() { #  LU-13798
24056         wait_delete_completed
24057         wait_mds_ost_sync
24058
24059         # 4 stripe file; we will cause out of space on OST0
24060         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24061
24062         # Fill OST0 (if it's not too large)
24063         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24064                    head -n1)
24065         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24066                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24067         fi
24068         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24069         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24070                 error "dd should fill OST0"
24071         stack_trap "rm -f $DIR/$tfile.1"
24072
24073         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24074         err=$?
24075
24076         ls -la $DIR/$tfile
24077         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24078                 error "file is not 0 bytes in size"
24079
24080         # dd above should not succeed, but don't error until here so we can
24081         # get debug info above
24082         [[ $err != 0 ]] ||
24083                 error "parallel dio write with enospc succeeded"
24084         stack_trap "rm -f $DIR/$tfile"
24085 }
24086 run_test 398k "test enospc on first stripe"
24087
24088 test_398l() { #  LU-13798
24089         wait_delete_completed
24090         wait_mds_ost_sync
24091
24092         # 4 stripe file; we will cause out of space on OST0
24093         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24094         # happens on the second i/o chunk we issue
24095         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24096
24097         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24098         stack_trap "rm -f $DIR/$tfile"
24099
24100         # Fill OST0 (if it's not too large)
24101         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24102                    head -n1)
24103         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24104                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24105         fi
24106         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24107         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24108                 error "dd should fill OST0"
24109         stack_trap "rm -f $DIR/$tfile.1"
24110
24111         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24112         err=$?
24113         stack_trap "rm -f $DIR/$tfile.2"
24114
24115         # Check that short write completed as expected
24116         ls -la $DIR/$tfile.2
24117         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24118                 error "file is not 1M in size"
24119
24120         # dd above should not succeed, but don't error until here so we can
24121         # get debug info above
24122         [[ $err != 0 ]] ||
24123                 error "parallel dio write with enospc succeeded"
24124
24125         # Truncate source file to same length as output file and diff them
24126         $TRUNCATE $DIR/$tfile 1048576
24127         diff $DIR/$tfile $DIR/$tfile.2
24128         [[ $? == 0 ]] || error "data incorrect after short write"
24129 }
24130 run_test 398l "test enospc on intermediate stripe/RPC"
24131
24132 test_398m() { #  LU-13798
24133         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24134
24135         # Set up failure on OST0, the first stripe:
24136         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24137         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24138         # So this fail_val specifies OST0
24139         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24140         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24141
24142         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24143                 error "parallel dio write with failure on first stripe succeeded"
24144         stack_trap "rm -f $DIR/$tfile"
24145         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24146
24147         # Place data in file for read
24148         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24149                 error "parallel dio write failed"
24150
24151         # Fail read on OST0, first stripe
24152         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24153         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24154         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24155                 error "parallel dio read with error on first stripe succeeded"
24156         rm -f $DIR/$tfile.2
24157         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24158
24159         # Switch to testing on OST1, second stripe
24160         # Clear file contents, maintain striping
24161         echo > $DIR/$tfile
24162         # Set up failure on OST1, second stripe:
24163         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24164         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24165
24166         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24167                 error "parallel dio write with failure on first stripe succeeded"
24168         stack_trap "rm -f $DIR/$tfile"
24169         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24170
24171         # Place data in file for read
24172         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24173                 error "parallel dio write failed"
24174
24175         # Fail read on OST1, second stripe
24176         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24177         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24178         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24179                 error "parallel dio read with error on first stripe succeeded"
24180         rm -f $DIR/$tfile.2
24181         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24182 }
24183 run_test 398m "test RPC failures with parallel dio"
24184
24185 # Parallel submission of DIO should not cause problems for append, but it's
24186 # important to verify.
24187 test_398n() { #  LU-13798
24188         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24189
24190         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24191                 error "dd to create source file failed"
24192         stack_trap "rm -f $DIR/$tfile"
24193
24194         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24195                 error "parallel dio write with failure on second stripe succeeded"
24196         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24197         diff $DIR/$tfile $DIR/$tfile.1
24198         [[ $? == 0 ]] || error "data incorrect after append"
24199
24200 }
24201 run_test 398n "test append with parallel DIO"
24202
24203 test_fake_rw() {
24204         local read_write=$1
24205         if [ "$read_write" = "write" ]; then
24206                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24207         elif [ "$read_write" = "read" ]; then
24208                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24209         else
24210                 error "argument error"
24211         fi
24212
24213         # turn off debug for performance testing
24214         local saved_debug=$($LCTL get_param -n debug)
24215         $LCTL set_param debug=0
24216
24217         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24218
24219         # get ost1 size - $FSNAME-OST0000
24220         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24221         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24222         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24223
24224         if [ "$read_write" = "read" ]; then
24225                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24226         fi
24227
24228         local start_time=$(date +%s.%N)
24229         $dd_cmd bs=1M count=$blocks oflag=sync ||
24230                 error "real dd $read_write error"
24231         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24232
24233         if [ "$read_write" = "write" ]; then
24234                 rm -f $DIR/$tfile
24235         fi
24236
24237         # define OBD_FAIL_OST_FAKE_RW           0x238
24238         do_facet ost1 $LCTL set_param fail_loc=0x238
24239
24240         local start_time=$(date +%s.%N)
24241         $dd_cmd bs=1M count=$blocks oflag=sync ||
24242                 error "fake dd $read_write error"
24243         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24244
24245         if [ "$read_write" = "write" ]; then
24246                 # verify file size
24247                 cancel_lru_locks osc
24248                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24249                         error "$tfile size not $blocks MB"
24250         fi
24251         do_facet ost1 $LCTL set_param fail_loc=0
24252
24253         echo "fake $read_write $duration_fake vs. normal $read_write" \
24254                 "$duration in seconds"
24255         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24256                 error_not_in_vm "fake write is slower"
24257
24258         $LCTL set_param -n debug="$saved_debug"
24259         rm -f $DIR/$tfile
24260 }
24261 test_399a() { # LU-7655 for OST fake write
24262         remote_ost_nodsh && skip "remote OST with nodsh"
24263
24264         test_fake_rw write
24265 }
24266 run_test 399a "fake write should not be slower than normal write"
24267
24268 test_399b() { # LU-8726 for OST fake read
24269         remote_ost_nodsh && skip "remote OST with nodsh"
24270         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24271                 skip_env "ldiskfs only test"
24272         fi
24273
24274         test_fake_rw read
24275 }
24276 run_test 399b "fake read should not be slower than normal read"
24277
24278 test_400a() { # LU-1606, was conf-sanity test_74
24279         if ! which $CC > /dev/null 2>&1; then
24280                 skip_env "$CC is not installed"
24281         fi
24282
24283         local extra_flags=''
24284         local out=$TMP/$tfile
24285         local prefix=/usr/include/lustre
24286         local prog
24287
24288         # Oleg removes c files in his test rig so test if any c files exist
24289         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24290                 skip_env "Needed c test files are missing"
24291
24292         if ! [[ -d $prefix ]]; then
24293                 # Assume we're running in tree and fixup the include path.
24294                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24295                 extra_flags+=" -L$LUSTRE/utils/.lib"
24296         fi
24297
24298         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24299                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24300                         error "client api broken"
24301         done
24302         rm -f $out
24303 }
24304 run_test 400a "Lustre client api program can compile and link"
24305
24306 test_400b() { # LU-1606, LU-5011
24307         local header
24308         local out=$TMP/$tfile
24309         local prefix=/usr/include/linux/lustre
24310
24311         # We use a hard coded prefix so that this test will not fail
24312         # when run in tree. There are headers in lustre/include/lustre/
24313         # that are not packaged (like lustre_idl.h) and have more
24314         # complicated include dependencies (like config.h and lnet/types.h).
24315         # Since this test about correct packaging we just skip them when
24316         # they don't exist (see below) rather than try to fixup cppflags.
24317
24318         if ! which $CC > /dev/null 2>&1; then
24319                 skip_env "$CC is not installed"
24320         fi
24321
24322         for header in $prefix/*.h; do
24323                 if ! [[ -f "$header" ]]; then
24324                         continue
24325                 fi
24326
24327                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24328                         continue # lustre_ioctl.h is internal header
24329                 fi
24330
24331                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24332                         error "cannot compile '$header'"
24333         done
24334         rm -f $out
24335 }
24336 run_test 400b "packaged headers can be compiled"
24337
24338 test_401a() { #LU-7437
24339         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24340         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24341
24342         #count the number of parameters by "list_param -R"
24343         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24344         #count the number of parameters by listing proc files
24345         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24346         echo "proc_dirs='$proc_dirs'"
24347         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24348         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24349                       sort -u | wc -l)
24350
24351         [ $params -eq $procs ] ||
24352                 error "found $params parameters vs. $procs proc files"
24353
24354         # test the list_param -D option only returns directories
24355         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24356         #count the number of parameters by listing proc directories
24357         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24358                 sort -u | wc -l)
24359
24360         [ $params -eq $procs ] ||
24361                 error "found $params parameters vs. $procs proc files"
24362 }
24363 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24364
24365 test_401b() {
24366         # jobid_var may not allow arbitrary values, so use jobid_name
24367         # if available
24368         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24369                 local testname=jobid_name tmp='testing%p'
24370         else
24371                 local testname=jobid_var tmp=testing
24372         fi
24373
24374         local save=$($LCTL get_param -n $testname)
24375
24376         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24377                 error "no error returned when setting bad parameters"
24378
24379         local jobid_new=$($LCTL get_param -n foe $testname baz)
24380         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24381
24382         $LCTL set_param -n fog=bam $testname=$save bat=fog
24383         local jobid_old=$($LCTL get_param -n foe $testname bag)
24384         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24385 }
24386 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24387
24388 test_401c() {
24389         # jobid_var may not allow arbitrary values, so use jobid_name
24390         # if available
24391         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24392                 local testname=jobid_name
24393         else
24394                 local testname=jobid_var
24395         fi
24396
24397         local jobid_var_old=$($LCTL get_param -n $testname)
24398         local jobid_var_new
24399
24400         $LCTL set_param $testname= &&
24401                 error "no error returned for 'set_param a='"
24402
24403         jobid_var_new=$($LCTL get_param -n $testname)
24404         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24405                 error "$testname was changed by setting without value"
24406
24407         $LCTL set_param $testname &&
24408                 error "no error returned for 'set_param a'"
24409
24410         jobid_var_new=$($LCTL get_param -n $testname)
24411         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24412                 error "$testname was changed by setting without value"
24413 }
24414 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24415
24416 test_401d() {
24417         # jobid_var may not allow arbitrary values, so use jobid_name
24418         # if available
24419         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24420                 local testname=jobid_name new_value='foo=bar%p'
24421         else
24422                 local testname=jobid_var new_valuie=foo=bar
24423         fi
24424
24425         local jobid_var_old=$($LCTL get_param -n $testname)
24426         local jobid_var_new
24427
24428         $LCTL set_param $testname=$new_value ||
24429                 error "'set_param a=b' did not accept a value containing '='"
24430
24431         jobid_var_new=$($LCTL get_param -n $testname)
24432         [[ "$jobid_var_new" == "$new_value" ]] ||
24433                 error "'set_param a=b' failed on a value containing '='"
24434
24435         # Reset the $testname to test the other format
24436         $LCTL set_param $testname=$jobid_var_old
24437         jobid_var_new=$($LCTL get_param -n $testname)
24438         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24439                 error "failed to reset $testname"
24440
24441         $LCTL set_param $testname $new_value ||
24442                 error "'set_param a b' did not accept a value containing '='"
24443
24444         jobid_var_new=$($LCTL get_param -n $testname)
24445         [[ "$jobid_var_new" == "$new_value" ]] ||
24446                 error "'set_param a b' failed on a value containing '='"
24447
24448         $LCTL set_param $testname $jobid_var_old
24449         jobid_var_new=$($LCTL get_param -n $testname)
24450         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24451                 error "failed to reset $testname"
24452 }
24453 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24454
24455 test_401e() { # LU-14779
24456         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24457                 error "lctl list_param MGC* failed"
24458         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24459         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24460                 error "lctl get_param lru_size failed"
24461 }
24462 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24463
24464 test_402() {
24465         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24466         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24467                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24468         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24469                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24470                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24471         remote_mds_nodsh && skip "remote MDS with nodsh"
24472
24473         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24474 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24475         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24476         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24477                 echo "Touch failed - OK"
24478 }
24479 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24480
24481 test_403() {
24482         local file1=$DIR/$tfile.1
24483         local file2=$DIR/$tfile.2
24484         local tfile=$TMP/$tfile
24485
24486         rm -f $file1 $file2 $tfile
24487
24488         touch $file1
24489         ln $file1 $file2
24490
24491         # 30 sec OBD_TIMEOUT in ll_getattr()
24492         # right before populating st_nlink
24493         $LCTL set_param fail_loc=0x80001409
24494         stat -c %h $file1 > $tfile &
24495
24496         # create an alias, drop all locks and reclaim the dentry
24497         < $file2
24498         cancel_lru_locks mdc
24499         cancel_lru_locks osc
24500         sysctl -w vm.drop_caches=2
24501
24502         wait
24503
24504         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24505
24506         rm -f $tfile $file1 $file2
24507 }
24508 run_test 403 "i_nlink should not drop to zero due to aliasing"
24509
24510 test_404() { # LU-6601
24511         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24512                 skip "Need server version newer than 2.8.52"
24513         remote_mds_nodsh && skip "remote MDS with nodsh"
24514
24515         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24516                 awk '/osp .*-osc-MDT/ { print $4}')
24517
24518         local osp
24519         for osp in $mosps; do
24520                 echo "Deactivate: " $osp
24521                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24522                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24523                         awk -vp=$osp '$4 == p { print $2 }')
24524                 [ $stat = IN ] || {
24525                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24526                         error "deactivate error"
24527                 }
24528                 echo "Activate: " $osp
24529                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24530                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24531                         awk -vp=$osp '$4 == p { print $2 }')
24532                 [ $stat = UP ] || {
24533                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24534                         error "activate error"
24535                 }
24536         done
24537 }
24538 run_test 404 "validate manual {de}activated works properly for OSPs"
24539
24540 test_405() {
24541         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24542         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24543                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24544                         skip "Layout swap lock is not supported"
24545
24546         check_swap_layouts_support
24547         check_swap_layout_no_dom $DIR
24548
24549         test_mkdir $DIR/$tdir
24550         swap_lock_test -d $DIR/$tdir ||
24551                 error "One layout swap locked test failed"
24552 }
24553 run_test 405 "Various layout swap lock tests"
24554
24555 test_406() {
24556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24557         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24558         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24560         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24561                 skip "Need MDS version at least 2.8.50"
24562
24563         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24564         local test_pool=$TESTNAME
24565
24566         pool_add $test_pool || error "pool_add failed"
24567         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24568                 error "pool_add_targets failed"
24569
24570         save_layout_restore_at_exit $MOUNT
24571
24572         # parent set default stripe count only, child will stripe from both
24573         # parent and fs default
24574         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24575                 error "setstripe $MOUNT failed"
24576         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24577         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24578         for i in $(seq 10); do
24579                 local f=$DIR/$tdir/$tfile.$i
24580                 touch $f || error "touch failed"
24581                 local count=$($LFS getstripe -c $f)
24582                 [ $count -eq $OSTCOUNT ] ||
24583                         error "$f stripe count $count != $OSTCOUNT"
24584                 local offset=$($LFS getstripe -i $f)
24585                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24586                 local size=$($LFS getstripe -S $f)
24587                 [ $size -eq $((def_stripe_size * 2)) ] ||
24588                         error "$f stripe size $size != $((def_stripe_size * 2))"
24589                 local pool=$($LFS getstripe -p $f)
24590                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24591         done
24592
24593         # change fs default striping, delete parent default striping, now child
24594         # will stripe from new fs default striping only
24595         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24596                 error "change $MOUNT default stripe failed"
24597         $LFS setstripe -c 0 $DIR/$tdir ||
24598                 error "delete $tdir default stripe failed"
24599         for i in $(seq 11 20); do
24600                 local f=$DIR/$tdir/$tfile.$i
24601                 touch $f || error "touch $f failed"
24602                 local count=$($LFS getstripe -c $f)
24603                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24604                 local offset=$($LFS getstripe -i $f)
24605                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24606                 local size=$($LFS getstripe -S $f)
24607                 [ $size -eq $def_stripe_size ] ||
24608                         error "$f stripe size $size != $def_stripe_size"
24609                 local pool=$($LFS getstripe -p $f)
24610                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24611         done
24612
24613         unlinkmany $DIR/$tdir/$tfile. 1 20
24614
24615         local f=$DIR/$tdir/$tfile
24616         pool_remove_all_targets $test_pool $f
24617         pool_remove $test_pool $f
24618 }
24619 run_test 406 "DNE support fs default striping"
24620
24621 test_407() {
24622         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24623         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24624                 skip "Need MDS version at least 2.8.55"
24625         remote_mds_nodsh && skip "remote MDS with nodsh"
24626
24627         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24628                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24629         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24630                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24631         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24632
24633         #define OBD_FAIL_DT_TXN_STOP    0x2019
24634         for idx in $(seq $MDSCOUNT); do
24635                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24636         done
24637         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24638         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24639                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24640         true
24641 }
24642 run_test 407 "transaction fail should cause operation fail"
24643
24644 test_408() {
24645         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24646
24647         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24648         lctl set_param fail_loc=0x8000040a
24649         # let ll_prepare_partial_page() fail
24650         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24651
24652         rm -f $DIR/$tfile
24653
24654         # create at least 100 unused inodes so that
24655         # shrink_icache_memory(0) should not return 0
24656         touch $DIR/$tfile-{0..100}
24657         rm -f $DIR/$tfile-{0..100}
24658         sync
24659
24660         echo 2 > /proc/sys/vm/drop_caches
24661 }
24662 run_test 408 "drop_caches should not hang due to page leaks"
24663
24664 test_409()
24665 {
24666         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24667
24668         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24669         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24670         touch $DIR/$tdir/guard || error "(2) Fail to create"
24671
24672         local PREFIX=$(str_repeat 'A' 128)
24673         echo "Create 1K hard links start at $(date)"
24674         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24675                 error "(3) Fail to hard link"
24676
24677         echo "Links count should be right although linkEA overflow"
24678         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24679         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24680         [ $linkcount -eq 1001 ] ||
24681                 error "(5) Unexpected hard links count: $linkcount"
24682
24683         echo "List all links start at $(date)"
24684         ls -l $DIR/$tdir/foo > /dev/null ||
24685                 error "(6) Fail to list $DIR/$tdir/foo"
24686
24687         echo "Unlink hard links start at $(date)"
24688         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24689                 error "(7) Fail to unlink"
24690         echo "Unlink hard links finished at $(date)"
24691 }
24692 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24693
24694 test_410()
24695 {
24696         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24697                 skip "Need client version at least 2.9.59"
24698         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24699                 skip "Need MODULES build"
24700
24701         # Create a file, and stat it from the kernel
24702         local testfile=$DIR/$tfile
24703         touch $testfile
24704
24705         local run_id=$RANDOM
24706         local my_ino=$(stat --format "%i" $testfile)
24707
24708         # Try to insert the module. This will always fail as the
24709         # module is designed to not be inserted.
24710         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24711             &> /dev/null
24712
24713         # Anything but success is a test failure
24714         dmesg | grep -q \
24715             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24716             error "no inode match"
24717 }
24718 run_test 410 "Test inode number returned from kernel thread"
24719
24720 cleanup_test411_cgroup() {
24721         trap 0
24722         rmdir "$1"
24723 }
24724
24725 test_411() {
24726         local cg_basedir=/sys/fs/cgroup/memory
24727         # LU-9966
24728         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24729                 skip "no setup for cgroup"
24730
24731         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24732                 error "test file creation failed"
24733         cancel_lru_locks osc
24734
24735         # Create a very small memory cgroup to force a slab allocation error
24736         local cgdir=$cg_basedir/osc_slab_alloc
24737         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24738         trap "cleanup_test411_cgroup $cgdir" EXIT
24739         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24740         echo 1M > $cgdir/memory.limit_in_bytes
24741
24742         # Should not LBUG, just be killed by oom-killer
24743         # dd will return 0 even allocation failure in some environment.
24744         # So don't check return value
24745         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24746         cleanup_test411_cgroup $cgdir
24747
24748         return 0
24749 }
24750 run_test 411 "Slab allocation error with cgroup does not LBUG"
24751
24752 test_412() {
24753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24754         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24755                 skip "Need server version at least 2.10.55"
24756         fi
24757
24758         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24759                 error "mkdir failed"
24760         $LFS getdirstripe $DIR/$tdir
24761         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24762         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24763                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24764         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24765         [ $stripe_count -eq 2 ] ||
24766                 error "expect 2 get $stripe_count"
24767 }
24768 run_test 412 "mkdir on specific MDTs"
24769
24770 generate_uneven_mdts() {
24771         local threshold=$1
24772         local ffree
24773         local bavail
24774         local max
24775         local min
24776         local max_index
24777         local min_index
24778         local tmp
24779         local i
24780
24781         echo
24782         echo "Check for uneven MDTs: "
24783
24784         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24785         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24786         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24787
24788         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24789         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24790         max_index=0
24791         min_index=0
24792         for ((i = 1; i < ${#ffree[@]}; i++)); do
24793                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24794                 if [ $tmp -gt $max ]; then
24795                         max=$tmp
24796                         max_index=$i
24797                 fi
24798                 if [ $tmp -lt $min ]; then
24799                         min=$tmp
24800                         min_index=$i
24801                 fi
24802         done
24803
24804         # Check if we need to generate uneven MDTs
24805         local diff=$(((max - min) * 100 / min))
24806         local testdir=$DIR/$tdir-fillmdt
24807
24808         mkdir -p $testdir
24809
24810         i=0
24811         while (( diff < threshold )); do
24812                 # generate uneven MDTs, create till $threshold% diff
24813                 echo -n "weight diff=$diff% must be > $threshold% ..."
24814                 echo "Fill MDT$min_index with 100 files: loop $i"
24815                 testdir=$DIR/$tdir-fillmdt/$i
24816                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24817                         error "mkdir $testdir failed"
24818                 $LFS setstripe -E 1M -L mdt $testdir ||
24819                         error "setstripe $testdir failed"
24820                 for F in f.{0..99}; do
24821                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24822                                 /dev/null 2>&1 || error "dd $F failed"
24823                 done
24824
24825                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24826                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24827                 max=$(((${ffree[max_index]} >> 8) * \
24828                         (${bavail[max_index]} * bsize >> 16)))
24829                 min=$(((${ffree[min_index]} >> 8) * \
24830                         (${bavail[min_index]} * bsize >> 16)))
24831                 diff=$(((max - min) * 100 / min))
24832                 i=$((i + 1))
24833         done
24834
24835         echo "MDT filesfree available: ${ffree[@]}"
24836         echo "MDT blocks available: ${bavail[@]}"
24837         echo "weight diff=$diff%"
24838 }
24839
24840 test_qos_mkdir() {
24841         local mkdir_cmd=$1
24842         local stripe_count=$2
24843         local mdts=$(comma_list $(mdts_nodes))
24844
24845         local testdir
24846         local lmv_qos_prio_free
24847         local lmv_qos_threshold_rr
24848         local lmv_qos_maxage
24849         local lod_qos_prio_free
24850         local lod_qos_threshold_rr
24851         local lod_qos_maxage
24852         local count
24853         local i
24854
24855         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24856         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24857         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24858                 head -n1)
24859         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24860         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24861         stack_trap "$LCTL set_param \
24862                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24863         stack_trap "$LCTL set_param \
24864                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24865         stack_trap "$LCTL set_param \
24866                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24867
24868         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24869                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24870         lod_qos_prio_free=${lod_qos_prio_free%%%}
24871         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24872                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24873         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24874         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24875                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24876         stack_trap "do_nodes $mdts $LCTL set_param \
24877                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24878         stack_trap "do_nodes $mdts $LCTL set_param \
24879                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24880         stack_trap "do_nodes $mdts $LCTL set_param \
24881                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24882
24883         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24884         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24885
24886         testdir=$DIR/$tdir-s$stripe_count/rr
24887
24888         local stripe_index=$($LFS getstripe -m $testdir)
24889         local test_mkdir_rr=true
24890
24891         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24892         getfattr -d -m dmv -e hex $testdir | grep dmv
24893         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24894                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24895                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24896                         test_mkdir_rr=false
24897         fi
24898
24899         echo
24900         $test_mkdir_rr &&
24901                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24902                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24903
24904         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24905         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24906                 eval $mkdir_cmd $testdir/subdir$i ||
24907                         error "$mkdir_cmd subdir$i failed"
24908         done
24909
24910         for (( i = 0; i < $MDSCOUNT; i++ )); do
24911                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24912                 echo "$count directories created on MDT$i"
24913                 if $test_mkdir_rr; then
24914                         (( $count == 100 )) ||
24915                                 error "subdirs are not evenly distributed"
24916                 elif (( $i == $stripe_index )); then
24917                         (( $count == 100 * MDSCOUNT )) ||
24918                                 error "$count subdirs created on MDT$i"
24919                 else
24920                         (( $count == 0 )) ||
24921                                 error "$count subdirs created on MDT$i"
24922                 fi
24923
24924                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24925                         count=$($LFS getdirstripe $testdir/* |
24926                                 grep -c -P "^\s+$i\t")
24927                         echo "$count stripes created on MDT$i"
24928                         # deviation should < 5% of average
24929                         (( $count >= 95 * stripe_count &&
24930                            $count <= 105 * stripe_count)) ||
24931                                 error "stripes are not evenly distributed"
24932                 fi
24933         done
24934
24935         echo
24936         echo "Check for uneven MDTs: "
24937
24938         local ffree
24939         local bavail
24940         local max
24941         local min
24942         local max_index
24943         local min_index
24944         local tmp
24945
24946         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24947         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24948         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24949
24950         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24951         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24952         max_index=0
24953         min_index=0
24954         for ((i = 1; i < ${#ffree[@]}; i++)); do
24955                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24956                 if [ $tmp -gt $max ]; then
24957                         max=$tmp
24958                         max_index=$i
24959                 fi
24960                 if [ $tmp -lt $min ]; then
24961                         min=$tmp
24962                         min_index=$i
24963                 fi
24964         done
24965
24966         (( ${ffree[min_index]} > 0 )) ||
24967                 skip "no free files in MDT$min_index"
24968         (( ${ffree[min_index]} < 100000000 )) ||
24969                 skip "too many free files in MDT$min_index"
24970
24971         echo "MDT filesfree available: ${ffree[@]}"
24972         echo "MDT blocks available: ${bavail[@]}"
24973         echo "weight diff=$(((max - min) * 100 / min))%"
24974         echo
24975         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24976
24977         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24978         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24979         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24980         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24981         # decrease statfs age, so that it can be updated in time
24982         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24983         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24984
24985         sleep 1
24986
24987         testdir=$DIR/$tdir-s$stripe_count/qos
24988         local num=200
24989
24990         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24991         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24992                 eval $mkdir_cmd $testdir/subdir$i ||
24993                         error "$mkdir_cmd subdir$i failed"
24994         done
24995
24996         for (( i = 0; i < $MDSCOUNT; i++ )); do
24997                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24998                 echo "$count directories created on MDT$i"
24999
25000                 if [ $stripe_count -gt 1 ]; then
25001                         count=$($LFS getdirstripe $testdir/* |
25002                                 grep -c -P "^\s+$i\t")
25003                         echo "$count stripes created on MDT$i"
25004                 fi
25005         done
25006
25007         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
25008         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25009
25010         # D-value should > 10% of averge
25011         (( max - min >= num / 10 )) ||
25012                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25013
25014         # 5% for stripes
25015         if (( stripe_count > 1 )); then
25016                 max=$($LFS getdirstripe $testdir/* |
25017                       grep -c -P "^\s+$max_index\t")
25018                 min=$($LFS getdirstripe $testdir/* |
25019                         grep -c -P "^\s+$min_index\t")
25020                 (( max - min >= num * stripe_count / 20 )) ||
25021                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
25022         fi
25023 }
25024
25025 most_full_mdt() {
25026         local ffree
25027         local bavail
25028         local bsize
25029         local min
25030         local min_index
25031         local tmp
25032
25033         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25034         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25035         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25036
25037         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25038         min_index=0
25039         for ((i = 1; i < ${#ffree[@]}; i++)); do
25040                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25041                 (( tmp < min )) && min=$tmp && min_index=$i
25042         done
25043
25044         echo -n $min_index
25045 }
25046
25047 test_413a() {
25048         [ $MDSCOUNT -lt 2 ] &&
25049                 skip "We need at least 2 MDTs for this test"
25050
25051         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25052                 skip "Need server version at least 2.12.52"
25053
25054         local stripe_count
25055
25056         generate_uneven_mdts 100
25057         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25058                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25059                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25060                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25061                         error "mkdir failed"
25062                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25063         done
25064 }
25065 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25066
25067 test_413b() {
25068         [ $MDSCOUNT -lt 2 ] &&
25069                 skip "We need at least 2 MDTs for this test"
25070
25071         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25072                 skip "Need server version at least 2.12.52"
25073
25074         local testdir
25075         local stripe_count
25076
25077         generate_uneven_mdts 100
25078         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25079                 testdir=$DIR/$tdir-s$stripe_count
25080                 mkdir $testdir || error "mkdir $testdir failed"
25081                 mkdir $testdir/rr || error "mkdir rr failed"
25082                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25083                         error "mkdir qos failed"
25084                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25085                         $testdir/rr || error "setdirstripe rr failed"
25086                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25087                         error "setdirstripe failed"
25088                 test_qos_mkdir "mkdir" $stripe_count
25089         done
25090 }
25091 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25092
25093 test_413c() {
25094         (( $MDSCOUNT >= 2 )) ||
25095                 skip "We need at least 2 MDTs for this test"
25096
25097         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25098                 skip "Need server version at least 2.14.51"
25099
25100         local testdir
25101         local inherit
25102         local inherit_rr
25103
25104         testdir=$DIR/${tdir}-s1
25105         mkdir $testdir || error "mkdir $testdir failed"
25106         mkdir $testdir/rr || error "mkdir rr failed"
25107         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25108         # default max_inherit is -1, default max_inherit_rr is 0
25109         $LFS setdirstripe -D -c 1 $testdir/rr ||
25110                 error "setdirstripe rr failed"
25111         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25112                 error "setdirstripe qos failed"
25113         test_qos_mkdir "mkdir" 1
25114
25115         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25116         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25117         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25118         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25119         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25120
25121         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25122         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25123         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25124         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25125         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25126         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25127         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25128                 error "level2 shouldn't have default LMV" || true
25129 }
25130 run_test 413c "mkdir with default LMV max inherit rr"
25131
25132 test_413d() {
25133         (( MDSCOUNT >= 2 )) ||
25134                 skip "We need at least 2 MDTs for this test"
25135
25136         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25137                 skip "Need server version at least 2.14.51"
25138
25139         local lmv_qos_threshold_rr
25140
25141         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25142                 head -n1)
25143         stack_trap "$LCTL set_param \
25144                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25145
25146         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25147         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25148         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25149                 error "$tdir shouldn't have default LMV"
25150         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25151                 error "mkdir sub failed"
25152
25153         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25154
25155         (( count == 100 )) || error "$count subdirs on MDT0"
25156 }
25157 run_test 413d "inherit ROOT default LMV"
25158
25159 test_413z() {
25160         local pids=""
25161         local subdir
25162         local pid
25163
25164         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25165                 unlinkmany $subdir/f. 100 &
25166                 pids="$pids $!"
25167         done
25168
25169         for pid in $pids; do
25170                 wait $pid
25171         done
25172 }
25173 run_test 413z "413 test cleanup"
25174
25175 test_414() {
25176 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25177         $LCTL set_param fail_loc=0x80000521
25178         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25179         rm -f $DIR/$tfile
25180 }
25181 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25182
25183 test_415() {
25184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25185         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25186                 skip "Need server version at least 2.11.52"
25187
25188         # LU-11102
25189         local total
25190         local setattr_pid
25191         local start_time
25192         local end_time
25193         local duration
25194
25195         total=500
25196         # this test may be slow on ZFS
25197         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25198
25199         # though this test is designed for striped directory, let's test normal
25200         # directory too since lock is always saved as CoS lock.
25201         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25202         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25203
25204         (
25205                 while true; do
25206                         touch $DIR/$tdir
25207                 done
25208         ) &
25209         setattr_pid=$!
25210
25211         start_time=$(date +%s)
25212         for i in $(seq $total); do
25213                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25214                         > /dev/null
25215         done
25216         end_time=$(date +%s)
25217         duration=$((end_time - start_time))
25218
25219         kill -9 $setattr_pid
25220
25221         echo "rename $total files took $duration sec"
25222         [ $duration -lt 100 ] || error "rename took $duration sec"
25223 }
25224 run_test 415 "lock revoke is not missing"
25225
25226 test_416() {
25227         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25228                 skip "Need server version at least 2.11.55"
25229
25230         # define OBD_FAIL_OSD_TXN_START    0x19a
25231         do_facet mds1 lctl set_param fail_loc=0x19a
25232
25233         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25234
25235         true
25236 }
25237 run_test 416 "transaction start failure won't cause system hung"
25238
25239 cleanup_417() {
25240         trap 0
25241         do_nodes $(comma_list $(mdts_nodes)) \
25242                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25243         do_nodes $(comma_list $(mdts_nodes)) \
25244                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25245         do_nodes $(comma_list $(mdts_nodes)) \
25246                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25247 }
25248
25249 test_417() {
25250         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25251         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25252                 skip "Need MDS version at least 2.11.56"
25253
25254         trap cleanup_417 RETURN EXIT
25255
25256         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25257         do_nodes $(comma_list $(mdts_nodes)) \
25258                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25259         $LFS migrate -m 0 $DIR/$tdir.1 &&
25260                 error "migrate dir $tdir.1 should fail"
25261
25262         do_nodes $(comma_list $(mdts_nodes)) \
25263                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25264         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25265                 error "create remote dir $tdir.2 should fail"
25266
25267         do_nodes $(comma_list $(mdts_nodes)) \
25268                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25269         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25270                 error "create striped dir $tdir.3 should fail"
25271         true
25272 }
25273 run_test 417 "disable remote dir, striped dir and dir migration"
25274
25275 # Checks that the outputs of df [-i] and lfs df [-i] match
25276 #
25277 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25278 check_lfs_df() {
25279         local dir=$2
25280         local inodes
25281         local df_out
25282         local lfs_df_out
25283         local count
25284         local passed=false
25285
25286         # blocks or inodes
25287         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25288
25289         for count in {1..100}; do
25290                 do_rpc_nodes "$CLIENTS" cancel_lru_locks
25291                 sync; sleep 0.2
25292
25293                 # read the lines of interest
25294                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25295                         error "df $inodes $dir | tail -n +2 failed"
25296                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25297                         error "lfs df $inodes $dir | grep summary: failed"
25298
25299                 # skip first substrings of each output as they are different
25300                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25301                 # compare the two outputs
25302                 passed=true
25303                 for i in {1..5}; do
25304                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25305                 done
25306                 $passed && break
25307         done
25308
25309         if ! $passed; then
25310                 df -P $inodes $dir
25311                 echo
25312                 lfs df $inodes $dir
25313                 error "df and lfs df $1 output mismatch: "      \
25314                       "df ${inodes}: ${df_out[*]}, "            \
25315                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25316         fi
25317 }
25318
25319 test_418() {
25320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25321
25322         local dir=$DIR/$tdir
25323         local numfiles=$((RANDOM % 4096 + 2))
25324         local numblocks=$((RANDOM % 256 + 1))
25325
25326         wait_delete_completed
25327         test_mkdir $dir
25328
25329         # check block output
25330         check_lfs_df blocks $dir
25331         # check inode output
25332         check_lfs_df inodes $dir
25333
25334         # create a single file and retest
25335         echo "Creating a single file and testing"
25336         createmany -o $dir/$tfile- 1 &>/dev/null ||
25337                 error "creating 1 file in $dir failed"
25338         check_lfs_df blocks $dir
25339         check_lfs_df inodes $dir
25340
25341         # create a random number of files
25342         echo "Creating $((numfiles - 1)) files and testing"
25343         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25344                 error "creating $((numfiles - 1)) files in $dir failed"
25345
25346         # write a random number of blocks to the first test file
25347         echo "Writing $numblocks 4K blocks and testing"
25348         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25349                 count=$numblocks &>/dev/null ||
25350                 error "dd to $dir/${tfile}-0 failed"
25351
25352         # retest
25353         check_lfs_df blocks $dir
25354         check_lfs_df inodes $dir
25355
25356         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25357                 error "unlinking $numfiles files in $dir failed"
25358 }
25359 run_test 418 "df and lfs df outputs match"
25360
25361 test_419()
25362 {
25363         local dir=$DIR/$tdir
25364
25365         mkdir -p $dir
25366         touch $dir/file
25367
25368         cancel_lru_locks mdc
25369
25370         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25371         $LCTL set_param fail_loc=0x1410
25372         cat $dir/file
25373         $LCTL set_param fail_loc=0
25374         rm -rf $dir
25375 }
25376 run_test 419 "Verify open file by name doesn't crash kernel"
25377
25378 test_420()
25379 {
25380         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25381                 skip "Need MDS version at least 2.12.53"
25382
25383         local SAVE_UMASK=$(umask)
25384         local dir=$DIR/$tdir
25385         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25386
25387         mkdir -p $dir
25388         umask 0000
25389         mkdir -m03777 $dir/testdir
25390         ls -dn $dir/testdir
25391         # Need to remove trailing '.' when SELinux is enabled
25392         local dirperms=$(ls -dn $dir/testdir |
25393                          awk '{ sub(/\.$/, "", $1); print $1}')
25394         [ $dirperms == "drwxrwsrwt" ] ||
25395                 error "incorrect perms on $dir/testdir"
25396
25397         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25398                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25399         ls -n $dir/testdir/testfile
25400         local fileperms=$(ls -n $dir/testdir/testfile |
25401                           awk '{ sub(/\.$/, "", $1); print $1}')
25402         [ $fileperms == "-rwxr-xr-x" ] ||
25403                 error "incorrect perms on $dir/testdir/testfile"
25404
25405         umask $SAVE_UMASK
25406 }
25407 run_test 420 "clear SGID bit on non-directories for non-members"
25408
25409 test_421a() {
25410         local cnt
25411         local fid1
25412         local fid2
25413
25414         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25415                 skip "Need MDS version at least 2.12.54"
25416
25417         test_mkdir $DIR/$tdir
25418         createmany -o $DIR/$tdir/f 3
25419         cnt=$(ls -1 $DIR/$tdir | wc -l)
25420         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25421
25422         fid1=$(lfs path2fid $DIR/$tdir/f1)
25423         fid2=$(lfs path2fid $DIR/$tdir/f2)
25424         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25425
25426         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25427         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25428
25429         cnt=$(ls -1 $DIR/$tdir | wc -l)
25430         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25431
25432         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25433         createmany -o $DIR/$tdir/f 3
25434         cnt=$(ls -1 $DIR/$tdir | wc -l)
25435         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25436
25437         fid1=$(lfs path2fid $DIR/$tdir/f1)
25438         fid2=$(lfs path2fid $DIR/$tdir/f2)
25439         echo "remove using fsname $FSNAME"
25440         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25441
25442         cnt=$(ls -1 $DIR/$tdir | wc -l)
25443         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25444 }
25445 run_test 421a "simple rm by fid"
25446
25447 test_421b() {
25448         local cnt
25449         local FID1
25450         local FID2
25451
25452         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25453                 skip "Need MDS version at least 2.12.54"
25454
25455         test_mkdir $DIR/$tdir
25456         createmany -o $DIR/$tdir/f 3
25457         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25458         MULTIPID=$!
25459
25460         FID1=$(lfs path2fid $DIR/$tdir/f1)
25461         FID2=$(lfs path2fid $DIR/$tdir/f2)
25462         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25463
25464         kill -USR1 $MULTIPID
25465         wait
25466
25467         cnt=$(ls $DIR/$tdir | wc -l)
25468         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25469 }
25470 run_test 421b "rm by fid on open file"
25471
25472 test_421c() {
25473         local cnt
25474         local FIDS
25475
25476         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25477                 skip "Need MDS version at least 2.12.54"
25478
25479         test_mkdir $DIR/$tdir
25480         createmany -o $DIR/$tdir/f 3
25481         touch $DIR/$tdir/$tfile
25482         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25483         cnt=$(ls -1 $DIR/$tdir | wc -l)
25484         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25485
25486         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25487         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25488
25489         cnt=$(ls $DIR/$tdir | wc -l)
25490         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25491 }
25492 run_test 421c "rm by fid against hardlinked files"
25493
25494 test_421d() {
25495         local cnt
25496         local FIDS
25497
25498         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25499                 skip "Need MDS version at least 2.12.54"
25500
25501         test_mkdir $DIR/$tdir
25502         createmany -o $DIR/$tdir/f 4097
25503         cnt=$(ls -1 $DIR/$tdir | wc -l)
25504         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25505
25506         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25507         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25508
25509         cnt=$(ls $DIR/$tdir | wc -l)
25510         rm -rf $DIR/$tdir
25511         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25512 }
25513 run_test 421d "rmfid en masse"
25514
25515 test_421e() {
25516         local cnt
25517         local FID
25518
25519         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25520         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25521                 skip "Need MDS version at least 2.12.54"
25522
25523         mkdir -p $DIR/$tdir
25524         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25525         createmany -o $DIR/$tdir/striped_dir/f 512
25526         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25527         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25528
25529         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25530                 sed "s/[/][^:]*://g")
25531         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25532
25533         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25534         rm -rf $DIR/$tdir
25535         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25536 }
25537 run_test 421e "rmfid in DNE"
25538
25539 test_421f() {
25540         local cnt
25541         local FID
25542
25543         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25544                 skip "Need MDS version at least 2.12.54"
25545
25546         test_mkdir $DIR/$tdir
25547         touch $DIR/$tdir/f
25548         cnt=$(ls -1 $DIR/$tdir | wc -l)
25549         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25550
25551         FID=$(lfs path2fid $DIR/$tdir/f)
25552         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25553         # rmfid should fail
25554         cnt=$(ls -1 $DIR/$tdir | wc -l)
25555         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25556
25557         chmod a+rw $DIR/$tdir
25558         ls -la $DIR/$tdir
25559         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25560         # rmfid should fail
25561         cnt=$(ls -1 $DIR/$tdir | wc -l)
25562         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25563
25564         rm -f $DIR/$tdir/f
25565         $RUNAS touch $DIR/$tdir/f
25566         FID=$(lfs path2fid $DIR/$tdir/f)
25567         echo "rmfid as root"
25568         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25569         cnt=$(ls -1 $DIR/$tdir | wc -l)
25570         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25571
25572         rm -f $DIR/$tdir/f
25573         $RUNAS touch $DIR/$tdir/f
25574         cnt=$(ls -1 $DIR/$tdir | wc -l)
25575         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25576         FID=$(lfs path2fid $DIR/$tdir/f)
25577         # rmfid w/o user_fid2path mount option should fail
25578         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25579         cnt=$(ls -1 $DIR/$tdir | wc -l)
25580         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25581
25582         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25583         stack_trap "rmdir $tmpdir"
25584         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25585                 error "failed to mount client'"
25586         stack_trap "umount_client $tmpdir"
25587
25588         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25589         # rmfid should succeed
25590         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25591         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25592
25593         # rmfid shouldn't allow to remove files due to dir's permission
25594         chmod a+rwx $tmpdir/$tdir
25595         touch $tmpdir/$tdir/f
25596         ls -la $tmpdir/$tdir
25597         FID=$(lfs path2fid $tmpdir/$tdir/f)
25598         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25599         return 0
25600 }
25601 run_test 421f "rmfid checks permissions"
25602
25603 test_421g() {
25604         local cnt
25605         local FIDS
25606
25607         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25608         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25609                 skip "Need MDS version at least 2.12.54"
25610
25611         mkdir -p $DIR/$tdir
25612         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25613         createmany -o $DIR/$tdir/striped_dir/f 512
25614         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25615         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25616
25617         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25618                 sed "s/[/][^:]*://g")
25619
25620         rm -f $DIR/$tdir/striped_dir/f1*
25621         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25622         removed=$((512 - cnt))
25623
25624         # few files have been just removed, so we expect
25625         # rmfid to fail on their fids
25626         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25627         [ $removed != $errors ] && error "$errors != $removed"
25628
25629         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25630         rm -rf $DIR/$tdir
25631         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25632 }
25633 run_test 421g "rmfid to return errors properly"
25634
25635 test_422() {
25636         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25637         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25638         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25639         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25640         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25641
25642         local amc=$(at_max_get client)
25643         local amo=$(at_max_get mds1)
25644         local timeout=`lctl get_param -n timeout`
25645
25646         at_max_set 0 client
25647         at_max_set 0 mds1
25648
25649 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25650         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25651                         fail_val=$(((2*timeout + 10)*1000))
25652         touch $DIR/$tdir/d3/file &
25653         sleep 2
25654 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25655         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25656                         fail_val=$((2*timeout + 5))
25657         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25658         local pid=$!
25659         sleep 1
25660         kill -9 $pid
25661         sleep $((2 * timeout))
25662         echo kill $pid
25663         kill -9 $pid
25664         lctl mark touch
25665         touch $DIR/$tdir/d2/file3
25666         touch $DIR/$tdir/d2/file4
25667         touch $DIR/$tdir/d2/file5
25668
25669         wait
25670         at_max_set $amc client
25671         at_max_set $amo mds1
25672
25673         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25674         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25675                 error "Watchdog is always throttled"
25676 }
25677 run_test 422 "kill a process with RPC in progress"
25678
25679 stat_test() {
25680     df -h $MOUNT &
25681     df -h $MOUNT &
25682     df -h $MOUNT &
25683     df -h $MOUNT &
25684     df -h $MOUNT &
25685     df -h $MOUNT &
25686 }
25687
25688 test_423() {
25689     local _stats
25690     # ensure statfs cache is expired
25691     sleep 2;
25692
25693     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25694     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25695
25696     return 0
25697 }
25698 run_test 423 "statfs should return a right data"
25699
25700 test_424() {
25701 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25702         $LCTL set_param fail_loc=0x80000522
25703         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25704         rm -f $DIR/$tfile
25705 }
25706 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25707
25708 test_425() {
25709         test_mkdir -c -1 $DIR/$tdir
25710         $LFS setstripe -c -1 $DIR/$tdir
25711
25712         lru_resize_disable "" 100
25713         stack_trap "lru_resize_enable" EXIT
25714
25715         sleep 5
25716
25717         for i in $(seq $((MDSCOUNT * 125))); do
25718                 local t=$DIR/$tdir/$tfile_$i
25719
25720                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25721                         error_noexit "Create file $t"
25722         done
25723         stack_trap "rm -rf $DIR/$tdir" EXIT
25724
25725         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25726                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25727                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25728
25729                 [ $lock_count -le $lru_size ] ||
25730                         error "osc lock count $lock_count > lru size $lru_size"
25731         done
25732
25733         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25734                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25735                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25736
25737                 [ $lock_count -le $lru_size ] ||
25738                         error "mdc lock count $lock_count > lru size $lru_size"
25739         done
25740 }
25741 run_test 425 "lock count should not exceed lru size"
25742
25743 test_426() {
25744         splice-test -r $DIR/$tfile
25745         splice-test -rd $DIR/$tfile
25746         splice-test $DIR/$tfile
25747         splice-test -d $DIR/$tfile
25748 }
25749 run_test 426 "splice test on Lustre"
25750
25751 test_427() {
25752         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25753         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25754                 skip "Need MDS version at least 2.12.4"
25755         local log
25756
25757         mkdir $DIR/$tdir
25758         mkdir $DIR/$tdir/1
25759         mkdir $DIR/$tdir/2
25760         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25761         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25762
25763         $LFS getdirstripe $DIR/$tdir/1/dir
25764
25765         #first setfattr for creating updatelog
25766         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25767
25768 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25769         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25770         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25771         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25772
25773         sleep 2
25774         fail mds2
25775         wait_recovery_complete mds2 $((2*TIMEOUT))
25776
25777         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25778         echo $log | grep "get update log failed" &&
25779                 error "update log corruption is detected" || true
25780 }
25781 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25782
25783 test_428() {
25784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25785         local cache_limit=$CACHE_MAX
25786
25787         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25788         $LCTL set_param -n llite.*.max_cached_mb=64
25789
25790         mkdir $DIR/$tdir
25791         $LFS setstripe -c 1 $DIR/$tdir
25792         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25793         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25794         #test write
25795         for f in $(seq 4); do
25796                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25797         done
25798         wait
25799
25800         cancel_lru_locks osc
25801         # Test read
25802         for f in $(seq 4); do
25803                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25804         done
25805         wait
25806 }
25807 run_test 428 "large block size IO should not hang"
25808
25809 test_429() { # LU-7915 / LU-10948
25810         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25811         local testfile=$DIR/$tfile
25812         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25813         local new_flag=1
25814         local first_rpc
25815         local second_rpc
25816         local third_rpc
25817
25818         $LCTL get_param $ll_opencache_threshold_count ||
25819                 skip "client does not have opencache parameter"
25820
25821         set_opencache $new_flag
25822         stack_trap "restore_opencache"
25823         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25824                 error "enable opencache failed"
25825         touch $testfile
25826         # drop MDC DLM locks
25827         cancel_lru_locks mdc
25828         # clear MDC RPC stats counters
25829         $LCTL set_param $mdc_rpcstats=clear
25830
25831         # According to the current implementation, we need to run 3 times
25832         # open & close file to verify if opencache is enabled correctly.
25833         # 1st, RPCs are sent for lookup/open and open handle is released on
25834         #      close finally.
25835         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25836         #      so open handle won't be released thereafter.
25837         # 3rd, No RPC is sent out.
25838         $MULTIOP $testfile oc || error "multiop failed"
25839         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25840         echo "1st: $first_rpc RPCs in flight"
25841
25842         $MULTIOP $testfile oc || error "multiop failed"
25843         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25844         echo "2nd: $second_rpc RPCs in flight"
25845
25846         $MULTIOP $testfile oc || error "multiop failed"
25847         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25848         echo "3rd: $third_rpc RPCs in flight"
25849
25850         #verify no MDC RPC is sent
25851         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25852 }
25853 run_test 429 "verify if opencache flag on client side does work"
25854
25855 lseek_test_430() {
25856         local offset
25857         local file=$1
25858
25859         # data at [200K, 400K)
25860         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25861                 error "256K->512K dd fails"
25862         # data at [2M, 3M)
25863         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25864                 error "2M->3M dd fails"
25865         # data at [4M, 5M)
25866         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25867                 error "4M->5M dd fails"
25868         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25869         # start at first component hole #1
25870         printf "Seeking hole from 1000 ... "
25871         offset=$(lseek_test -l 1000 $file)
25872         echo $offset
25873         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25874         printf "Seeking data from 1000 ... "
25875         offset=$(lseek_test -d 1000 $file)
25876         echo $offset
25877         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25878
25879         # start at first component data block
25880         printf "Seeking hole from 300000 ... "
25881         offset=$(lseek_test -l 300000 $file)
25882         echo $offset
25883         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25884         printf "Seeking data from 300000 ... "
25885         offset=$(lseek_test -d 300000 $file)
25886         echo $offset
25887         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25888
25889         # start at the first component but beyond end of object size
25890         printf "Seeking hole from 1000000 ... "
25891         offset=$(lseek_test -l 1000000 $file)
25892         echo $offset
25893         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25894         printf "Seeking data from 1000000 ... "
25895         offset=$(lseek_test -d 1000000 $file)
25896         echo $offset
25897         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25898
25899         # start at second component stripe 2 (empty file)
25900         printf "Seeking hole from 1500000 ... "
25901         offset=$(lseek_test -l 1500000 $file)
25902         echo $offset
25903         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25904         printf "Seeking data from 1500000 ... "
25905         offset=$(lseek_test -d 1500000 $file)
25906         echo $offset
25907         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25908
25909         # start at second component stripe 1 (all data)
25910         printf "Seeking hole from 3000000 ... "
25911         offset=$(lseek_test -l 3000000 $file)
25912         echo $offset
25913         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25914         printf "Seeking data from 3000000 ... "
25915         offset=$(lseek_test -d 3000000 $file)
25916         echo $offset
25917         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25918
25919         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25920                 error "2nd dd fails"
25921         echo "Add data block at 640K...1280K"
25922
25923         # start at before new data block, in hole
25924         printf "Seeking hole from 600000 ... "
25925         offset=$(lseek_test -l 600000 $file)
25926         echo $offset
25927         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25928         printf "Seeking data from 600000 ... "
25929         offset=$(lseek_test -d 600000 $file)
25930         echo $offset
25931         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25932
25933         # start at the first component new data block
25934         printf "Seeking hole from 1000000 ... "
25935         offset=$(lseek_test -l 1000000 $file)
25936         echo $offset
25937         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25938         printf "Seeking data from 1000000 ... "
25939         offset=$(lseek_test -d 1000000 $file)
25940         echo $offset
25941         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25942
25943         # start at second component stripe 2, new data
25944         printf "Seeking hole from 1200000 ... "
25945         offset=$(lseek_test -l 1200000 $file)
25946         echo $offset
25947         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25948         printf "Seeking data from 1200000 ... "
25949         offset=$(lseek_test -d 1200000 $file)
25950         echo $offset
25951         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25952
25953         # start beyond file end
25954         printf "Using offset > filesize ... "
25955         lseek_test -l 4000000 $file && error "lseek should fail"
25956         printf "Using offset > filesize ... "
25957         lseek_test -d 4000000 $file && error "lseek should fail"
25958
25959         printf "Done\n\n"
25960 }
25961
25962 test_430a() {
25963         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25964                 skip "MDT does not support SEEK_HOLE"
25965
25966         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25967                 skip "OST does not support SEEK_HOLE"
25968
25969         local file=$DIR/$tdir/$tfile
25970
25971         mkdir -p $DIR/$tdir
25972
25973         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25974         # OST stripe #1 will have continuous data at [1M, 3M)
25975         # OST stripe #2 is empty
25976         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25977         lseek_test_430 $file
25978         rm $file
25979         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25980         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25981         lseek_test_430 $file
25982         rm $file
25983         $LFS setstripe -c2 -S 512K $file
25984         echo "Two stripes, stripe size 512K"
25985         lseek_test_430 $file
25986         rm $file
25987         # FLR with stale mirror
25988         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25989                        -N -c2 -S 1M $file
25990         echo "Mirrored file:"
25991         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25992         echo "Plain 2 stripes 1M"
25993         lseek_test_430 $file
25994         rm $file
25995 }
25996 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25997
25998 test_430b() {
25999         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26000                 skip "OST does not support SEEK_HOLE"
26001
26002         local offset
26003         local file=$DIR/$tdir/$tfile
26004
26005         mkdir -p $DIR/$tdir
26006         # Empty layout lseek should fail
26007         $MCREATE $file
26008         # seek from 0
26009         printf "Seeking hole from 0 ... "
26010         lseek_test -l 0 $file && error "lseek should fail"
26011         printf "Seeking data from 0 ... "
26012         lseek_test -d 0 $file && error "lseek should fail"
26013         rm $file
26014
26015         # 1M-hole file
26016         $LFS setstripe -E 1M -c2 -E eof $file
26017         $TRUNCATE $file 1048576
26018         printf "Seeking hole from 1000000 ... "
26019         offset=$(lseek_test -l 1000000 $file)
26020         echo $offset
26021         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26022         printf "Seeking data from 1000000 ... "
26023         lseek_test -d 1000000 $file && error "lseek should fail"
26024         rm $file
26025
26026         # full component followed by non-inited one
26027         $LFS setstripe -E 1M -c2 -E eof $file
26028         dd if=/dev/urandom of=$file bs=1M count=1
26029         printf "Seeking hole from 1000000 ... "
26030         offset=$(lseek_test -l 1000000 $file)
26031         echo $offset
26032         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26033         printf "Seeking hole from 1048576 ... "
26034         lseek_test -l 1048576 $file && error "lseek should fail"
26035         # init second component and truncate back
26036         echo "123" >> $file
26037         $TRUNCATE $file 1048576
26038         printf "Seeking hole from 1000000 ... "
26039         offset=$(lseek_test -l 1000000 $file)
26040         echo $offset
26041         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26042         printf "Seeking hole from 1048576 ... "
26043         lseek_test -l 1048576 $file && error "lseek should fail"
26044         # boundary checks for big values
26045         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26046         offset=$(lseek_test -d 0 $file.10g)
26047         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26048         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26049         offset=$(lseek_test -d 0 $file.100g)
26050         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26051         return 0
26052 }
26053 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26054
26055 test_430c() {
26056         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26057                 skip "OST does not support SEEK_HOLE"
26058
26059         local file=$DIR/$tdir/$tfile
26060         local start
26061
26062         mkdir -p $DIR/$tdir
26063         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26064
26065         # cp version 8.33+ prefers lseek over fiemap
26066         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26067                 start=$SECONDS
26068                 time cp $file /dev/null
26069                 (( SECONDS - start < 5 )) ||
26070                         error "cp: too long runtime $((SECONDS - start))"
26071
26072         fi
26073         # tar version 1.29+ supports SEEK_HOLE/DATA
26074         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26075                 start=$SECONDS
26076                 time tar cS $file - | cat > /dev/null
26077                 (( SECONDS - start < 5 )) ||
26078                         error "tar: too long runtime $((SECONDS - start))"
26079         fi
26080 }
26081 run_test 430c "lseek: external tools check"
26082
26083 test_431() { # LU-14187
26084         local file=$DIR/$tdir/$tfile
26085
26086         mkdir -p $DIR/$tdir
26087         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26088         dd if=/dev/urandom of=$file bs=4k count=1
26089         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26090         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26091         #define OBD_FAIL_OST_RESTART_IO 0x251
26092         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26093         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26094         cp $file $file.0
26095         cancel_lru_locks
26096         sync_all_data
26097         echo 3 > /proc/sys/vm/drop_caches
26098         diff  $file $file.0 || error "data diff"
26099 }
26100 run_test 431 "Restart transaction for IO"
26101
26102 cleanup_test_432() {
26103         do_facet mgs $LCTL nodemap_activate 0
26104         wait_nm_sync active
26105 }
26106
26107 test_432() {
26108         local tmpdir=$TMP/dir432
26109
26110         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26111                 skip "Need MDS version at least 2.14.52"
26112
26113         stack_trap cleanup_test_432 EXIT
26114         mkdir $DIR/$tdir
26115         mkdir $tmpdir
26116
26117         do_facet mgs $LCTL nodemap_activate 1
26118         wait_nm_sync active
26119         do_facet mgs $LCTL nodemap_modify --name default \
26120                 --property admin --value 1
26121         do_facet mgs $LCTL nodemap_modify --name default \
26122                 --property trusted --value 1
26123         cancel_lru_locks mdc
26124         wait_nm_sync default admin_nodemap
26125         wait_nm_sync default trusted_nodemap
26126
26127         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26128                grep -ci "Operation not permitted") -ne 0 ]; then
26129                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26130         fi
26131 }
26132 run_test 432 "mv dir from outside Lustre"
26133
26134 prep_801() {
26135         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26136         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26137                 skip "Need server version at least 2.9.55"
26138
26139         start_full_debug_logging
26140 }
26141
26142 post_801() {
26143         stop_full_debug_logging
26144 }
26145
26146 barrier_stat() {
26147         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26148                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26149                            awk '/The barrier for/ { print $7 }')
26150                 echo $st
26151         else
26152                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26153                 echo \'$st\'
26154         fi
26155 }
26156
26157 barrier_expired() {
26158         local expired
26159
26160         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26161                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26162                           awk '/will be expired/ { print $7 }')
26163         else
26164                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26165         fi
26166
26167         echo $expired
26168 }
26169
26170 test_801a() {
26171         prep_801
26172
26173         echo "Start barrier_freeze at: $(date)"
26174         #define OBD_FAIL_BARRIER_DELAY          0x2202
26175         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26176         # Do not reduce barrier time - See LU-11873
26177         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26178
26179         sleep 2
26180         local b_status=$(barrier_stat)
26181         echo "Got barrier status at: $(date)"
26182         [ "$b_status" = "'freezing_p1'" ] ||
26183                 error "(1) unexpected barrier status $b_status"
26184
26185         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26186         wait
26187         b_status=$(barrier_stat)
26188         [ "$b_status" = "'frozen'" ] ||
26189                 error "(2) unexpected barrier status $b_status"
26190
26191         local expired=$(barrier_expired)
26192         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26193         sleep $((expired + 3))
26194
26195         b_status=$(barrier_stat)
26196         [ "$b_status" = "'expired'" ] ||
26197                 error "(3) unexpected barrier status $b_status"
26198
26199         # Do not reduce barrier time - See LU-11873
26200         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26201                 error "(4) fail to freeze barrier"
26202
26203         b_status=$(barrier_stat)
26204         [ "$b_status" = "'frozen'" ] ||
26205                 error "(5) unexpected barrier status $b_status"
26206
26207         echo "Start barrier_thaw at: $(date)"
26208         #define OBD_FAIL_BARRIER_DELAY          0x2202
26209         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26210         do_facet mgs $LCTL barrier_thaw $FSNAME &
26211
26212         sleep 2
26213         b_status=$(barrier_stat)
26214         echo "Got barrier status at: $(date)"
26215         [ "$b_status" = "'thawing'" ] ||
26216                 error "(6) unexpected barrier status $b_status"
26217
26218         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26219         wait
26220         b_status=$(barrier_stat)
26221         [ "$b_status" = "'thawed'" ] ||
26222                 error "(7) unexpected barrier status $b_status"
26223
26224         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26225         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26226         do_facet mgs $LCTL barrier_freeze $FSNAME
26227
26228         b_status=$(barrier_stat)
26229         [ "$b_status" = "'failed'" ] ||
26230                 error "(8) unexpected barrier status $b_status"
26231
26232         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26233         do_facet mgs $LCTL barrier_thaw $FSNAME
26234
26235         post_801
26236 }
26237 run_test 801a "write barrier user interfaces and stat machine"
26238
26239 test_801b() {
26240         prep_801
26241
26242         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26243         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26244         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26245         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26246         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26247
26248         cancel_lru_locks mdc
26249
26250         # 180 seconds should be long enough
26251         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26252
26253         local b_status=$(barrier_stat)
26254         [ "$b_status" = "'frozen'" ] ||
26255                 error "(6) unexpected barrier status $b_status"
26256
26257         mkdir $DIR/$tdir/d0/d10 &
26258         mkdir_pid=$!
26259
26260         touch $DIR/$tdir/d1/f13 &
26261         touch_pid=$!
26262
26263         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26264         ln_pid=$!
26265
26266         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26267         mv_pid=$!
26268
26269         rm -f $DIR/$tdir/d4/f12 &
26270         rm_pid=$!
26271
26272         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26273
26274         # To guarantee taht the 'stat' is not blocked
26275         b_status=$(barrier_stat)
26276         [ "$b_status" = "'frozen'" ] ||
26277                 error "(8) unexpected barrier status $b_status"
26278
26279         # let above commands to run at background
26280         sleep 5
26281
26282         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26283         ps -p $touch_pid || error "(10) touch should be blocked"
26284         ps -p $ln_pid || error "(11) link should be blocked"
26285         ps -p $mv_pid || error "(12) rename should be blocked"
26286         ps -p $rm_pid || error "(13) unlink should be blocked"
26287
26288         b_status=$(barrier_stat)
26289         [ "$b_status" = "'frozen'" ] ||
26290                 error "(14) unexpected barrier status $b_status"
26291
26292         do_facet mgs $LCTL barrier_thaw $FSNAME
26293         b_status=$(barrier_stat)
26294         [ "$b_status" = "'thawed'" ] ||
26295                 error "(15) unexpected barrier status $b_status"
26296
26297         wait $mkdir_pid || error "(16) mkdir should succeed"
26298         wait $touch_pid || error "(17) touch should succeed"
26299         wait $ln_pid || error "(18) link should succeed"
26300         wait $mv_pid || error "(19) rename should succeed"
26301         wait $rm_pid || error "(20) unlink should succeed"
26302
26303         post_801
26304 }
26305 run_test 801b "modification will be blocked by write barrier"
26306
26307 test_801c() {
26308         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26309
26310         prep_801
26311
26312         stop mds2 || error "(1) Fail to stop mds2"
26313
26314         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26315
26316         local b_status=$(barrier_stat)
26317         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26318                 do_facet mgs $LCTL barrier_thaw $FSNAME
26319                 error "(2) unexpected barrier status $b_status"
26320         }
26321
26322         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26323                 error "(3) Fail to rescan barrier bitmap"
26324
26325         # Do not reduce barrier time - See LU-11873
26326         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26327
26328         b_status=$(barrier_stat)
26329         [ "$b_status" = "'frozen'" ] ||
26330                 error "(4) unexpected barrier status $b_status"
26331
26332         do_facet mgs $LCTL barrier_thaw $FSNAME
26333         b_status=$(barrier_stat)
26334         [ "$b_status" = "'thawed'" ] ||
26335                 error "(5) unexpected barrier status $b_status"
26336
26337         local devname=$(mdsdevname 2)
26338
26339         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26340
26341         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26342                 error "(7) Fail to rescan barrier bitmap"
26343
26344         post_801
26345 }
26346 run_test 801c "rescan barrier bitmap"
26347
26348 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26349 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26350 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26351 saved_MOUNT_OPTS=$MOUNT_OPTS
26352
26353 cleanup_802a() {
26354         trap 0
26355
26356         stopall
26357         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26358         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26359         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26360         MOUNT_OPTS=$saved_MOUNT_OPTS
26361         setupall
26362 }
26363
26364 test_802a() {
26365         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26366         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26367         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26368                 skip "Need server version at least 2.9.55"
26369
26370         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26371
26372         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26373
26374         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26375                 error "(2) Fail to copy"
26376
26377         trap cleanup_802a EXIT
26378
26379         # sync by force before remount as readonly
26380         sync; sync_all_data; sleep 3; sync_all_data
26381
26382         stopall
26383
26384         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26385         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26386         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26387
26388         echo "Mount the server as read only"
26389         setupall server_only || error "(3) Fail to start servers"
26390
26391         echo "Mount client without ro should fail"
26392         mount_client $MOUNT &&
26393                 error "(4) Mount client without 'ro' should fail"
26394
26395         echo "Mount client with ro should succeed"
26396         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26397         mount_client $MOUNT ||
26398                 error "(5) Mount client with 'ro' should succeed"
26399
26400         echo "Modify should be refused"
26401         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26402
26403         echo "Read should be allowed"
26404         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26405                 error "(7) Read should succeed under ro mode"
26406
26407         cleanup_802a
26408 }
26409 run_test 802a "simulate readonly device"
26410
26411 test_802b() {
26412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26413         remote_mds_nodsh && skip "remote MDS with nodsh"
26414
26415         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26416                 skip "readonly option not available"
26417
26418         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26419
26420         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26421                 error "(2) Fail to copy"
26422
26423         # write back all cached data before setting MDT to readonly
26424         cancel_lru_locks
26425         sync_all_data
26426
26427         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26428         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26429
26430         echo "Modify should be refused"
26431         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26432
26433         echo "Read should be allowed"
26434         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26435                 error "(7) Read should succeed under ro mode"
26436
26437         # disable readonly
26438         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26439 }
26440 run_test 802b "be able to set MDTs to readonly"
26441
26442 test_803a() {
26443         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26444         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26445                 skip "MDS needs to be newer than 2.10.54"
26446
26447         mkdir_on_mdt0 $DIR/$tdir
26448         # Create some objects on all MDTs to trigger related logs objects
26449         for idx in $(seq $MDSCOUNT); do
26450                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26451                         $DIR/$tdir/dir${idx} ||
26452                         error "Fail to create $DIR/$tdir/dir${idx}"
26453         done
26454
26455         sync; sleep 3
26456         wait_delete_completed # ensure old test cleanups are finished
26457         echo "before create:"
26458         $LFS df -i $MOUNT
26459         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26460
26461         for i in {1..10}; do
26462                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26463                         error "Fail to create $DIR/$tdir/foo$i"
26464         done
26465
26466         sync; sleep 3
26467         echo "after create:"
26468         $LFS df -i $MOUNT
26469         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26470
26471         # allow for an llog to be cleaned up during the test
26472         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26473                 error "before ($before_used) + 10 > after ($after_used)"
26474
26475         for i in {1..10}; do
26476                 rm -rf $DIR/$tdir/foo$i ||
26477                         error "Fail to remove $DIR/$tdir/foo$i"
26478         done
26479
26480         sleep 3 # avoid MDT return cached statfs
26481         wait_delete_completed
26482         echo "after unlink:"
26483         $LFS df -i $MOUNT
26484         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26485
26486         # allow for an llog to be created during the test
26487         [ $after_used -le $((before_used + 1)) ] ||
26488                 error "after ($after_used) > before ($before_used) + 1"
26489 }
26490 run_test 803a "verify agent object for remote object"
26491
26492 test_803b() {
26493         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26494         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26495                 skip "MDS needs to be newer than 2.13.56"
26496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26497
26498         for i in $(seq 0 $((MDSCOUNT - 1))); do
26499                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26500         done
26501
26502         local before=0
26503         local after=0
26504
26505         local tmp
26506
26507         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26508         for i in $(seq 0 $((MDSCOUNT - 1))); do
26509                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26510                         awk '/getattr/ { print $2 }')
26511                 before=$((before + tmp))
26512         done
26513         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26514         for i in $(seq 0 $((MDSCOUNT - 1))); do
26515                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26516                         awk '/getattr/ { print $2 }')
26517                 after=$((after + tmp))
26518         done
26519
26520         [ $before -eq $after ] || error "getattr count $before != $after"
26521 }
26522 run_test 803b "remote object can getattr from cache"
26523
26524 test_804() {
26525         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26526         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26527                 skip "MDS needs to be newer than 2.10.54"
26528         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26529
26530         mkdir -p $DIR/$tdir
26531         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26532                 error "Fail to create $DIR/$tdir/dir0"
26533
26534         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26535         local dev=$(mdsdevname 2)
26536
26537         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26538                 grep ${fid} || error "NOT found agent entry for dir0"
26539
26540         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26541                 error "Fail to create $DIR/$tdir/dir1"
26542
26543         touch $DIR/$tdir/dir1/foo0 ||
26544                 error "Fail to create $DIR/$tdir/dir1/foo0"
26545         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26546         local rc=0
26547
26548         for idx in $(seq $MDSCOUNT); do
26549                 dev=$(mdsdevname $idx)
26550                 do_facet mds${idx} \
26551                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26552                         grep ${fid} && rc=$idx
26553         done
26554
26555         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26556                 error "Fail to rename foo0 to foo1"
26557         if [ $rc -eq 0 ]; then
26558                 for idx in $(seq $MDSCOUNT); do
26559                         dev=$(mdsdevname $idx)
26560                         do_facet mds${idx} \
26561                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26562                         grep ${fid} && rc=$idx
26563                 done
26564         fi
26565
26566         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26567                 error "Fail to rename foo1 to foo2"
26568         if [ $rc -eq 0 ]; then
26569                 for idx in $(seq $MDSCOUNT); do
26570                         dev=$(mdsdevname $idx)
26571                         do_facet mds${idx} \
26572                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26573                         grep ${fid} && rc=$idx
26574                 done
26575         fi
26576
26577         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26578
26579         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26580                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26581         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26582                 error "Fail to rename foo2 to foo0"
26583         unlink $DIR/$tdir/dir1/foo0 ||
26584                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26585         rm -rf $DIR/$tdir/dir0 ||
26586                 error "Fail to rm $DIR/$tdir/dir0"
26587
26588         for idx in $(seq $MDSCOUNT); do
26589                 dev=$(mdsdevname $idx)
26590                 rc=0
26591
26592                 stop mds${idx}
26593                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26594                         rc=$?
26595                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26596                         error "mount mds$idx failed"
26597                 df $MOUNT > /dev/null 2>&1
26598
26599                 # e2fsck should not return error
26600                 [ $rc -eq 0 ] ||
26601                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26602         done
26603 }
26604 run_test 804 "verify agent entry for remote entry"
26605
26606 cleanup_805() {
26607         do_facet $SINGLEMDS zfs set quota=$old $fsset
26608         unlinkmany $DIR/$tdir/f- 1000000
26609         trap 0
26610 }
26611
26612 test_805() {
26613         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26614         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26615         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26616                 skip "netfree not implemented before 0.7"
26617         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26618                 skip "Need MDS version at least 2.10.57"
26619
26620         local fsset
26621         local freekb
26622         local usedkb
26623         local old
26624         local quota
26625         local pref="osd-zfs.$FSNAME-MDT0000."
26626
26627         # limit available space on MDS dataset to meet nospace issue
26628         # quickly. then ZFS 0.7.2 can use reserved space if asked
26629         # properly (using netfree flag in osd_declare_destroy()
26630         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26631         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26632                 gawk '{print $3}')
26633         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26634         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26635         let "usedkb=usedkb-freekb"
26636         let "freekb=freekb/2"
26637         if let "freekb > 5000"; then
26638                 let "freekb=5000"
26639         fi
26640         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26641         trap cleanup_805 EXIT
26642         mkdir_on_mdt0 $DIR/$tdir
26643         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26644                 error "Can't set PFL layout"
26645         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26646         rm -rf $DIR/$tdir || error "not able to remove"
26647         do_facet $SINGLEMDS zfs set quota=$old $fsset
26648         trap 0
26649 }
26650 run_test 805 "ZFS can remove from full fs"
26651
26652 # Size-on-MDS test
26653 check_lsom_data()
26654 {
26655         local file=$1
26656         local expect=$(stat -c %s $file)
26657
26658         check_lsom_size $1 $expect
26659
26660         local blocks=$($LFS getsom -b $file)
26661         expect=$(stat -c %b $file)
26662         [[ $blocks == $expect ]] ||
26663                 error "$file expected blocks: $expect, got: $blocks"
26664 }
26665
26666 check_lsom_size()
26667 {
26668         local size
26669         local expect=$2
26670
26671         cancel_lru_locks mdc
26672
26673         size=$($LFS getsom -s $1)
26674         [[ $size == $expect ]] ||
26675                 error "$file expected size: $expect, got: $size"
26676 }
26677
26678 test_806() {
26679         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26680                 skip "Need MDS version at least 2.11.52"
26681
26682         local bs=1048576
26683
26684         touch $DIR/$tfile || error "touch $tfile failed"
26685
26686         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26687         save_lustre_params client "llite.*.xattr_cache" > $save
26688         lctl set_param llite.*.xattr_cache=0
26689         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26690
26691         # single-threaded write
26692         echo "Test SOM for single-threaded write"
26693         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26694                 error "write $tfile failed"
26695         check_lsom_size $DIR/$tfile $bs
26696
26697         local num=32
26698         local size=$(($num * $bs))
26699         local offset=0
26700         local i
26701
26702         echo "Test SOM for single client multi-threaded($num) write"
26703         $TRUNCATE $DIR/$tfile 0
26704         for ((i = 0; i < $num; i++)); do
26705                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26706                 local pids[$i]=$!
26707                 offset=$((offset + $bs))
26708         done
26709         for (( i=0; i < $num; i++ )); do
26710                 wait ${pids[$i]}
26711         done
26712         check_lsom_size $DIR/$tfile $size
26713
26714         $TRUNCATE $DIR/$tfile 0
26715         for ((i = 0; i < $num; i++)); do
26716                 offset=$((offset - $bs))
26717                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26718                 local pids[$i]=$!
26719         done
26720         for (( i=0; i < $num; i++ )); do
26721                 wait ${pids[$i]}
26722         done
26723         check_lsom_size $DIR/$tfile $size
26724
26725         # multi-client writes
26726         num=$(get_node_count ${CLIENTS//,/ })
26727         size=$(($num * $bs))
26728         offset=0
26729         i=0
26730
26731         echo "Test SOM for multi-client ($num) writes"
26732         $TRUNCATE $DIR/$tfile 0
26733         for client in ${CLIENTS//,/ }; do
26734                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26735                 local pids[$i]=$!
26736                 i=$((i + 1))
26737                 offset=$((offset + $bs))
26738         done
26739         for (( i=0; i < $num; i++ )); do
26740                 wait ${pids[$i]}
26741         done
26742         check_lsom_size $DIR/$tfile $offset
26743
26744         i=0
26745         $TRUNCATE $DIR/$tfile 0
26746         for client in ${CLIENTS//,/ }; do
26747                 offset=$((offset - $bs))
26748                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26749                 local pids[$i]=$!
26750                 i=$((i + 1))
26751         done
26752         for (( i=0; i < $num; i++ )); do
26753                 wait ${pids[$i]}
26754         done
26755         check_lsom_size $DIR/$tfile $size
26756
26757         # verify truncate
26758         echo "Test SOM for truncate"
26759         $TRUNCATE $DIR/$tfile 1048576
26760         check_lsom_size $DIR/$tfile 1048576
26761         $TRUNCATE $DIR/$tfile 1234
26762         check_lsom_size $DIR/$tfile 1234
26763
26764         # verify SOM blocks count
26765         echo "Verify SOM block count"
26766         $TRUNCATE $DIR/$tfile 0
26767         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26768                 error "failed to write file $tfile"
26769         check_lsom_data $DIR/$tfile
26770 }
26771 run_test 806 "Verify Lazy Size on MDS"
26772
26773 test_807() {
26774         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26775         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26776                 skip "Need MDS version at least 2.11.52"
26777
26778         # Registration step
26779         changelog_register || error "changelog_register failed"
26780         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26781         changelog_users $SINGLEMDS | grep -q $cl_user ||
26782                 error "User $cl_user not found in changelog_users"
26783
26784         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26785         save_lustre_params client "llite.*.xattr_cache" > $save
26786         lctl set_param llite.*.xattr_cache=0
26787         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26788
26789         rm -rf $DIR/$tdir || error "rm $tdir failed"
26790         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26791         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26792         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26793         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26794                 error "truncate $tdir/trunc failed"
26795
26796         local bs=1048576
26797         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26798                 error "write $tfile failed"
26799
26800         # multi-client wirtes
26801         local num=$(get_node_count ${CLIENTS//,/ })
26802         local offset=0
26803         local i=0
26804
26805         echo "Test SOM for multi-client ($num) writes"
26806         touch $DIR/$tfile || error "touch $tfile failed"
26807         $TRUNCATE $DIR/$tfile 0
26808         for client in ${CLIENTS//,/ }; do
26809                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26810                 local pids[$i]=$!
26811                 i=$((i + 1))
26812                 offset=$((offset + $bs))
26813         done
26814         for (( i=0; i < $num; i++ )); do
26815                 wait ${pids[$i]}
26816         done
26817
26818         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26819         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26820         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26821         check_lsom_data $DIR/$tdir/trunc
26822         check_lsom_data $DIR/$tdir/single_dd
26823         check_lsom_data $DIR/$tfile
26824
26825         rm -rf $DIR/$tdir
26826         # Deregistration step
26827         changelog_deregister || error "changelog_deregister failed"
26828 }
26829 run_test 807 "verify LSOM syncing tool"
26830
26831 check_som_nologged()
26832 {
26833         local lines=$($LFS changelog $FSNAME-MDT0000 |
26834                 grep 'x=trusted.som' | wc -l)
26835         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26836 }
26837
26838 test_808() {
26839         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26840                 skip "Need MDS version at least 2.11.55"
26841
26842         # Registration step
26843         changelog_register || error "changelog_register failed"
26844
26845         touch $DIR/$tfile || error "touch $tfile failed"
26846         check_som_nologged
26847
26848         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26849                 error "write $tfile failed"
26850         check_som_nologged
26851
26852         $TRUNCATE $DIR/$tfile 1234
26853         check_som_nologged
26854
26855         $TRUNCATE $DIR/$tfile 1048576
26856         check_som_nologged
26857
26858         # Deregistration step
26859         changelog_deregister || error "changelog_deregister failed"
26860 }
26861 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26862
26863 check_som_nodata()
26864 {
26865         $LFS getsom $1
26866         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26867 }
26868
26869 test_809() {
26870         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26871                 skip "Need MDS version at least 2.11.56"
26872
26873         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26874                 error "failed to create DoM-only file $DIR/$tfile"
26875         touch $DIR/$tfile || error "touch $tfile failed"
26876         check_som_nodata $DIR/$tfile
26877
26878         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26879                 error "write $tfile failed"
26880         check_som_nodata $DIR/$tfile
26881
26882         $TRUNCATE $DIR/$tfile 1234
26883         check_som_nodata $DIR/$tfile
26884
26885         $TRUNCATE $DIR/$tfile 4097
26886         check_som_nodata $DIR/$file
26887 }
26888 run_test 809 "Verify no SOM xattr store for DoM-only files"
26889
26890 test_810() {
26891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26892         $GSS && skip_env "could not run with gss"
26893         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26894                 skip "OST < 2.12.58 doesn't align checksum"
26895
26896         set_checksums 1
26897         stack_trap "set_checksums $ORIG_CSUM" EXIT
26898         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26899
26900         local csum
26901         local before
26902         local after
26903         for csum in $CKSUM_TYPES; do
26904                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26905                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26906                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26907                         eval set -- $i
26908                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26909                         before=$(md5sum $DIR/$tfile)
26910                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26911                         after=$(md5sum $DIR/$tfile)
26912                         [ "$before" == "$after" ] ||
26913                                 error "$csum: $before != $after bs=$1 seek=$2"
26914                 done
26915         done
26916 }
26917 run_test 810 "partial page writes on ZFS (LU-11663)"
26918
26919 test_812a() {
26920         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26921                 skip "OST < 2.12.51 doesn't support this fail_loc"
26922
26923         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26924         # ensure ost1 is connected
26925         stat $DIR/$tfile >/dev/null || error "can't stat"
26926         wait_osc_import_state client ost1 FULL
26927         # no locks, no reqs to let the connection idle
26928         cancel_lru_locks osc
26929
26930         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26931 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26932         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26933         wait_osc_import_state client ost1 CONNECTING
26934         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26935
26936         stat $DIR/$tfile >/dev/null || error "can't stat file"
26937 }
26938 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26939
26940 test_812b() { # LU-12378
26941         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26942                 skip "OST < 2.12.51 doesn't support this fail_loc"
26943
26944         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26945         # ensure ost1 is connected
26946         stat $DIR/$tfile >/dev/null || error "can't stat"
26947         wait_osc_import_state client ost1 FULL
26948         # no locks, no reqs to let the connection idle
26949         cancel_lru_locks osc
26950
26951         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26952 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26953         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26954         wait_osc_import_state client ost1 CONNECTING
26955         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26956
26957         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26958         wait_osc_import_state client ost1 IDLE
26959 }
26960 run_test 812b "do not drop no resend request for idle connect"
26961
26962 test_812c() {
26963         local old
26964
26965         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26966
26967         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26968         $LFS getstripe $DIR/$tfile
26969         $LCTL set_param osc.*.idle_timeout=10
26970         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26971         # ensure ost1 is connected
26972         stat $DIR/$tfile >/dev/null || error "can't stat"
26973         wait_osc_import_state client ost1 FULL
26974         # no locks, no reqs to let the connection idle
26975         cancel_lru_locks osc
26976
26977 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26978         $LCTL set_param fail_loc=0x80000533
26979         sleep 15
26980         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26981 }
26982 run_test 812c "idle import vs lock enqueue race"
26983
26984 test_813() {
26985         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26986         [ -z "$file_heat_sav" ] && skip "no file heat support"
26987
26988         local readsample
26989         local writesample
26990         local readbyte
26991         local writebyte
26992         local readsample1
26993         local writesample1
26994         local readbyte1
26995         local writebyte1
26996
26997         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26998         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26999
27000         $LCTL set_param -n llite.*.file_heat=1
27001         echo "Turn on file heat"
27002         echo "Period second: $period_second, Decay percentage: $decay_pct"
27003
27004         echo "QQQQ" > $DIR/$tfile
27005         echo "QQQQ" > $DIR/$tfile
27006         echo "QQQQ" > $DIR/$tfile
27007         cat $DIR/$tfile > /dev/null
27008         cat $DIR/$tfile > /dev/null
27009         cat $DIR/$tfile > /dev/null
27010         cat $DIR/$tfile > /dev/null
27011
27012         local out=$($LFS heat_get $DIR/$tfile)
27013
27014         $LFS heat_get $DIR/$tfile
27015         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27016         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27017         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27018         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27019
27020         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27021         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27022         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27023         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27024
27025         sleep $((period_second + 3))
27026         echo "Sleep $((period_second + 3)) seconds..."
27027         # The recursion formula to calculate the heat of the file f is as
27028         # follow:
27029         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27030         # Where Hi is the heat value in the period between time points i*I and
27031         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27032         # to the weight of Ci.
27033         out=$($LFS heat_get $DIR/$tfile)
27034         $LFS heat_get $DIR/$tfile
27035         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27036         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27037         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27038         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27039
27040         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27041                 error "read sample ($readsample) is wrong"
27042         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27043                 error "write sample ($writesample) is wrong"
27044         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27045                 error "read bytes ($readbyte) is wrong"
27046         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27047                 error "write bytes ($writebyte) is wrong"
27048
27049         echo "QQQQ" > $DIR/$tfile
27050         echo "QQQQ" > $DIR/$tfile
27051         echo "QQQQ" > $DIR/$tfile
27052         cat $DIR/$tfile > /dev/null
27053         cat $DIR/$tfile > /dev/null
27054         cat $DIR/$tfile > /dev/null
27055         cat $DIR/$tfile > /dev/null
27056
27057         sleep $((period_second + 3))
27058         echo "Sleep $((period_second + 3)) seconds..."
27059
27060         out=$($LFS heat_get $DIR/$tfile)
27061         $LFS heat_get $DIR/$tfile
27062         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27063         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27064         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27065         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27066
27067         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27068                 4 * $decay_pct) / 100") -eq 1 ] ||
27069                 error "read sample ($readsample1) is wrong"
27070         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27071                 3 * $decay_pct) / 100") -eq 1 ] ||
27072                 error "write sample ($writesample1) is wrong"
27073         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27074                 20 * $decay_pct) / 100") -eq 1 ] ||
27075                 error "read bytes ($readbyte1) is wrong"
27076         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27077                 15 * $decay_pct) / 100") -eq 1 ] ||
27078                 error "write bytes ($writebyte1) is wrong"
27079
27080         echo "Turn off file heat for the file $DIR/$tfile"
27081         $LFS heat_set -o $DIR/$tfile
27082
27083         echo "QQQQ" > $DIR/$tfile
27084         echo "QQQQ" > $DIR/$tfile
27085         echo "QQQQ" > $DIR/$tfile
27086         cat $DIR/$tfile > /dev/null
27087         cat $DIR/$tfile > /dev/null
27088         cat $DIR/$tfile > /dev/null
27089         cat $DIR/$tfile > /dev/null
27090
27091         out=$($LFS heat_get $DIR/$tfile)
27092         $LFS heat_get $DIR/$tfile
27093         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27094         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27095         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27096         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27097
27098         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27099         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27100         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27101         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27102
27103         echo "Trun on file heat for the file $DIR/$tfile"
27104         $LFS heat_set -O $DIR/$tfile
27105
27106         echo "QQQQ" > $DIR/$tfile
27107         echo "QQQQ" > $DIR/$tfile
27108         echo "QQQQ" > $DIR/$tfile
27109         cat $DIR/$tfile > /dev/null
27110         cat $DIR/$tfile > /dev/null
27111         cat $DIR/$tfile > /dev/null
27112         cat $DIR/$tfile > /dev/null
27113
27114         out=$($LFS heat_get $DIR/$tfile)
27115         $LFS heat_get $DIR/$tfile
27116         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27117         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27118         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27119         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27120
27121         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27122         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27123         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27124         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27125
27126         $LFS heat_set -c $DIR/$tfile
27127         $LCTL set_param -n llite.*.file_heat=0
27128         echo "Turn off file heat support for the Lustre filesystem"
27129
27130         echo "QQQQ" > $DIR/$tfile
27131         echo "QQQQ" > $DIR/$tfile
27132         echo "QQQQ" > $DIR/$tfile
27133         cat $DIR/$tfile > /dev/null
27134         cat $DIR/$tfile > /dev/null
27135         cat $DIR/$tfile > /dev/null
27136         cat $DIR/$tfile > /dev/null
27137
27138         out=$($LFS heat_get $DIR/$tfile)
27139         $LFS heat_get $DIR/$tfile
27140         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27141         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27142         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27143         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27144
27145         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27146         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27147         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27148         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27149
27150         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27151         rm -f $DIR/$tfile
27152 }
27153 run_test 813 "File heat verfication"
27154
27155 test_814()
27156 {
27157         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27158         echo -n y >> $DIR/$tfile
27159         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27160         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27161 }
27162 run_test 814 "sparse cp works as expected (LU-12361)"
27163
27164 test_815()
27165 {
27166         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27167         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27168 }
27169 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27170
27171 test_816() {
27172         local ost1_imp=$(get_osc_import_name client ost1)
27173         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27174                          cut -d'.' -f2)
27175
27176         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27177         # ensure ost1 is connected
27178
27179         stat $DIR/$tfile >/dev/null || error "can't stat"
27180         wait_osc_import_state client ost1 FULL
27181         # no locks, no reqs to let the connection idle
27182         cancel_lru_locks osc
27183         lru_resize_disable osc
27184         local before
27185         local now
27186         before=$($LCTL get_param -n \
27187                  ldlm.namespaces.$imp_name.lru_size)
27188
27189         wait_osc_import_state client ost1 IDLE
27190         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27191         now=$($LCTL get_param -n \
27192               ldlm.namespaces.$imp_name.lru_size)
27193         [ $before == $now ] || error "lru_size changed $before != $now"
27194 }
27195 run_test 816 "do not reset lru_resize on idle reconnect"
27196
27197 cleanup_817() {
27198         umount $tmpdir
27199         exportfs -u localhost:$DIR/nfsexp
27200         rm -rf $DIR/nfsexp
27201 }
27202
27203 test_817() {
27204         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27205
27206         mkdir -p $DIR/nfsexp
27207         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27208                 error "failed to export nfs"
27209
27210         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27211         stack_trap cleanup_817 EXIT
27212
27213         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27214                 error "failed to mount nfs to $tmpdir"
27215
27216         cp /bin/true $tmpdir
27217         $DIR/nfsexp/true || error "failed to execute 'true' command"
27218 }
27219 run_test 817 "nfsd won't cache write lock for exec file"
27220
27221 test_818() {
27222         mkdir $DIR/$tdir
27223         $LFS setstripe -c1 -i0 $DIR/$tfile
27224         $LFS setstripe -c1 -i1 $DIR/$tfile
27225         stop $SINGLEMDS
27226         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27227         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27228         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27229                 error "start $SINGLEMDS failed"
27230         rm -rf $DIR/$tdir
27231 }
27232 run_test 818 "unlink with failed llog"
27233
27234 test_819a() {
27235         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27236         cancel_lru_locks osc
27237         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27238         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27239         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27240         rm -f $TDIR/$tfile
27241 }
27242 run_test 819a "too big niobuf in read"
27243
27244 test_819b() {
27245         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27246         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27247         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27248         cancel_lru_locks osc
27249         sleep 1
27250         rm -f $TDIR/$tfile
27251 }
27252 run_test 819b "too big niobuf in write"
27253
27254
27255 function test_820_start_ost() {
27256         sleep 5
27257
27258         for num in $(seq $OSTCOUNT); do
27259                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27260         done
27261 }
27262
27263 test_820() {
27264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27265
27266         mkdir $DIR/$tdir
27267         umount_client $MOUNT || error "umount failed"
27268         for num in $(seq $OSTCOUNT); do
27269                 stop ost$num
27270         done
27271
27272         # mount client with no active OSTs
27273         # so that the client can't initialize max LOV EA size
27274         # from OSC notifications
27275         mount_client $MOUNT || error "mount failed"
27276         # delay OST starting to keep this 0 max EA size for a while
27277         test_820_start_ost &
27278
27279         # create a directory on MDS2
27280         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27281                 error "Failed to create directory"
27282         # open intent should update default EA size
27283         # see mdc_update_max_ea_from_body()
27284         # notice this is the very first RPC to MDS2
27285         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27286         ret=$?
27287         echo $out
27288         # With SSK, this situation can lead to -EPERM being returned.
27289         # In that case, simply retry.
27290         if [ $ret -ne 0 ] && $SHARED_KEY; then
27291                 if echo "$out" | grep -q "not permitted"; then
27292                         cp /etc/services $DIR/$tdir/mds2
27293                         ret=$?
27294                 fi
27295         fi
27296         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27297 }
27298 run_test 820 "update max EA from open intent"
27299
27300 test_822() {
27301         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27302
27303         save_lustre_params mds1 \
27304                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27305         do_facet $SINGLEMDS "$LCTL set_param -n \
27306                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27307         do_facet $SINGLEMDS "$LCTL set_param -n \
27308                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27309
27310         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27311         local maxage=$(do_facet mds1 $LCTL get_param -n \
27312                        osp.$FSNAME-OST0000*MDT0000.maxage)
27313         sleep $((maxage + 1))
27314
27315         #define OBD_FAIL_NET_ERROR_RPC          0x532
27316         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27317
27318         stack_trap "restore_lustre_params < $p; rm $p"
27319
27320         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27321                       osp.$FSNAME-OST0000*MDT0000.create_count")
27322         for i in $(seq 1 $count); do
27323                 touch $DIR/$tfile.${i} || error "touch failed"
27324         done
27325 }
27326 run_test 822 "test precreate failure"
27327
27328 #
27329 # tests that do cleanup/setup should be run at the end
27330 #
27331
27332 test_900() {
27333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27334         local ls
27335
27336         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27337         $LCTL set_param fail_loc=0x903
27338
27339         cancel_lru_locks MGC
27340
27341         FAIL_ON_ERROR=true cleanup
27342         FAIL_ON_ERROR=true setup
27343 }
27344 run_test 900 "umount should not race with any mgc requeue thread"
27345
27346 # LUS-6253/LU-11185
27347 test_901() {
27348         local oldc
27349         local newc
27350         local olds
27351         local news
27352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27353
27354         # some get_param have a bug to handle dot in param name
27355         cancel_lru_locks MGC
27356         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27357         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27358         umount_client $MOUNT || error "umount failed"
27359         mount_client $MOUNT || error "mount failed"
27360         cancel_lru_locks MGC
27361         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27362         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27363
27364         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27365         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27366
27367         return 0
27368 }
27369 run_test 901 "don't leak a mgc lock on client umount"
27370
27371 # LU-13377
27372 test_902() {
27373         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27374                 skip "client does not have LU-13377 fix"
27375         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27376         $LCTL set_param fail_loc=0x1415
27377         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27378         cancel_lru_locks osc
27379         rm -f $DIR/$tfile
27380 }
27381 run_test 902 "test short write doesn't hang lustre"
27382
27383 # LU-14711
27384 test_903() {
27385         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27386         echo "blah" > $DIR/${tfile}-2
27387         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27388         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27389         $LCTL set_param fail_loc=0x417 fail_val=20
27390
27391         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27392         sleep 1 # To start the destroy
27393         wait_destroy_complete 150 || error "Destroy taking too long"
27394         cat $DIR/$tfile > /dev/null || error "Evicted"
27395 }
27396 run_test 903 "Test long page discard does not cause evictions"
27397
27398 complete $SECONDS
27399 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27400 check_and_cleanup_lustre
27401 if [ "$I_MOUNTED" != "yes" ]; then
27402         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27403 fi
27404 exit_status