Whamcloud - gitweb
3a9f141cbfe5de2cdb18c083e8582e0d78019dd0
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_0e() { # LU-13417
257         (( $MDSCOUNT > 1 )) ||
258                 skip "We need at least 2 MDTs for this test"
259
260         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
261                 skip "Need server version at least 2.14.51"
262
263         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
264         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
265
266         [ $default_lmv_count -eq 1 ] ||
267                 error "$MOUNT default stripe count $default_lmv_count"
268
269         [ $default_lmv_index -eq -1 ] ||
270                 error "$MOUNT default stripe index $default_lmv_index"
271
272         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
273         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
274
275         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
276         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
277
278         [ $mdt_index1 -eq $mdt_index2 ] &&
279                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
280
281         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
282 }
283 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718         local devname=$(mdsdevname $mds_index)
719
720         echo "stop and checking mds${mds_index}:"
721         # e2fsck should not return error
722         stop mds${mds_index}
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 local devname=$(mdsdevname $mdt_index)
743                 # e2fsck should not return error
744                 stop mds${mdt_index}
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170 test_24t() {
1171         test_mkdir $DIR/R16a
1172         test_mkdir $DIR/R16a/b
1173         test_mkdir $DIR/R16a/b/c
1174         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1175         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1176         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1177 }
1178 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1179
1180 test_24u() { # bug12192
1181         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1182         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1183 }
1184 run_test 24u "create stripe file"
1185
1186 simple_cleanup_common() {
1187         local rc=0
1188         trap 0
1189         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1190
1191         local start=$SECONDS
1192         rm -rf $DIR/$tdir
1193         rc=$?
1194         wait_delete_completed
1195         echo "cleanup time $((SECONDS - start))"
1196         return $rc
1197 }
1198
1199 max_pages_per_rpc() {
1200         local mdtname="$(printf "MDT%04x" ${1:-0})"
1201         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1202 }
1203
1204 test_24v() {
1205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1206
1207         local nrfiles=${COUNT:-100000}
1208         local fname="$DIR/$tdir/$tfile"
1209
1210         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1211         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1212
1213         test_mkdir "$(dirname $fname)"
1214         # assume MDT0000 has the fewest inodes
1215         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1216         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1217         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1218
1219         trap simple_cleanup_common EXIT
1220
1221         createmany -m "$fname" $nrfiles
1222
1223         cancel_lru_locks mdc
1224         lctl set_param mdc.*.stats clear
1225
1226         # was previously test_24D: LU-6101
1227         # readdir() returns correct number of entries after cursor reload
1228         local num_ls=$(ls $DIR/$tdir | wc -l)
1229         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1230         local num_all=$(ls -a $DIR/$tdir | wc -l)
1231         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1232                 [ $num_all -ne $((nrfiles + 2)) ]; then
1233                         error "Expected $nrfiles files, got $num_ls " \
1234                                 "($num_uniq unique $num_all .&..)"
1235         fi
1236         # LU-5 large readdir
1237         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1238         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1239         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1240         # take into account of overhead in lu_dirpage header and end mark in
1241         # each page, plus one in rpc_num calculation.
1242         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1243         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1244         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1245         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1246         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1247         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1248         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1249         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1250                 error "large readdir doesn't take effect: " \
1251                       "$mds_readpage should be about $rpc_max"
1252
1253         simple_cleanup_common
1254 }
1255 run_test 24v "list large directory (test hash collision, b=17560)"
1256
1257 test_24w() { # bug21506
1258         SZ1=234852
1259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1260         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1261         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1262         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1263         [[ "$SZ1" -eq "$SZ2" ]] ||
1264                 error "Error reading at the end of the file $tfile"
1265 }
1266 run_test 24w "Reading a file larger than 4Gb"
1267
1268 test_24x() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1272                 skip "Need MDS version at least 2.7.56"
1273
1274         local MDTIDX=1
1275         local remote_dir=$DIR/$tdir/remote_dir
1276
1277         test_mkdir $DIR/$tdir
1278         $LFS mkdir -i $MDTIDX $remote_dir ||
1279                 error "create remote directory failed"
1280
1281         test_mkdir $DIR/$tdir/src_dir
1282         touch $DIR/$tdir/src_file
1283         test_mkdir $remote_dir/tgt_dir
1284         touch $remote_dir/tgt_file
1285
1286         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1287                 error "rename dir cross MDT failed!"
1288
1289         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1290                 error "rename file cross MDT failed!"
1291
1292         touch $DIR/$tdir/ln_file
1293         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1294                 error "ln file cross MDT failed"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24x "cross MDT rename/link"
1299
1300 test_24y() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1303
1304         local remote_dir=$DIR/$tdir/remote_dir
1305         local mdtidx=1
1306
1307         test_mkdir $DIR/$tdir
1308         $LFS mkdir -i $mdtidx $remote_dir ||
1309                 error "create remote directory failed"
1310
1311         test_mkdir $remote_dir/src_dir
1312         touch $remote_dir/src_file
1313         test_mkdir $remote_dir/tgt_dir
1314         touch $remote_dir/tgt_file
1315
1316         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1317                 error "rename subdir in the same remote dir failed!"
1318
1319         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1320                 error "rename files in the same remote dir failed!"
1321
1322         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1323                 error "link files in the same remote dir failed!"
1324
1325         rm -rf $DIR/$tdir || error "Can not delete directories"
1326 }
1327 run_test 24y "rename/link on the same dir should succeed"
1328
1329 test_24z() {
1330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1331         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1332                 skip "Need MDS version at least 2.12.51"
1333
1334         local index
1335
1336         for index in 0 1; do
1337                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1338                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1339         done
1340
1341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1344         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1345
1346         local mdts=$(comma_list $(mdts_nodes))
1347
1348         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1349         stack_trap "do_nodes $mdts $LCTL \
1350                 set_param mdt.*.enable_remote_rename=1" EXIT
1351
1352         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1353
1354         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1355         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1356 }
1357 run_test 24z "cross-MDT rename is done as cp"
1358
1359 test_24A() { # LU-3182
1360         local NFILES=5000
1361
1362         rm -rf $DIR/$tdir
1363         test_mkdir $DIR/$tdir
1364         trap simple_cleanup_common EXIT
1365         createmany -m $DIR/$tdir/$tfile $NFILES
1366         local t=$(ls $DIR/$tdir | wc -l)
1367         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1368         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1369         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1370            [ $v -ne $((NFILES + 2)) ] ; then
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372         fi
1373
1374         simple_cleanup_common || error "Can not delete directories"
1375 }
1376 run_test 24A "readdir() returns correct number of entries."
1377
1378 test_24B() { # LU-4805
1379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1380
1381         local count
1382
1383         test_mkdir $DIR/$tdir
1384         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1385                 error "create striped dir failed"
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 2 ] || error "Expected 2, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/a
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 3 ] || error "Expected 3, got $count"
1394
1395         touch $DIR/$tdir/striped_dir/.f
1396
1397         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1398         [ $count -eq 4 ] || error "Expected 4, got $count"
1399
1400         rm -rf $DIR/$tdir || error "Can not delete directories"
1401 }
1402 run_test 24B "readdir for striped dir return correct number of entries"
1403
1404 test_24C() {
1405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1406
1407         mkdir $DIR/$tdir
1408         mkdir $DIR/$tdir/d0
1409         mkdir $DIR/$tdir/d1
1410
1411         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1412                 error "create striped dir failed"
1413
1414         cd $DIR/$tdir/d0/striped_dir
1415
1416         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1417         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1418         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d0_ino" = "$parent_ino" ] ||
1421                 error ".. wrong, expect $d0_ino, get $parent_ino"
1422
1423         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1424                 error "mv striped dir failed"
1425
1426         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1427
1428         [ "$d1_ino" = "$parent_ino" ] ||
1429                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1430 }
1431 run_test 24C "check .. in striped dir"
1432
1433 test_24E() {
1434         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1436
1437         mkdir -p $DIR/$tdir
1438         mkdir $DIR/$tdir/src_dir
1439         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1440                 error "create remote source failed"
1441
1442         touch $DIR/$tdir/src_dir/src_child/a
1443
1444         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1445                 error "create remote target dir failed"
1446
1447         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "create remote target child failed"
1449
1450         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1451                 error "rename dir cross MDT failed!"
1452
1453         find $DIR/$tdir
1454
1455         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1456                 error "src_child still exists after rename"
1457
1458         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1459                 error "missing file(a) after rename"
1460
1461         rm -rf $DIR/$tdir || error "Can not delete directories"
1462 }
1463 run_test 24E "cross MDT rename/link"
1464
1465 test_24F () {
1466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1467
1468         local repeats=1000
1469         [ "$SLOW" = "no" ] && repeats=100
1470
1471         mkdir -p $DIR/$tdir
1472
1473         echo "$repeats repeats"
1474         for ((i = 0; i < repeats; i++)); do
1475                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1476                 touch $DIR/$tdir/test/a || error "touch fails"
1477                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1478                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1479         done
1480
1481         true
1482 }
1483 run_test 24F "hash order vs readdir (LU-11330)"
1484
1485 test_24G () {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487
1488         local ino1
1489         local ino2
1490
1491         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1492         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1493         touch $DIR/$tdir-0/f1 || error "touch f1"
1494         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1495         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1496         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1497         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1498         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1499 }
1500 run_test 24G "migrate symlink in rename"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27d() {
1724         test_mkdir $DIR/$tdir
1725         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1726                 error "setstripe failed"
1727         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1729 }
1730 run_test 27d "create file with default settings"
1731
1732 test_27e() {
1733         # LU-5839 adds check for existed layout before setting it
1734         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1735                 skip "Need MDS version at least 2.7.56"
1736
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741 }
1742 run_test 27e "setstripe existing file (should return error)"
1743
1744 test_27f() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1747                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1749                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1751         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1752 }
1753 run_test 27f "setstripe with bad stripe size (should return error)"
1754
1755 test_27g() {
1756         test_mkdir $DIR/$tdir
1757         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1758         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1759                 error "$DIR/$tdir/$tfile has object"
1760 }
1761 run_test 27g "$LFS getstripe with no objects"
1762
1763 test_27ga() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1767         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1768         local rc=$?
1769         (( rc == 2 )) || error "getstripe did not return ENOENT"
1770 }
1771 run_test 27ga "$LFS getstripe with missing file (should return error)"
1772
1773 test_27i() {
1774         test_mkdir $DIR/$tdir
1775         touch $DIR/$tdir/$tfile || error "touch failed"
1776         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1777                 error "missing objects"
1778 }
1779 run_test 27i "$LFS getstripe with some objects"
1780
1781 test_27j() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1784                 error "setstripe failed" || true
1785 }
1786 run_test 27j "setstripe with bad stripe offset (should return error)"
1787
1788 test_27k() { # bug 2844
1789         test_mkdir $DIR/$tdir
1790         local file=$DIR/$tdir/$tfile
1791         local ll_max_blksize=$((4 * 1024 * 1024))
1792         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1793         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1795         dd if=/dev/zero of=$file bs=4k count=1
1796         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1797         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1798 }
1799 run_test 27k "limit i_blksize for broken user apps"
1800
1801 test_27l() {
1802         mcreate $DIR/$tfile || error "creating file"
1803         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1804                 error "setstripe should have failed" || true
1805 }
1806 run_test 27l "check setstripe permissions (should return error)"
1807
1808 test_27m() {
1809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1810
1811         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1812                 skip_env "multiple clients -- skipping"
1813
1814         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1815                    head -n1)
1816         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1817                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1818         fi
1819         trap simple_cleanup_common EXIT
1820         test_mkdir $DIR/$tdir
1821         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1822         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1823                 error "dd should fill OST0"
1824         i=2
1825         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1826                 i=$((i + 1))
1827                 [ $i -gt 256 ] && break
1828         done
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it"
1834         i=$((i + 1))
1835         touch $DIR/$tdir/$tfile.$i
1836         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1837             awk '{print $1}'| grep -w "0") ] &&
1838                 error "OST0 was full but new created file still use it"
1839         simple_cleanup_common
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 __exhaust_precreations() {
1864         local OSTIDX=$1
1865         local FAILLOC=$2
1866         local FAILIDX=${3:-$OSTIDX}
1867         local ofacet=ost$((OSTIDX + 1))
1868
1869         mkdir_on_mdt0 $DIR/$tdir
1870         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1871         local mfacet=mds$((mdtidx + 1))
1872         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1873
1874         local OST=$(ostname_from_index $OSTIDX)
1875
1876         # on the mdt's osc
1877         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1878         local last_id=$(do_facet $mfacet lctl get_param -n \
1879                         osp.$mdtosc_proc1.prealloc_last_id)
1880         local next_id=$(do_facet $mfacet lctl get_param -n \
1881                         osp.$mdtosc_proc1.prealloc_next_id)
1882
1883         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1884         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1885
1886         test_mkdir -p $DIR/$tdir/${OST}
1887         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1888 #define OBD_FAIL_OST_ENOSPC              0x215
1889         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1890         echo "Creating to objid $last_id on ost $OST..."
1891         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1892         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1893         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1894 }
1895
1896 exhaust_precreations() {
1897         __exhaust_precreations $1 $2 $3
1898         sleep_maxage
1899 }
1900
1901 exhaust_all_precreations() {
1902         local i
1903         for (( i=0; i < OSTCOUNT; i++ )) ; do
1904                 __exhaust_precreations $i $1 -1
1905         done
1906         sleep_maxage
1907 }
1908
1909 test_27n() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917         exhaust_precreations 0 0x80000215
1918         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1919         touch $DIR/$tdir/$tfile || error "touch failed"
1920         $LFS getstripe $DIR/$tdir/$tfile
1921         reset_enospc
1922 }
1923 run_test 27n "create file with some full OSTs"
1924
1925 test_27o() {
1926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930
1931         reset_enospc
1932         rm -f $DIR/$tdir/$tfile
1933         exhaust_all_precreations 0x215
1934
1935         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1936
1937         reset_enospc
1938         rm -rf $DIR/$tdir/*
1939 }
1940 run_test 27o "create file with all full OSTs (should error)"
1941
1942 function create_and_checktime() {
1943         local fname=$1
1944         local loops=$2
1945         local i
1946
1947         for ((i=0; i < $loops; i++)); do
1948                 local start=$SECONDS
1949                 multiop $fname-$i Oc
1950                 ((SECONDS-start < TIMEOUT)) ||
1951                         error "creation took " $((SECONDS-$start)) && return 1
1952         done
1953 }
1954
1955 test_27oo() {
1956         local mdts=$(comma_list $(mdts_nodes))
1957
1958         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1959                 skip "Need MDS version at least 2.13.57"
1960
1961         local f0=$DIR/${tfile}-0
1962         local f1=$DIR/${tfile}-1
1963
1964         wait_delete_completed
1965
1966         # refill precreated objects
1967         $LFS setstripe -i0 -c1 $f0
1968
1969         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1970         # force QoS allocation policy
1971         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1972         stack_trap "do_nodes $mdts $LCTL set_param \
1973                 lov.*.qos_threshold_rr=$saved" EXIT
1974         sleep_maxage
1975
1976         # one OST is unavailable, but still have few objects preallocated
1977         stop ost1
1978         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1979                 rm -rf $f1 $DIR/$tdir*" EXIT
1980
1981         for ((i=0; i < 7; i++)); do
1982                 mkdir $DIR/$tdir$i || error "can't create dir"
1983                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1984                         error "can't set striping"
1985         done
1986         for ((i=0; i < 7; i++)); do
1987                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1988         done
1989         wait
1990 }
1991 run_test 27oo "don't let few threads to reserve too many objects"
1992
1993 test_27p() {
1994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1996         remote_mds_nodsh && skip "remote MDS with nodsh"
1997         remote_ost_nodsh && skip "remote OST with nodsh"
1998
1999         reset_enospc
2000         rm -f $DIR/$tdir/$tfile
2001         test_mkdir $DIR/$tdir
2002
2003         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2004         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2005         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2006
2007         exhaust_precreations 0 0x80000215
2008         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2009         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2010         $LFS getstripe $DIR/$tdir/$tfile
2011
2012         reset_enospc
2013 }
2014 run_test 27p "append to a truncated file with some full OSTs"
2015
2016 test_27q() {
2017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2019         remote_mds_nodsh && skip "remote MDS with nodsh"
2020         remote_ost_nodsh && skip "remote OST with nodsh"
2021
2022         reset_enospc
2023         rm -f $DIR/$tdir/$tfile
2024
2025         mkdir_on_mdt0 $DIR/$tdir
2026         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2027         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2028                 error "truncate $DIR/$tdir/$tfile failed"
2029         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2030
2031         exhaust_all_precreations 0x215
2032
2033         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2034         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2035
2036         reset_enospc
2037 }
2038 run_test 27q "append to truncated file with all OSTs full (should error)"
2039
2040 test_27r() {
2041         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2043         remote_mds_nodsh && skip "remote MDS with nodsh"
2044         remote_ost_nodsh && skip "remote OST with nodsh"
2045
2046         reset_enospc
2047         rm -f $DIR/$tdir/$tfile
2048         exhaust_precreations 0 0x80000215
2049
2050         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2051
2052         reset_enospc
2053 }
2054 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2055
2056 test_27s() { # bug 10725
2057         test_mkdir $DIR/$tdir
2058         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2059         local stripe_count=0
2060         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2061         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2062                 error "stripe width >= 2^32 succeeded" || true
2063
2064 }
2065 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2066
2067 test_27t() { # bug 10864
2068         WDIR=$(pwd)
2069         WLFS=$(which lfs)
2070         cd $DIR
2071         touch $tfile
2072         $WLFS getstripe $tfile
2073         cd $WDIR
2074 }
2075 run_test 27t "check that utils parse path correctly"
2076
2077 test_27u() { # bug 4900
2078         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2079         remote_mds_nodsh && skip "remote MDS with nodsh"
2080
2081         local index
2082         local list=$(comma_list $(mdts_nodes))
2083
2084 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2085         do_nodes $list $LCTL set_param fail_loc=0x139
2086         test_mkdir -p $DIR/$tdir
2087         trap simple_cleanup_common EXIT
2088         createmany -o $DIR/$tdir/t- 1000
2089         do_nodes $list $LCTL set_param fail_loc=0
2090
2091         TLOG=$TMP/$tfile.getstripe
2092         $LFS getstripe $DIR/$tdir > $TLOG
2093         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2094         unlinkmany $DIR/$tdir/t- 1000
2095         trap 0
2096         [[ $OBJS -gt 0 ]] &&
2097                 error "$OBJS objects created on OST-0. See $TLOG" ||
2098                 rm -f $TLOG
2099 }
2100 run_test 27u "skip object creation on OSC w/o objects"
2101
2102 test_27v() { # bug 4900
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105         remote_mds_nodsh && skip "remote MDS with nodsh"
2106         remote_ost_nodsh && skip "remote OST with nodsh"
2107
2108         exhaust_all_precreations 0x215
2109         reset_enospc
2110
2111         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2112
2113         touch $DIR/$tdir/$tfile
2114         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2115         # all except ost1
2116         for (( i=1; i < OSTCOUNT; i++ )); do
2117                 do_facet ost$i lctl set_param fail_loc=0x705
2118         done
2119         local START=`date +%s`
2120         createmany -o $DIR/$tdir/$tfile 32
2121
2122         local FINISH=`date +%s`
2123         local TIMEOUT=`lctl get_param -n timeout`
2124         local PROCESS=$((FINISH - START))
2125         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2126                error "$FINISH - $START >= $TIMEOUT / 2"
2127         sleep $((TIMEOUT / 2 - PROCESS))
2128         reset_enospc
2129 }
2130 run_test 27v "skip object creation on slow OST"
2131
2132 test_27w() { # bug 10997
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2135         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2136                 error "stripe size $size != 65536" || true
2137         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2138                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2139 }
2140 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2141
2142 test_27wa() {
2143         [[ $OSTCOUNT -lt 2 ]] &&
2144                 skip_env "skipping multiple stripe count/offset test"
2145
2146         test_mkdir $DIR/$tdir
2147         for i in $(seq 1 $OSTCOUNT); do
2148                 offset=$((i - 1))
2149                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2150                         error "setstripe -c $i -i $offset failed"
2151                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2152                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2153                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2154                 [ $index -ne $offset ] &&
2155                         error "stripe offset $index != $offset" || true
2156         done
2157 }
2158 run_test 27wa "check $LFS setstripe -c -i options"
2159
2160 test_27x() {
2161         remote_ost_nodsh && skip "remote OST with nodsh"
2162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2164
2165         OFFSET=$(($OSTCOUNT - 1))
2166         OSTIDX=0
2167         local OST=$(ostname_from_index $OSTIDX)
2168
2169         test_mkdir $DIR/$tdir
2170         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2171         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2174         for i in $(seq 0 $OFFSET); do
2175                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2176                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2177                 error "OST0 was degraded but new created file still use it"
2178         done
2179         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2180 }
2181 run_test 27x "create files while OST0 is degraded"
2182
2183 test_27y() {
2184         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2185         remote_mds_nodsh && skip "remote MDS with nodsh"
2186         remote_ost_nodsh && skip "remote OST with nodsh"
2187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2188
2189         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2190         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2191                 osp.$mdtosc.prealloc_last_id)
2192         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2193                 osp.$mdtosc.prealloc_next_id)
2194         local fcount=$((last_id - next_id))
2195         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2196         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2197
2198         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2199                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2200         local OST_DEACTIVE_IDX=-1
2201         local OSC
2202         local OSTIDX
2203         local OST
2204
2205         for OSC in $MDS_OSCS; do
2206                 OST=$(osc_to_ost $OSC)
2207                 OSTIDX=$(index_from_ostuuid $OST)
2208                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2209                         OST_DEACTIVE_IDX=$OSTIDX
2210                 fi
2211                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2212                         echo $OSC "is Deactivated:"
2213                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2214                 fi
2215         done
2216
2217         OSTIDX=$(index_from_ostuuid $OST)
2218         test_mkdir $DIR/$tdir
2219         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2220
2221         for OSC in $MDS_OSCS; do
2222                 OST=$(osc_to_ost $OSC)
2223                 OSTIDX=$(index_from_ostuuid $OST)
2224                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2225                         echo $OST "is degraded:"
2226                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2227                                                 obdfilter.$OST.degraded=1
2228                 fi
2229         done
2230
2231         sleep_maxage
2232         createmany -o $DIR/$tdir/$tfile $fcount
2233
2234         for OSC in $MDS_OSCS; do
2235                 OST=$(osc_to_ost $OSC)
2236                 OSTIDX=$(index_from_ostuuid $OST)
2237                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2238                         echo $OST "is recovered from degraded:"
2239                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2240                                                 obdfilter.$OST.degraded=0
2241                 else
2242                         do_facet $SINGLEMDS lctl --device %$OSC activate
2243                 fi
2244         done
2245
2246         # all osp devices get activated, hence -1 stripe count restored
2247         local stripe_count=0
2248
2249         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2250         # devices get activated.
2251         sleep_maxage
2252         $LFS setstripe -c -1 $DIR/$tfile
2253         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2254         rm -f $DIR/$tfile
2255         [ $stripe_count -ne $OSTCOUNT ] &&
2256                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2257         return 0
2258 }
2259 run_test 27y "create files while OST0 is degraded and the rest inactive"
2260
2261 check_seq_oid()
2262 {
2263         log "check file $1"
2264
2265         lmm_count=$($LFS getstripe -c $1)
2266         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2267         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2268
2269         local old_ifs="$IFS"
2270         IFS=$'[:]'
2271         fid=($($LFS path2fid $1))
2272         IFS="$old_ifs"
2273
2274         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2275         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2276
2277         # compare lmm_seq and lu_fid->f_seq
2278         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2279         # compare lmm_object_id and lu_fid->oid
2280         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2281
2282         # check the trusted.fid attribute of the OST objects of the file
2283         local have_obdidx=false
2284         local stripe_nr=0
2285         $LFS getstripe $1 | while read obdidx oid hex seq; do
2286                 # skip lines up to and including "obdidx"
2287                 [ -z "$obdidx" ] && break
2288                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2289                 $have_obdidx || continue
2290
2291                 local ost=$((obdidx + 1))
2292                 local dev=$(ostdevname $ost)
2293                 local oid_hex
2294
2295                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2296
2297                 seq=$(echo $seq | sed -e "s/^0x//g")
2298                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2299                         oid_hex=$(echo $oid)
2300                 else
2301                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2302                 fi
2303                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2304
2305                 local ff=""
2306                 #
2307                 # Don't unmount/remount the OSTs if we don't need to do that.
2308                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2309                 # update too, until that use mount/ll_decode_filter_fid/mount.
2310                 # Re-enable when debugfs will understand new filter_fid.
2311                 #
2312                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2313                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2314                                 $dev 2>/dev/null" | grep "parent=")
2315                 fi
2316                 if [ -z "$ff" ]; then
2317                         stop ost$ost
2318                         mount_fstype ost$ost
2319                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2320                                 $(facet_mntpt ost$ost)/$obj_file)
2321                         unmount_fstype ost$ost
2322                         start ost$ost $dev $OST_MOUNT_OPTS
2323                         clients_up
2324                 fi
2325
2326                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2327
2328                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2329
2330                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2331                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2332                 #
2333                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2334                 #       stripe_size=1048576 component_id=1 component_start=0 \
2335                 #       component_end=33554432
2336                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2337                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2338                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2339                 local ff_pstripe
2340                 if grep -q 'stripe=' <<<$ff; then
2341                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2342                 else
2343                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2344                         # into f_ver in this case.  See comment on ff_parent.
2345                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2346                 fi
2347
2348                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2349                 [ $ff_pseq = $lmm_seq ] ||
2350                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2351                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2352                 [ $ff_poid = $lmm_oid ] ||
2353                         error "FF parent OID $ff_poid != $lmm_oid"
2354                 (($ff_pstripe == $stripe_nr)) ||
2355                         error "FF stripe $ff_pstripe != $stripe_nr"
2356
2357                 stripe_nr=$((stripe_nr + 1))
2358                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2359                         continue
2360                 if grep -q 'stripe_count=' <<<$ff; then
2361                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2362                                             -e 's/ .*//' <<<$ff)
2363                         [ $lmm_count = $ff_scnt ] ||
2364                                 error "FF stripe count $lmm_count != $ff_scnt"
2365                 fi
2366         done
2367 }
2368
2369 test_27z() {
2370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2371         remote_ost_nodsh && skip "remote OST with nodsh"
2372
2373         test_mkdir $DIR/$tdir
2374         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2375                 { error "setstripe -c -1 failed"; return 1; }
2376         # We need to send a write to every object to get parent FID info set.
2377         # This _should_ also work for setattr, but does not currently.
2378         # touch $DIR/$tdir/$tfile-1 ||
2379         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2380                 { error "dd $tfile-1 failed"; return 2; }
2381         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2382                 { error "setstripe -c -1 failed"; return 3; }
2383         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2384                 { error "dd $tfile-2 failed"; return 4; }
2385
2386         # make sure write RPCs have been sent to OSTs
2387         sync; sleep 5; sync
2388
2389         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2390         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2391 }
2392 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2393
2394 test_27A() { # b=19102
2395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2396
2397         save_layout_restore_at_exit $MOUNT
2398         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2399         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2400                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2401         local default_size=$($LFS getstripe -S $MOUNT)
2402         local default_offset=$($LFS getstripe -i $MOUNT)
2403         local dsize=$(do_facet $SINGLEMDS \
2404                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2405         [ $default_size -eq $dsize ] ||
2406                 error "stripe size $default_size != $dsize"
2407         [ $default_offset -eq -1 ] ||
2408                 error "stripe offset $default_offset != -1"
2409 }
2410 run_test 27A "check filesystem-wide default LOV EA values"
2411
2412 test_27B() { # LU-2523
2413         test_mkdir $DIR/$tdir
2414         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2415         touch $DIR/$tdir/f0
2416         # open f1 with O_LOV_DELAY_CREATE
2417         # rename f0 onto f1
2418         # call setstripe ioctl on open file descriptor for f1
2419         # close
2420         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2421                 $DIR/$tdir/f0
2422
2423         rm -f $DIR/$tdir/f1
2424         # open f1 with O_LOV_DELAY_CREATE
2425         # unlink f1
2426         # call setstripe ioctl on open file descriptor for f1
2427         # close
2428         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2429
2430         # Allow multiop to fail in imitation of NFS's busted semantics.
2431         true
2432 }
2433 run_test 27B "call setstripe on open unlinked file/rename victim"
2434
2435 # 27C family tests full striping and overstriping
2436 test_27Ca() { #LU-2871
2437         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2438
2439         declare -a ost_idx
2440         local index
2441         local found
2442         local i
2443         local j
2444
2445         test_mkdir $DIR/$tdir
2446         cd $DIR/$tdir
2447         for i in $(seq 0 $((OSTCOUNT - 1))); do
2448                 # set stripe across all OSTs starting from OST$i
2449                 $LFS setstripe -i $i -c -1 $tfile$i
2450                 # get striping information
2451                 ost_idx=($($LFS getstripe $tfile$i |
2452                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2453                 echo ${ost_idx[@]}
2454
2455                 # check the layout
2456                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2457                         error "${#ost_idx[@]} != $OSTCOUNT"
2458
2459                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2460                         found=0
2461                         for j in $(echo ${ost_idx[@]}); do
2462                                 if [ $index -eq $j ]; then
2463                                         found=1
2464                                         break
2465                                 fi
2466                         done
2467                         [ $found = 1 ] ||
2468                                 error "Can not find $index in ${ost_idx[@]}"
2469                 done
2470         done
2471 }
2472 run_test 27Ca "check full striping across all OSTs"
2473
2474 test_27Cb() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2478                 skip_env "too many osts, skipping"
2479
2480         test_mkdir -p $DIR/$tdir
2481         local setcount=$(($OSTCOUNT * 2))
2482         [ $setcount -lt 160 ] || large_xattr_enabled ||
2483                 skip_env "ea_inode feature disabled"
2484
2485         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2486                 error "setstripe failed"
2487
2488         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2489         [ $count -eq $setcount ] ||
2490                 error "stripe count $count, should be $setcount"
2491
2492         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2493                 error "overstriped should be set in pattern"
2494
2495         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2496                 error "dd failed"
2497 }
2498 run_test 27Cb "more stripes than OSTs with -C"
2499
2500 test_27Cc() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2504
2505         test_mkdir -p $DIR/$tdir
2506         local setcount=$(($OSTCOUNT - 1))
2507
2508         [ $setcount -lt 160 ] || large_xattr_enabled ||
2509                 skip_env "ea_inode feature disabled"
2510
2511         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2512                 error "setstripe failed"
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2519                 error "overstriped should not be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523 }
2524 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2525
2526 test_27Cd() {
2527         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2528                 skip "server does not support overstriping"
2529         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2530         large_xattr_enabled || skip_env "ea_inode feature disabled"
2531
2532         test_mkdir -p $DIR/$tdir
2533         local setcount=$LOV_MAX_STRIPE_COUNT
2534
2535         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2536                 error "setstripe failed"
2537
2538         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2539         [ $count -eq $setcount ] ||
2540                 error "stripe count $count, should be $setcount"
2541
2542         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2543                 error "overstriped should be set in pattern"
2544
2545         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2546                 error "dd failed"
2547
2548         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2549 }
2550 run_test 27Cd "test maximum stripe count"
2551
2552 test_27Ce() {
2553         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2554                 skip "server does not support overstriping"
2555         test_mkdir -p $DIR/$tdir
2556
2557         pool_add $TESTNAME || error "Pool creation failed"
2558         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2559
2560         local setcount=8
2561
2562         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2563                 error "setstripe failed"
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Ce "test pool with overstriping"
2578
2579 test_27Cf() {
2580         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2581                 skip "server does not support overstriping"
2582         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2583                 skip_env "too many osts, skipping"
2584
2585         test_mkdir -p $DIR/$tdir
2586
2587         local setcount=$(($OSTCOUNT * 2))
2588         [ $setcount -lt 160 ] || large_xattr_enabled ||
2589                 skip_env "ea_inode feature disabled"
2590
2591         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2592                 error "setstripe failed"
2593
2594         echo 1 > $DIR/$tdir/$tfile
2595
2596         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2597         [ $count -eq $setcount ] ||
2598                 error "stripe count $count, should be $setcount"
2599
2600         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2601                 error "overstriped should be set in pattern"
2602
2603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2604                 error "dd failed"
2605
2606         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2607 }
2608 run_test 27Cf "test default inheritance with overstriping"
2609
2610 test_27D() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2613         remote_mds_nodsh && skip "remote MDS with nodsh"
2614
2615         local POOL=${POOL:-testpool}
2616         local first_ost=0
2617         local last_ost=$(($OSTCOUNT - 1))
2618         local ost_step=1
2619         local ost_list=$(seq $first_ost $ost_step $last_ost)
2620         local ost_range="$first_ost $last_ost $ost_step"
2621
2622         test_mkdir $DIR/$tdir
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2625
2626         local skip27D
2627         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2628                 skip27D+="-s 29"
2629         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2630                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2631                         skip27D+=" -s 30,31"
2632         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2633           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2634                 skip27D+=" -s 32,33"
2635         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2636                 skip27D+=" -s 34"
2637         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2638                 error "llapi_layout_test failed"
2639
2640         destroy_test_pools || error "destroy test pools failed"
2641 }
2642 run_test 27D "validate llapi_layout API"
2643
2644 # Verify that default_easize is increased from its initial value after
2645 # accessing a widely striped file.
2646 test_27E() {
2647         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2648         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2649                 skip "client does not have LU-3338 fix"
2650
2651         # 72 bytes is the minimum space required to store striping
2652         # information for a file striped across one OST:
2653         # (sizeof(struct lov_user_md_v3) +
2654         #  sizeof(struct lov_user_ost_data_v1))
2655         local min_easize=72
2656         $LCTL set_param -n llite.*.default_easize $min_easize ||
2657                 error "lctl set_param failed"
2658         local easize=$($LCTL get_param -n llite.*.default_easize)
2659
2660         [ $easize -eq $min_easize ] ||
2661                 error "failed to set default_easize"
2662
2663         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2664                 error "setstripe failed"
2665         # In order to ensure stat() call actually talks to MDS we need to
2666         # do something drastic to this file to shake off all lock, e.g.
2667         # rename it (kills lookup lock forcing cache cleaning)
2668         mv $DIR/$tfile $DIR/${tfile}-1
2669         ls -l $DIR/${tfile}-1
2670         rm $DIR/${tfile}-1
2671
2672         easize=$($LCTL get_param -n llite.*.default_easize)
2673
2674         [ $easize -gt $min_easize ] ||
2675                 error "default_easize not updated"
2676 }
2677 run_test 27E "check that default extended attribute size properly increases"
2678
2679 test_27F() { # LU-5346/LU-7975
2680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2681         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2682         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2683                 skip "Need MDS version at least 2.8.51"
2684         remote_ost_nodsh && skip "remote OST with nodsh"
2685
2686         test_mkdir $DIR/$tdir
2687         rm -f $DIR/$tdir/f0
2688         $LFS setstripe -c 2 $DIR/$tdir
2689
2690         # stop all OSTs to reproduce situation for LU-7975 ticket
2691         for num in $(seq $OSTCOUNT); do
2692                 stop ost$num
2693         done
2694
2695         # open/create f0 with O_LOV_DELAY_CREATE
2696         # truncate f0 to a non-0 size
2697         # close
2698         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2699
2700         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2701         # open/write it again to force delayed layout creation
2702         cat /etc/hosts > $DIR/$tdir/f0 &
2703         catpid=$!
2704
2705         # restart OSTs
2706         for num in $(seq $OSTCOUNT); do
2707                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2708                         error "ost$num failed to start"
2709         done
2710
2711         wait $catpid || error "cat failed"
2712
2713         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2714         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2715                 error "wrong stripecount"
2716
2717 }
2718 run_test 27F "Client resend delayed layout creation with non-zero size"
2719
2720 test_27G() { #LU-10629
2721         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2722                 skip "Need MDS version at least 2.11.51"
2723         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2724         remote_mds_nodsh && skip "remote MDS with nodsh"
2725         local POOL=${POOL:-testpool}
2726         local ostrange="0 0 1"
2727
2728         test_mkdir $DIR/$tdir
2729         touch $DIR/$tdir/$tfile.nopool
2730         pool_add $POOL || error "pool_add failed"
2731         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2732         $LFS setstripe -p $POOL $DIR/$tdir
2733
2734         local pool=$($LFS getstripe -p $DIR/$tdir)
2735
2736         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2737         touch $DIR/$tdir/$tfile.default
2738         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2739         $LFS find $DIR/$tdir -type f --pool $POOL
2740         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2741         [[ "$found" == "2" ]] ||
2742                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2743
2744         $LFS setstripe -d $DIR/$tdir
2745
2746         pool=$($LFS getstripe -p -d $DIR/$tdir)
2747
2748         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2749 }
2750 run_test 27G "Clear OST pool from stripe"
2751
2752 test_27H() {
2753         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2754                 skip "Need MDS version newer than 2.11.54"
2755         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2756         test_mkdir $DIR/$tdir
2757         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2758         touch $DIR/$tdir/$tfile
2759         $LFS getstripe -c $DIR/$tdir/$tfile
2760         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2761                 error "two-stripe file doesn't have two stripes"
2762
2763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2764         $LFS getstripe -y $DIR/$tdir/$tfile
2765         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2766              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2767                 error "expected l_ost_idx: [02]$ not matched"
2768
2769         # make sure ost list has been cleared
2770         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2771         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2772                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2773         touch $DIR/$tdir/f3
2774         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2775 }
2776 run_test 27H "Set specific OSTs stripe"
2777
2778 test_27I() {
2779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2780         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2781         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2782                 skip "Need MDS version newer than 2.12.52"
2783         local pool=$TESTNAME
2784         local ostrange="1 1 1"
2785
2786         save_layout_restore_at_exit $MOUNT
2787         $LFS setstripe -c 2 -i 0 $MOUNT
2788         pool_add $pool || error "pool_add failed"
2789         pool_add_targets $pool $ostrange ||
2790                 error "pool_add_targets failed"
2791         test_mkdir $DIR/$tdir
2792         $LFS setstripe -p $pool $DIR/$tdir
2793         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2794         $LFS getstripe $DIR/$tdir/$tfile
2795 }
2796 run_test 27I "check that root dir striping does not break parent dir one"
2797
2798 test_27J() {
2799         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2800                 skip "Need MDS version newer than 2.12.51"
2801
2802         test_mkdir $DIR/$tdir
2803         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2804         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2805
2806         # create foreign file (raw way)
2807         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2808                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2809
2810         ! $LFS setstripe --foreign --flags foo \
2811                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2812                         error "creating $tfile with '--flags foo' should fail"
2813
2814         ! $LFS setstripe --foreign --flags 0xffffffff \
2815                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2816                         error "creating $tfile w/ 0xffffffff flags should fail"
2817
2818         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2819                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2820
2821         # verify foreign file (raw way)
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2825         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_size: 73" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2830         parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_type: 1" ||
2832                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2833         parse_foreign_file -f $DIR/$tdir/$tfile |
2834                 grep "lov_foreign_flags: 0x0000DA08" ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2836         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2837                 grep "lov_foreign_value: 0x" |
2838                 sed -e 's/lov_foreign_value: 0x//')
2839         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2840         [[ $lov = ${lov2// /} ]] ||
2841                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2842
2843         # create foreign file (lfs + API)
2844         $LFS setstripe --foreign=none --flags 0xda08 \
2845                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: create failed"
2847
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2849                 grep "lfm_magic:.*0x0BD70BD0" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2851         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2852         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2854         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2856         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2857                 grep "lfm_flags:.*0x0000DA08" ||
2858                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2859         $LFS getstripe $DIR/$tdir/${tfile}2 |
2860                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2861                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2862
2863         # modify striping should fail
2864         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2865                 error "$DIR/$tdir/$tfile: setstripe should fail"
2866         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2868
2869         # R/W should fail
2870         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2871         cat $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: read should fail"
2873         cat /etc/passwd > $DIR/$tdir/$tfile &&
2874                 error "$DIR/$tdir/$tfile: write should fail"
2875         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2876                 error "$DIR/$tdir/${tfile}2: write should fail"
2877
2878         # chmod should work
2879         chmod 222 $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chmod failed"
2881         chmod 222 $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chmod failed"
2883
2884         # chown should work
2885         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2886                 error "$DIR/$tdir/$tfile: chown failed"
2887         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2888                 error "$DIR/$tdir/${tfile}2: chown failed"
2889
2890         # rename should work
2891         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2893         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2895
2896         #remove foreign file
2897         rm $DIR/$tdir/${tfile}.new ||
2898                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2899         rm $DIR/$tdir/${tfile}2.new ||
2900                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2901 }
2902 run_test 27J "basic ops on file with foreign LOV"
2903
2904 test_27K() {
2905         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2906                 skip "Need MDS version newer than 2.12.49"
2907
2908         test_mkdir $DIR/$tdir
2909         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2910         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2911
2912         # create foreign dir (raw way)
2913         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2914                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2915
2916         ! $LFS setdirstripe --foreign --flags foo \
2917                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2918                         error "creating $tdir with '--flags foo' should fail"
2919
2920         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2921                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2922                         error "creating $tdir w/ 0xffffffff flags should fail"
2923
2924         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2925                 error "create_foreign_dir FAILED"
2926
2927         # verify foreign dir (raw way)
2928         parse_foreign_dir -d $DIR/$tdir/$tdir |
2929                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2930                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2931         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2933         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2934                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2935         parse_foreign_dir -d $DIR/$tdir/$tdir |
2936                 grep "lmv_foreign_flags: 55813$" ||
2937                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2938         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2939                 grep "lmv_foreign_value: 0x" |
2940                 sed 's/lmv_foreign_value: 0x//')
2941         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2942                 sed 's/ //g')
2943         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2944
2945         # create foreign dir (lfs + API)
2946         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2947                 $DIR/$tdir/${tdir}2 ||
2948                 error "$DIR/$tdir/${tdir}2: create failed"
2949
2950         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2951                 grep "lfm_magic:.*0x0CD50CD0" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2953         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2954         # - sizeof(lfm_type) - sizeof(lfm_flags)
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2956                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2959         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_flags:.*0x0000DA05" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2962         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2963                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2964                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2965
2966         # file create in dir should fail
2967         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2968         touch $DIR/$tdir/${tdir}2/$tfile &&
2969                 "$DIR/${tdir}2: file create should fail"
2970
2971         # chmod should work
2972         chmod 777 $DIR/$tdir/$tdir ||
2973                 error "$DIR/$tdir: chmod failed"
2974         chmod 777 $DIR/$tdir/${tdir}2 ||
2975                 error "$DIR/${tdir}2: chmod failed"
2976
2977         # chown should work
2978         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2979                 error "$DIR/$tdir: chown failed"
2980         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2981                 error "$DIR/${tdir}2: chown failed"
2982
2983         # rename should work
2984         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2985                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2986         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2987                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2988
2989         #remove foreign dir
2990         rmdir $DIR/$tdir/${tdir}.new ||
2991                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2992         rmdir $DIR/$tdir/${tdir}2.new ||
2993                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2994 }
2995 run_test 27K "basic ops on dir with foreign LMV"
2996
2997 test_27L() {
2998         remote_mds_nodsh && skip "remote MDS with nodsh"
2999
3000         local POOL=${POOL:-$TESTNAME}
3001
3002         pool_add $POOL || error "pool_add failed"
3003
3004         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3005                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3006                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3007 }
3008 run_test 27L "lfs pool_list gives correct pool name"
3009
3010 test_27M() {
3011         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3012                 skip "Need MDS version >= than 2.12.57"
3013         remote_mds_nodsh && skip "remote MDS with nodsh"
3014         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3015
3016         test_mkdir $DIR/$tdir
3017
3018         # Set default striping on directory
3019         local setcount=4
3020         local stripe_opt
3021
3022         # if we run against a 2.12 server which lacks overstring support
3023         # then the connect_flag will not report overstriping, even if client
3024         # is 2.14+
3025         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3026                 stripe_opt="-C $setcount"
3027         elif (( $OSTCOUNT >= $setcount )); then
3028                 stripe_opt="-c $setcount"
3029         else
3030                 skip "server does not support overstriping"
3031         fi
3032         $LFS setstripe $stripe_opt $DIR/$tdir
3033
3034         echo 1 > $DIR/$tdir/${tfile}.1
3035         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3036         [ $count -eq $setcount ] ||
3037                 error "(1) stripe count $count, should be $setcount"
3038
3039         # Capture existing append_stripe_count setting for restore
3040         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3041         local mdts=$(comma_list $(mdts_nodes))
3042         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3043
3044         local appendcount=$orig_count
3045         echo 1 >> $DIR/$tdir/${tfile}.2_append
3046         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3047         [ $count -eq $appendcount ] ||
3048                 error "(2)stripe count $count, should be $appendcount for append"
3049
3050         # Disable O_APPEND striping, verify it works
3051         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3052
3053         # Should now get the default striping, which is 4
3054         setcount=4
3055         echo 1 >> $DIR/$tdir/${tfile}.3_append
3056         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3057         [ $count -eq $setcount ] ||
3058                 error "(3) stripe count $count, should be $setcount"
3059
3060         # Try changing the stripe count for append files
3061         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3062
3063         # Append striping is now 2 (directory default is still 4)
3064         appendcount=2
3065         echo 1 >> $DIR/$tdir/${tfile}.4_append
3066         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3067         [ $count -eq $appendcount ] ||
3068                 error "(4) stripe count $count, should be $appendcount for append"
3069
3070         # Test append stripe count of -1
3071         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3072         appendcount=$OSTCOUNT
3073         echo 1 >> $DIR/$tdir/${tfile}.5
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3075         [ $count -eq $appendcount ] ||
3076                 error "(5) stripe count $count, should be $appendcount for append"
3077
3078         # Set append striping back to default of 1
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3080
3081         # Try a new default striping, PFL + DOM
3082         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3083
3084         # Create normal DOM file, DOM returns stripe count == 0
3085         setcount=0
3086         touch $DIR/$tdir/${tfile}.6
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3088         [ $count -eq $setcount ] ||
3089                 error "(6) stripe count $count, should be $setcount"
3090
3091         # Show
3092         appendcount=1
3093         echo 1 >> $DIR/$tdir/${tfile}.7_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3095         [ $count -eq $appendcount ] ||
3096                 error "(7) stripe count $count, should be $appendcount for append"
3097
3098         # Clean up DOM layout
3099         $LFS setstripe -d $DIR/$tdir
3100
3101         save_layout_restore_at_exit $MOUNT
3102         # Now test that append striping works when layout is from root
3103         $LFS setstripe -c 2 $MOUNT
3104         # Make a special directory for this
3105         mkdir $DIR/${tdir}/${tdir}.2
3106
3107         # Verify for normal file
3108         setcount=2
3109         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3110         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3111         [ $count -eq $setcount ] ||
3112                 error "(8) stripe count $count, should be $setcount"
3113
3114         appendcount=1
3115         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3116         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3117         [ $count -eq $appendcount ] ||
3118                 error "(9) stripe count $count, should be $appendcount for append"
3119
3120         # Now test O_APPEND striping with pools
3121         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3122         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3123
3124         # Create the pool
3125         pool_add $TESTNAME || error "pool creation failed"
3126         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3127
3128         echo 1 >> $DIR/$tdir/${tfile}.10_append
3129
3130         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3131         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3132
3133         # Check that count is still correct
3134         appendcount=1
3135         echo 1 >> $DIR/$tdir/${tfile}.11_append
3136         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3137         [ $count -eq $appendcount ] ||
3138                 error "(11) stripe count $count, should be $appendcount for append"
3139
3140         # Disable O_APPEND stripe count, verify pool works separately
3141         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3142
3143         echo 1 >> $DIR/$tdir/${tfile}.12_append
3144
3145         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3146         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3147
3148         # Remove pool setting, verify it's not applied
3149         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3150
3151         echo 1 >> $DIR/$tdir/${tfile}.13_append
3152
3153         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3154         [ "$pool" = "" ] || error "(13) pool found: $pool"
3155 }
3156 run_test 27M "test O_APPEND striping"
3157
3158 test_27N() {
3159         combined_mgs_mds && skip "needs separate MGS/MDT"
3160
3161         pool_add $TESTNAME || error "pool_add failed"
3162         do_facet mgs "$LCTL pool_list $FSNAME" |
3163                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3164                 error "lctl pool_list on MGS failed"
3165 }
3166 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3167
3168 clean_foreign_symlink() {
3169         trap 0
3170         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3171         for i in $DIR/$tdir/* ; do
3172                 $LFS unlink_foreign $i || true
3173         done
3174 }
3175
3176 test_27O() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3178                 skip "Need MDS version newer than 2.12.51"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LOV format is a partial path by default
3190
3191         # create foreign file (lfs + API)
3192         $LFS setstripe --foreign=symlink --flags 0xda05 \
3193                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3194                 error "$DIR/$tdir/${tfile}: create failed"
3195
3196         $LFS getstripe -v $DIR/$tdir/${tfile} |
3197                 grep "lfm_magic:.*0x0BD70BD0" ||
3198                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3199         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3204         $LFS getstripe $DIR/$tdir/${tfile} |
3205                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3207
3208         # modify striping should fail
3209         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3210                 error "$DIR/$tdir/$tfile: setstripe should fail"
3211
3212         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3213         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3214         cat /etc/passwd > $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: write should fail"
3216
3217         # rename should succeed
3218         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3219                 error "$DIR/$tdir/$tfile: rename has failed"
3220
3221         #remove foreign_symlink file should fail
3222         rm $DIR/$tdir/${tfile}.new &&
3223                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3224
3225         #test fake symlink
3226         mkdir /tmp/${uuid1} ||
3227                 error "/tmp/${uuid1}: mkdir has failed"
3228         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3229                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3231         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3232                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3233         #read should succeed now
3234         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3235                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3236         #write should succeed now
3237         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3239         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3240                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3241         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3242                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3243
3244         #check that getstripe still works
3245         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3247
3248         # chmod should still succeed
3249         chmod 644 $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3251
3252         # chown should still succeed
3253         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3254                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3255
3256         # rename should still succeed
3257         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3258                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3259
3260         #remove foreign_symlink file should still fail
3261         rm $DIR/$tdir/${tfile} &&
3262                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3263
3264         #use special ioctl() to unlink foreign_symlink file
3265         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3266                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3267
3268 }
3269 run_test 27O "basic ops on foreign file of symlink type"
3270
3271 test_27P() {
3272         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3273                 skip "Need MDS version newer than 2.12.49"
3274
3275         test_mkdir $DIR/$tdir
3276         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3277         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3278
3279         trap clean_foreign_symlink EXIT
3280
3281         # enable foreign_symlink behaviour
3282         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3283
3284         # foreign symlink LMV format is a partial path by default
3285
3286         # create foreign dir (lfs + API)
3287         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3288                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3289                 error "$DIR/$tdir/${tdir}: create failed"
3290
3291         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3292                 grep "lfm_magic:.*0x0CD50CD0" ||
3293                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3294         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3295                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3297                 grep "lfm_flags:.*0x0000DA05" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3299         $LFS getdirstripe $DIR/$tdir/${tdir} |
3300                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3302
3303         # file create in dir should fail
3304         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3305         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3306
3307         # rename should succeed
3308         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3309                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3310
3311         #remove foreign_symlink dir should fail
3312         rmdir $DIR/$tdir/${tdir}.new &&
3313                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3314
3315         #test fake symlink
3316         mkdir -p /tmp/${uuid1}/${uuid2} ||
3317                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3318         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3319                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3320         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3321         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3322                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3323         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3324                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3325
3326         #check that getstripe fails now that foreign_symlink enabled
3327         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3328                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3329
3330         # file create in dir should work now
3331         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3332                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3333         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3334                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3335         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3336                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3337
3338         # chmod should still succeed
3339         chmod 755 $DIR/$tdir/${tdir}.new ||
3340                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3341
3342         # chown should still succeed
3343         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3344                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3345
3346         # rename should still succeed
3347         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3348                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3349
3350         #remove foreign_symlink dir should still fail
3351         rmdir $DIR/$tdir/${tdir} &&
3352                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3353
3354         #use special ioctl() to unlink foreign_symlink file
3355         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3356                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3357
3358         #created file should still exist
3359         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3360                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3361         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3362                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3363 }
3364 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3365
3366 test_27Q() {
3367         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3368         stack_trap "rm -f $TMP/$tfile*"
3369
3370         test_mkdir $DIR/$tdir-1
3371         test_mkdir $DIR/$tdir-2
3372
3373         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3374         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3375
3376         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3377         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3378
3379         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3380         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3381
3382         # Create some bad symlinks and ensure that we don't loop
3383         # forever or something. These should return ELOOP (40) and
3384         # ENOENT (2) but I don't want to test for that because there's
3385         # always some weirdo architecture that needs to ruin
3386         # everything by defining these error numbers differently.
3387
3388         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3389         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3390
3391         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3392         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3393
3394         return 0
3395 }
3396 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3397
3398 # createtest also checks that device nodes are created and
3399 # then visible correctly (#2091)
3400 test_28() { # bug 2091
3401         test_mkdir $DIR/d28
3402         $CREATETEST $DIR/d28/ct || error "createtest failed"
3403 }
3404 run_test 28 "create/mknod/mkdir with bad file types ============"
3405
3406 test_29() {
3407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3408
3409         sync; sleep 1; sync # flush out any dirty pages from previous tests
3410         cancel_lru_locks
3411         test_mkdir $DIR/d29
3412         touch $DIR/d29/foo
3413         log 'first d29'
3414         ls -l $DIR/d29
3415
3416         declare -i LOCKCOUNTORIG=0
3417         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3418                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3419         done
3420         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3421
3422         declare -i LOCKUNUSEDCOUNTORIG=0
3423         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3424                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3425         done
3426
3427         log 'second d29'
3428         ls -l $DIR/d29
3429         log 'done'
3430
3431         declare -i LOCKCOUNTCURRENT=0
3432         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3433                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3434         done
3435
3436         declare -i LOCKUNUSEDCOUNTCURRENT=0
3437         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3438                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3439         done
3440
3441         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3442                 $LCTL set_param -n ldlm.dump_namespaces ""
3443                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3444                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3445                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3446                 return 2
3447         fi
3448         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3449                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3450                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3451                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3452                 return 3
3453         fi
3454 }
3455 run_test 29 "IT_GETATTR regression  ============================"
3456
3457 test_30a() { # was test_30
3458         cp $(which ls) $DIR || cp /bin/ls $DIR
3459         $DIR/ls / || error "Can't execute binary from lustre"
3460         rm $DIR/ls
3461 }
3462 run_test 30a "execute binary from Lustre (execve) =============="
3463
3464 test_30b() {
3465         cp `which ls` $DIR || cp /bin/ls $DIR
3466         chmod go+rx $DIR/ls
3467         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3468         rm $DIR/ls
3469 }
3470 run_test 30b "execute binary from Lustre as non-root ==========="
3471
3472 test_30c() { # b=22376
3473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3474
3475         cp $(which ls) $DIR || cp /bin/ls $DIR
3476         chmod a-rw $DIR/ls
3477         cancel_lru_locks mdc
3478         cancel_lru_locks osc
3479         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3480         rm -f $DIR/ls
3481 }
3482 run_test 30c "execute binary from Lustre without read perms ===="
3483
3484 test_30d() {
3485         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3486
3487         for i in {1..10}; do
3488                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3489                 local PID=$!
3490                 sleep 1
3491                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3492                 wait $PID || error "executing dd from Lustre failed"
3493                 rm -f $DIR/$tfile
3494         done
3495
3496         rm -f $DIR/dd
3497 }
3498 run_test 30d "execute binary from Lustre while clear locks"
3499
3500 test_31a() {
3501         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3502         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3503 }
3504 run_test 31a "open-unlink file =================================="
3505
3506 test_31b() {
3507         touch $DIR/f31 || error "touch $DIR/f31 failed"
3508         ln $DIR/f31 $DIR/f31b || error "ln failed"
3509         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3510         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3511 }
3512 run_test 31b "unlink file with multiple links while open ======="
3513
3514 test_31c() {
3515         touch $DIR/f31 || error "touch $DIR/f31 failed"
3516         ln $DIR/f31 $DIR/f31c || error "ln failed"
3517         multiop_bg_pause $DIR/f31 O_uc ||
3518                 error "multiop_bg_pause for $DIR/f31 failed"
3519         MULTIPID=$!
3520         $MULTIOP $DIR/f31c Ouc
3521         kill -USR1 $MULTIPID
3522         wait $MULTIPID
3523 }
3524 run_test 31c "open-unlink file with multiple links ============="
3525
3526 test_31d() {
3527         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3528         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3529 }
3530 run_test 31d "remove of open directory ========================="
3531
3532 test_31e() { # bug 2904
3533         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3534 }
3535 run_test 31e "remove of open non-empty directory ==============="
3536
3537 test_31f() { # bug 4554
3538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3539
3540         set -vx
3541         test_mkdir $DIR/d31f
3542         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3543         cp /etc/hosts $DIR/d31f
3544         ls -l $DIR/d31f
3545         $LFS getstripe $DIR/d31f/hosts
3546         multiop_bg_pause $DIR/d31f D_c || return 1
3547         MULTIPID=$!
3548
3549         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3550         test_mkdir $DIR/d31f
3551         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3552         cp /etc/hosts $DIR/d31f
3553         ls -l $DIR/d31f
3554         $LFS getstripe $DIR/d31f/hosts
3555         multiop_bg_pause $DIR/d31f D_c || return 1
3556         MULTIPID2=$!
3557
3558         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3559         wait $MULTIPID || error "first opendir $MULTIPID failed"
3560
3561         sleep 6
3562
3563         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3564         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3565         set +vx
3566 }
3567 run_test 31f "remove of open directory with open-unlink file ==="
3568
3569 test_31g() {
3570         echo "-- cross directory link --"
3571         test_mkdir -c1 $DIR/${tdir}ga
3572         test_mkdir -c1 $DIR/${tdir}gb
3573         touch $DIR/${tdir}ga/f
3574         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3575         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3576         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3577         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3578         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3579 }
3580 run_test 31g "cross directory link==============="
3581
3582 test_31h() {
3583         echo "-- cross directory link --"
3584         test_mkdir -c1 $DIR/${tdir}
3585         test_mkdir -c1 $DIR/${tdir}/dir
3586         touch $DIR/${tdir}/f
3587         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3588         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3589         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3590         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3591         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3592 }
3593 run_test 31h "cross directory link under child==============="
3594
3595 test_31i() {
3596         echo "-- cross directory link --"
3597         test_mkdir -c1 $DIR/$tdir
3598         test_mkdir -c1 $DIR/$tdir/dir
3599         touch $DIR/$tdir/dir/f
3600         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3601         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3602         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3603         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3604         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3605 }
3606 run_test 31i "cross directory link under parent==============="
3607
3608 test_31j() {
3609         test_mkdir -c1 -p $DIR/$tdir
3610         test_mkdir -c1 -p $DIR/$tdir/dir1
3611         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3612         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3613         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3614         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3615         return 0
3616 }
3617 run_test 31j "link for directory==============="
3618
3619 test_31k() {
3620         test_mkdir -c1 -p $DIR/$tdir
3621         touch $DIR/$tdir/s
3622         touch $DIR/$tdir/exist
3623         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3624         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3625         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3626         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3627         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3628         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3629         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3630         return 0
3631 }
3632 run_test 31k "link to file: the same, non-existing, dir==============="
3633
3634 test_31m() {
3635         mkdir $DIR/d31m
3636         touch $DIR/d31m/s
3637         mkdir $DIR/d31m2
3638         touch $DIR/d31m2/exist
3639         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3640         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3641         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3642         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3643         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3644         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3645         return 0
3646 }
3647 run_test 31m "link to file: the same, non-existing, dir==============="
3648
3649 test_31n() {
3650         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3651         nlink=$(stat --format=%h $DIR/$tfile)
3652         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3653         local fd=$(free_fd)
3654         local cmd="exec $fd<$DIR/$tfile"
3655         eval $cmd
3656         cmd="exec $fd<&-"
3657         trap "eval $cmd" EXIT
3658         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3659         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3660         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3661         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3662         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3663         eval $cmd
3664 }
3665 run_test 31n "check link count of unlinked file"
3666
3667 link_one() {
3668         local tempfile=$(mktemp $1_XXXXXX)
3669         mlink $tempfile $1 2> /dev/null &&
3670                 echo "$BASHPID: link $tempfile to $1 succeeded"
3671         munlink $tempfile
3672 }
3673
3674 test_31o() { # LU-2901
3675         test_mkdir $DIR/$tdir
3676         for LOOP in $(seq 100); do
3677                 rm -f $DIR/$tdir/$tfile*
3678                 for THREAD in $(seq 8); do
3679                         link_one $DIR/$tdir/$tfile.$LOOP &
3680                 done
3681                 wait
3682                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3683                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3684                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3685                         break || true
3686         done
3687 }
3688 run_test 31o "duplicate hard links with same filename"
3689
3690 test_31p() {
3691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3692
3693         test_mkdir $DIR/$tdir
3694         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3695         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3696
3697         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3698                 error "open unlink test1 failed"
3699         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3700                 error "open unlink test2 failed"
3701
3702         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3703                 error "test1 still exists"
3704         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3705                 error "test2 still exists"
3706 }
3707 run_test 31p "remove of open striped directory"
3708
3709 test_31q() {
3710         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3711
3712         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3713         index=$($LFS getdirstripe -i $DIR/$tdir)
3714         [ $index -eq 3 ] || error "first stripe index $index != 3"
3715         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3716         [ $index -eq 1 ] || error "second stripe index $index != 1"
3717
3718         # when "-c <stripe_count>" is set, the number of MDTs specified after
3719         # "-i" should equal to the stripe count
3720         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3721 }
3722 run_test 31q "create striped directory on specific MDTs"
3723
3724 #LU-14949
3725 test_31r() {
3726         touch $DIR/$tfile.target
3727         touch $DIR/$tfile.source
3728
3729         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3730         $LCTL set_param fail_loc=0x1419 fail_val=3
3731         cat $DIR/$tfile.target &
3732         CATPID=$!
3733
3734         # Guarantee open is waiting before we get here
3735         sleep 1
3736         mv $DIR/$tfile.source $DIR/$tfile.target
3737
3738         wait $CATPID
3739         RC=$?
3740         if [[ $RC -ne 0 ]]; then
3741                 error "open with cat failed, rc=$RC"
3742         fi
3743 }
3744 run_test 31r "open-rename(replace) race"
3745
3746 cleanup_test32_mount() {
3747         local rc=0
3748         trap 0
3749         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3750         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3751         losetup -d $loopdev || true
3752         rm -rf $DIR/$tdir
3753         return $rc
3754 }
3755
3756 test_32a() {
3757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3758
3759         echo "== more mountpoints and symlinks ================="
3760         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3761         trap cleanup_test32_mount EXIT
3762         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3763         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3764                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3765         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3766                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3767         cleanup_test32_mount
3768 }
3769 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3770
3771 test_32b() {
3772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3773
3774         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3775         trap cleanup_test32_mount EXIT
3776         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3777         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3778                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3779         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3780                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3781         cleanup_test32_mount
3782 }
3783 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3784
3785 test_32c() {
3786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3787
3788         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3789         trap cleanup_test32_mount EXIT
3790         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3791         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3792                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3793         test_mkdir -p $DIR/$tdir/d2/test_dir
3794         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3795                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3796         cleanup_test32_mount
3797 }
3798 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3799
3800 test_32d() {
3801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3802
3803         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3804         trap cleanup_test32_mount EXIT
3805         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3806         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3807                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3808         test_mkdir -p $DIR/$tdir/d2/test_dir
3809         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3810                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3811         cleanup_test32_mount
3812 }
3813 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3814
3815 test_32e() {
3816         rm -fr $DIR/$tdir
3817         test_mkdir -p $DIR/$tdir/tmp
3818         local tmp_dir=$DIR/$tdir/tmp
3819         ln -s $DIR/$tdir $tmp_dir/symlink11
3820         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3821         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3822         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3823 }
3824 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3825
3826 test_32f() {
3827         rm -fr $DIR/$tdir
3828         test_mkdir -p $DIR/$tdir/tmp
3829         local tmp_dir=$DIR/$tdir/tmp
3830         ln -s $DIR/$tdir $tmp_dir/symlink11
3831         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3832         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3833         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3834 }
3835 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3836
3837 test_32g() {
3838         local tmp_dir=$DIR/$tdir/tmp
3839         test_mkdir -p $tmp_dir
3840         test_mkdir $DIR/${tdir}2
3841         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3842         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3843         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3844         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3845         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3846         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3847 }
3848 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3849
3850 test_32h() {
3851         rm -fr $DIR/$tdir $DIR/${tdir}2
3852         tmp_dir=$DIR/$tdir/tmp
3853         test_mkdir -p $tmp_dir
3854         test_mkdir $DIR/${tdir}2
3855         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3856         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3857         ls $tmp_dir/symlink12 || error "listing symlink12"
3858         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3859 }
3860 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3861
3862 test_32i() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         touch $DIR/$tdir/test_file
3871         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3872                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3873         cleanup_test32_mount
3874 }
3875 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3876
3877 test_32j() {
3878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3879
3880         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3881         trap cleanup_test32_mount EXIT
3882         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3883         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3884                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3885         touch $DIR/$tdir/test_file
3886         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3887                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3888         cleanup_test32_mount
3889 }
3890 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3891
3892 test_32k() {
3893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3894
3895         rm -fr $DIR/$tdir
3896         trap cleanup_test32_mount EXIT
3897         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3898         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3899                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3900         test_mkdir -p $DIR/$tdir/d2
3901         touch $DIR/$tdir/d2/test_file || error "touch failed"
3902         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3903                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3904         cleanup_test32_mount
3905 }
3906 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3907
3908 test_32l() {
3909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3910
3911         rm -fr $DIR/$tdir
3912         trap cleanup_test32_mount EXIT
3913         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3914         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3915                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3916         test_mkdir -p $DIR/$tdir/d2
3917         touch $DIR/$tdir/d2/test_file || error "touch failed"
3918         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3919                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3920         cleanup_test32_mount
3921 }
3922 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3923
3924 test_32m() {
3925         rm -fr $DIR/d32m
3926         test_mkdir -p $DIR/d32m/tmp
3927         TMP_DIR=$DIR/d32m/tmp
3928         ln -s $DIR $TMP_DIR/symlink11
3929         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3930         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3931                 error "symlink11 not a link"
3932         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3933                 error "symlink01 not a link"
3934 }
3935 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3936
3937 test_32n() {
3938         rm -fr $DIR/d32n
3939         test_mkdir -p $DIR/d32n/tmp
3940         TMP_DIR=$DIR/d32n/tmp
3941         ln -s $DIR $TMP_DIR/symlink11
3942         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3943         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3944         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3945 }
3946 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3947
3948 test_32o() {
3949         touch $DIR/$tfile
3950         test_mkdir -p $DIR/d32o/tmp
3951         TMP_DIR=$DIR/d32o/tmp
3952         ln -s $DIR/$tfile $TMP_DIR/symlink12
3953         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3954         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3955                 error "symlink12 not a link"
3956         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3957         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3958                 error "$DIR/d32o/tmp/symlink12 not file type"
3959         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3960                 error "$DIR/d32o/symlink02 not file type"
3961 }
3962 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3963
3964 test_32p() {
3965         log 32p_1
3966         rm -fr $DIR/d32p
3967         log 32p_2
3968         rm -f $DIR/$tfile
3969         log 32p_3
3970         touch $DIR/$tfile
3971         log 32p_4
3972         test_mkdir -p $DIR/d32p/tmp
3973         log 32p_5
3974         TMP_DIR=$DIR/d32p/tmp
3975         log 32p_6
3976         ln -s $DIR/$tfile $TMP_DIR/symlink12
3977         log 32p_7
3978         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3979         log 32p_8
3980         cat $DIR/d32p/tmp/symlink12 ||
3981                 error "Can't open $DIR/d32p/tmp/symlink12"
3982         log 32p_9
3983         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3984         log 32p_10
3985 }
3986 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3987
3988 test_32q() {
3989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3990
3991         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3992         trap cleanup_test32_mount EXIT
3993         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3994         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3995         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3996                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3997         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3998         cleanup_test32_mount
3999 }
4000 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4001
4002 test_32r() {
4003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4004
4005         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4006         trap cleanup_test32_mount EXIT
4007         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4008         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4009         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4010                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4011         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4012         cleanup_test32_mount
4013 }
4014 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4015
4016 test_33aa() {
4017         rm -f $DIR/$tfile
4018         touch $DIR/$tfile
4019         chmod 444 $DIR/$tfile
4020         chown $RUNAS_ID $DIR/$tfile
4021         log 33_1
4022         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4023         log 33_2
4024 }
4025 run_test 33aa "write file with mode 444 (should return error)"
4026
4027 test_33a() {
4028         rm -fr $DIR/$tdir
4029         test_mkdir $DIR/$tdir
4030         chown $RUNAS_ID $DIR/$tdir
4031         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4032                 error "$RUNAS create $tdir/$tfile failed"
4033         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4034                 error "open RDWR" || true
4035 }
4036 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4037
4038 test_33b() {
4039         rm -fr $DIR/$tdir
4040         test_mkdir $DIR/$tdir
4041         chown $RUNAS_ID $DIR/$tdir
4042         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4043 }
4044 run_test 33b "test open file with malformed flags (No panic)"
4045
4046 test_33c() {
4047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4048         remote_ost_nodsh && skip "remote OST with nodsh"
4049
4050         local ostnum
4051         local ostname
4052         local write_bytes
4053         local all_zeros
4054
4055         all_zeros=true
4056         test_mkdir $DIR/$tdir
4057         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4058
4059         sync
4060         for ostnum in $(seq $OSTCOUNT); do
4061                 # test-framework's OST numbering is one-based, while Lustre's
4062                 # is zero-based
4063                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4064                 # check if at least some write_bytes stats are counted
4065                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4066                               obdfilter.$ostname.stats |
4067                               awk '/^write_bytes/ {print $7}' )
4068                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4069                 if (( ${write_bytes:-0} > 0 )); then
4070                         all_zeros=false
4071                         break
4072                 fi
4073         done
4074
4075         $all_zeros || return 0
4076
4077         # Write four bytes
4078         echo foo > $DIR/$tdir/bar
4079         # Really write them
4080         sync
4081
4082         # Total up write_bytes after writing.  We'd better find non-zeros.
4083         for ostnum in $(seq $OSTCOUNT); do
4084                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4085                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4086                               obdfilter/$ostname/stats |
4087                               awk '/^write_bytes/ {print $7}' )
4088                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4089                 if (( ${write_bytes:-0} > 0 )); then
4090                         all_zeros=false
4091                         break
4092                 fi
4093         done
4094
4095         if $all_zeros; then
4096                 for ostnum in $(seq $OSTCOUNT); do
4097                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4098                         echo "Check write_bytes is in obdfilter.*.stats:"
4099                         do_facet ost$ostnum lctl get_param -n \
4100                                 obdfilter.$ostname.stats
4101                 done
4102                 error "OST not keeping write_bytes stats (b=22312)"
4103         fi
4104 }
4105 run_test 33c "test write_bytes stats"
4106
4107 test_33d() {
4108         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110
4111         local MDTIDX=1
4112         local remote_dir=$DIR/$tdir/remote_dir
4113
4114         test_mkdir $DIR/$tdir
4115         $LFS mkdir -i $MDTIDX $remote_dir ||
4116                 error "create remote directory failed"
4117
4118         touch $remote_dir/$tfile
4119         chmod 444 $remote_dir/$tfile
4120         chown $RUNAS_ID $remote_dir/$tfile
4121
4122         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4123
4124         chown $RUNAS_ID $remote_dir
4125         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4126                                         error "create" || true
4127         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4128                                     error "open RDWR" || true
4129         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4130 }
4131 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4132
4133 test_33e() {
4134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4135
4136         mkdir $DIR/$tdir
4137
4138         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4139         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4140         mkdir $DIR/$tdir/local_dir
4141
4142         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4143         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4144         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4145
4146         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4147                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4148
4149         rmdir $DIR/$tdir/* || error "rmdir failed"
4150
4151         umask 777
4152         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4153         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4154         mkdir $DIR/$tdir/local_dir
4155
4156         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4157         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4158         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4159
4160         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4161                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4162
4163         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4164
4165         umask 000
4166         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4167         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4168         mkdir $DIR/$tdir/local_dir
4169
4170         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4171         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4172         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4173
4174         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4175                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4176 }
4177 run_test 33e "mkdir and striped directory should have same mode"
4178
4179 cleanup_33f() {
4180         trap 0
4181         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4182 }
4183
4184 test_33f() {
4185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4186         remote_mds_nodsh && skip "remote MDS with nodsh"
4187
4188         mkdir $DIR/$tdir
4189         chmod go+rwx $DIR/$tdir
4190         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4191         trap cleanup_33f EXIT
4192
4193         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4194                 error "cannot create striped directory"
4195
4196         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4197                 error "cannot create files in striped directory"
4198
4199         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4200                 error "cannot remove files in striped directory"
4201
4202         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4203                 error "cannot remove striped directory"
4204
4205         cleanup_33f
4206 }
4207 run_test 33f "nonroot user can create, access, and remove a striped directory"
4208
4209 test_33g() {
4210         mkdir -p $DIR/$tdir/dir2
4211
4212         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4213         echo $err
4214         [[ $err =~ "exists" ]] || error "Not exists error"
4215 }
4216 run_test 33g "nonroot user create already existing root created file"
4217
4218 test_33h() {
4219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4220         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4221                 skip "Need MDS version at least 2.13.50"
4222
4223         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4224                 error "mkdir $tdir failed"
4225         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4226
4227         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4228         local index2
4229
4230         for fname in $DIR/$tdir/$tfile.bak \
4231                      $DIR/$tdir/$tfile.SAV \
4232                      $DIR/$tdir/$tfile.orig \
4233                      $DIR/$tdir/$tfile~; do
4234                 touch $fname  || error "touch $fname failed"
4235                 index2=$($LFS getstripe -m $fname)
4236                 [ $index -eq $index2 ] ||
4237                         error "$fname MDT index mismatch $index != $index2"
4238         done
4239
4240         local failed=0
4241         for i in {1..250}; do
4242                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4243                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4244                         touch $fname  || error "touch $fname failed"
4245                         index2=$($LFS getstripe -m $fname)
4246                         if [[ $index != $index2 ]]; then
4247                                 failed=$((failed + 1))
4248                                 echo "$fname MDT index mismatch $index != $index2"
4249                         fi
4250                 done
4251         done
4252         echo "$failed MDT index mismatches"
4253         (( failed < 20 )) || error "MDT index mismatch $failed times"
4254
4255 }
4256 run_test 33h "temp file is located on the same MDT as target"
4257
4258 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4259 test_34a() {
4260         rm -f $DIR/f34
4261         $MCREATE $DIR/f34 || error "mcreate failed"
4262         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4263                 error "getstripe failed"
4264         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4265         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4266                 error "getstripe failed"
4267         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4268                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4269 }
4270 run_test 34a "truncate file that has not been opened ==========="
4271
4272 test_34b() {
4273         [ ! -f $DIR/f34 ] && test_34a
4274         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4275                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4276         $OPENFILE -f O_RDONLY $DIR/f34
4277         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4278                 error "getstripe failed"
4279         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4280                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4281 }
4282 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4283
4284 test_34c() {
4285         [ ! -f $DIR/f34 ] && test_34a
4286         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4287                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4288         $OPENFILE -f O_RDWR $DIR/f34
4289         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4290                 error "$LFS getstripe failed"
4291         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4292                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4293 }
4294 run_test 34c "O_RDWR opening file-with-size works =============="
4295
4296 test_34d() {
4297         [ ! -f $DIR/f34 ] && test_34a
4298         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4299                 error "dd failed"
4300         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4301                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4302         rm $DIR/f34
4303 }
4304 run_test 34d "write to sparse file ============================="
4305
4306 test_34e() {
4307         rm -f $DIR/f34e
4308         $MCREATE $DIR/f34e || error "mcreate failed"
4309         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4310         $CHECKSTAT -s 1000 $DIR/f34e ||
4311                 error "Size of $DIR/f34e not equal to 1000 bytes"
4312         $OPENFILE -f O_RDWR $DIR/f34e
4313         $CHECKSTAT -s 1000 $DIR/f34e ||
4314                 error "Size of $DIR/f34e not equal to 1000 bytes"
4315 }
4316 run_test 34e "create objects, some with size and some without =="
4317
4318 test_34f() { # bug 6242, 6243
4319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4320
4321         SIZE34F=48000
4322         rm -f $DIR/f34f
4323         $MCREATE $DIR/f34f || error "mcreate failed"
4324         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4325         dd if=$DIR/f34f of=$TMP/f34f
4326         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4327         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4328         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4329         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4330         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4331 }
4332 run_test 34f "read from a file with no objects until EOF ======="
4333
4334 test_34g() {
4335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4336
4337         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4338                 error "dd failed"
4339         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4340         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4341                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4342         cancel_lru_locks osc
4343         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4344                 error "wrong size after lock cancel"
4345
4346         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4347         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4348                 error "expanding truncate failed"
4349         cancel_lru_locks osc
4350         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4351                 error "wrong expanded size after lock cancel"
4352 }
4353 run_test 34g "truncate long file ==============================="
4354
4355 test_34h() {
4356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4357
4358         local gid=10
4359         local sz=1000
4360
4361         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4362         sync # Flush the cache so that multiop below does not block on cache
4363              # flush when getting the group lock
4364         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4365         MULTIPID=$!
4366
4367         # Since just timed wait is not good enough, let's do a sync write
4368         # that way we are sure enough time for a roundtrip + processing
4369         # passed + 2 seconds of extra margin.
4370         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4371         rm $DIR/${tfile}-1
4372         sleep 2
4373
4374         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4375                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4376                 kill -9 $MULTIPID
4377         fi
4378         wait $MULTIPID
4379         local nsz=`stat -c %s $DIR/$tfile`
4380         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4381 }
4382 run_test 34h "ftruncate file under grouplock should not block"
4383
4384 test_35a() {
4385         cp /bin/sh $DIR/f35a
4386         chmod 444 $DIR/f35a
4387         chown $RUNAS_ID $DIR/f35a
4388         $RUNAS $DIR/f35a && error || true
4389         rm $DIR/f35a
4390 }
4391 run_test 35a "exec file with mode 444 (should return and not leak)"
4392
4393 test_36a() {
4394         rm -f $DIR/f36
4395         utime $DIR/f36 || error "utime failed for MDS"
4396 }
4397 run_test 36a "MDS utime check (mknod, utime)"
4398
4399 test_36b() {
4400         echo "" > $DIR/f36
4401         utime $DIR/f36 || error "utime failed for OST"
4402 }
4403 run_test 36b "OST utime check (open, utime)"
4404
4405 test_36c() {
4406         rm -f $DIR/d36/f36
4407         test_mkdir $DIR/d36
4408         chown $RUNAS_ID $DIR/d36
4409         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4410 }
4411 run_test 36c "non-root MDS utime check (mknod, utime)"
4412
4413 test_36d() {
4414         [ ! -d $DIR/d36 ] && test_36c
4415         echo "" > $DIR/d36/f36
4416         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4417 }
4418 run_test 36d "non-root OST utime check (open, utime)"
4419
4420 test_36e() {
4421         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4422
4423         test_mkdir $DIR/$tdir
4424         touch $DIR/$tdir/$tfile
4425         $RUNAS utime $DIR/$tdir/$tfile &&
4426                 error "utime worked, expected failure" || true
4427 }
4428 run_test 36e "utime on non-owned file (should return error)"
4429
4430 subr_36fh() {
4431         local fl="$1"
4432         local LANG_SAVE=$LANG
4433         local LC_LANG_SAVE=$LC_LANG
4434         export LANG=C LC_LANG=C # for date language
4435
4436         DATESTR="Dec 20  2000"
4437         test_mkdir $DIR/$tdir
4438         lctl set_param fail_loc=$fl
4439         date; date +%s
4440         cp /etc/hosts $DIR/$tdir/$tfile
4441         sync & # write RPC generated with "current" inode timestamp, but delayed
4442         sleep 1
4443         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4444         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4445         cancel_lru_locks $OSC
4446         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4447         date; date +%s
4448         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4449                 echo "BEFORE: $LS_BEFORE" && \
4450                 echo "AFTER : $LS_AFTER" && \
4451                 echo "WANT  : $DATESTR" && \
4452                 error "$DIR/$tdir/$tfile timestamps changed" || true
4453
4454         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4455 }
4456
4457 test_36f() {
4458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4459
4460         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4461         subr_36fh "0x80000214"
4462 }
4463 run_test 36f "utime on file racing with OST BRW write =========="
4464
4465 test_36g() {
4466         remote_ost_nodsh && skip "remote OST with nodsh"
4467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4468         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4469                 skip "Need MDS version at least 2.12.51"
4470
4471         local fmd_max_age
4472         local fmd
4473         local facet="ost1"
4474         local tgt="obdfilter"
4475
4476         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4477
4478         test_mkdir $DIR/$tdir
4479         fmd_max_age=$(do_facet $facet \
4480                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4481                 head -n 1")
4482
4483         echo "FMD max age: ${fmd_max_age}s"
4484         touch $DIR/$tdir/$tfile
4485         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4486                 gawk '{cnt=cnt+$1}  END{print cnt}')
4487         echo "FMD before: $fmd"
4488         [[ $fmd == 0 ]] &&
4489                 error "FMD wasn't create by touch"
4490         sleep $((fmd_max_age + 12))
4491         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4492                 gawk '{cnt=cnt+$1}  END{print cnt}')
4493         echo "FMD after: $fmd"
4494         [[ $fmd == 0 ]] ||
4495                 error "FMD wasn't expired by ping"
4496 }
4497 run_test 36g "FMD cache expiry ====================="
4498
4499 test_36h() {
4500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4501
4502         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4503         subr_36fh "0x80000227"
4504 }
4505 run_test 36h "utime on file racing with OST BRW write =========="
4506
4507 test_36i() {
4508         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4509
4510         test_mkdir $DIR/$tdir
4511         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4512
4513         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4514         local new_mtime=$((mtime + 200))
4515
4516         #change Modify time of striped dir
4517         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4518                         error "change mtime failed"
4519
4520         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4521
4522         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4523 }
4524 run_test 36i "change mtime on striped directory"
4525
4526 # test_37 - duplicate with tests 32q 32r
4527
4528 test_38() {
4529         local file=$DIR/$tfile
4530         touch $file
4531         openfile -f O_DIRECTORY $file
4532         local RC=$?
4533         local ENOTDIR=20
4534         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4535         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4536 }
4537 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4538
4539 test_39a() { # was test_39
4540         touch $DIR/$tfile
4541         touch $DIR/${tfile}2
4542 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4543 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4544 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4545         sleep 2
4546         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4547         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4548                 echo "mtime"
4549                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4550                 echo "atime"
4551                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4552                 echo "ctime"
4553                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4554                 error "O_TRUNC didn't change timestamps"
4555         fi
4556 }
4557 run_test 39a "mtime changed on create"
4558
4559 test_39b() {
4560         test_mkdir -c1 $DIR/$tdir
4561         cp -p /etc/passwd $DIR/$tdir/fopen
4562         cp -p /etc/passwd $DIR/$tdir/flink
4563         cp -p /etc/passwd $DIR/$tdir/funlink
4564         cp -p /etc/passwd $DIR/$tdir/frename
4565         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4566
4567         sleep 1
4568         echo "aaaaaa" >> $DIR/$tdir/fopen
4569         echo "aaaaaa" >> $DIR/$tdir/flink
4570         echo "aaaaaa" >> $DIR/$tdir/funlink
4571         echo "aaaaaa" >> $DIR/$tdir/frename
4572
4573         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4574         local link_new=`stat -c %Y $DIR/$tdir/flink`
4575         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4576         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4577
4578         cat $DIR/$tdir/fopen > /dev/null
4579         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4580         rm -f $DIR/$tdir/funlink2
4581         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4582
4583         for (( i=0; i < 2; i++ )) ; do
4584                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4585                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4586                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4587                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4588
4589                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4590                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4591                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4592                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4593
4594                 cancel_lru_locks $OSC
4595                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4596         done
4597 }
4598 run_test 39b "mtime change on open, link, unlink, rename  ======"
4599
4600 # this should be set to past
4601 TEST_39_MTIME=`date -d "1 year ago" +%s`
4602
4603 # bug 11063
4604 test_39c() {
4605         touch $DIR1/$tfile
4606         sleep 2
4607         local mtime0=`stat -c %Y $DIR1/$tfile`
4608
4609         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4610         local mtime1=`stat -c %Y $DIR1/$tfile`
4611         [ "$mtime1" = $TEST_39_MTIME ] || \
4612                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4613
4614         local d1=`date +%s`
4615         echo hello >> $DIR1/$tfile
4616         local d2=`date +%s`
4617         local mtime2=`stat -c %Y $DIR1/$tfile`
4618         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4619                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4620
4621         mv $DIR1/$tfile $DIR1/$tfile-1
4622
4623         for (( i=0; i < 2; i++ )) ; do
4624                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4625                 [ "$mtime2" = "$mtime3" ] || \
4626                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4627
4628                 cancel_lru_locks $OSC
4629                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4630         done
4631 }
4632 run_test 39c "mtime change on rename ==========================="
4633
4634 # bug 21114
4635 test_39d() {
4636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4637
4638         touch $DIR1/$tfile
4639         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4640
4641         for (( i=0; i < 2; i++ )) ; do
4642                 local mtime=`stat -c %Y $DIR1/$tfile`
4643                 [ $mtime = $TEST_39_MTIME ] || \
4644                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4645
4646                 cancel_lru_locks $OSC
4647                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4648         done
4649 }
4650 run_test 39d "create, utime, stat =============================="
4651
4652 # bug 21114
4653 test_39e() {
4654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4655
4656         touch $DIR1/$tfile
4657         local mtime1=`stat -c %Y $DIR1/$tfile`
4658
4659         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4660
4661         for (( i=0; i < 2; i++ )) ; do
4662                 local mtime2=`stat -c %Y $DIR1/$tfile`
4663                 [ $mtime2 = $TEST_39_MTIME ] || \
4664                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4665
4666                 cancel_lru_locks $OSC
4667                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4668         done
4669 }
4670 run_test 39e "create, stat, utime, stat ========================"
4671
4672 # bug 21114
4673 test_39f() {
4674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4675
4676         touch $DIR1/$tfile
4677         mtime1=`stat -c %Y $DIR1/$tfile`
4678
4679         sleep 2
4680         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4681
4682         for (( i=0; i < 2; i++ )) ; do
4683                 local mtime2=`stat -c %Y $DIR1/$tfile`
4684                 [ $mtime2 = $TEST_39_MTIME ] || \
4685                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4686
4687                 cancel_lru_locks $OSC
4688                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4689         done
4690 }
4691 run_test 39f "create, stat, sleep, utime, stat ================="
4692
4693 # bug 11063
4694 test_39g() {
4695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4696
4697         echo hello >> $DIR1/$tfile
4698         local mtime1=`stat -c %Y $DIR1/$tfile`
4699
4700         sleep 2
4701         chmod o+r $DIR1/$tfile
4702
4703         for (( i=0; i < 2; i++ )) ; do
4704                 local mtime2=`stat -c %Y $DIR1/$tfile`
4705                 [ "$mtime1" = "$mtime2" ] || \
4706                         error "lost mtime: $mtime2, should be $mtime1"
4707
4708                 cancel_lru_locks $OSC
4709                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4710         done
4711 }
4712 run_test 39g "write, chmod, stat ==============================="
4713
4714 # bug 11063
4715 test_39h() {
4716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4717
4718         touch $DIR1/$tfile
4719         sleep 1
4720
4721         local d1=`date`
4722         echo hello >> $DIR1/$tfile
4723         local mtime1=`stat -c %Y $DIR1/$tfile`
4724
4725         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4726         local d2=`date`
4727         if [ "$d1" != "$d2" ]; then
4728                 echo "write and touch not within one second"
4729         else
4730                 for (( i=0; i < 2; i++ )) ; do
4731                         local mtime2=`stat -c %Y $DIR1/$tfile`
4732                         [ "$mtime2" = $TEST_39_MTIME ] || \
4733                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4734
4735                         cancel_lru_locks $OSC
4736                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4737                 done
4738         fi
4739 }
4740 run_test 39h "write, utime within one second, stat ============="
4741
4742 test_39i() {
4743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4744
4745         touch $DIR1/$tfile
4746         sleep 1
4747
4748         echo hello >> $DIR1/$tfile
4749         local mtime1=`stat -c %Y $DIR1/$tfile`
4750
4751         mv $DIR1/$tfile $DIR1/$tfile-1
4752
4753         for (( i=0; i < 2; i++ )) ; do
4754                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4755
4756                 [ "$mtime1" = "$mtime2" ] || \
4757                         error "lost mtime: $mtime2, should be $mtime1"
4758
4759                 cancel_lru_locks $OSC
4760                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4761         done
4762 }
4763 run_test 39i "write, rename, stat =============================="
4764
4765 test_39j() {
4766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4767
4768         start_full_debug_logging
4769         touch $DIR1/$tfile
4770         sleep 1
4771
4772         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4773         lctl set_param fail_loc=0x80000412
4774         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4775                 error "multiop failed"
4776         local multipid=$!
4777         local mtime1=`stat -c %Y $DIR1/$tfile`
4778
4779         mv $DIR1/$tfile $DIR1/$tfile-1
4780
4781         kill -USR1 $multipid
4782         wait $multipid || error "multiop close failed"
4783
4784         for (( i=0; i < 2; i++ )) ; do
4785                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4786                 [ "$mtime1" = "$mtime2" ] ||
4787                         error "mtime is lost on close: $mtime2, " \
4788                               "should be $mtime1"
4789
4790                 cancel_lru_locks
4791                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4792         done
4793         lctl set_param fail_loc=0
4794         stop_full_debug_logging
4795 }
4796 run_test 39j "write, rename, close, stat ======================="
4797
4798 test_39k() {
4799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4800
4801         touch $DIR1/$tfile
4802         sleep 1
4803
4804         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4805         local multipid=$!
4806         local mtime1=`stat -c %Y $DIR1/$tfile`
4807
4808         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4809
4810         kill -USR1 $multipid
4811         wait $multipid || error "multiop close failed"
4812
4813         for (( i=0; i < 2; i++ )) ; do
4814                 local mtime2=`stat -c %Y $DIR1/$tfile`
4815
4816                 [ "$mtime2" = $TEST_39_MTIME ] || \
4817                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4818
4819                 cancel_lru_locks
4820                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4821         done
4822 }
4823 run_test 39k "write, utime, close, stat ========================"
4824
4825 # this should be set to future
4826 TEST_39_ATIME=`date -d "1 year" +%s`
4827
4828 test_39l() {
4829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4830         remote_mds_nodsh && skip "remote MDS with nodsh"
4831
4832         local atime_diff=$(do_facet $SINGLEMDS \
4833                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4834         rm -rf $DIR/$tdir
4835         mkdir_on_mdt0 $DIR/$tdir
4836
4837         # test setting directory atime to future
4838         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4839         local atime=$(stat -c %X $DIR/$tdir)
4840         [ "$atime" = $TEST_39_ATIME ] ||
4841                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4842
4843         # test setting directory atime from future to now
4844         local now=$(date +%s)
4845         touch -a -d @$now $DIR/$tdir
4846
4847         atime=$(stat -c %X $DIR/$tdir)
4848         [ "$atime" -eq "$now"  ] ||
4849                 error "atime is not updated from future: $atime, $now"
4850
4851         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4852         sleep 3
4853
4854         # test setting directory atime when now > dir atime + atime_diff
4855         local d1=$(date +%s)
4856         ls $DIR/$tdir
4857         local d2=$(date +%s)
4858         cancel_lru_locks mdc
4859         atime=$(stat -c %X $DIR/$tdir)
4860         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4861                 error "atime is not updated  : $atime, should be $d2"
4862
4863         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4864         sleep 3
4865
4866         # test not setting directory atime when now < dir atime + atime_diff
4867         ls $DIR/$tdir
4868         cancel_lru_locks mdc
4869         atime=$(stat -c %X $DIR/$tdir)
4870         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4871                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4872
4873         do_facet $SINGLEMDS \
4874                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4875 }
4876 run_test 39l "directory atime update ==========================="
4877
4878 test_39m() {
4879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4880
4881         touch $DIR1/$tfile
4882         sleep 2
4883         local far_past_mtime=$(date -d "May 29 1953" +%s)
4884         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4885
4886         touch -m -d @$far_past_mtime $DIR1/$tfile
4887         touch -a -d @$far_past_atime $DIR1/$tfile
4888
4889         for (( i=0; i < 2; i++ )) ; do
4890                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4891                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4892                         error "atime or mtime set incorrectly"
4893
4894                 cancel_lru_locks $OSC
4895                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4896         done
4897 }
4898 run_test 39m "test atime and mtime before 1970"
4899
4900 test_39n() { # LU-3832
4901         remote_mds_nodsh && skip "remote MDS with nodsh"
4902
4903         local atime_diff=$(do_facet $SINGLEMDS \
4904                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4905         local atime0
4906         local atime1
4907         local atime2
4908
4909         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4910
4911         rm -rf $DIR/$tfile
4912         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4913         atime0=$(stat -c %X $DIR/$tfile)
4914
4915         sleep 5
4916         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4917         atime1=$(stat -c %X $DIR/$tfile)
4918
4919         sleep 5
4920         cancel_lru_locks mdc
4921         cancel_lru_locks osc
4922         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4923         atime2=$(stat -c %X $DIR/$tfile)
4924
4925         do_facet $SINGLEMDS \
4926                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4927
4928         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4929         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4930 }
4931 run_test 39n "check that O_NOATIME is honored"
4932
4933 test_39o() {
4934         TESTDIR=$DIR/$tdir/$tfile
4935         [ -e $TESTDIR ] && rm -rf $TESTDIR
4936         mkdir -p $TESTDIR
4937         cd $TESTDIR
4938         links1=2
4939         ls
4940         mkdir a b
4941         ls
4942         links2=$(stat -c %h .)
4943         [ $(($links1 + 2)) != $links2 ] &&
4944                 error "wrong links count $(($links1 + 2)) != $links2"
4945         rmdir b
4946         links3=$(stat -c %h .)
4947         [ $(($links1 + 1)) != $links3 ] &&
4948                 error "wrong links count $links1 != $links3"
4949         return 0
4950 }
4951 run_test 39o "directory cached attributes updated after create"
4952
4953 test_39p() {
4954         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4955
4956         local MDTIDX=1
4957         TESTDIR=$DIR/$tdir/$tdir
4958         [ -e $TESTDIR ] && rm -rf $TESTDIR
4959         test_mkdir -p $TESTDIR
4960         cd $TESTDIR
4961         links1=2
4962         ls
4963         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4964         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4965         ls
4966         links2=$(stat -c %h .)
4967         [ $(($links1 + 2)) != $links2 ] &&
4968                 error "wrong links count $(($links1 + 2)) != $links2"
4969         rmdir remote_dir2
4970         links3=$(stat -c %h .)
4971         [ $(($links1 + 1)) != $links3 ] &&
4972                 error "wrong links count $links1 != $links3"
4973         return 0
4974 }
4975 run_test 39p "remote directory cached attributes updated after create ========"
4976
4977 test_39r() {
4978         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4979                 skip "no atime update on old OST"
4980         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4981                 skip_env "ldiskfs only test"
4982         fi
4983
4984         local saved_adiff
4985         saved_adiff=$(do_facet ost1 \
4986                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4987         stack_trap "do_facet ost1 \
4988                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4989
4990         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4991
4992         $LFS setstripe -i 0 $DIR/$tfile
4993         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4994                 error "can't write initial file"
4995         cancel_lru_locks osc
4996
4997         # exceed atime_diff and access file
4998         sleep 6
4999         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5000                 error "can't udpate atime"
5001
5002         local atime_cli=$(stat -c %X $DIR/$tfile)
5003         echo "client atime: $atime_cli"
5004         # allow atime update to be written to device
5005         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5006         sleep 5
5007
5008         local ostdev=$(ostdevname 1)
5009         local fid=($(lfs getstripe -y $DIR/$tfile |
5010                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5011         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5012         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5013
5014         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5015         local atime_ost=$(do_facet ost1 "$cmd" |&
5016                           awk -F'[: ]' '/atime:/ { print $4 }')
5017         (( atime_cli == atime_ost )) ||
5018                 error "atime on client $atime_cli != ost $atime_ost"
5019 }
5020 run_test 39r "lazy atime update on OST"
5021
5022 test_39q() { # LU-8041
5023         local testdir=$DIR/$tdir
5024         mkdir -p $testdir
5025         multiop_bg_pause $testdir D_c || error "multiop failed"
5026         local multipid=$!
5027         cancel_lru_locks mdc
5028         kill -USR1 $multipid
5029         local atime=$(stat -c %X $testdir)
5030         [ "$atime" -ne 0 ] || error "atime is zero"
5031 }
5032 run_test 39q "close won't zero out atime"
5033
5034 test_40() {
5035         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5036         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5037                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5038         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5039                 error "$tfile is not 4096 bytes in size"
5040 }
5041 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5042
5043 test_41() {
5044         # bug 1553
5045         small_write $DIR/f41 18
5046 }
5047 run_test 41 "test small file write + fstat ====================="
5048
5049 count_ost_writes() {
5050         lctl get_param -n ${OSC}.*.stats |
5051                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5052                         END { printf("%0.0f", writes) }'
5053 }
5054
5055 # decent default
5056 WRITEBACK_SAVE=500
5057 DIRTY_RATIO_SAVE=40
5058 MAX_DIRTY_RATIO=50
5059 BG_DIRTY_RATIO_SAVE=10
5060 MAX_BG_DIRTY_RATIO=25
5061
5062 start_writeback() {
5063         trap 0
5064         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5065         # dirty_ratio, dirty_background_ratio
5066         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5067                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5068                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5069                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5070         else
5071                 # if file not here, we are a 2.4 kernel
5072                 kill -CONT `pidof kupdated`
5073         fi
5074 }
5075
5076 stop_writeback() {
5077         # setup the trap first, so someone cannot exit the test at the
5078         # exact wrong time and mess up a machine
5079         trap start_writeback EXIT
5080         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5081         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5082                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5083                 sysctl -w vm.dirty_writeback_centisecs=0
5084                 sysctl -w vm.dirty_writeback_centisecs=0
5085                 # save and increase /proc/sys/vm/dirty_ratio
5086                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5087                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5088                 # save and increase /proc/sys/vm/dirty_background_ratio
5089                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5090                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5091         else
5092                 # if file not here, we are a 2.4 kernel
5093                 kill -STOP `pidof kupdated`
5094         fi
5095 }
5096
5097 # ensure that all stripes have some grant before we test client-side cache
5098 setup_test42() {
5099         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5100                 dd if=/dev/zero of=$i bs=4k count=1
5101                 rm $i
5102         done
5103 }
5104
5105 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5106 # file truncation, and file removal.
5107 test_42a() {
5108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5109
5110         setup_test42
5111         cancel_lru_locks $OSC
5112         stop_writeback
5113         sync; sleep 1; sync # just to be safe
5114         BEFOREWRITES=`count_ost_writes`
5115         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5116         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5117         AFTERWRITES=`count_ost_writes`
5118         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5119                 error "$BEFOREWRITES < $AFTERWRITES"
5120         start_writeback
5121 }
5122 run_test 42a "ensure that we don't flush on close"
5123
5124 test_42b() {
5125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5126
5127         setup_test42
5128         cancel_lru_locks $OSC
5129         stop_writeback
5130         sync
5131         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5132         BEFOREWRITES=$(count_ost_writes)
5133         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5134         AFTERWRITES=$(count_ost_writes)
5135         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5136                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5137         fi
5138         BEFOREWRITES=$(count_ost_writes)
5139         sync || error "sync: $?"
5140         AFTERWRITES=$(count_ost_writes)
5141         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5142                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5143         fi
5144         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5145         start_writeback
5146         return 0
5147 }
5148 run_test 42b "test destroy of file with cached dirty data ======"
5149
5150 # if these tests just want to test the effect of truncation,
5151 # they have to be very careful.  consider:
5152 # - the first open gets a {0,EOF}PR lock
5153 # - the first write conflicts and gets a {0, count-1}PW
5154 # - the rest of the writes are under {count,EOF}PW
5155 # - the open for truncate tries to match a {0,EOF}PR
5156 #   for the filesize and cancels the PWs.
5157 # any number of fixes (don't get {0,EOF} on open, match
5158 # composite locks, do smarter file size management) fix
5159 # this, but for now we want these tests to verify that
5160 # the cancellation with truncate intent works, so we
5161 # start the file with a full-file pw lock to match against
5162 # until the truncate.
5163 trunc_test() {
5164         test=$1
5165         file=$DIR/$test
5166         offset=$2
5167         cancel_lru_locks $OSC
5168         stop_writeback
5169         # prime the file with 0,EOF PW to match
5170         touch $file
5171         $TRUNCATE $file 0
5172         sync; sync
5173         # now the real test..
5174         dd if=/dev/zero of=$file bs=1024 count=100
5175         BEFOREWRITES=`count_ost_writes`
5176         $TRUNCATE $file $offset
5177         cancel_lru_locks $OSC
5178         AFTERWRITES=`count_ost_writes`
5179         start_writeback
5180 }
5181
5182 test_42c() {
5183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5184
5185         trunc_test 42c 1024
5186         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5187                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5188         rm $file
5189 }
5190 run_test 42c "test partial truncate of file with cached dirty data"
5191
5192 test_42d() {
5193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5194
5195         trunc_test 42d 0
5196         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5197                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5198         rm $file
5199 }
5200 run_test 42d "test complete truncate of file with cached dirty data"
5201
5202 test_42e() { # bug22074
5203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5204
5205         local TDIR=$DIR/${tdir}e
5206         local pages=16 # hardcoded 16 pages, don't change it.
5207         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5208         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5209         local max_dirty_mb
5210         local warmup_files
5211
5212         test_mkdir $DIR/${tdir}e
5213         $LFS setstripe -c 1 $TDIR
5214         createmany -o $TDIR/f $files
5215
5216         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5217
5218         # we assume that with $OSTCOUNT files, at least one of them will
5219         # be allocated on OST0.
5220         warmup_files=$((OSTCOUNT * max_dirty_mb))
5221         createmany -o $TDIR/w $warmup_files
5222
5223         # write a large amount of data into one file and sync, to get good
5224         # avail_grant number from OST.
5225         for ((i=0; i<$warmup_files; i++)); do
5226                 idx=$($LFS getstripe -i $TDIR/w$i)
5227                 [ $idx -ne 0 ] && continue
5228                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5229                 break
5230         done
5231         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5232         sync
5233         $LCTL get_param $proc_osc0/cur_dirty_bytes
5234         $LCTL get_param $proc_osc0/cur_grant_bytes
5235
5236         # create as much dirty pages as we can while not to trigger the actual
5237         # RPCs directly. but depends on the env, VFS may trigger flush during this
5238         # period, hopefully we are good.
5239         for ((i=0; i<$warmup_files; i++)); do
5240                 idx=$($LFS getstripe -i $TDIR/w$i)
5241                 [ $idx -ne 0 ] && continue
5242                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5243         done
5244         $LCTL get_param $proc_osc0/cur_dirty_bytes
5245         $LCTL get_param $proc_osc0/cur_grant_bytes
5246
5247         # perform the real test
5248         $LCTL set_param $proc_osc0/rpc_stats 0
5249         for ((;i<$files; i++)); do
5250                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5251                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5252         done
5253         sync
5254         $LCTL get_param $proc_osc0/rpc_stats
5255
5256         local percent=0
5257         local have_ppr=false
5258         $LCTL get_param $proc_osc0/rpc_stats |
5259                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5260                         # skip lines until we are at the RPC histogram data
5261                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5262                         $have_ppr || continue
5263
5264                         # we only want the percent stat for < 16 pages
5265                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5266
5267                         percent=$((percent + WPCT))
5268                         if [[ $percent -gt 15 ]]; then
5269                                 error "less than 16-pages write RPCs" \
5270                                       "$percent% > 15%"
5271                                 break
5272                         fi
5273                 done
5274         rm -rf $TDIR
5275 }
5276 run_test 42e "verify sub-RPC writes are not done synchronously"
5277
5278 test_43A() { # was test_43
5279         test_mkdir $DIR/$tdir
5280         cp -p /bin/ls $DIR/$tdir/$tfile
5281         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5282         pid=$!
5283         # give multiop a chance to open
5284         sleep 1
5285
5286         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5287         kill -USR1 $pid
5288         # Wait for multiop to exit
5289         wait $pid
5290 }
5291 run_test 43A "execution of file opened for write should return -ETXTBSY"
5292
5293 test_43a() {
5294         test_mkdir $DIR/$tdir
5295         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5296         $DIR/$tdir/sleep 60 &
5297         SLEEP_PID=$!
5298         # Make sure exec of $tdir/sleep wins race with truncate
5299         sleep 1
5300         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5301         kill $SLEEP_PID
5302 }
5303 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5304
5305 test_43b() {
5306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5307
5308         test_mkdir $DIR/$tdir
5309         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5310         $DIR/$tdir/sleep 60 &
5311         SLEEP_PID=$!
5312         # Make sure exec of $tdir/sleep wins race with truncate
5313         sleep 1
5314         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5315         kill $SLEEP_PID
5316 }
5317 run_test 43b "truncate of file being executed should return -ETXTBSY"
5318
5319 test_43c() {
5320         local testdir="$DIR/$tdir"
5321         test_mkdir $testdir
5322         cp $SHELL $testdir/
5323         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5324                 ( cd $testdir && md5sum -c )
5325 }
5326 run_test 43c "md5sum of copy into lustre"
5327
5328 test_44A() { # was test_44
5329         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5330
5331         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5332         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5333 }
5334 run_test 44A "zero length read from a sparse stripe"
5335
5336 test_44a() {
5337         local nstripe=$($LFS getstripe -c -d $DIR)
5338         [ -z "$nstripe" ] && skip "can't get stripe info"
5339         [[ $nstripe -gt $OSTCOUNT ]] &&
5340                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5341
5342         local stride=$($LFS getstripe -S -d $DIR)
5343         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5344                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5345         fi
5346
5347         OFFSETS="0 $((stride/2)) $((stride-1))"
5348         for offset in $OFFSETS; do
5349                 for i in $(seq 0 $((nstripe-1))); do
5350                         local GLOBALOFFSETS=""
5351                         # size in Bytes
5352                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5353                         local myfn=$DIR/d44a-$size
5354                         echo "--------writing $myfn at $size"
5355                         ll_sparseness_write $myfn $size ||
5356                                 error "ll_sparseness_write"
5357                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5358                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5359                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5360
5361                         for j in $(seq 0 $((nstripe-1))); do
5362                                 # size in Bytes
5363                                 size=$((((j + $nstripe )*$stride + $offset)))
5364                                 ll_sparseness_write $myfn $size ||
5365                                         error "ll_sparseness_write"
5366                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5367                         done
5368                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5369                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5370                         rm -f $myfn
5371                 done
5372         done
5373 }
5374 run_test 44a "test sparse pwrite ==============================="
5375
5376 dirty_osc_total() {
5377         tot=0
5378         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5379                 tot=$(($tot + $d))
5380         done
5381         echo $tot
5382 }
5383 do_dirty_record() {
5384         before=`dirty_osc_total`
5385         echo executing "\"$*\""
5386         eval $*
5387         after=`dirty_osc_total`
5388         echo before $before, after $after
5389 }
5390 test_45() {
5391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5392
5393         f="$DIR/f45"
5394         # Obtain grants from OST if it supports it
5395         echo blah > ${f}_grant
5396         stop_writeback
5397         sync
5398         do_dirty_record "echo blah > $f"
5399         [[ $before -eq $after ]] && error "write wasn't cached"
5400         do_dirty_record "> $f"
5401         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5402         do_dirty_record "echo blah > $f"
5403         [[ $before -eq $after ]] && error "write wasn't cached"
5404         do_dirty_record "sync"
5405         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5406         do_dirty_record "echo blah > $f"
5407         [[ $before -eq $after ]] && error "write wasn't cached"
5408         do_dirty_record "cancel_lru_locks osc"
5409         [[ $before -gt $after ]] ||
5410                 error "lock cancellation didn't lower dirty count"
5411         start_writeback
5412 }
5413 run_test 45 "osc io page accounting ============================"
5414
5415 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5416 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5417 # objects offset and an assert hit when an rpc was built with 1023's mapped
5418 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5419 test_46() {
5420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5421
5422         f="$DIR/f46"
5423         stop_writeback
5424         sync
5425         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5426         sync
5427         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5428         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5429         sync
5430         start_writeback
5431 }
5432 run_test 46 "dirtying a previously written page ================"
5433
5434 # test_47 is removed "Device nodes check" is moved to test_28
5435
5436 test_48a() { # bug 2399
5437         [ "$mds1_FSTYPE" = "zfs" ] &&
5438         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5439                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5440
5441         test_mkdir $DIR/$tdir
5442         cd $DIR/$tdir
5443         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5444         test_mkdir $DIR/$tdir
5445         touch foo || error "'touch foo' failed after recreating cwd"
5446         test_mkdir bar
5447         touch .foo || error "'touch .foo' failed after recreating cwd"
5448         test_mkdir .bar
5449         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5450         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5451         cd . || error "'cd .' failed after recreating cwd"
5452         mkdir . && error "'mkdir .' worked after recreating cwd"
5453         rmdir . && error "'rmdir .' worked after recreating cwd"
5454         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5455         cd .. || error "'cd ..' failed after recreating cwd"
5456 }
5457 run_test 48a "Access renamed working dir (should return errors)="
5458
5459 test_48b() { # bug 2399
5460         rm -rf $DIR/$tdir
5461         test_mkdir $DIR/$tdir
5462         cd $DIR/$tdir
5463         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5464         touch foo && error "'touch foo' worked after removing cwd"
5465         mkdir foo && error "'mkdir foo' worked after removing cwd"
5466         touch .foo && error "'touch .foo' worked after removing cwd"
5467         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5468         ls . > /dev/null && error "'ls .' worked after removing cwd"
5469         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5470         mkdir . && error "'mkdir .' worked after removing cwd"
5471         rmdir . && error "'rmdir .' worked after removing cwd"
5472         ln -s . foo && error "'ln -s .' worked after removing cwd"
5473         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5474 }
5475 run_test 48b "Access removed working dir (should return errors)="
5476
5477 test_48c() { # bug 2350
5478         #lctl set_param debug=-1
5479         #set -vx
5480         rm -rf $DIR/$tdir
5481         test_mkdir -p $DIR/$tdir/dir
5482         cd $DIR/$tdir/dir
5483         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5484         $TRACE touch foo && error "touch foo worked after removing cwd"
5485         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5486         touch .foo && error "touch .foo worked after removing cwd"
5487         mkdir .foo && error "mkdir .foo worked after removing cwd"
5488         $TRACE ls . && error "'ls .' worked after removing cwd"
5489         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5490         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5491         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5492         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5493         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5494 }
5495 run_test 48c "Access removed working subdir (should return errors)"
5496
5497 test_48d() { # bug 2350
5498         #lctl set_param debug=-1
5499         #set -vx
5500         rm -rf $DIR/$tdir
5501         test_mkdir -p $DIR/$tdir/dir
5502         cd $DIR/$tdir/dir
5503         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5504         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5505         $TRACE touch foo && error "'touch foo' worked after removing parent"
5506         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5507         touch .foo && error "'touch .foo' worked after removing parent"
5508         mkdir .foo && error "mkdir .foo worked after removing parent"
5509         $TRACE ls . && error "'ls .' worked after removing parent"
5510         $TRACE ls .. && error "'ls ..' worked after removing parent"
5511         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5512         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5513         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5514         true
5515 }
5516 run_test 48d "Access removed parent subdir (should return errors)"
5517
5518 test_48e() { # bug 4134
5519         #lctl set_param debug=-1
5520         #set -vx
5521         rm -rf $DIR/$tdir
5522         test_mkdir -p $DIR/$tdir/dir
5523         cd $DIR/$tdir/dir
5524         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5525         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5526         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5527         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5528         # On a buggy kernel addition of "touch foo" after cd .. will
5529         # produce kernel oops in lookup_hash_it
5530         touch ../foo && error "'cd ..' worked after recreate parent"
5531         cd $DIR
5532         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5533 }
5534 run_test 48e "Access to recreated parent subdir (should return errors)"
5535
5536 test_48f() {
5537         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5538                 skip "need MDS >= 2.13.55"
5539         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5540         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5541                 skip "needs different host for mdt1 mdt2"
5542         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5543
5544         $LFS mkdir -i0 $DIR/$tdir
5545         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5546
5547         for d in sub1 sub2 sub3; do
5548                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5549                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5550                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5551         done
5552
5553         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5554 }
5555 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5556
5557 test_49() { # LU-1030
5558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5559         remote_ost_nodsh && skip "remote OST with nodsh"
5560
5561         # get ost1 size - $FSNAME-OST0000
5562         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5563                 awk '{ print $4 }')
5564         # write 800M at maximum
5565         [[ $ost1_size -lt 2 ]] && ost1_size=2
5566         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5567
5568         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5569         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5570         local dd_pid=$!
5571
5572         # change max_pages_per_rpc while writing the file
5573         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5574         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5575         # loop until dd process exits
5576         while ps ax -opid | grep -wq $dd_pid; do
5577                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5578                 sleep $((RANDOM % 5 + 1))
5579         done
5580         # restore original max_pages_per_rpc
5581         $LCTL set_param $osc1_mppc=$orig_mppc
5582         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5583 }
5584 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5585
5586 test_50() {
5587         # bug 1485
5588         test_mkdir $DIR/$tdir
5589         cd $DIR/$tdir
5590         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5591 }
5592 run_test 50 "special situations: /proc symlinks  ==============="
5593
5594 test_51a() {    # was test_51
5595         # bug 1516 - create an empty entry right after ".." then split dir
5596         test_mkdir -c1 $DIR/$tdir
5597         touch $DIR/$tdir/foo
5598         $MCREATE $DIR/$tdir/bar
5599         rm $DIR/$tdir/foo
5600         createmany -m $DIR/$tdir/longfile 201
5601         FNUM=202
5602         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5603                 $MCREATE $DIR/$tdir/longfile$FNUM
5604                 FNUM=$(($FNUM + 1))
5605                 echo -n "+"
5606         done
5607         echo
5608         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5609 }
5610 run_test 51a "special situations: split htree with empty entry =="
5611
5612 cleanup_print_lfs_df () {
5613         trap 0
5614         $LFS df
5615         $LFS df -i
5616 }
5617
5618 test_51b() {
5619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5620
5621         local dir=$DIR/$tdir
5622         local nrdirs=$((65536 + 100))
5623
5624         # cleanup the directory
5625         rm -fr $dir
5626
5627         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5628
5629         $LFS df
5630         $LFS df -i
5631         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5632         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5633         [[ $numfree -lt $nrdirs ]] &&
5634                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5635
5636         # need to check free space for the directories as well
5637         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5638         numfree=$(( blkfree / $(fs_inode_ksize) ))
5639         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5640
5641         trap cleanup_print_lfs_df EXIT
5642
5643         # create files
5644         createmany -d $dir/d $nrdirs || {
5645                 unlinkmany $dir/d $nrdirs
5646                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5647         }
5648
5649         # really created :
5650         nrdirs=$(ls -U $dir | wc -l)
5651
5652         # unlink all but 100 subdirectories, then check it still works
5653         local left=100
5654         local delete=$((nrdirs - left))
5655
5656         $LFS df
5657         $LFS df -i
5658
5659         # for ldiskfs the nlink count should be 1, but this is OSD specific
5660         # and so this is listed for informational purposes only
5661         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5662         unlinkmany -d $dir/d $delete ||
5663                 error "unlink of first $delete subdirs failed"
5664
5665         echo "nlink between: $(stat -c %h $dir)"
5666         local found=$(ls -U $dir | wc -l)
5667         [ $found -ne $left ] &&
5668                 error "can't find subdirs: found only $found, expected $left"
5669
5670         unlinkmany -d $dir/d $delete $left ||
5671                 error "unlink of second $left subdirs failed"
5672         # regardless of whether the backing filesystem tracks nlink accurately
5673         # or not, the nlink count shouldn't be more than "." and ".." here
5674         local after=$(stat -c %h $dir)
5675         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5676                 echo "nlink after: $after"
5677
5678         cleanup_print_lfs_df
5679 }
5680 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5681
5682 test_51d() {
5683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5684         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5685
5686         test_mkdir $DIR/$tdir
5687         createmany -o $DIR/$tdir/t- 1000
5688         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5689         for N in $(seq 0 $((OSTCOUNT - 1))); do
5690                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5691                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5692                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5693                         '($1 == '$N') { objs += 1 } \
5694                         END { printf("%0.0f", objs) }')
5695                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5696         done
5697         unlinkmany $DIR/$tdir/t- 1000
5698
5699         NLAST=0
5700         for N in $(seq 1 $((OSTCOUNT - 1))); do
5701                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5702                         error "OST $N has less objects vs OST $NLAST" \
5703                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5704                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5705                         error "OST $N has less objects vs OST $NLAST" \
5706                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5707
5708                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5709                         error "OST $N has less #0 objects vs OST $NLAST" \
5710                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5711                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5712                         error "OST $N has less #0 objects vs OST $NLAST" \
5713                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5714                 NLAST=$N
5715         done
5716         rm -f $TMP/$tfile
5717 }
5718 run_test 51d "check object distribution"
5719
5720 test_51e() {
5721         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5722                 skip_env "ldiskfs only test"
5723         fi
5724
5725         test_mkdir -c1 $DIR/$tdir
5726         test_mkdir -c1 $DIR/$tdir/d0
5727
5728         touch $DIR/$tdir/d0/foo
5729         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5730                 error "file exceed 65000 nlink limit!"
5731         unlinkmany $DIR/$tdir/d0/f- 65001
5732         return 0
5733 }
5734 run_test 51e "check file nlink limit"
5735
5736 test_51f() {
5737         test_mkdir $DIR/$tdir
5738
5739         local max=100000
5740         local ulimit_old=$(ulimit -n)
5741         local spare=20 # number of spare fd's for scripts/libraries, etc.
5742         local mdt=$($LFS getstripe -m $DIR/$tdir)
5743         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5744
5745         echo "MDT$mdt numfree=$numfree, max=$max"
5746         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5747         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5748                 while ! ulimit -n $((numfree + spare)); do
5749                         numfree=$((numfree * 3 / 4))
5750                 done
5751                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5752         else
5753                 echo "left ulimit at $ulimit_old"
5754         fi
5755
5756         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5757                 unlinkmany $DIR/$tdir/f $numfree
5758                 error "create+open $numfree files in $DIR/$tdir failed"
5759         }
5760         ulimit -n $ulimit_old
5761
5762         # if createmany exits at 120s there will be fewer than $numfree files
5763         unlinkmany $DIR/$tdir/f $numfree || true
5764 }
5765 run_test 51f "check many open files limit"
5766
5767 test_52a() {
5768         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5769         test_mkdir $DIR/$tdir
5770         touch $DIR/$tdir/foo
5771         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5772         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5773         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5774         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5775         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5776                                         error "link worked"
5777         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5778         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5779         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5780                                                      error "lsattr"
5781         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5782         cp -r $DIR/$tdir $TMP/
5783         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5784 }
5785 run_test 52a "append-only flag test (should return errors)"
5786
5787 test_52b() {
5788         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5789         test_mkdir $DIR/$tdir
5790         touch $DIR/$tdir/foo
5791         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5792         cat test > $DIR/$tdir/foo && error "cat test worked"
5793         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5794         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5795         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5796                                         error "link worked"
5797         echo foo >> $DIR/$tdir/foo && error "echo worked"
5798         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5799         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5800         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5801         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5802                                                         error "lsattr"
5803         chattr -i $DIR/$tdir/foo || error "chattr failed"
5804
5805         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5806 }
5807 run_test 52b "immutable flag test (should return errors) ======="
5808
5809 test_53() {
5810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5811         remote_mds_nodsh && skip "remote MDS with nodsh"
5812         remote_ost_nodsh && skip "remote OST with nodsh"
5813
5814         local param
5815         local param_seq
5816         local ostname
5817         local mds_last
5818         local mds_last_seq
5819         local ost_last
5820         local ost_last_seq
5821         local ost_last_id
5822         local ostnum
5823         local node
5824         local found=false
5825         local support_last_seq=true
5826
5827         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5828                 support_last_seq=false
5829
5830         # only test MDT0000
5831         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5832         local value
5833         for value in $(do_facet $SINGLEMDS \
5834                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5835                 param=$(echo ${value[0]} | cut -d "=" -f1)
5836                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5837
5838                 if $support_last_seq; then
5839                         param_seq=$(echo $param |
5840                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5841                         mds_last_seq=$(do_facet $SINGLEMDS \
5842                                        $LCTL get_param -n $param_seq)
5843                 fi
5844                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5845
5846                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5847                 node=$(facet_active_host ost$((ostnum+1)))
5848                 param="obdfilter.$ostname.last_id"
5849                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5850                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5851                         ost_last_id=$ost_last
5852
5853                         if $support_last_seq; then
5854                                 ost_last_id=$(echo $ost_last |
5855                                               awk -F':' '{print $2}' |
5856                                               sed -e "s/^0x//g")
5857                                 ost_last_seq=$(echo $ost_last |
5858                                                awk -F':' '{print $1}')
5859                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5860                         fi
5861
5862                         if [[ $ost_last_id != $mds_last ]]; then
5863                                 error "$ost_last_id != $mds_last"
5864                         else
5865                                 found=true
5866                                 break
5867                         fi
5868                 done
5869         done
5870         $found || error "can not match last_seq/last_id for $mdtosc"
5871         return 0
5872 }
5873 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5874
5875 test_54a() {
5876         perl -MSocket -e ';' || skip "no Socket perl module installed"
5877
5878         $SOCKETSERVER $DIR/socket ||
5879                 error "$SOCKETSERVER $DIR/socket failed: $?"
5880         $SOCKETCLIENT $DIR/socket ||
5881                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5882         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5883 }
5884 run_test 54a "unix domain socket test =========================="
5885
5886 test_54b() {
5887         f="$DIR/f54b"
5888         mknod $f c 1 3
5889         chmod 0666 $f
5890         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5891 }
5892 run_test 54b "char device works in lustre ======================"
5893
5894 find_loop_dev() {
5895         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5896         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5897         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5898
5899         for i in $(seq 3 7); do
5900                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5901                 LOOPDEV=$LOOPBASE$i
5902                 LOOPNUM=$i
5903                 break
5904         done
5905 }
5906
5907 cleanup_54c() {
5908         local rc=0
5909         loopdev="$DIR/loop54c"
5910
5911         trap 0
5912         $UMOUNT $DIR/$tdir || rc=$?
5913         losetup -d $loopdev || true
5914         losetup -d $LOOPDEV || true
5915         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5916         return $rc
5917 }
5918
5919 test_54c() {
5920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5921
5922         loopdev="$DIR/loop54c"
5923
5924         find_loop_dev
5925         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5926         trap cleanup_54c EXIT
5927         mknod $loopdev b 7 $LOOPNUM
5928         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5929         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5930         losetup $loopdev $DIR/$tfile ||
5931                 error "can't set up $loopdev for $DIR/$tfile"
5932         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5933         test_mkdir $DIR/$tdir
5934         mount -t ext2 $loopdev $DIR/$tdir ||
5935                 error "error mounting $loopdev on $DIR/$tdir"
5936         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5937                 error "dd write"
5938         df $DIR/$tdir
5939         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5940                 error "dd read"
5941         cleanup_54c
5942 }
5943 run_test 54c "block device works in lustre ====================="
5944
5945 test_54d() {
5946         f="$DIR/f54d"
5947         string="aaaaaa"
5948         mknod $f p
5949         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5950 }
5951 run_test 54d "fifo device works in lustre ======================"
5952
5953 test_54e() {
5954         f="$DIR/f54e"
5955         string="aaaaaa"
5956         cp -aL /dev/console $f
5957         echo $string > $f || error "echo $string to $f failed"
5958 }
5959 run_test 54e "console/tty device works in lustre ======================"
5960
5961 test_56a() {
5962         local numfiles=3
5963         local numdirs=2
5964         local dir=$DIR/$tdir
5965
5966         rm -rf $dir
5967         test_mkdir -p $dir/dir
5968         for i in $(seq $numfiles); do
5969                 touch $dir/file$i
5970                 touch $dir/dir/file$i
5971         done
5972
5973         local numcomp=$($LFS getstripe --component-count $dir)
5974
5975         [[ $numcomp == 0 ]] && numcomp=1
5976
5977         # test lfs getstripe with --recursive
5978         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5979
5980         [[ $filenum -eq $((numfiles * 2)) ]] ||
5981                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5982         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5983         [[ $filenum -eq $numfiles ]] ||
5984                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5985         echo "$LFS getstripe showed obdidx or l_ost_idx"
5986
5987         # test lfs getstripe with file instead of dir
5988         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5989         [[ $filenum -eq 1 ]] ||
5990                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5991         echo "$LFS getstripe file1 passed"
5992
5993         #test lfs getstripe with --verbose
5994         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5995         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5996                 error "$LFS getstripe --verbose $dir: "\
5997                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5998         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5999                 error "$LFS getstripe $dir: showed lmm_magic"
6000
6001         #test lfs getstripe with -v prints lmm_fid
6002         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6003         local countfids=$((numdirs + numfiles * numcomp))
6004         [[ $filenum -eq $countfids ]] ||
6005                 error "$LFS getstripe -v $dir: "\
6006                       "got $filenum want $countfids lmm_fid"
6007         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6008                 error "$LFS getstripe $dir: showed lmm_fid by default"
6009         echo "$LFS getstripe --verbose passed"
6010
6011         #check for FID information
6012         local fid1=$($LFS getstripe --fid $dir/file1)
6013         local fid2=$($LFS getstripe --verbose $dir/file1 |
6014                      awk '/lmm_fid: / { print $2; exit; }')
6015         local fid3=$($LFS path2fid $dir/file1)
6016
6017         [ "$fid1" != "$fid2" ] &&
6018                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6019         [ "$fid1" != "$fid3" ] &&
6020                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6021         echo "$LFS getstripe --fid passed"
6022
6023         #test lfs getstripe with --obd
6024         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6025                 error "$LFS getstripe --obd wrong_uuid: should return error"
6026
6027         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6028
6029         local ostidx=1
6030         local obduuid=$(ostuuid_from_index $ostidx)
6031         local found=$($LFS getstripe -r --obd $obduuid $dir |
6032                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6033
6034         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6035         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6036                 ((filenum--))
6037         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6038                 ((filenum--))
6039
6040         [[ $found -eq $filenum ]] ||
6041                 error "$LFS getstripe --obd: found $found expect $filenum"
6042         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6043                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6044                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6045                 error "$LFS getstripe --obd: should not show file on other obd"
6046         echo "$LFS getstripe --obd passed"
6047 }
6048 run_test 56a "check $LFS getstripe"
6049
6050 test_56b() {
6051         local dir=$DIR/$tdir
6052         local numdirs=3
6053
6054         test_mkdir $dir
6055         for i in $(seq $numdirs); do
6056                 test_mkdir $dir/dir$i
6057         done
6058
6059         # test lfs getdirstripe default mode is non-recursion, which is
6060         # different from lfs getstripe
6061         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6062
6063         [[ $dircnt -eq 1 ]] ||
6064                 error "$LFS getdirstripe: found $dircnt, not 1"
6065         dircnt=$($LFS getdirstripe --recursive $dir |
6066                 grep -c lmv_stripe_count)
6067         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6068                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6069 }
6070 run_test 56b "check $LFS getdirstripe"
6071
6072 test_56c() {
6073         remote_ost_nodsh && skip "remote OST with nodsh"
6074
6075         local ost_idx=0
6076         local ost_name=$(ostname_from_index $ost_idx)
6077         local old_status=$(ost_dev_status $ost_idx)
6078         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6079
6080         [[ -z "$old_status" ]] ||
6081                 skip_env "OST $ost_name is in $old_status status"
6082
6083         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6084         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6085                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6086         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6087                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6088                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6089         fi
6090
6091         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6092                 error "$LFS df -v showing inactive devices"
6093         sleep_maxage
6094
6095         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6096
6097         [[ "$new_status" =~ "D" ]] ||
6098                 error "$ost_name status is '$new_status', missing 'D'"
6099         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6100                 [[ "$new_status" =~ "N" ]] ||
6101                         error "$ost_name status is '$new_status', missing 'N'"
6102         fi
6103         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6104                 [[ "$new_status" =~ "f" ]] ||
6105                         error "$ost_name status is '$new_status', missing 'f'"
6106         fi
6107
6108         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6109         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6110                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6111         [[ -z "$p" ]] && restore_lustre_params < $p || true
6112         sleep_maxage
6113
6114         new_status=$(ost_dev_status $ost_idx)
6115         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6116                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6117         # can't check 'f' as devices may actually be on flash
6118 }
6119 run_test 56c "check 'lfs df' showing device status"
6120
6121 test_56d() {
6122         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6123         local osts=$($LFS df -v $MOUNT | grep -c OST)
6124
6125         $LFS df $MOUNT
6126
6127         (( mdts == MDSCOUNT )) ||
6128                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6129         (( osts == OSTCOUNT )) ||
6130                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6131 }
6132 run_test 56d "'lfs df -v' prints only configured devices"
6133
6134 NUMFILES=3
6135 NUMDIRS=3
6136 setup_56() {
6137         local local_tdir="$1"
6138         local local_numfiles="$2"
6139         local local_numdirs="$3"
6140         local dir_params="$4"
6141         local dir_stripe_params="$5"
6142
6143         if [ ! -d "$local_tdir" ] ; then
6144                 test_mkdir -p $dir_stripe_params $local_tdir
6145                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6146                 for i in $(seq $local_numfiles) ; do
6147                         touch $local_tdir/file$i
6148                 done
6149                 for i in $(seq $local_numdirs) ; do
6150                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6151                         for j in $(seq $local_numfiles) ; do
6152                                 touch $local_tdir/dir$i/file$j
6153                         done
6154                 done
6155         fi
6156 }
6157
6158 setup_56_special() {
6159         local local_tdir=$1
6160         local local_numfiles=$2
6161         local local_numdirs=$3
6162
6163         setup_56 $local_tdir $local_numfiles $local_numdirs
6164
6165         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6166                 for i in $(seq $local_numfiles) ; do
6167                         mknod $local_tdir/loop${i}b b 7 $i
6168                         mknod $local_tdir/null${i}c c 1 3
6169                         ln -s $local_tdir/file1 $local_tdir/link${i}
6170                 done
6171                 for i in $(seq $local_numdirs) ; do
6172                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6173                         mknod $local_tdir/dir$i/null${i}c c 1 3
6174                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6175                 done
6176         fi
6177 }
6178
6179 test_56g() {
6180         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6181         local expected=$(($NUMDIRS + 2))
6182
6183         setup_56 $dir $NUMFILES $NUMDIRS
6184
6185         # test lfs find with -name
6186         for i in $(seq $NUMFILES) ; do
6187                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6188
6189                 [ $nums -eq $expected ] ||
6190                         error "lfs find -name '*$i' $dir wrong: "\
6191                               "found $nums, expected $expected"
6192         done
6193 }
6194 run_test 56g "check lfs find -name"
6195
6196 test_56h() {
6197         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6198         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6199
6200         setup_56 $dir $NUMFILES $NUMDIRS
6201
6202         # test lfs find with ! -name
6203         for i in $(seq $NUMFILES) ; do
6204                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6205
6206                 [ $nums -eq $expected ] ||
6207                         error "lfs find ! -name '*$i' $dir wrong: "\
6208                               "found $nums, expected $expected"
6209         done
6210 }
6211 run_test 56h "check lfs find ! -name"
6212
6213 test_56i() {
6214         local dir=$DIR/$tdir
6215
6216         test_mkdir $dir
6217
6218         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6219         local out=$($cmd)
6220
6221         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6222 }
6223 run_test 56i "check 'lfs find -ost UUID' skips directories"
6224
6225 test_56j() {
6226         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6227
6228         setup_56_special $dir $NUMFILES $NUMDIRS
6229
6230         local expected=$((NUMDIRS + 1))
6231         local cmd="$LFS find -type d $dir"
6232         local nums=$($cmd | wc -l)
6233
6234         [ $nums -eq $expected ] ||
6235                 error "'$cmd' wrong: found $nums, expected $expected"
6236 }
6237 run_test 56j "check lfs find -type d"
6238
6239 test_56k() {
6240         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6241
6242         setup_56_special $dir $NUMFILES $NUMDIRS
6243
6244         local expected=$(((NUMDIRS + 1) * NUMFILES))
6245         local cmd="$LFS find -type f $dir"
6246         local nums=$($cmd | wc -l)
6247
6248         [ $nums -eq $expected ] ||
6249                 error "'$cmd' wrong: found $nums, expected $expected"
6250 }
6251 run_test 56k "check lfs find -type f"
6252
6253 test_56l() {
6254         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6255
6256         setup_56_special $dir $NUMFILES $NUMDIRS
6257
6258         local expected=$((NUMDIRS + NUMFILES))
6259         local cmd="$LFS find -type b $dir"
6260         local nums=$($cmd | wc -l)
6261
6262         [ $nums -eq $expected ] ||
6263                 error "'$cmd' wrong: found $nums, expected $expected"
6264 }
6265 run_test 56l "check lfs find -type b"
6266
6267 test_56m() {
6268         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6269
6270         setup_56_special $dir $NUMFILES $NUMDIRS
6271
6272         local expected=$((NUMDIRS + NUMFILES))
6273         local cmd="$LFS find -type c $dir"
6274         local nums=$($cmd | wc -l)
6275         [ $nums -eq $expected ] ||
6276                 error "'$cmd' wrong: found $nums, expected $expected"
6277 }
6278 run_test 56m "check lfs find -type c"
6279
6280 test_56n() {
6281         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6282         setup_56_special $dir $NUMFILES $NUMDIRS
6283
6284         local expected=$((NUMDIRS + NUMFILES))
6285         local cmd="$LFS find -type l $dir"
6286         local nums=$($cmd | wc -l)
6287
6288         [ $nums -eq $expected ] ||
6289                 error "'$cmd' wrong: found $nums, expected $expected"
6290 }
6291 run_test 56n "check lfs find -type l"
6292
6293 test_56o() {
6294         local dir=$DIR/$tdir
6295
6296         setup_56 $dir $NUMFILES $NUMDIRS
6297         utime $dir/file1 > /dev/null || error "utime (1)"
6298         utime $dir/file2 > /dev/null || error "utime (2)"
6299         utime $dir/dir1 > /dev/null || error "utime (3)"
6300         utime $dir/dir2 > /dev/null || error "utime (4)"
6301         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6302         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6303
6304         local expected=4
6305         local nums=$($LFS find -mtime +0 $dir | wc -l)
6306
6307         [ $nums -eq $expected ] ||
6308                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6309
6310         expected=12
6311         cmd="$LFS find -mtime 0 $dir"
6312         nums=$($cmd | wc -l)
6313         [ $nums -eq $expected ] ||
6314                 error "'$cmd' wrong: found $nums, expected $expected"
6315 }
6316 run_test 56o "check lfs find -mtime for old files"
6317
6318 test_56ob() {
6319         local dir=$DIR/$tdir
6320         local expected=1
6321         local count=0
6322
6323         # just to make sure there is something that won't be found
6324         test_mkdir $dir
6325         touch $dir/$tfile.now
6326
6327         for age in year week day hour min; do
6328                 count=$((count + 1))
6329
6330                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6331                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6332                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6333
6334                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6335                 local nums=$($cmd | wc -l)
6336                 [ $nums -eq $expected ] ||
6337                         error "'$cmd' wrong: found $nums, expected $expected"
6338
6339                 cmd="$LFS find $dir -atime $count${age:0:1}"
6340                 nums=$($cmd | wc -l)
6341                 [ $nums -eq $expected ] ||
6342                         error "'$cmd' wrong: found $nums, expected $expected"
6343         done
6344
6345         sleep 2
6346         cmd="$LFS find $dir -ctime +1s -type f"
6347         nums=$($cmd | wc -l)
6348         (( $nums == $count * 2 + 1)) ||
6349                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6350 }
6351 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6352
6353 test_newerXY_base() {
6354         local x=$1
6355         local y=$2
6356         local dir=$DIR/$tdir
6357         local ref
6358         local negref
6359
6360         if [ $y == "t" ]; then
6361                 if [ $x == "b" ]; then
6362                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6363                 else
6364                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6365                 fi
6366         else
6367                 ref=$DIR/$tfile.newer.$x$y
6368                 touch $ref || error "touch $ref failed"
6369         fi
6370
6371         echo "before = $ref"
6372         sleep 2
6373         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6374         sleep 2
6375         if [ $y == "t" ]; then
6376                 if [ $x == "b" ]; then
6377                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6378                 else
6379                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6380                 fi
6381         else
6382                 negref=$DIR/$tfile.negnewer.$x$y
6383                 touch $negref || error "touch $negref failed"
6384         fi
6385
6386         echo "after = $negref"
6387         local cmd="$LFS find $dir -newer$x$y $ref"
6388         local nums=$(eval $cmd | wc -l)
6389         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6390
6391         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6392                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6393
6394         cmd="$LFS find $dir ! -newer$x$y $negref"
6395         nums=$(eval $cmd | wc -l)
6396         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6397                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6398
6399         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6400         nums=$(eval $cmd | wc -l)
6401         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6402                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6403
6404         rm -rf $DIR/*
6405 }
6406
6407 test_56oc() {
6408         test_newerXY_base "a" "a"
6409         test_newerXY_base "a" "m"
6410         test_newerXY_base "a" "c"
6411         test_newerXY_base "m" "a"
6412         test_newerXY_base "m" "m"
6413         test_newerXY_base "m" "c"
6414         test_newerXY_base "c" "a"
6415         test_newerXY_base "c" "m"
6416         test_newerXY_base "c" "c"
6417
6418         [[ -n "$sles_version" ]] &&
6419                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6420
6421         test_newerXY_base "a" "t"
6422         test_newerXY_base "m" "t"
6423         test_newerXY_base "c" "t"
6424
6425         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6426            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6427                 ! btime_supported && echo "btime unsupported" && return 0
6428
6429         test_newerXY_base "b" "b"
6430         test_newerXY_base "b" "t"
6431 }
6432 run_test 56oc "check lfs find -newerXY work"
6433
6434 btime_supported() {
6435         local dir=$DIR/$tdir
6436         local rc
6437
6438         mkdir -p $dir
6439         touch $dir/$tfile
6440         $LFS find $dir -btime -1d -type f
6441         rc=$?
6442         rm -rf $dir
6443         return $rc
6444 }
6445
6446 test_56od() {
6447         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6448                 ! btime_supported && skip "btime unsupported on MDS"
6449
6450         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6451                 ! btime_supported && skip "btime unsupported on clients"
6452
6453         local dir=$DIR/$tdir
6454         local ref=$DIR/$tfile.ref
6455         local negref=$DIR/$tfile.negref
6456
6457         mkdir $dir || error "mkdir $dir failed"
6458         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6459         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6460         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6461         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6462         touch $ref || error "touch $ref failed"
6463         # sleep 3 seconds at least
6464         sleep 3
6465
6466         local before=$(do_facet mds1 date +%s)
6467         local skew=$(($(date +%s) - before + 1))
6468
6469         if (( skew < 0 && skew > -5 )); then
6470                 sleep $((0 - skew + 1))
6471                 skew=0
6472         fi
6473
6474         # Set the dir stripe params to limit files all on MDT0,
6475         # otherwise we need to calc the max clock skew between
6476         # the client and MDTs.
6477         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6478         sleep 2
6479         touch $negref || error "touch $negref failed"
6480
6481         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6482         local nums=$($cmd | wc -l)
6483         local expected=$(((NUMFILES + 1) * NUMDIRS))
6484
6485         [ $nums -eq $expected ] ||
6486                 error "'$cmd' wrong: found $nums, expected $expected"
6487
6488         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6489         nums=$($cmd | wc -l)
6490         expected=$((NUMFILES + 1))
6491         [ $nums -eq $expected ] ||
6492                 error "'$cmd' wrong: found $nums, expected $expected"
6493
6494         [ $skew -lt 0 ] && return
6495
6496         local after=$(do_facet mds1 date +%s)
6497         local age=$((after - before + 1 + skew))
6498
6499         cmd="$LFS find $dir -btime -${age}s -type f"
6500         nums=$($cmd | wc -l)
6501         expected=$(((NUMFILES + 1) * NUMDIRS))
6502
6503         echo "Clock skew between client and server: $skew, age:$age"
6504         [ $nums -eq $expected ] ||
6505                 error "'$cmd' wrong: found $nums, expected $expected"
6506
6507         expected=$(($NUMDIRS + 1))
6508         cmd="$LFS find $dir -btime -${age}s -type d"
6509         nums=$($cmd | wc -l)
6510         [ $nums -eq $expected ] ||
6511                 error "'$cmd' wrong: found $nums, expected $expected"
6512         rm -f $ref $negref || error "Failed to remove $ref $negref"
6513 }
6514 run_test 56od "check lfs find -btime with units"
6515
6516 test_56p() {
6517         [ $RUNAS_ID -eq $UID ] &&
6518                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6519
6520         local dir=$DIR/$tdir
6521
6522         setup_56 $dir $NUMFILES $NUMDIRS
6523         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6524
6525         local expected=$NUMFILES
6526         local cmd="$LFS find -uid $RUNAS_ID $dir"
6527         local nums=$($cmd | wc -l)
6528
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6533         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6534         nums=$($cmd | wc -l)
6535         [ $nums -eq $expected ] ||
6536                 error "'$cmd' wrong: found $nums, expected $expected"
6537 }
6538 run_test 56p "check lfs find -uid and ! -uid"
6539
6540 test_56q() {
6541         [ $RUNAS_ID -eq $UID ] &&
6542                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6543
6544         local dir=$DIR/$tdir
6545
6546         setup_56 $dir $NUMFILES $NUMDIRS
6547         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6548
6549         local expected=$NUMFILES
6550         local cmd="$LFS find -gid $RUNAS_GID $dir"
6551         local nums=$($cmd | wc -l)
6552
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555
6556         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6557         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6558         nums=$($cmd | wc -l)
6559         [ $nums -eq $expected ] ||
6560                 error "'$cmd' wrong: found $nums, expected $expected"
6561 }
6562 run_test 56q "check lfs find -gid and ! -gid"
6563
6564 test_56r() {
6565         local dir=$DIR/$tdir
6566
6567         setup_56 $dir $NUMFILES $NUMDIRS
6568
6569         local expected=12
6570         local cmd="$LFS find -size 0 -type f -lazy $dir"
6571         local nums=$($cmd | wc -l)
6572
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575         cmd="$LFS find -size 0 -type f $dir"
6576         nums=$($cmd | wc -l)
6577         [ $nums -eq $expected ] ||
6578                 error "'$cmd' wrong: found $nums, expected $expected"
6579
6580         expected=0
6581         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6582         nums=$($cmd | wc -l)
6583         [ $nums -eq $expected ] ||
6584                 error "'$cmd' wrong: found $nums, expected $expected"
6585         cmd="$LFS find ! -size 0 -type f $dir"
6586         nums=$($cmd | wc -l)
6587         [ $nums -eq $expected ] ||
6588                 error "'$cmd' wrong: found $nums, expected $expected"
6589
6590         echo "test" > $dir/$tfile
6591         echo "test2" > $dir/$tfile.2 && sync
6592         expected=1
6593         cmd="$LFS find -size 5 -type f -lazy $dir"
6594         nums=$($cmd | wc -l)
6595         [ $nums -eq $expected ] ||
6596                 error "'$cmd' wrong: found $nums, expected $expected"
6597         cmd="$LFS find -size 5 -type f $dir"
6598         nums=$($cmd | wc -l)
6599         [ $nums -eq $expected ] ||
6600                 error "'$cmd' wrong: found $nums, expected $expected"
6601
6602         expected=1
6603         cmd="$LFS find -size +5 -type f -lazy $dir"
6604         nums=$($cmd | wc -l)
6605         [ $nums -eq $expected ] ||
6606                 error "'$cmd' wrong: found $nums, expected $expected"
6607         cmd="$LFS find -size +5 -type f $dir"
6608         nums=$($cmd | wc -l)
6609         [ $nums -eq $expected ] ||
6610                 error "'$cmd' wrong: found $nums, expected $expected"
6611
6612         expected=2
6613         cmd="$LFS find -size +0 -type f -lazy $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617         cmd="$LFS find -size +0 -type f $dir"
6618         nums=$($cmd | wc -l)
6619         [ $nums -eq $expected ] ||
6620                 error "'$cmd' wrong: found $nums, expected $expected"
6621
6622         expected=2
6623         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6624         nums=$($cmd | wc -l)
6625         [ $nums -eq $expected ] ||
6626                 error "'$cmd' wrong: found $nums, expected $expected"
6627         cmd="$LFS find ! -size -5 -type f $dir"
6628         nums=$($cmd | wc -l)
6629         [ $nums -eq $expected ] ||
6630                 error "'$cmd' wrong: found $nums, expected $expected"
6631
6632         expected=12
6633         cmd="$LFS find -size -5 -type f -lazy $dir"
6634         nums=$($cmd | wc -l)
6635         [ $nums -eq $expected ] ||
6636                 error "'$cmd' wrong: found $nums, expected $expected"
6637         cmd="$LFS find -size -5 -type f $dir"
6638         nums=$($cmd | wc -l)
6639         [ $nums -eq $expected ] ||
6640                 error "'$cmd' wrong: found $nums, expected $expected"
6641 }
6642 run_test 56r "check lfs find -size works"
6643
6644 test_56ra_sub() {
6645         local expected=$1
6646         local glimpses=$2
6647         local cmd="$3"
6648
6649         cancel_lru_locks $OSC
6650
6651         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6652         local nums=$($cmd | wc -l)
6653
6654         [ $nums -eq $expected ] ||
6655                 error "'$cmd' wrong: found $nums, expected $expected"
6656
6657         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6658
6659         if (( rpcs_before + glimpses != rpcs_after )); then
6660                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6661                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6662
6663                 if [[ $glimpses == 0 ]]; then
6664                         error "'$cmd' should not send glimpse RPCs to OST"
6665                 else
6666                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6667                 fi
6668         fi
6669 }
6670
6671 test_56ra() {
6672         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6673                 skip "MDS < 2.12.58 doesn't return LSOM data"
6674         local dir=$DIR/$tdir
6675         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6676
6677         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6678
6679         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6680         $LCTL set_param -n llite.*.statahead_agl=0
6681         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6682
6683         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6684         # open and close all files to ensure LSOM is updated
6685         cancel_lru_locks $OSC
6686         find $dir -type f | xargs cat > /dev/null
6687
6688         #   expect_found  glimpse_rpcs  command_to_run
6689         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6690         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6691         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6692         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6693
6694         echo "test" > $dir/$tfile
6695         echo "test2" > $dir/$tfile.2 && sync
6696         cancel_lru_locks $OSC
6697         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6698
6699         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6700         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6701         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6702         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6703
6704         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6705         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6706         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6707         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6708         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6709         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6710 }
6711 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6712
6713 test_56rb() {
6714         local dir=$DIR/$tdir
6715         local tmp=$TMP/$tfile.log
6716         local mdt_idx;
6717
6718         test_mkdir -p $dir || error "failed to mkdir $dir"
6719         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6720                 error "failed to setstripe $dir/$tfile"
6721         mdt_idx=$($LFS getdirstripe -i $dir)
6722         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6723
6724         stack_trap "rm -f $tmp" EXIT
6725         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6726         ! grep -q obd_uuid $tmp ||
6727                 error "failed to find --size +100K --ost 0 $dir"
6728         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6729         ! grep -q obd_uuid $tmp ||
6730                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6731 }
6732 run_test 56rb "check lfs find --size --ost/--mdt works"
6733
6734 test_56rc() {
6735         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6736         local dir=$DIR/$tdir
6737         local found
6738
6739         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6740         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6741         (( $MDSCOUNT > 2 )) &&
6742                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6743         mkdir $dir/$tdir-{1..10}
6744         touch $dir/$tfile-{1..10}
6745
6746         found=$($LFS find $dir --mdt-count 2 | wc -l)
6747         expect=11
6748         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6749
6750         found=$($LFS find $dir -T +1 | wc -l)
6751         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6752         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6753
6754         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6755         expect=11
6756         (( $found == $expect )) || error "found $found all_char, expect $expect"
6757
6758         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6759         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6760         (( $found == $expect )) || error "found $found all_char, expect $expect"
6761 }
6762 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6763
6764 test_56s() { # LU-611 #LU-9369
6765         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6766
6767         local dir=$DIR/$tdir
6768         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6769
6770         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6771         for i in $(seq $NUMDIRS); do
6772                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6773         done
6774
6775         local expected=$NUMDIRS
6776         local cmd="$LFS find -c $OSTCOUNT $dir"
6777         local nums=$($cmd | wc -l)
6778
6779         [ $nums -eq $expected ] || {
6780                 $LFS getstripe -R $dir
6781                 error "'$cmd' wrong: found $nums, expected $expected"
6782         }
6783
6784         expected=$((NUMDIRS + onestripe))
6785         cmd="$LFS find -stripe-count +0 -type f $dir"
6786         nums=$($cmd | wc -l)
6787         [ $nums -eq $expected ] || {
6788                 $LFS getstripe -R $dir
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790         }
6791
6792         expected=$onestripe
6793         cmd="$LFS find -stripe-count 1 -type f $dir"
6794         nums=$($cmd | wc -l)
6795         [ $nums -eq $expected ] || {
6796                 $LFS getstripe -R $dir
6797                 error "'$cmd' wrong: found $nums, expected $expected"
6798         }
6799
6800         cmd="$LFS find -stripe-count -2 -type f $dir"
6801         nums=$($cmd | wc -l)
6802         [ $nums -eq $expected ] || {
6803                 $LFS getstripe -R $dir
6804                 error "'$cmd' wrong: found $nums, expected $expected"
6805         }
6806
6807         expected=0
6808         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] || {
6811                 $LFS getstripe -R $dir
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813         }
6814 }
6815 run_test 56s "check lfs find -stripe-count works"
6816
6817 test_56t() { # LU-611 #LU-9369
6818         local dir=$DIR/$tdir
6819
6820         setup_56 $dir 0 $NUMDIRS
6821         for i in $(seq $NUMDIRS); do
6822                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6823         done
6824
6825         local expected=$NUMDIRS
6826         local cmd="$LFS find -S 8M $dir"
6827         local nums=$($cmd | wc -l)
6828
6829         [ $nums -eq $expected ] || {
6830                 $LFS getstripe -R $dir
6831                 error "'$cmd' wrong: found $nums, expected $expected"
6832         }
6833         rm -rf $dir
6834
6835         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6836
6837         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6838
6839         expected=$(((NUMDIRS + 1) * NUMFILES))
6840         cmd="$LFS find -stripe-size 512k -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         cmd="$LFS find -stripe-size +320k -type f $dir"
6846         nums=$($cmd | wc -l)
6847         [ $nums -eq $expected ] ||
6848                 error "'$cmd' wrong: found $nums, expected $expected"
6849
6850         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6851         cmd="$LFS find -stripe-size +200k -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855
6856         cmd="$LFS find -stripe-size -640k -type f $dir"
6857         nums=$($cmd | wc -l)
6858         [ $nums -eq $expected ] ||
6859                 error "'$cmd' wrong: found $nums, expected $expected"
6860
6861         expected=4
6862         cmd="$LFS find -stripe-size 256k -type f $dir"
6863         nums=$($cmd | wc -l)
6864         [ $nums -eq $expected ] ||
6865                 error "'$cmd' wrong: found $nums, expected $expected"
6866
6867         cmd="$LFS find -stripe-size -320k -type f $dir"
6868         nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871
6872         expected=0
6873         cmd="$LFS find -stripe-size 1024k -type f $dir"
6874         nums=$($cmd | wc -l)
6875         [ $nums -eq $expected ] ||
6876                 error "'$cmd' wrong: found $nums, expected $expected"
6877 }
6878 run_test 56t "check lfs find -stripe-size works"
6879
6880 test_56u() { # LU-611
6881         local dir=$DIR/$tdir
6882
6883         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6884
6885         if [[ $OSTCOUNT -gt 1 ]]; then
6886                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6887                 onestripe=4
6888         else
6889                 onestripe=0
6890         fi
6891
6892         local expected=$(((NUMDIRS + 1) * NUMFILES))
6893         local cmd="$LFS find -stripe-index 0 -type f $dir"
6894         local nums=$($cmd | wc -l)
6895
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898
6899         expected=$onestripe
6900         cmd="$LFS find -stripe-index 1 -type f $dir"
6901         nums=$($cmd | wc -l)
6902         [ $nums -eq $expected ] ||
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904
6905         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         expected=0
6911         # This should produce an error and not return any files
6912         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6913         nums=$($cmd 2>/dev/null | wc -l)
6914         [ $nums -eq $expected ] ||
6915                 error "'$cmd' wrong: found $nums, expected $expected"
6916
6917         if [[ $OSTCOUNT -gt 1 ]]; then
6918                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6919                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6920                 nums=$($cmd | wc -l)
6921                 [ $nums -eq $expected ] ||
6922                         error "'$cmd' wrong: found $nums, expected $expected"
6923         fi
6924 }
6925 run_test 56u "check lfs find -stripe-index works"
6926
6927 test_56v() {
6928         local mdt_idx=0
6929         local dir=$DIR/$tdir
6930
6931         setup_56 $dir $NUMFILES $NUMDIRS
6932
6933         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6934         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6935
6936         for file in $($LFS find -m $UUID $dir); do
6937                 file_midx=$($LFS getstripe -m $file)
6938                 [ $file_midx -eq $mdt_idx ] ||
6939                         error "lfs find -m $UUID != getstripe -m $file_midx"
6940         done
6941 }
6942 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6943
6944 test_56w() {
6945         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6947
6948         local dir=$DIR/$tdir
6949
6950         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6951
6952         local stripe_size=$($LFS getstripe -S -d $dir) ||
6953                 error "$LFS getstripe -S -d $dir failed"
6954         stripe_size=${stripe_size%% *}
6955
6956         local file_size=$((stripe_size * OSTCOUNT))
6957         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6958         local required_space=$((file_num * file_size))
6959         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6960                            head -n1)
6961         [[ $free_space -le $((required_space / 1024)) ]] &&
6962                 skip_env "need $required_space, have $free_space kbytes"
6963
6964         local dd_bs=65536
6965         local dd_count=$((file_size / dd_bs))
6966
6967         # write data into the files
6968         local i
6969         local j
6970         local file
6971
6972         for i in $(seq $NUMFILES); do
6973                 file=$dir/file$i
6974                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6975                         error "write data into $file failed"
6976         done
6977         for i in $(seq $NUMDIRS); do
6978                 for j in $(seq $NUMFILES); do
6979                         file=$dir/dir$i/file$j
6980                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6981                                 error "write data into $file failed"
6982                 done
6983         done
6984
6985         # $LFS_MIGRATE will fail if hard link migration is unsupported
6986         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6987                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6988                         error "creating links to $dir/dir1/file1 failed"
6989         fi
6990
6991         local expected=-1
6992
6993         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6994
6995         # lfs_migrate file
6996         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6997
6998         echo "$cmd"
6999         eval $cmd || error "$cmd failed"
7000
7001         check_stripe_count $dir/file1 $expected
7002
7003         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7004         then
7005                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7006                 # OST 1 if it is on OST 0. This file is small enough to
7007                 # be on only one stripe.
7008                 file=$dir/migr_1_ost
7009                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7010                         error "write data into $file failed"
7011                 local obdidx=$($LFS getstripe -i $file)
7012                 local oldmd5=$(md5sum $file)
7013                 local newobdidx=0
7014
7015                 [[ $obdidx -eq 0 ]] && newobdidx=1
7016                 cmd="$LFS migrate -i $newobdidx $file"
7017                 echo $cmd
7018                 eval $cmd || error "$cmd failed"
7019
7020                 local realobdix=$($LFS getstripe -i $file)
7021                 local newmd5=$(md5sum $file)
7022
7023                 [[ $newobdidx -ne $realobdix ]] &&
7024                         error "new OST is different (was=$obdidx, "\
7025                               "wanted=$newobdidx, got=$realobdix)"
7026                 [[ "$oldmd5" != "$newmd5" ]] &&
7027                         error "md5sum differ: $oldmd5, $newmd5"
7028         fi
7029
7030         # lfs_migrate dir
7031         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7032         echo "$cmd"
7033         eval $cmd || error "$cmd failed"
7034
7035         for j in $(seq $NUMFILES); do
7036                 check_stripe_count $dir/dir1/file$j $expected
7037         done
7038
7039         # lfs_migrate works with lfs find
7040         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7041              $LFS_MIGRATE -y -c $expected"
7042         echo "$cmd"
7043         eval $cmd || error "$cmd failed"
7044
7045         for i in $(seq 2 $NUMFILES); do
7046                 check_stripe_count $dir/file$i $expected
7047         done
7048         for i in $(seq 2 $NUMDIRS); do
7049                 for j in $(seq $NUMFILES); do
7050                 check_stripe_count $dir/dir$i/file$j $expected
7051                 done
7052         done
7053 }
7054 run_test 56w "check lfs_migrate -c stripe_count works"
7055
7056 test_56wb() {
7057         local file1=$DIR/$tdir/file1
7058         local create_pool=false
7059         local initial_pool=$($LFS getstripe -p $DIR)
7060         local pool_list=()
7061         local pool=""
7062
7063         echo -n "Creating test dir..."
7064         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7065         echo "done."
7066
7067         echo -n "Creating test file..."
7068         touch $file1 || error "cannot create file"
7069         echo "done."
7070
7071         echo -n "Detecting existing pools..."
7072         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7073
7074         if [ ${#pool_list[@]} -gt 0 ]; then
7075                 echo "${pool_list[@]}"
7076                 for thispool in "${pool_list[@]}"; do
7077                         if [[ -z "$initial_pool" ||
7078                               "$initial_pool" != "$thispool" ]]; then
7079                                 pool="$thispool"
7080                                 echo "Using existing pool '$pool'"
7081                                 break
7082                         fi
7083                 done
7084         else
7085                 echo "none detected."
7086         fi
7087         if [ -z "$pool" ]; then
7088                 pool=${POOL:-testpool}
7089                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7090                 echo -n "Creating pool '$pool'..."
7091                 create_pool=true
7092                 pool_add $pool &> /dev/null ||
7093                         error "pool_add failed"
7094                 echo "done."
7095
7096                 echo -n "Adding target to pool..."
7097                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7098                         error "pool_add_targets failed"
7099                 echo "done."
7100         fi
7101
7102         echo -n "Setting pool using -p option..."
7103         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7104                 error "migrate failed rc = $?"
7105         echo "done."
7106
7107         echo -n "Verifying test file is in pool after migrating..."
7108         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7109                 error "file was not migrated to pool $pool"
7110         echo "done."
7111
7112         echo -n "Removing test file from pool '$pool'..."
7113         # "lfs migrate $file" won't remove the file from the pool
7114         # until some striping information is changed.
7115         $LFS migrate -c 1 $file1 &> /dev/null ||
7116                 error "cannot remove from pool"
7117         [ "$($LFS getstripe -p $file1)" ] &&
7118                 error "pool still set"
7119         echo "done."
7120
7121         echo -n "Setting pool using --pool option..."
7122         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7123                 error "migrate failed rc = $?"
7124         echo "done."
7125
7126         # Clean up
7127         rm -f $file1
7128         if $create_pool; then
7129                 destroy_test_pools 2> /dev/null ||
7130                         error "destroy test pools failed"
7131         fi
7132 }
7133 run_test 56wb "check lfs_migrate pool support"
7134
7135 test_56wc() {
7136         local file1="$DIR/$tdir/file1"
7137         local parent_ssize
7138         local parent_scount
7139         local cur_ssize
7140         local cur_scount
7141         local orig_ssize
7142
7143         echo -n "Creating test dir..."
7144         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7145         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7146                 error "cannot set stripe by '-S 1M -c 1'"
7147         echo "done"
7148
7149         echo -n "Setting initial stripe for test file..."
7150         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7151                 error "cannot set stripe"
7152         cur_ssize=$($LFS getstripe -S "$file1")
7153         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7154         echo "done."
7155
7156         # File currently set to -S 512K -c 1
7157
7158         # Ensure -c and -S options are rejected when -R is set
7159         echo -n "Verifying incompatible options are detected..."
7160         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7161                 error "incompatible -c and -R options not detected"
7162         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7163                 error "incompatible -S and -R options not detected"
7164         echo "done."
7165
7166         # Ensure unrecognized options are passed through to 'lfs migrate'
7167         echo -n "Verifying -S option is passed through to lfs migrate..."
7168         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7169                 error "migration failed"
7170         cur_ssize=$($LFS getstripe -S "$file1")
7171         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7172         echo "done."
7173
7174         # File currently set to -S 1M -c 1
7175
7176         # Ensure long options are supported
7177         echo -n "Verifying long options supported..."
7178         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7179                 error "long option without argument not supported"
7180         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7181                 error "long option with argument not supported"
7182         cur_ssize=$($LFS getstripe -S "$file1")
7183         [ $cur_ssize -eq 524288 ] ||
7184                 error "migrate --stripe-size $cur_ssize != 524288"
7185         echo "done."
7186
7187         # File currently set to -S 512K -c 1
7188
7189         if [ "$OSTCOUNT" -gt 1 ]; then
7190                 echo -n "Verifying explicit stripe count can be set..."
7191                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7192                         error "migrate failed"
7193                 cur_scount=$($LFS getstripe -c "$file1")
7194                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7195                 echo "done."
7196         fi
7197
7198         # File currently set to -S 512K -c 1 or -S 512K -c 2
7199
7200         # Ensure parent striping is used if -R is set, and no stripe
7201         # count or size is specified
7202         echo -n "Setting stripe for parent directory..."
7203         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7204                 error "cannot set stripe '-S 2M -c 1'"
7205         echo "done."
7206
7207         echo -n "Verifying restripe option uses parent stripe settings..."
7208         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7209         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7210         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7211                 error "migrate failed"
7212         cur_ssize=$($LFS getstripe -S "$file1")
7213         [ $cur_ssize -eq $parent_ssize ] ||
7214                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7215         cur_scount=$($LFS getstripe -c "$file1")
7216         [ $cur_scount -eq $parent_scount ] ||
7217                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7218         echo "done."
7219
7220         # File currently set to -S 1M -c 1
7221
7222         # Ensure striping is preserved if -R is not set, and no stripe
7223         # count or size is specified
7224         echo -n "Verifying striping size preserved when not specified..."
7225         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7226         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7227                 error "cannot set stripe on parent directory"
7228         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7229                 error "migrate failed"
7230         cur_ssize=$($LFS getstripe -S "$file1")
7231         [ $cur_ssize -eq $orig_ssize ] ||
7232                 error "migrate by default $cur_ssize != $orig_ssize"
7233         echo "done."
7234
7235         # Ensure file name properly detected when final option has no argument
7236         echo -n "Verifying file name properly detected..."
7237         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7238                 error "file name interpreted as option argument"
7239         echo "done."
7240
7241         # Clean up
7242         rm -f "$file1"
7243 }
7244 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7245
7246 test_56wd() {
7247         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7248
7249         local file1=$DIR/$tdir/file1
7250
7251         echo -n "Creating test dir..."
7252         test_mkdir $DIR/$tdir || error "cannot create dir"
7253         echo "done."
7254
7255         echo -n "Creating test file..."
7256         touch $file1
7257         echo "done."
7258
7259         # Ensure 'lfs migrate' will fail by using a non-existent option,
7260         # and make sure rsync is not called to recover
7261         echo -n "Make sure --no-rsync option works..."
7262         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7263                 grep -q 'refusing to fall back to rsync' ||
7264                 error "rsync was called with --no-rsync set"
7265         echo "done."
7266
7267         # Ensure rsync is called without trying 'lfs migrate' first
7268         echo -n "Make sure --rsync option works..."
7269         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7270                 grep -q 'falling back to rsync' &&
7271                 error "lfs migrate was called with --rsync set"
7272         echo "done."
7273
7274         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7275         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7276                 grep -q 'at the same time' ||
7277                 error "--rsync and --no-rsync accepted concurrently"
7278         echo "done."
7279
7280         # Clean up
7281         rm -f $file1
7282 }
7283 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7284
7285 test_56we() {
7286         local td=$DIR/$tdir
7287         local tf=$td/$tfile
7288
7289         test_mkdir $td || error "cannot create $td"
7290         touch $tf || error "cannot touch $tf"
7291
7292         echo -n "Make sure --non-direct|-D works..."
7293         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7294                 grep -q "lfs migrate --non-direct" ||
7295                 error "--non-direct option cannot work correctly"
7296         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7297                 grep -q "lfs migrate -D" ||
7298                 error "-D option cannot work correctly"
7299         echo "done."
7300 }
7301 run_test 56we "check lfs_migrate --non-direct|-D support"
7302
7303 test_56x() {
7304         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7305         check_swap_layouts_support
7306
7307         local dir=$DIR/$tdir
7308         local ref1=/etc/passwd
7309         local file1=$dir/file1
7310
7311         test_mkdir $dir || error "creating dir $dir"
7312         $LFS setstripe -c 2 $file1
7313         cp $ref1 $file1
7314         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7315         stripe=$($LFS getstripe -c $file1)
7316         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7317         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7318
7319         # clean up
7320         rm -f $file1
7321 }
7322 run_test 56x "lfs migration support"
7323
7324 test_56xa() {
7325         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7326         check_swap_layouts_support
7327
7328         local dir=$DIR/$tdir/$testnum
7329
7330         test_mkdir -p $dir
7331
7332         local ref1=/etc/passwd
7333         local file1=$dir/file1
7334
7335         $LFS setstripe -c 2 $file1
7336         cp $ref1 $file1
7337         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7338
7339         local stripe=$($LFS getstripe -c $file1)
7340
7341         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7342         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7343
7344         # clean up
7345         rm -f $file1
7346 }
7347 run_test 56xa "lfs migration --block support"
7348
7349 check_migrate_links() {
7350         local dir="$1"
7351         local file1="$dir/file1"
7352         local begin="$2"
7353         local count="$3"
7354         local runas="$4"
7355         local total_count=$(($begin + $count - 1))
7356         local symlink_count=10
7357         local uniq_count=10
7358
7359         if [ ! -f "$file1" ]; then
7360                 echo -n "creating initial file..."
7361                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7362                         error "cannot setstripe initial file"
7363                 echo "done"
7364
7365                 echo -n "creating symlinks..."
7366                 for s in $(seq 1 $symlink_count); do
7367                         ln -s "$file1" "$dir/slink$s" ||
7368                                 error "cannot create symlinks"
7369                 done
7370                 echo "done"
7371
7372                 echo -n "creating nonlinked files..."
7373                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7374                         error "cannot create nonlinked files"
7375                 echo "done"
7376         fi
7377
7378         # create hard links
7379         if [ ! -f "$dir/file$total_count" ]; then
7380                 echo -n "creating hard links $begin:$total_count..."
7381                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7382                         /dev/null || error "cannot create hard links"
7383                 echo "done"
7384         fi
7385
7386         echo -n "checking number of hard links listed in xattrs..."
7387         local fid=$($LFS getstripe -F "$file1")
7388         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7389
7390         echo "${#paths[*]}"
7391         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7392                         skip "hard link list has unexpected size, skipping test"
7393         fi
7394         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7395                         error "link names should exceed xattrs size"
7396         fi
7397
7398         echo -n "migrating files..."
7399         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7400         local rc=$?
7401         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7402         echo "done"
7403
7404         # make sure all links have been properly migrated
7405         echo -n "verifying files..."
7406         fid=$($LFS getstripe -F "$file1") ||
7407                 error "cannot get fid for file $file1"
7408         for i in $(seq 2 $total_count); do
7409                 local fid2=$($LFS getstripe -F $dir/file$i)
7410
7411                 [ "$fid2" == "$fid" ] ||
7412                         error "migrated hard link has mismatched FID"
7413         done
7414
7415         # make sure hard links were properly detected, and migration was
7416         # performed only once for the entire link set; nonlinked files should
7417         # also be migrated
7418         local actual=$(grep -c 'done' <<< "$migrate_out")
7419         local expected=$(($uniq_count + 1))
7420
7421         [ "$actual" -eq  "$expected" ] ||
7422                 error "hard links individually migrated ($actual != $expected)"
7423
7424         # make sure the correct number of hard links are present
7425         local hardlinks=$(stat -c '%h' "$file1")
7426
7427         [ $hardlinks -eq $total_count ] ||
7428                 error "num hard links $hardlinks != $total_count"
7429         echo "done"
7430
7431         return 0
7432 }
7433
7434 test_56xb() {
7435         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7436                 skip "Need MDS version at least 2.10.55"
7437
7438         local dir="$DIR/$tdir"
7439
7440         test_mkdir "$dir" || error "cannot create dir $dir"
7441
7442         echo "testing lfs migrate mode when all links fit within xattrs"
7443         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7444
7445         echo "testing rsync mode when all links fit within xattrs"
7446         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7447
7448         echo "testing lfs migrate mode when all links do not fit within xattrs"
7449         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7450
7451         echo "testing rsync mode when all links do not fit within xattrs"
7452         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7453
7454         chown -R $RUNAS_ID $dir
7455         echo "testing non-root lfs migrate mode when not all links are in xattr"
7456         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7457
7458         # clean up
7459         rm -rf $dir
7460 }
7461 run_test 56xb "lfs migration hard link support"
7462
7463 test_56xc() {
7464         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7465
7466         local dir="$DIR/$tdir"
7467
7468         test_mkdir "$dir" || error "cannot create dir $dir"
7469
7470         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7471         echo -n "Setting initial stripe for 20MB test file..."
7472         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7473                 error "cannot setstripe 20MB file"
7474         echo "done"
7475         echo -n "Sizing 20MB test file..."
7476         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7477         echo "done"
7478         echo -n "Verifying small file autostripe count is 1..."
7479         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7480                 error "cannot migrate 20MB file"
7481         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7482                 error "cannot get stripe for $dir/20mb"
7483         [ $stripe_count -eq 1 ] ||
7484                 error "unexpected stripe count $stripe_count for 20MB file"
7485         rm -f "$dir/20mb"
7486         echo "done"
7487
7488         # Test 2: File is small enough to fit within the available space on
7489         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7490         # have at least an additional 1KB for each desired stripe for test 3
7491         echo -n "Setting stripe for 1GB test file..."
7492         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7493         echo "done"
7494         echo -n "Sizing 1GB test file..."
7495         # File size is 1GB + 3KB
7496         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7497         echo "done"
7498
7499         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7500         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7501         if (( avail > 524288 * OSTCOUNT )); then
7502                 echo -n "Migrating 1GB file..."
7503                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7504                         error "cannot migrate 1GB file"
7505                 echo "done"
7506                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7507                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7508                         error "cannot getstripe for 1GB file"
7509                 [ $stripe_count -eq 2 ] ||
7510                         error "unexpected stripe count $stripe_count != 2"
7511                 echo "done"
7512         fi
7513
7514         # Test 3: File is too large to fit within the available space on
7515         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7516         if [ $OSTCOUNT -ge 3 ]; then
7517                 # The required available space is calculated as
7518                 # file size (1GB + 3KB) / OST count (3).
7519                 local kb_per_ost=349526
7520
7521                 echo -n "Migrating 1GB file with limit..."
7522                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7523                         error "cannot migrate 1GB file with limit"
7524                 echo "done"
7525
7526                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7527                 echo -n "Verifying 1GB autostripe count with limited space..."
7528                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7529                         error "unexpected stripe count $stripe_count (min 3)"
7530                 echo "done"
7531         fi
7532
7533         # clean up
7534         rm -rf $dir
7535 }
7536 run_test 56xc "lfs migration autostripe"
7537
7538 test_56xd() {
7539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7540
7541         local dir=$DIR/$tdir
7542         local f_mgrt=$dir/$tfile.mgrt
7543         local f_yaml=$dir/$tfile.yaml
7544         local f_copy=$dir/$tfile.copy
7545         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7546         local layout_copy="-c 2 -S 2M -i 1"
7547         local yamlfile=$dir/yamlfile
7548         local layout_before;
7549         local layout_after;
7550
7551         test_mkdir "$dir" || error "cannot create dir $dir"
7552         $LFS setstripe $layout_yaml $f_yaml ||
7553                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7554         $LFS getstripe --yaml $f_yaml > $yamlfile
7555         $LFS setstripe $layout_copy $f_copy ||
7556                 error "cannot setstripe $f_copy with layout $layout_copy"
7557         touch $f_mgrt
7558         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7559
7560         # 1. test option --yaml
7561         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7562                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7563         layout_before=$(get_layout_param $f_yaml)
7564         layout_after=$(get_layout_param $f_mgrt)
7565         [ "$layout_after" == "$layout_before" ] ||
7566                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7567
7568         # 2. test option --copy
7569         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7570                 error "cannot migrate $f_mgrt with --copy $f_copy"
7571         layout_before=$(get_layout_param $f_copy)
7572         layout_after=$(get_layout_param $f_mgrt)
7573         [ "$layout_after" == "$layout_before" ] ||
7574                 error "lfs_migrate --copy: $layout_after != $layout_before"
7575 }
7576 run_test 56xd "check lfs_migrate --yaml and --copy support"
7577
7578 test_56xe() {
7579         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7580
7581         local dir=$DIR/$tdir
7582         local f_comp=$dir/$tfile
7583         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7584         local layout_before=""
7585         local layout_after=""
7586
7587         test_mkdir "$dir" || error "cannot create dir $dir"
7588         $LFS setstripe $layout $f_comp ||
7589                 error "cannot setstripe $f_comp with layout $layout"
7590         layout_before=$(get_layout_param $f_comp)
7591         dd if=/dev/zero of=$f_comp bs=1M count=4
7592
7593         # 1. migrate a comp layout file by lfs_migrate
7594         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7595         layout_after=$(get_layout_param $f_comp)
7596         [ "$layout_before" == "$layout_after" ] ||
7597                 error "lfs_migrate: $layout_before != $layout_after"
7598
7599         # 2. migrate a comp layout file by lfs migrate
7600         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7601         layout_after=$(get_layout_param $f_comp)
7602         [ "$layout_before" == "$layout_after" ] ||
7603                 error "lfs migrate: $layout_before != $layout_after"
7604 }
7605 run_test 56xe "migrate a composite layout file"
7606
7607 test_56xf() {
7608         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7609
7610         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7611                 skip "Need server version at least 2.13.53"
7612
7613         local dir=$DIR/$tdir
7614         local f_comp=$dir/$tfile
7615         local layout="-E 1M -c1 -E -1 -c2"
7616         local fid_before=""
7617         local fid_after=""
7618
7619         test_mkdir "$dir" || error "cannot create dir $dir"
7620         $LFS setstripe $layout $f_comp ||
7621                 error "cannot setstripe $f_comp with layout $layout"
7622         fid_before=$($LFS getstripe --fid $f_comp)
7623         dd if=/dev/zero of=$f_comp bs=1M count=4
7624
7625         # 1. migrate a comp layout file to a comp layout
7626         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7627         fid_after=$($LFS getstripe --fid $f_comp)
7628         [ "$fid_before" == "$fid_after" ] ||
7629                 error "comp-to-comp migrate: $fid_before != $fid_after"
7630
7631         # 2. migrate a comp layout file to a plain layout
7632         $LFS migrate -c2 $f_comp ||
7633                 error "cannot migrate $f_comp by lfs migrate"
7634         fid_after=$($LFS getstripe --fid $f_comp)
7635         [ "$fid_before" == "$fid_after" ] ||
7636                 error "comp-to-plain migrate: $fid_before != $fid_after"
7637
7638         # 3. migrate a plain layout file to a comp layout
7639         $LFS migrate $layout $f_comp ||
7640                 error "cannot migrate $f_comp by lfs migrate"
7641         fid_after=$($LFS getstripe --fid $f_comp)
7642         [ "$fid_before" == "$fid_after" ] ||
7643                 error "plain-to-comp migrate: $fid_before != $fid_after"
7644 }
7645 run_test 56xf "FID is not lost during migration of a composite layout file"
7646
7647 check_file_ost_range() {
7648         local file="$1"
7649         shift
7650         local range="$*"
7651         local -a file_range
7652         local idx
7653
7654         file_range=($($LFS getstripe -y "$file" |
7655                 awk '/l_ost_idx:/ { print $NF }'))
7656
7657         if [[ "${#file_range[@]}" = 0 ]]; then
7658                 echo "No osts found for $file"
7659                 return 1
7660         fi
7661
7662         for idx in "${file_range[@]}"; do
7663                 [[ " $range " =~ " $idx " ]] ||
7664                         return 1
7665         done
7666
7667         return 0
7668 }
7669
7670 sub_test_56xg() {
7671         local stripe_opt="$1"
7672         local pool="$2"
7673         shift 2
7674         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7675
7676         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7677                 error "Fail to migrate $tfile on $pool"
7678         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7679                 error "$tfile is not in pool $pool"
7680         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7681                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7682 }
7683
7684 test_56xg() {
7685         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7686         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7687         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7688                 skip "Need MDS version newer than 2.14.52"
7689
7690         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7691         local -a pool_ranges=("0 0" "1 1" "0 1")
7692
7693         # init pools
7694         for i in "${!pool_names[@]}"; do
7695                 pool_add ${pool_names[$i]} ||
7696                         error "pool_add failed (pool: ${pool_names[$i]})"
7697                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7698                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7699         done
7700
7701         # init the file to migrate
7702         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7703                 error "Unable to create $tfile on OST1"
7704         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7705                 error "Unable to write on $tfile"
7706
7707         echo "1. migrate $tfile on pool ${pool_names[0]}"
7708         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7709
7710         echo "2. migrate $tfile on pool ${pool_names[2]}"
7711         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7712
7713         echo "3. migrate $tfile on pool ${pool_names[1]}"
7714         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7715
7716         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7717         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7718         echo
7719
7720         # Clean pools
7721         destroy_test_pools ||
7722                 error "pool_destroy failed"
7723 }
7724 run_test 56xg "lfs migrate pool support"
7725
7726 test_56y() {
7727         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7728                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7729
7730         local res=""
7731         local dir=$DIR/$tdir
7732         local f1=$dir/file1
7733         local f2=$dir/file2
7734
7735         test_mkdir -p $dir || error "creating dir $dir"
7736         touch $f1 || error "creating std file $f1"
7737         $MULTIOP $f2 H2c || error "creating released file $f2"
7738
7739         # a directory can be raid0, so ask only for files
7740         res=$($LFS find $dir -L raid0 -type f | wc -l)
7741         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7742
7743         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7744         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7745
7746         # only files can be released, so no need to force file search
7747         res=$($LFS find $dir -L released)
7748         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7749
7750         res=$($LFS find $dir -type f \! -L released)
7751         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7752 }
7753 run_test 56y "lfs find -L raid0|released"
7754
7755 test_56z() { # LU-4824
7756         # This checks to make sure 'lfs find' continues after errors
7757         # There are two classes of errors that should be caught:
7758         # - If multiple paths are provided, all should be searched even if one
7759         #   errors out
7760         # - If errors are encountered during the search, it should not terminate
7761         #   early
7762         local dir=$DIR/$tdir
7763         local i
7764
7765         test_mkdir $dir
7766         for i in d{0..9}; do
7767                 test_mkdir $dir/$i
7768                 touch $dir/$i/$tfile
7769         done
7770         $LFS find $DIR/non_existent_dir $dir &&
7771                 error "$LFS find did not return an error"
7772         # Make a directory unsearchable. This should NOT be the last entry in
7773         # directory order.  Arbitrarily pick the 6th entry
7774         chmod 700 $($LFS find $dir -type d | sed '6!d')
7775
7776         $RUNAS $LFS find $DIR/non_existent $dir
7777         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7778
7779         # The user should be able to see 10 directories and 9 files
7780         (( count == 19 )) ||
7781                 error "$LFS find found $count != 19 entries after error"
7782 }
7783 run_test 56z "lfs find should continue after an error"
7784
7785 test_56aa() { # LU-5937
7786         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7787
7788         local dir=$DIR/$tdir
7789
7790         mkdir $dir
7791         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7792
7793         createmany -o $dir/striped_dir/${tfile}- 1024
7794         local dirs=$($LFS find --size +8k $dir/)
7795
7796         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7797 }
7798 run_test 56aa "lfs find --size under striped dir"
7799
7800 test_56ab() { # LU-10705
7801         test_mkdir $DIR/$tdir
7802         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7803         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7804         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7805         # Flush writes to ensure valid blocks.  Need to be more thorough for
7806         # ZFS, since blocks are not allocated/returned to client immediately.
7807         sync_all_data
7808         wait_zfs_commit ost1 2
7809         cancel_lru_locks osc
7810         ls -ls $DIR/$tdir
7811
7812         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7813
7814         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7815
7816         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7817         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7818
7819         rm -f $DIR/$tdir/$tfile.[123]
7820 }
7821 run_test 56ab "lfs find --blocks"
7822
7823 # LU-11188
7824 test_56aca() {
7825         local dir="$DIR/$tdir"
7826         local perms=(001 002 003 004 005 006 007
7827                      010 020 030 040 050 060 070
7828                      100 200 300 400 500 600 700
7829                      111 222 333 444 555 666 777)
7830         local perm_minus=(8 8 4 8 4 4 2
7831                           8 8 4 8 4 4 2
7832                           8 8 4 8 4 4 2
7833                           4 4 2 4 2 2 1)
7834         local perm_slash=(8  8 12  8 12 12 14
7835                           8  8 12  8 12 12 14
7836                           8  8 12  8 12 12 14
7837                          16 16 24 16 24 24 28)
7838
7839         test_mkdir "$dir"
7840         for perm in ${perms[*]}; do
7841                 touch "$dir/$tfile.$perm"
7842                 chmod $perm "$dir/$tfile.$perm"
7843         done
7844
7845         for ((i = 0; i < ${#perms[*]}; i++)); do
7846                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7847                 (( $num == 1 )) ||
7848                         error "lfs find -perm ${perms[i]}:"\
7849                               "$num != 1"
7850
7851                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7852                 (( $num == ${perm_minus[i]} )) ||
7853                         error "lfs find -perm -${perms[i]}:"\
7854                               "$num != ${perm_minus[i]}"
7855
7856                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7857                 (( $num == ${perm_slash[i]} )) ||
7858                         error "lfs find -perm /${perms[i]}:"\
7859                               "$num != ${perm_slash[i]}"
7860         done
7861 }
7862 run_test 56aca "check lfs find -perm with octal representation"
7863
7864 test_56acb() {
7865         local dir=$DIR/$tdir
7866         # p is the permission of write and execute for user, group and other
7867         # without the umask. It is used to test +wx.
7868         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7869         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7870         local symbolic=(+t  a+t u+t g+t o+t
7871                         g+s u+s o+s +s o+sr
7872                         o=r,ug+o,u+w
7873                         u+ g+ o+ a+ ugo+
7874                         u- g- o- a- ugo-
7875                         u= g= o= a= ugo=
7876                         o=r,ug+o,u+w u=r,a+u,u+w
7877                         g=r,ugo=g,u+w u+x,+X +X
7878                         u+x,u+X u+X u+x,g+X o+r,+X
7879                         u+x,go+X +wx +rwx)
7880
7881         test_mkdir $dir
7882         for perm in ${perms[*]}; do
7883                 touch "$dir/$tfile.$perm"
7884                 chmod $perm "$dir/$tfile.$perm"
7885         done
7886
7887         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7888                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7889
7890                 (( $num == 1 )) ||
7891                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7892         done
7893 }
7894 run_test 56acb "check lfs find -perm with symbolic representation"
7895
7896 test_56acc() {
7897         local dir=$DIR/$tdir
7898         local tests="17777 787 789 abcd
7899                 ug=uu ug=a ug=gu uo=ou urw
7900                 u+xg+x a=r,u+x,"
7901
7902         test_mkdir $dir
7903         for err in $tests; do
7904                 if $LFS find $dir -perm $err 2>/dev/null; then
7905                         error "lfs find -perm $err: parsing should have failed"
7906                 fi
7907         done
7908 }
7909 run_test 56acc "check parsing error for lfs find -perm"
7910
7911 test_56ba() {
7912         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7913                 skip "Need MDS version at least 2.10.50"
7914
7915         # Create composite files with one component
7916         local dir=$DIR/$tdir
7917
7918         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7919         # Create composite files with three components
7920         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7921         # Create non-composite files
7922         createmany -o $dir/${tfile}- 10
7923
7924         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7925
7926         [[ $nfiles == 10 ]] ||
7927                 error "lfs find -E 1M found $nfiles != 10 files"
7928
7929         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7930         [[ $nfiles == 25 ]] ||
7931                 error "lfs find ! -E 1M found $nfiles != 25 files"
7932
7933         # All files have a component that starts at 0
7934         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7935         [[ $nfiles == 35 ]] ||
7936                 error "lfs find --component-start 0 - $nfiles != 35 files"
7937
7938         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7939         [[ $nfiles == 15 ]] ||
7940                 error "lfs find --component-start 2M - $nfiles != 15 files"
7941
7942         # All files created here have a componenet that does not starts at 2M
7943         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7944         [[ $nfiles == 35 ]] ||
7945                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7946
7947         # Find files with a specified number of components
7948         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7949         [[ $nfiles == 15 ]] ||
7950                 error "lfs find --component-count 3 - $nfiles != 15 files"
7951
7952         # Remember non-composite files have a component count of zero
7953         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7954         [[ $nfiles == 10 ]] ||
7955                 error "lfs find --component-count 0 - $nfiles != 10 files"
7956
7957         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7958         [[ $nfiles == 20 ]] ||
7959                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7960
7961         # All files have a flag called "init"
7962         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7963         [[ $nfiles == 35 ]] ||
7964                 error "lfs find --component-flags init - $nfiles != 35 files"
7965
7966         # Multi-component files will have a component not initialized
7967         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7968         [[ $nfiles == 15 ]] ||
7969                 error "lfs find !--component-flags init - $nfiles != 15 files"
7970
7971         rm -rf $dir
7972
7973 }
7974 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7975
7976 test_56ca() {
7977         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7978                 skip "Need MDS version at least 2.10.57"
7979
7980         local td=$DIR/$tdir
7981         local tf=$td/$tfile
7982         local dir
7983         local nfiles
7984         local cmd
7985         local i
7986         local j
7987
7988         # create mirrored directories and mirrored files
7989         mkdir $td || error "mkdir $td failed"
7990         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7991         createmany -o $tf- 10 || error "create $tf- failed"
7992
7993         for i in $(seq 2); do
7994                 dir=$td/dir$i
7995                 mkdir $dir || error "mkdir $dir failed"
7996                 $LFS mirror create -N$((3 + i)) $dir ||
7997                         error "create mirrored dir $dir failed"
7998                 createmany -o $dir/$tfile- 10 ||
7999                         error "create $dir/$tfile- failed"
8000         done
8001
8002         # change the states of some mirrored files
8003         echo foo > $tf-6
8004         for i in $(seq 2); do
8005                 dir=$td/dir$i
8006                 for j in $(seq 4 9); do
8007                         echo foo > $dir/$tfile-$j
8008                 done
8009         done
8010
8011         # find mirrored files with specific mirror count
8012         cmd="$LFS find --mirror-count 3 --type f $td"
8013         nfiles=$($cmd | wc -l)
8014         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8015
8016         cmd="$LFS find ! --mirror-count 3 --type f $td"
8017         nfiles=$($cmd | wc -l)
8018         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8019
8020         cmd="$LFS find --mirror-count +2 --type f $td"
8021         nfiles=$($cmd | wc -l)
8022         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8023
8024         cmd="$LFS find --mirror-count -6 --type f $td"
8025         nfiles=$($cmd | wc -l)
8026         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8027
8028         # find mirrored files with specific file state
8029         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8030         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8031
8032         cmd="$LFS find --mirror-state=ro --type f $td"
8033         nfiles=$($cmd | wc -l)
8034         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8035
8036         cmd="$LFS find ! --mirror-state=ro --type f $td"
8037         nfiles=$($cmd | wc -l)
8038         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8039
8040         cmd="$LFS find --mirror-state=wp --type f $td"
8041         nfiles=$($cmd | wc -l)
8042         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8043
8044         cmd="$LFS find ! --mirror-state=sp --type f $td"
8045         nfiles=$($cmd | wc -l)
8046         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8047 }
8048 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8049
8050 test_56da() { # LU-14179
8051         local path=$DIR/$tdir
8052
8053         test_mkdir $path
8054         cd $path
8055
8056         local longdir=$(str_repeat 'a' 255)
8057
8058         for i in {1..15}; do
8059                 path=$path/$longdir
8060                 test_mkdir $longdir
8061                 cd $longdir
8062         done
8063
8064         local len=${#path}
8065         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8066
8067         test_mkdir $lastdir
8068         cd $lastdir
8069         # PATH_MAX-1
8070         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8071
8072         # NAME_MAX
8073         touch $(str_repeat 'f' 255)
8074
8075         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8076                 error "lfs find reported an error"
8077
8078         rm -rf $DIR/$tdir
8079 }
8080 run_test 56da "test lfs find with long paths"
8081
8082 test_57a() {
8083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8084         # note test will not do anything if MDS is not local
8085         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8086                 skip_env "ldiskfs only test"
8087         fi
8088         remote_mds_nodsh && skip "remote MDS with nodsh"
8089
8090         local MNTDEV="osd*.*MDT*.mntdev"
8091         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8092         [ -z "$DEV" ] && error "can't access $MNTDEV"
8093         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8094                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8095                         error "can't access $DEV"
8096                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8097                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8098                 rm $TMP/t57a.dump
8099         done
8100 }
8101 run_test 57a "verify MDS filesystem created with large inodes =="
8102
8103 test_57b() {
8104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8105         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8106                 skip_env "ldiskfs only test"
8107         fi
8108         remote_mds_nodsh && skip "remote MDS with nodsh"
8109
8110         local dir=$DIR/$tdir
8111         local filecount=100
8112         local file1=$dir/f1
8113         local fileN=$dir/f$filecount
8114
8115         rm -rf $dir || error "removing $dir"
8116         test_mkdir -c1 $dir
8117         local mdtidx=$($LFS getstripe -m $dir)
8118         local mdtname=MDT$(printf %04x $mdtidx)
8119         local facet=mds$((mdtidx + 1))
8120
8121         echo "mcreating $filecount files"
8122         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8123
8124         # verify that files do not have EAs yet
8125         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8126                 error "$file1 has an EA"
8127         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8128                 error "$fileN has an EA"
8129
8130         sync
8131         sleep 1
8132         df $dir  #make sure we get new statfs data
8133         local mdsfree=$(do_facet $facet \
8134                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8135         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8136         local file
8137
8138         echo "opening files to create objects/EAs"
8139         for file in $(seq -f $dir/f%g 1 $filecount); do
8140                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8141                         error "opening $file"
8142         done
8143
8144         # verify that files have EAs now
8145         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8146         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8147
8148         sleep 1  #make sure we get new statfs data
8149         df $dir
8150         local mdsfree2=$(do_facet $facet \
8151                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8152         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8153
8154         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8155                 if [ "$mdsfree" != "$mdsfree2" ]; then
8156                         error "MDC before $mdcfree != after $mdcfree2"
8157                 else
8158                         echo "MDC before $mdcfree != after $mdcfree2"
8159                         echo "unable to confirm if MDS has large inodes"
8160                 fi
8161         fi
8162         rm -rf $dir
8163 }
8164 run_test 57b "default LOV EAs are stored inside large inodes ==="
8165
8166 test_58() {
8167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8168         [ -z "$(which wiretest 2>/dev/null)" ] &&
8169                         skip_env "could not find wiretest"
8170
8171         wiretest
8172 }
8173 run_test 58 "verify cross-platform wire constants =============="
8174
8175 test_59() {
8176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8177
8178         echo "touch 130 files"
8179         createmany -o $DIR/f59- 130
8180         echo "rm 130 files"
8181         unlinkmany $DIR/f59- 130
8182         sync
8183         # wait for commitment of removal
8184         wait_delete_completed
8185 }
8186 run_test 59 "verify cancellation of llog records async ========="
8187
8188 TEST60_HEAD="test_60 run $RANDOM"
8189 test_60a() {
8190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8191         remote_mgs_nodsh && skip "remote MGS with nodsh"
8192         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8193                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8194                         skip_env "missing subtest run-llog.sh"
8195
8196         log "$TEST60_HEAD - from kernel mode"
8197         do_facet mgs "$LCTL dk > /dev/null"
8198         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8199         do_facet mgs $LCTL dk > $TMP/$tfile
8200
8201         # LU-6388: test llog_reader
8202         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8203         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8204         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8205                         skip_env "missing llog_reader"
8206         local fstype=$(facet_fstype mgs)
8207         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8208                 skip_env "Only for ldiskfs or zfs type mgs"
8209
8210         local mntpt=$(facet_mntpt mgs)
8211         local mgsdev=$(mgsdevname 1)
8212         local fid_list
8213         local fid
8214         local rec_list
8215         local rec
8216         local rec_type
8217         local obj_file
8218         local path
8219         local seq
8220         local oid
8221         local pass=true
8222
8223         #get fid and record list
8224         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8225                 tail -n 4))
8226         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8227                 tail -n 4))
8228         #remount mgs as ldiskfs or zfs type
8229         stop mgs || error "stop mgs failed"
8230         mount_fstype mgs || error "remount mgs failed"
8231         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8232                 fid=${fid_list[i]}
8233                 rec=${rec_list[i]}
8234                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8235                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8236                 oid=$((16#$oid))
8237
8238                 case $fstype in
8239                         ldiskfs )
8240                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8241                         zfs )
8242                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8243                 esac
8244                 echo "obj_file is $obj_file"
8245                 do_facet mgs $llog_reader $obj_file
8246
8247                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8248                         awk '{ print $3 }' | sed -e "s/^type=//g")
8249                 if [ $rec_type != $rec ]; then
8250                         echo "FAILED test_60a wrong record type $rec_type," \
8251                               "should be $rec"
8252                         pass=false
8253                         break
8254                 fi
8255
8256                 #check obj path if record type is LLOG_LOGID_MAGIC
8257                 if [ "$rec" == "1064553b" ]; then
8258                         path=$(do_facet mgs $llog_reader $obj_file |
8259                                 grep "path=" | awk '{ print $NF }' |
8260                                 sed -e "s/^path=//g")
8261                         if [ $obj_file != $mntpt/$path ]; then
8262                                 echo "FAILED test_60a wrong obj path" \
8263                                       "$montpt/$path, should be $obj_file"
8264                                 pass=false
8265                                 break
8266                         fi
8267                 fi
8268         done
8269         rm -f $TMP/$tfile
8270         #restart mgs before "error", otherwise it will block the next test
8271         stop mgs || error "stop mgs failed"
8272         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8273         $pass || error "test failed, see FAILED test_60a messages for specifics"
8274 }
8275 run_test 60a "llog_test run from kernel module and test llog_reader"
8276
8277 test_60b() { # bug 6411
8278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8279
8280         dmesg > $DIR/$tfile
8281         LLOG_COUNT=$(do_facet mgs dmesg |
8282                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8283                           /llog_[a-z]*.c:[0-9]/ {
8284                                 if (marker)
8285                                         from_marker++
8286                                 from_begin++
8287                           }
8288                           END {
8289                                 if (marker)
8290                                         print from_marker
8291                                 else
8292                                         print from_begin
8293                           }")
8294
8295         [[ $LLOG_COUNT -gt 120 ]] &&
8296                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8297 }
8298 run_test 60b "limit repeated messages from CERROR/CWARN"
8299
8300 test_60c() {
8301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8302
8303         echo "create 5000 files"
8304         createmany -o $DIR/f60c- 5000
8305 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8306         lctl set_param fail_loc=0x80000137
8307         unlinkmany $DIR/f60c- 5000
8308         lctl set_param fail_loc=0
8309 }
8310 run_test 60c "unlink file when mds full"
8311
8312 test_60d() {
8313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8314
8315         SAVEPRINTK=$(lctl get_param -n printk)
8316         # verify "lctl mark" is even working"
8317         MESSAGE="test message ID $RANDOM $$"
8318         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8319         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8320
8321         lctl set_param printk=0 || error "set lnet.printk failed"
8322         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8323         MESSAGE="new test message ID $RANDOM $$"
8324         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8325         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8326         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8327
8328         lctl set_param -n printk="$SAVEPRINTK"
8329 }
8330 run_test 60d "test printk console message masking"
8331
8332 test_60e() {
8333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8334         remote_mds_nodsh && skip "remote MDS with nodsh"
8335
8336         touch $DIR/$tfile
8337 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8338         do_facet mds1 lctl set_param fail_loc=0x15b
8339         rm $DIR/$tfile
8340 }
8341 run_test 60e "no space while new llog is being created"
8342
8343 test_60f() {
8344         local old_path=$($LCTL get_param -n debug_path)
8345
8346         stack_trap "$LCTL set_param debug_path=$old_path"
8347         stack_trap "rm -f $TMP/$tfile*"
8348         rm -f $TMP/$tfile* 2> /dev/null
8349         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8350         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8351         test_mkdir $DIR/$tdir
8352         # retry in case the open is cached and not released
8353         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8354                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8355                 sleep 0.1
8356         done
8357         ls $TMP/$tfile*
8358         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8359 }
8360 run_test 60f "change debug_path works"
8361
8362 test_60g() {
8363         local pid
8364         local i
8365
8366         test_mkdir -c $MDSCOUNT $DIR/$tdir
8367
8368         (
8369                 local index=0
8370                 while true; do
8371                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8372                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8373                                 2>/dev/null
8374                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8375                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8376                         index=$((index + 1))
8377                 done
8378         ) &
8379
8380         pid=$!
8381
8382         for i in {0..100}; do
8383                 # define OBD_FAIL_OSD_TXN_START    0x19a
8384                 local index=$((i % MDSCOUNT + 1))
8385
8386                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8387                         > /dev/null
8388                 sleep 0.01
8389         done
8390
8391         kill -9 $pid
8392
8393         for i in $(seq $MDSCOUNT); do
8394                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8395         done
8396
8397         mkdir $DIR/$tdir/new || error "mkdir failed"
8398         rmdir $DIR/$tdir/new || error "rmdir failed"
8399
8400         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8401                 -t namespace
8402         for i in $(seq $MDSCOUNT); do
8403                 wait_update_facet mds$i "$LCTL get_param -n \
8404                         mdd.$(facet_svc mds$i).lfsck_namespace |
8405                         awk '/^status/ { print \\\$2 }'" "completed"
8406         done
8407
8408         ls -R $DIR/$tdir || error "ls failed"
8409         rm -rf $DIR/$tdir || error "rmdir failed"
8410 }
8411 run_test 60g "transaction abort won't cause MDT hung"
8412
8413 test_60h() {
8414         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8415                 skip "Need MDS version at least 2.12.52"
8416         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8417
8418         local f
8419
8420         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8421         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8422         for fail_loc in 0x80000188 0x80000189; do
8423                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8424                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8425                         error "mkdir $dir-$fail_loc failed"
8426                 for i in {0..10}; do
8427                         # create may fail on missing stripe
8428                         echo $i > $DIR/$tdir-$fail_loc/$i
8429                 done
8430                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8431                         error "getdirstripe $tdir-$fail_loc failed"
8432                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8433                         error "migrate $tdir-$fail_loc failed"
8434                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8435                         error "getdirstripe $tdir-$fail_loc failed"
8436                 pushd $DIR/$tdir-$fail_loc
8437                 for f in *; do
8438                         echo $f | cmp $f - || error "$f data mismatch"
8439                 done
8440                 popd
8441                 rm -rf $DIR/$tdir-$fail_loc
8442         done
8443 }
8444 run_test 60h "striped directory with missing stripes can be accessed"
8445
8446 function t60i_load() {
8447         mkdir $DIR/$tdir
8448         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8449         $LCTL set_param fail_loc=0x131c fail_val=1
8450         for ((i=0; i<5000; i++)); do
8451                 touch $DIR/$tdir/f$i
8452         done
8453 }
8454
8455 test_60i() {
8456         changelog_register || error "changelog_register failed"
8457         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8458         changelog_users $SINGLEMDS | grep -q $cl_user ||
8459                 error "User $cl_user not found in changelog_users"
8460         changelog_chmask "ALL"
8461         t60i_load &
8462         local PID=$!
8463         for((i=0; i<100; i++)); do
8464                 changelog_dump >/dev/null ||
8465                         error "can't read changelog"
8466         done
8467         kill $PID
8468         wait $PID
8469         changelog_deregister || error "changelog_deregister failed"
8470         $LCTL set_param fail_loc=0
8471 }
8472 run_test 60i "llog: new record vs reader race"
8473
8474 test_61a() {
8475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8476
8477         f="$DIR/f61"
8478         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8479         cancel_lru_locks osc
8480         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8481         sync
8482 }
8483 run_test 61a "mmap() writes don't make sync hang ================"
8484
8485 test_61b() {
8486         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8487 }
8488 run_test 61b "mmap() of unstriped file is successful"
8489
8490 # bug 2330 - insufficient obd_match error checking causes LBUG
8491 test_62() {
8492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8493
8494         f="$DIR/f62"
8495         echo foo > $f
8496         cancel_lru_locks osc
8497         lctl set_param fail_loc=0x405
8498         cat $f && error "cat succeeded, expect -EIO"
8499         lctl set_param fail_loc=0
8500 }
8501 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8502 # match every page all of the time.
8503 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8504
8505 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8506 # Though this test is irrelevant anymore, it helped to reveal some
8507 # other grant bugs (LU-4482), let's keep it.
8508 test_63a() {   # was test_63
8509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8510
8511         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8512
8513         for i in `seq 10` ; do
8514                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8515                 sleep 5
8516                 kill $!
8517                 sleep 1
8518         done
8519
8520         rm -f $DIR/f63 || true
8521 }
8522 run_test 63a "Verify oig_wait interruption does not crash ======="
8523
8524 # bug 2248 - async write errors didn't return to application on sync
8525 # bug 3677 - async write errors left page locked
8526 test_63b() {
8527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8528
8529         debugsave
8530         lctl set_param debug=-1
8531
8532         # ensure we have a grant to do async writes
8533         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8534         rm $DIR/$tfile
8535
8536         sync    # sync lest earlier test intercept the fail_loc
8537
8538         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8539         lctl set_param fail_loc=0x80000406
8540         $MULTIOP $DIR/$tfile Owy && \
8541                 error "sync didn't return ENOMEM"
8542         sync; sleep 2; sync     # do a real sync this time to flush page
8543         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8544                 error "locked page left in cache after async error" || true
8545         debugrestore
8546 }
8547 run_test 63b "async write errors should be returned to fsync ==="
8548
8549 test_64a () {
8550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8551
8552         lfs df $DIR
8553         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8554 }
8555 run_test 64a "verify filter grant calculations (in kernel) ====="
8556
8557 test_64b () {
8558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8559
8560         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8561 }
8562 run_test 64b "check out-of-space detection on client"
8563
8564 test_64c() {
8565         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8566 }
8567 run_test 64c "verify grant shrink"
8568
8569 import_param() {
8570         local tgt=$1
8571         local param=$2
8572
8573         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8574 }
8575
8576 # this does exactly what osc_request.c:osc_announce_cached() does in
8577 # order to calculate max amount of grants to ask from server
8578 want_grant() {
8579         local tgt=$1
8580
8581         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8582         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8583
8584         ((rpc_in_flight++));
8585         nrpages=$((nrpages * rpc_in_flight))
8586
8587         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8588
8589         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8590
8591         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8592         local undirty=$((nrpages * PAGE_SIZE))
8593
8594         local max_extent_pages
8595         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8596         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8597         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8598         local grant_extent_tax
8599         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8600
8601         undirty=$((undirty + nrextents * grant_extent_tax))
8602
8603         echo $undirty
8604 }
8605
8606 # this is size of unit for grant allocation. It should be equal to
8607 # what tgt_grant.c:tgt_grant_chunk() calculates
8608 grant_chunk() {
8609         local tgt=$1
8610         local max_brw_size
8611         local grant_extent_tax
8612
8613         max_brw_size=$(import_param $tgt max_brw_size)
8614
8615         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8616
8617         echo $(((max_brw_size + grant_extent_tax) * 2))
8618 }
8619
8620 test_64d() {
8621         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8622                 skip "OST < 2.10.55 doesn't limit grants enough"
8623
8624         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8625
8626         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8627                 skip "no grant_param connect flag"
8628
8629         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8630
8631         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8632         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8633
8634
8635         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8636         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8637
8638         $LFS setstripe $DIR/$tfile -i 0 -c 1
8639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8640         ddpid=$!
8641
8642         while kill -0 $ddpid; do
8643                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8644
8645                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8646                         kill $ddpid
8647                         error "cur_grant $cur_grant > $max_cur_granted"
8648                 fi
8649
8650                 sleep 1
8651         done
8652 }
8653 run_test 64d "check grant limit exceed"
8654
8655 check_grants() {
8656         local tgt=$1
8657         local expected=$2
8658         local msg=$3
8659         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8660
8661         ((cur_grants == expected)) ||
8662                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8663 }
8664
8665 round_up_p2() {
8666         echo $((($1 + $2 - 1) & ~($2 - 1)))
8667 }
8668
8669 test_64e() {
8670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8671         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8672                 skip "Need OSS version at least 2.11.56"
8673
8674         # Remount client to reset grant
8675         remount_client $MOUNT || error "failed to remount client"
8676         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8677
8678         local init_grants=$(import_param $osc_tgt initial_grant)
8679
8680         check_grants $osc_tgt $init_grants "init grants"
8681
8682         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8683         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8684         local gbs=$(import_param $osc_tgt grant_block_size)
8685
8686         # write random number of bytes from max_brw_size / 4 to max_brw_size
8687         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8688         # align for direct io
8689         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8690         # round to grant consumption unit
8691         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8692
8693         local grants=$((wb_round_up + extent_tax))
8694
8695         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8696
8697         # define OBD_FAIL_TGT_NO_GRANT 0x725
8698         # make the server not grant more back
8699         do_facet ost1 $LCTL set_param fail_loc=0x725
8700         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8701
8702         do_facet ost1 $LCTL set_param fail_loc=0
8703
8704         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8705
8706         rm -f $DIR/$tfile || error "rm failed"
8707
8708         # Remount client to reset grant
8709         remount_client $MOUNT || error "failed to remount client"
8710         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8711
8712         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8713
8714         # define OBD_FAIL_TGT_NO_GRANT 0x725
8715         # make the server not grant more back
8716         do_facet ost1 $LCTL set_param fail_loc=0x725
8717         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8718         do_facet ost1 $LCTL set_param fail_loc=0
8719
8720         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8721 }
8722 run_test 64e "check grant consumption (no grant allocation)"
8723
8724 test_64f() {
8725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8726
8727         # Remount client to reset grant
8728         remount_client $MOUNT || error "failed to remount client"
8729         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8730
8731         local init_grants=$(import_param $osc_tgt initial_grant)
8732         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8733         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8734         local gbs=$(import_param $osc_tgt grant_block_size)
8735         local chunk=$(grant_chunk $osc_tgt)
8736
8737         # write random number of bytes from max_brw_size / 4 to max_brw_size
8738         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8739         # align for direct io
8740         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8741         # round to grant consumption unit
8742         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8743
8744         local grants=$((wb_round_up + extent_tax))
8745
8746         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8747         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8748                 error "error writing to $DIR/$tfile"
8749
8750         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8751                 "direct io with grant allocation"
8752
8753         rm -f $DIR/$tfile || error "rm failed"
8754
8755         # Remount client to reset grant
8756         remount_client $MOUNT || error "failed to remount client"
8757         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8758
8759         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8760
8761         local cmd="oO_WRONLY:w${write_bytes}_yc"
8762
8763         $MULTIOP $DIR/$tfile $cmd &
8764         MULTIPID=$!
8765         sleep 1
8766
8767         check_grants $osc_tgt $((init_grants - grants)) \
8768                 "buffered io, not write rpc"
8769
8770         kill -USR1 $MULTIPID
8771         wait
8772
8773         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8774                 "buffered io, one RPC"
8775 }
8776 run_test 64f "check grant consumption (with grant allocation)"
8777
8778 # bug 1414 - set/get directories' stripe info
8779 test_65a() {
8780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8781
8782         test_mkdir $DIR/$tdir
8783         touch $DIR/$tdir/f1
8784         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8785 }
8786 run_test 65a "directory with no stripe info"
8787
8788 test_65b() {
8789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8790
8791         test_mkdir $DIR/$tdir
8792         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8793
8794         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8795                                                 error "setstripe"
8796         touch $DIR/$tdir/f2
8797         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8798 }
8799 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8800
8801 test_65c() {
8802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8803         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8804
8805         test_mkdir $DIR/$tdir
8806         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8807
8808         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8809                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8810         touch $DIR/$tdir/f3
8811         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8812 }
8813 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8814
8815 test_65d() {
8816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8817
8818         test_mkdir $DIR/$tdir
8819         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8820         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8821
8822         if [[ $STRIPECOUNT -le 0 ]]; then
8823                 sc=1
8824         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8825                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8826                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8827         else
8828                 sc=$(($STRIPECOUNT - 1))
8829         fi
8830         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8831         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8832         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8833                 error "lverify failed"
8834 }
8835 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8836
8837 test_65e() {
8838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8839
8840         test_mkdir $DIR/$tdir
8841
8842         $LFS setstripe $DIR/$tdir || error "setstripe"
8843         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8844                                         error "no stripe info failed"
8845         touch $DIR/$tdir/f6
8846         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8847 }
8848 run_test 65e "directory setstripe defaults"
8849
8850 test_65f() {
8851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8852
8853         test_mkdir $DIR/${tdir}f
8854         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8855                 error "setstripe succeeded" || true
8856 }
8857 run_test 65f "dir setstripe permission (should return error) ==="
8858
8859 test_65g() {
8860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8861
8862         test_mkdir $DIR/$tdir
8863         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8864
8865         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8866                 error "setstripe -S failed"
8867         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8868         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8869                 error "delete default stripe failed"
8870 }
8871 run_test 65g "directory setstripe -d"
8872
8873 test_65h() {
8874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8875
8876         test_mkdir $DIR/$tdir
8877         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8878
8879         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8880                 error "setstripe -S failed"
8881         test_mkdir $DIR/$tdir/dd1
8882         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8883                 error "stripe info inherit failed"
8884 }
8885 run_test 65h "directory stripe info inherit ===================="
8886
8887 test_65i() {
8888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8889
8890         save_layout_restore_at_exit $MOUNT
8891
8892         # bug6367: set non-default striping on root directory
8893         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8894
8895         # bug12836: getstripe on -1 default directory striping
8896         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8897
8898         # bug12836: getstripe -v on -1 default directory striping
8899         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8900
8901         # bug12836: new find on -1 default directory striping
8902         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8903 }
8904 run_test 65i "various tests to set root directory striping"
8905
8906 test_65j() { # bug6367
8907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8908
8909         sync; sleep 1
8910
8911         # if we aren't already remounting for each test, do so for this test
8912         if [ "$I_MOUNTED" = "yes" ]; then
8913                 cleanup || error "failed to unmount"
8914                 setup
8915         fi
8916
8917         save_layout_restore_at_exit $MOUNT
8918
8919         $LFS setstripe -d $MOUNT || error "setstripe failed"
8920 }
8921 run_test 65j "set default striping on root directory (bug 6367)="
8922
8923 cleanup_65k() {
8924         rm -rf $DIR/$tdir
8925         wait_delete_completed
8926         do_facet $SINGLEMDS "lctl set_param -n \
8927                 osp.$ost*MDT0000.max_create_count=$max_count"
8928         do_facet $SINGLEMDS "lctl set_param -n \
8929                 osp.$ost*MDT0000.create_count=$count"
8930         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8931         echo $INACTIVE_OSC "is Activate"
8932
8933         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8934 }
8935
8936 test_65k() { # bug11679
8937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8939         remote_mds_nodsh && skip "remote MDS with nodsh"
8940
8941         local disable_precreate=true
8942         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8943                 disable_precreate=false
8944
8945         echo "Check OST status: "
8946         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8947                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8948
8949         for OSC in $MDS_OSCS; do
8950                 echo $OSC "is active"
8951                 do_facet $SINGLEMDS lctl --device %$OSC activate
8952         done
8953
8954         for INACTIVE_OSC in $MDS_OSCS; do
8955                 local ost=$(osc_to_ost $INACTIVE_OSC)
8956                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8957                                lov.*md*.target_obd |
8958                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8959
8960                 mkdir -p $DIR/$tdir
8961                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8962                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8963
8964                 echo "Deactivate: " $INACTIVE_OSC
8965                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8966
8967                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8968                               osp.$ost*MDT0000.create_count")
8969                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8970                                   osp.$ost*MDT0000.max_create_count")
8971                 $disable_precreate &&
8972                         do_facet $SINGLEMDS "lctl set_param -n \
8973                                 osp.$ost*MDT0000.max_create_count=0"
8974
8975                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8976                         [ -f $DIR/$tdir/$idx ] && continue
8977                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8978                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8979                                 { cleanup_65k;
8980                                   error "setstripe $idx should succeed"; }
8981                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8982                 done
8983                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8984                 rmdir $DIR/$tdir
8985
8986                 do_facet $SINGLEMDS "lctl set_param -n \
8987                         osp.$ost*MDT0000.max_create_count=$max_count"
8988                 do_facet $SINGLEMDS "lctl set_param -n \
8989                         osp.$ost*MDT0000.create_count=$count"
8990                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8991                 echo $INACTIVE_OSC "is Activate"
8992
8993                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8994         done
8995 }
8996 run_test 65k "validate manual striping works properly with deactivated OSCs"
8997
8998 test_65l() { # bug 12836
8999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9000
9001         test_mkdir -p $DIR/$tdir/test_dir
9002         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9003         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9004 }
9005 run_test 65l "lfs find on -1 stripe dir ========================"
9006
9007 test_65m() {
9008         local layout=$(save_layout $MOUNT)
9009         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9010                 restore_layout $MOUNT $layout
9011                 error "setstripe should fail by non-root users"
9012         }
9013         true
9014 }
9015 run_test 65m "normal user can't set filesystem default stripe"
9016
9017 test_65n() {
9018         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9019         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9020                 skip "Need MDS version at least 2.12.50"
9021         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9022
9023         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9024         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9025         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9026
9027         save_layout_restore_at_exit $MOUNT
9028
9029         # new subdirectory under root directory should not inherit
9030         # the default layout from root
9031         local dir1=$MOUNT/$tdir-1
9032         mkdir $dir1 || error "mkdir $dir1 failed"
9033         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9034                 error "$dir1 shouldn't have LOV EA"
9035
9036         # delete the default layout on root directory
9037         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9038
9039         local dir2=$MOUNT/$tdir-2
9040         mkdir $dir2 || error "mkdir $dir2 failed"
9041         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9042                 error "$dir2 shouldn't have LOV EA"
9043
9044         # set a new striping pattern on root directory
9045         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9046         local new_def_stripe_size=$((def_stripe_size * 2))
9047         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9048                 error "set stripe size on $MOUNT failed"
9049
9050         # new file created in $dir2 should inherit the new stripe size from
9051         # the filesystem default
9052         local file2=$dir2/$tfile-2
9053         touch $file2 || error "touch $file2 failed"
9054
9055         local file2_stripe_size=$($LFS getstripe -S $file2)
9056         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9057         {
9058                 echo "file2_stripe_size: '$file2_stripe_size'"
9059                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9060                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9061         }
9062
9063         local dir3=$MOUNT/$tdir-3
9064         mkdir $dir3 || error "mkdir $dir3 failed"
9065         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9066         # the root layout, which is the actual default layout that will be used
9067         # when new files are created in $dir3.
9068         local dir3_layout=$(get_layout_param $dir3)
9069         local root_dir_layout=$(get_layout_param $MOUNT)
9070         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9071         {
9072                 echo "dir3_layout: '$dir3_layout'"
9073                 echo "root_dir_layout: '$root_dir_layout'"
9074                 error "$dir3 should show the default layout from $MOUNT"
9075         }
9076
9077         # set OST pool on root directory
9078         local pool=$TESTNAME
9079         pool_add $pool || error "add $pool failed"
9080         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9081                 error "add targets to $pool failed"
9082
9083         $LFS setstripe -p $pool $MOUNT ||
9084                 error "set OST pool on $MOUNT failed"
9085
9086         # new file created in $dir3 should inherit the pool from
9087         # the filesystem default
9088         local file3=$dir3/$tfile-3
9089         touch $file3 || error "touch $file3 failed"
9090
9091         local file3_pool=$($LFS getstripe -p $file3)
9092         [[ "$file3_pool" = "$pool" ]] ||
9093                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9094
9095         local dir4=$MOUNT/$tdir-4
9096         mkdir $dir4 || error "mkdir $dir4 failed"
9097         local dir4_layout=$(get_layout_param $dir4)
9098         root_dir_layout=$(get_layout_param $MOUNT)
9099         echo "$LFS getstripe -d $dir4"
9100         $LFS getstripe -d $dir4
9101         echo "$LFS getstripe -d $MOUNT"
9102         $LFS getstripe -d $MOUNT
9103         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9104         {
9105                 echo "dir4_layout: '$dir4_layout'"
9106                 echo "root_dir_layout: '$root_dir_layout'"
9107                 error "$dir4 should show the default layout from $MOUNT"
9108         }
9109
9110         # new file created in $dir4 should inherit the pool from
9111         # the filesystem default
9112         local file4=$dir4/$tfile-4
9113         touch $file4 || error "touch $file4 failed"
9114
9115         local file4_pool=$($LFS getstripe -p $file4)
9116         [[ "$file4_pool" = "$pool" ]] ||
9117                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9118
9119         # new subdirectory under non-root directory should inherit
9120         # the default layout from its parent directory
9121         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9122                 error "set directory layout on $dir4 failed"
9123
9124         local dir5=$dir4/$tdir-5
9125         mkdir $dir5 || error "mkdir $dir5 failed"
9126
9127         dir4_layout=$(get_layout_param $dir4)
9128         local dir5_layout=$(get_layout_param $dir5)
9129         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9130         {
9131                 echo "dir4_layout: '$dir4_layout'"
9132                 echo "dir5_layout: '$dir5_layout'"
9133                 error "$dir5 should inherit the default layout from $dir4"
9134         }
9135
9136         # though subdir under ROOT doesn't inherit default layout, but
9137         # its sub dir/file should be created with default layout.
9138         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9139         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9140                 skip "Need MDS version at least 2.12.59"
9141
9142         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9143         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9144         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9145
9146         if [ $default_lmv_hash == "none" ]; then
9147                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9148         else
9149                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9150                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9151         fi
9152
9153         $LFS setdirstripe -D -c 2 $MOUNT ||
9154                 error "setdirstripe -D -c 2 failed"
9155         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9156         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9157         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9158 }
9159 run_test 65n "don't inherit default layout from root for new subdirectories"
9160
9161 # bug 2543 - update blocks count on client
9162 test_66() {
9163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9164
9165         COUNT=${COUNT:-8}
9166         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9167         sync; sync_all_data; sync; sync_all_data
9168         cancel_lru_locks osc
9169         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9170         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9171 }
9172 run_test 66 "update inode blocks count on client ==============="
9173
9174 meminfo() {
9175         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9176 }
9177
9178 swap_used() {
9179         swapon -s | awk '($1 == "'$1'") { print $4 }'
9180 }
9181
9182 # bug5265, obdfilter oa2dentry return -ENOENT
9183 # #define OBD_FAIL_SRV_ENOENT 0x217
9184 test_69() {
9185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9186         remote_ost_nodsh && skip "remote OST with nodsh"
9187
9188         f="$DIR/$tfile"
9189         $LFS setstripe -c 1 -i 0 $f
9190
9191         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9192
9193         do_facet ost1 lctl set_param fail_loc=0x217
9194         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9195         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9196
9197         do_facet ost1 lctl set_param fail_loc=0
9198         $DIRECTIO write $f 0 2 || error "write error"
9199
9200         cancel_lru_locks osc
9201         $DIRECTIO read $f 0 1 || error "read error"
9202
9203         do_facet ost1 lctl set_param fail_loc=0x217
9204         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9205
9206         do_facet ost1 lctl set_param fail_loc=0
9207         rm -f $f
9208 }
9209 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9210
9211 test_71() {
9212         test_mkdir $DIR/$tdir
9213         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9214         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9215 }
9216 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9217
9218 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9220         [ "$RUNAS_ID" = "$UID" ] &&
9221                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9222         # Check that testing environment is properly set up. Skip if not
9223         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9224                 skip_env "User $RUNAS_ID does not exist - skipping"
9225
9226         touch $DIR/$tfile
9227         chmod 777 $DIR/$tfile
9228         chmod ug+s $DIR/$tfile
9229         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9230                 error "$RUNAS dd $DIR/$tfile failed"
9231         # See if we are still setuid/sgid
9232         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9233                 error "S/gid is not dropped on write"
9234         # Now test that MDS is updated too
9235         cancel_lru_locks mdc
9236         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9237                 error "S/gid is not dropped on MDS"
9238         rm -f $DIR/$tfile
9239 }
9240 run_test 72a "Test that remove suid works properly (bug5695) ===="
9241
9242 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9243         local perm
9244
9245         [ "$RUNAS_ID" = "$UID" ] &&
9246                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9247         [ "$RUNAS_ID" -eq 0 ] &&
9248                 skip_env "RUNAS_ID = 0 -- skipping"
9249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9250         # Check that testing environment is properly set up. Skip if not
9251         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9252                 skip_env "User $RUNAS_ID does not exist - skipping"
9253
9254         touch $DIR/${tfile}-f{g,u}
9255         test_mkdir $DIR/${tfile}-dg
9256         test_mkdir $DIR/${tfile}-du
9257         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9258         chmod g+s $DIR/${tfile}-{f,d}g
9259         chmod u+s $DIR/${tfile}-{f,d}u
9260         for perm in 777 2777 4777; do
9261                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9262                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9263                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9264                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9265         done
9266         true
9267 }
9268 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9269
9270 # bug 3462 - multiple simultaneous MDC requests
9271 test_73() {
9272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9273
9274         test_mkdir $DIR/d73-1
9275         test_mkdir $DIR/d73-2
9276         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9277         pid1=$!
9278
9279         lctl set_param fail_loc=0x80000129
9280         $MULTIOP $DIR/d73-1/f73-2 Oc &
9281         sleep 1
9282         lctl set_param fail_loc=0
9283
9284         $MULTIOP $DIR/d73-2/f73-3 Oc &
9285         pid3=$!
9286
9287         kill -USR1 $pid1
9288         wait $pid1 || return 1
9289
9290         sleep 25
9291
9292         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9293         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9294         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9295
9296         rm -rf $DIR/d73-*
9297 }
9298 run_test 73 "multiple MDC requests (should not deadlock)"
9299
9300 test_74a() { # bug 6149, 6184
9301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9302
9303         touch $DIR/f74a
9304         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9305         #
9306         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9307         # will spin in a tight reconnection loop
9308         $LCTL set_param fail_loc=0x8000030e
9309         # get any lock that won't be difficult - lookup works.
9310         ls $DIR/f74a
9311         $LCTL set_param fail_loc=0
9312         rm -f $DIR/f74a
9313         true
9314 }
9315 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9316
9317 test_74b() { # bug 13310
9318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9319
9320         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9321         #
9322         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9323         # will spin in a tight reconnection loop
9324         $LCTL set_param fail_loc=0x8000030e
9325         # get a "difficult" lock
9326         touch $DIR/f74b
9327         $LCTL set_param fail_loc=0
9328         rm -f $DIR/f74b
9329         true
9330 }
9331 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9332
9333 test_74c() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         #define OBD_FAIL_LDLM_NEW_LOCK
9337         $LCTL set_param fail_loc=0x319
9338         touch $DIR/$tfile && error "touch successful"
9339         $LCTL set_param fail_loc=0
9340         true
9341 }
9342 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9343
9344 slab_lic=/sys/kernel/slab/lustre_inode_cache
9345 num_objects() {
9346         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9347         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9348                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9349 }
9350
9351 test_76a() { # Now for b=20433, added originally in b=1443
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         cancel_lru_locks osc
9355         # there may be some slab objects cached per core
9356         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9357         local before=$(num_objects)
9358         local count=$((512 * cpus))
9359         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9360         local margin=$((count / 10))
9361         if [[ -f $slab_lic/aliases ]]; then
9362                 local aliases=$(cat $slab_lic/aliases)
9363                 (( aliases > 0 )) && margin=$((margin * aliases))
9364         fi
9365
9366         echo "before slab objects: $before"
9367         for i in $(seq $count); do
9368                 touch $DIR/$tfile
9369                 rm -f $DIR/$tfile
9370         done
9371         cancel_lru_locks osc
9372         local after=$(num_objects)
9373         echo "created: $count, after slab objects: $after"
9374         # shared slab counts are not very accurate, allow significant margin
9375         # the main goal is that the cache growth is not permanently > $count
9376         while (( after > before + margin )); do
9377                 sleep 1
9378                 after=$(num_objects)
9379                 wait=$((wait + 1))
9380                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9381                 if (( wait > 60 )); then
9382                         error "inode slab grew from $before+$margin to $after"
9383                 fi
9384         done
9385 }
9386 run_test 76a "confirm clients recycle inodes properly ===="
9387
9388 test_76b() {
9389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9390         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9391
9392         local count=512
9393         local before=$(num_objects)
9394
9395         for i in $(seq $count); do
9396                 mkdir $DIR/$tdir
9397                 rmdir $DIR/$tdir
9398         done
9399
9400         local after=$(num_objects)
9401         local wait=0
9402
9403         while (( after > before )); do
9404                 sleep 1
9405                 after=$(num_objects)
9406                 wait=$((wait + 1))
9407                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9408                 if (( wait > 60 )); then
9409                         error "inode slab grew from $before to $after"
9410                 fi
9411         done
9412
9413         echo "slab objects before: $before, after: $after"
9414 }
9415 run_test 76b "confirm clients recycle directory inodes properly ===="
9416
9417 export ORIG_CSUM=""
9418 set_checksums()
9419 {
9420         # Note: in sptlrpc modes which enable its own bulk checksum, the
9421         # original crc32_le bulk checksum will be automatically disabled,
9422         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9423         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9424         # In this case set_checksums() will not be no-op, because sptlrpc
9425         # bulk checksum will be enabled all through the test.
9426
9427         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9428         lctl set_param -n osc.*.checksums $1
9429         return 0
9430 }
9431
9432 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9433                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9434 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9435                              tr -d [] | head -n1)}
9436 set_checksum_type()
9437 {
9438         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9439         rc=$?
9440         log "set checksum type to $1, rc = $rc"
9441         return $rc
9442 }
9443
9444 get_osc_checksum_type()
9445 {
9446         # arugment 1: OST name, like OST0000
9447         ost=$1
9448         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9449                         sed 's/.*\[\(.*\)\].*/\1/g')
9450         rc=$?
9451         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9452         echo $checksum_type
9453 }
9454
9455 F77_TMP=$TMP/f77-temp
9456 F77SZ=8
9457 setup_f77() {
9458         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9459                 error "error writing to $F77_TMP"
9460 }
9461
9462 test_77a() { # bug 10889
9463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9464         $GSS && skip_env "could not run with gss"
9465
9466         [ ! -f $F77_TMP ] && setup_f77
9467         set_checksums 1
9468         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9469         set_checksums 0
9470         rm -f $DIR/$tfile
9471 }
9472 run_test 77a "normal checksum read/write operation"
9473
9474 test_77b() { # bug 10889
9475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9476         $GSS && skip_env "could not run with gss"
9477
9478         [ ! -f $F77_TMP ] && setup_f77
9479         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9480         $LCTL set_param fail_loc=0x80000409
9481         set_checksums 1
9482
9483         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9484                 error "dd error: $?"
9485         $LCTL set_param fail_loc=0
9486
9487         for algo in $CKSUM_TYPES; do
9488                 cancel_lru_locks osc
9489                 set_checksum_type $algo
9490                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9491                 $LCTL set_param fail_loc=0x80000408
9492                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9493                 $LCTL set_param fail_loc=0
9494         done
9495         set_checksums 0
9496         set_checksum_type $ORIG_CSUM_TYPE
9497         rm -f $DIR/$tfile
9498 }
9499 run_test 77b "checksum error on client write, read"
9500
9501 cleanup_77c() {
9502         trap 0
9503         set_checksums 0
9504         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9505         $check_ost &&
9506                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9507         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9508         $check_ost && [ -n "$ost_file_prefix" ] &&
9509                 do_facet ost1 rm -f ${ost_file_prefix}\*
9510 }
9511
9512 test_77c() {
9513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9514         $GSS && skip_env "could not run with gss"
9515         remote_ost_nodsh && skip "remote OST with nodsh"
9516
9517         local bad1
9518         local osc_file_prefix
9519         local osc_file
9520         local check_ost=false
9521         local ost_file_prefix
9522         local ost_file
9523         local orig_cksum
9524         local dump_cksum
9525         local fid
9526
9527         # ensure corruption will occur on first OSS/OST
9528         $LFS setstripe -i 0 $DIR/$tfile
9529
9530         [ ! -f $F77_TMP ] && setup_f77
9531         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9532                 error "dd write error: $?"
9533         fid=$($LFS path2fid $DIR/$tfile)
9534
9535         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9536         then
9537                 check_ost=true
9538                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9539                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9540         else
9541                 echo "OSS do not support bulk pages dump upon error"
9542         fi
9543
9544         osc_file_prefix=$($LCTL get_param -n debug_path)
9545         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9546
9547         trap cleanup_77c EXIT
9548
9549         set_checksums 1
9550         # enable bulk pages dump upon error on Client
9551         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9552         # enable bulk pages dump upon error on OSS
9553         $check_ost &&
9554                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9555
9556         # flush Client cache to allow next read to reach OSS
9557         cancel_lru_locks osc
9558
9559         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9560         $LCTL set_param fail_loc=0x80000408
9561         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9562         $LCTL set_param fail_loc=0
9563
9564         rm -f $DIR/$tfile
9565
9566         # check cksum dump on Client
9567         osc_file=$(ls ${osc_file_prefix}*)
9568         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9569         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9570         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9571         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9572         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9573                      cksum)
9574         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9575         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9576                 error "dump content does not match on Client"
9577
9578         $check_ost || skip "No need to check cksum dump on OSS"
9579
9580         # check cksum dump on OSS
9581         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9582         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9583         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9584         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9585         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9586                 error "dump content does not match on OSS"
9587
9588         cleanup_77c
9589 }
9590 run_test 77c "checksum error on client read with debug"
9591
9592 test_77d() { # bug 10889
9593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9594         $GSS && skip_env "could not run with gss"
9595
9596         stack_trap "rm -f $DIR/$tfile"
9597         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9598         $LCTL set_param fail_loc=0x80000409
9599         set_checksums 1
9600         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9601                 error "direct write: rc=$?"
9602         $LCTL set_param fail_loc=0
9603         set_checksums 0
9604
9605         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9606         $LCTL set_param fail_loc=0x80000408
9607         set_checksums 1
9608         cancel_lru_locks osc
9609         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9610                 error "direct read: rc=$?"
9611         $LCTL set_param fail_loc=0
9612         set_checksums 0
9613 }
9614 run_test 77d "checksum error on OST direct write, read"
9615
9616 test_77f() { # bug 10889
9617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9618         $GSS && skip_env "could not run with gss"
9619
9620         set_checksums 1
9621         stack_trap "rm -f $DIR/$tfile"
9622         for algo in $CKSUM_TYPES; do
9623                 cancel_lru_locks osc
9624                 set_checksum_type $algo
9625                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9626                 $LCTL set_param fail_loc=0x409
9627                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9628                         error "direct write succeeded"
9629                 $LCTL set_param fail_loc=0
9630         done
9631         set_checksum_type $ORIG_CSUM_TYPE
9632         set_checksums 0
9633 }
9634 run_test 77f "repeat checksum error on write (expect error)"
9635
9636 test_77g() { # bug 10889
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638         $GSS && skip_env "could not run with gss"
9639         remote_ost_nodsh && skip "remote OST with nodsh"
9640
9641         [ ! -f $F77_TMP ] && setup_f77
9642
9643         local file=$DIR/$tfile
9644         stack_trap "rm -f $file" EXIT
9645
9646         $LFS setstripe -c 1 -i 0 $file
9647         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9648         do_facet ost1 lctl set_param fail_loc=0x8000021a
9649         set_checksums 1
9650         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9651                 error "write error: rc=$?"
9652         do_facet ost1 lctl set_param fail_loc=0
9653         set_checksums 0
9654
9655         cancel_lru_locks osc
9656         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9657         do_facet ost1 lctl set_param fail_loc=0x8000021b
9658         set_checksums 1
9659         cmp $F77_TMP $file || error "file compare failed"
9660         do_facet ost1 lctl set_param fail_loc=0
9661         set_checksums 0
9662 }
9663 run_test 77g "checksum error on OST write, read"
9664
9665 test_77k() { # LU-10906
9666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9667         $GSS && skip_env "could not run with gss"
9668
9669         local cksum_param="osc.$FSNAME*.checksums"
9670         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9671         local checksum
9672         local i
9673
9674         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9675         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9676         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9677
9678         for i in 0 1; do
9679                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9680                         error "failed to set checksum=$i on MGS"
9681                 wait_update $HOSTNAME "$get_checksum" $i
9682                 #remount
9683                 echo "remount client, checksum should be $i"
9684                 remount_client $MOUNT || error "failed to remount client"
9685                 checksum=$(eval $get_checksum)
9686                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9687         done
9688         # remove persistent param to avoid races with checksum mountopt below
9689         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9690                 error "failed to delete checksum on MGS"
9691
9692         for opt in "checksum" "nochecksum"; do
9693                 #remount with mount option
9694                 echo "remount client with option $opt, checksum should be $i"
9695                 umount_client $MOUNT || error "failed to umount client"
9696                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9697                         error "failed to mount client with option '$opt'"
9698                 checksum=$(eval $get_checksum)
9699                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9700                 i=$((i - 1))
9701         done
9702
9703         remount_client $MOUNT || error "failed to remount client"
9704 }
9705 run_test 77k "enable/disable checksum correctly"
9706
9707 test_77l() {
9708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9709         $GSS && skip_env "could not run with gss"
9710
9711         set_checksums 1
9712         stack_trap "set_checksums $ORIG_CSUM" EXIT
9713         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9714
9715         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9716
9717         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9718         for algo in $CKSUM_TYPES; do
9719                 set_checksum_type $algo || error "fail to set checksum type $algo"
9720                 osc_algo=$(get_osc_checksum_type OST0000)
9721                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9722
9723                 # no locks, no reqs to let the connection idle
9724                 cancel_lru_locks osc
9725                 lru_resize_disable osc
9726                 wait_osc_import_state client ost1 IDLE
9727
9728                 # ensure ost1 is connected
9729                 stat $DIR/$tfile >/dev/null || error "can't stat"
9730                 wait_osc_import_state client ost1 FULL
9731
9732                 osc_algo=$(get_osc_checksum_type OST0000)
9733                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9734         done
9735         return 0
9736 }
9737 run_test 77l "preferred checksum type is remembered after reconnected"
9738
9739 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9740 rm -f $F77_TMP
9741 unset F77_TMP
9742
9743 test_77m() {
9744         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9745                 skip "Need at least version 2.14.52"
9746         local param=checksum_speed
9747
9748         $LCTL get_param $param || error "reading $param failed"
9749
9750         csum_speeds=$($LCTL get_param -n $param)
9751
9752         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9753                 error "known checksum types are missing"
9754 }
9755 run_test 77m "Verify checksum_speed is correctly read"
9756
9757 check_filefrag_77n() {
9758         local nr_ext=0
9759         local starts=()
9760         local ends=()
9761
9762         while read extidx a b start end rest; do
9763                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9764                         nr_ext=$(( $nr_ext + 1 ))
9765                         starts+=( ${start%..} )
9766                         ends+=( ${end%:} )
9767                 fi
9768         done < <( filefrag -sv $1 )
9769
9770         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9771         return 1
9772 }
9773
9774 test_77n() {
9775         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9776
9777         touch $DIR/$tfile
9778         $TRUNCATE $DIR/$tfile 0
9779         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9780         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9781         check_filefrag_77n $DIR/$tfile ||
9782                 skip "$tfile blocks not contiguous around hole"
9783
9784         set_checksums 1
9785         stack_trap "set_checksums $ORIG_CSUM" EXIT
9786         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9787         stack_trap "rm -f $DIR/$tfile"
9788
9789         for algo in $CKSUM_TYPES; do
9790                 if [[ "$algo" =~ ^t10 ]]; then
9791                         set_checksum_type $algo ||
9792                                 error "fail to set checksum type $algo"
9793                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9794                                 error "fail to read $tfile with $algo"
9795                 fi
9796         done
9797         rm -f $DIR/$tfile
9798         return 0
9799 }
9800 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9801
9802 cleanup_test_78() {
9803         trap 0
9804         rm -f $DIR/$tfile
9805 }
9806
9807 test_78() { # bug 10901
9808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9809         remote_ost || skip_env "local OST"
9810
9811         NSEQ=5
9812         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9813         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9814         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9815         echo "MemTotal: $MEMTOTAL"
9816
9817         # reserve 256MB of memory for the kernel and other running processes,
9818         # and then take 1/2 of the remaining memory for the read/write buffers.
9819         if [ $MEMTOTAL -gt 512 ] ;then
9820                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9821         else
9822                 # for those poor memory-starved high-end clusters...
9823                 MEMTOTAL=$((MEMTOTAL / 2))
9824         fi
9825         echo "Mem to use for directio: $MEMTOTAL"
9826
9827         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9828         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9829         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9830         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9831                 head -n1)
9832         echo "Smallest OST: $SMALLESTOST"
9833         [[ $SMALLESTOST -lt 10240 ]] &&
9834                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9835
9836         trap cleanup_test_78 EXIT
9837
9838         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9839                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9840
9841         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9842         echo "File size: $F78SIZE"
9843         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9844         for i in $(seq 1 $NSEQ); do
9845                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9846                 echo directIO rdwr round $i of $NSEQ
9847                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9848         done
9849
9850         cleanup_test_78
9851 }
9852 run_test 78 "handle large O_DIRECT writes correctly ============"
9853
9854 test_79() { # bug 12743
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856
9857         wait_delete_completed
9858
9859         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9860         BKFREE=$(calc_osc_kbytes kbytesfree)
9861         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9862
9863         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9864         DFTOTAL=`echo $STRING | cut -d, -f1`
9865         DFUSED=`echo $STRING  | cut -d, -f2`
9866         DFAVAIL=`echo $STRING | cut -d, -f3`
9867         DFFREE=$(($DFTOTAL - $DFUSED))
9868
9869         ALLOWANCE=$((64 * $OSTCOUNT))
9870
9871         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9872            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9873                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9874         fi
9875         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9876            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9877                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9878         fi
9879         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9880            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9881                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9882         fi
9883 }
9884 run_test 79 "df report consistency check ======================="
9885
9886 test_80() { # bug 10718
9887         remote_ost_nodsh && skip "remote OST with nodsh"
9888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9889
9890         # relax strong synchronous semantics for slow backends like ZFS
9891         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9892                 local soc="obdfilter.*.sync_lock_cancel"
9893                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9894
9895                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9896                 if [ -z "$save" ]; then
9897                         soc="obdfilter.*.sync_on_lock_cancel"
9898                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9899                 fi
9900
9901                 if [ "$save" != "never" ]; then
9902                         local hosts=$(comma_list $(osts_nodes))
9903
9904                         do_nodes $hosts $LCTL set_param $soc=never
9905                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9906                 fi
9907         fi
9908
9909         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9910         sync; sleep 1; sync
9911         local before=$(date +%s)
9912         cancel_lru_locks osc
9913         local after=$(date +%s)
9914         local diff=$((after - before))
9915         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9916
9917         rm -f $DIR/$tfile
9918 }
9919 run_test 80 "Page eviction is equally fast at high offsets too"
9920
9921 test_81a() { # LU-456
9922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9923         remote_ost_nodsh && skip "remote OST with nodsh"
9924
9925         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9926         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9927         do_facet ost1 lctl set_param fail_loc=0x80000228
9928
9929         # write should trigger a retry and success
9930         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9931         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9932         RC=$?
9933         if [ $RC -ne 0 ] ; then
9934                 error "write should success, but failed for $RC"
9935         fi
9936 }
9937 run_test 81a "OST should retry write when get -ENOSPC ==============="
9938
9939 test_81b() { # LU-456
9940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9941         remote_ost_nodsh && skip "remote OST with nodsh"
9942
9943         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9944         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9945         do_facet ost1 lctl set_param fail_loc=0x228
9946
9947         # write should retry several times and return -ENOSPC finally
9948         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9949         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9950         RC=$?
9951         ENOSPC=28
9952         if [ $RC -ne $ENOSPC ] ; then
9953                 error "dd should fail for -ENOSPC, but succeed."
9954         fi
9955 }
9956 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9957
9958 test_99() {
9959         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9960
9961         test_mkdir $DIR/$tdir.cvsroot
9962         chown $RUNAS_ID $DIR/$tdir.cvsroot
9963
9964         cd $TMP
9965         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9966
9967         cd /etc/init.d
9968         # some versions of cvs import exit(1) when asked to import links or
9969         # files they can't read.  ignore those files.
9970         local toignore=$(find . -type l -printf '-I %f\n' -o \
9971                          ! -perm /4 -printf '-I %f\n')
9972         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9973                 $tdir.reposname vtag rtag
9974
9975         cd $DIR
9976         test_mkdir $DIR/$tdir.reposname
9977         chown $RUNAS_ID $DIR/$tdir.reposname
9978         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9979
9980         cd $DIR/$tdir.reposname
9981         $RUNAS touch foo99
9982         $RUNAS cvs add -m 'addmsg' foo99
9983         $RUNAS cvs update
9984         $RUNAS cvs commit -m 'nomsg' foo99
9985         rm -fr $DIR/$tdir.cvsroot
9986 }
9987 run_test 99 "cvs strange file/directory operations"
9988
9989 test_100() {
9990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9991         [[ "$NETTYPE" =~ tcp ]] ||
9992                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9993         remote_ost_nodsh && skip "remote OST with nodsh"
9994         remote_mds_nodsh && skip "remote MDS with nodsh"
9995         remote_servers ||
9996                 skip "useless for local single node setup"
9997
9998         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9999                 [ "$PROT" != "tcp" ] && continue
10000                 RPORT=$(echo $REMOTE | cut -d: -f2)
10001                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10002
10003                 rc=0
10004                 LPORT=`echo $LOCAL | cut -d: -f2`
10005                 if [ $LPORT -ge 1024 ]; then
10006                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10007                         netstat -tna
10008                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10009                 fi
10010         done
10011         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10012 }
10013 run_test 100 "check local port using privileged port ==========="
10014
10015 function get_named_value()
10016 {
10017     local tag=$1
10018
10019     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10020 }
10021
10022 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10023                    awk '/^max_cached_mb/ { print $2 }')
10024
10025 cleanup_101a() {
10026         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10027         trap 0
10028 }
10029
10030 test_101a() {
10031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10032
10033         local s
10034         local discard
10035         local nreads=10000
10036         local cache_limit=32
10037
10038         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10039         trap cleanup_101a EXIT
10040         $LCTL set_param -n llite.*.read_ahead_stats=0
10041         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10042
10043         #
10044         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10045         #
10046         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10047         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10048
10049         discard=0
10050         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10051                    get_named_value 'read.but.discarded'); do
10052                         discard=$(($discard + $s))
10053         done
10054         cleanup_101a
10055
10056         $LCTL get_param osc.*-osc*.rpc_stats
10057         $LCTL get_param llite.*.read_ahead_stats
10058
10059         # Discard is generally zero, but sometimes a few random reads line up
10060         # and trigger larger readahead, which is wasted & leads to discards.
10061         if [[ $(($discard)) -gt $nreads ]]; then
10062                 error "too many ($discard) discarded pages"
10063         fi
10064         rm -f $DIR/$tfile || true
10065 }
10066 run_test 101a "check read-ahead for random reads"
10067
10068 setup_test101bc() {
10069         test_mkdir $DIR/$tdir
10070         local ssize=$1
10071         local FILE_LENGTH=$2
10072         STRIPE_OFFSET=0
10073
10074         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10075
10076         local list=$(comma_list $(osts_nodes))
10077         set_osd_param $list '' read_cache_enable 0
10078         set_osd_param $list '' writethrough_cache_enable 0
10079
10080         trap cleanup_test101bc EXIT
10081         # prepare the read-ahead file
10082         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10083
10084         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10085                                 count=$FILE_SIZE_MB 2> /dev/null
10086
10087 }
10088
10089 cleanup_test101bc() {
10090         trap 0
10091         rm -rf $DIR/$tdir
10092         rm -f $DIR/$tfile
10093
10094         local list=$(comma_list $(osts_nodes))
10095         set_osd_param $list '' read_cache_enable 1
10096         set_osd_param $list '' writethrough_cache_enable 1
10097 }
10098
10099 calc_total() {
10100         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10101 }
10102
10103 ra_check_101() {
10104         local READ_SIZE=$1
10105         local STRIPE_SIZE=$2
10106         local FILE_LENGTH=$3
10107         local RA_INC=1048576
10108         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10109         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10110                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10111         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10112                   get_named_value 'read.but.discarded' | calc_total)
10113         if [[ $DISCARD -gt $discard_limit ]]; then
10114                 $LCTL get_param llite.*.read_ahead_stats
10115                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10116         else
10117                 echo "Read-ahead success for size ${READ_SIZE}"
10118         fi
10119 }
10120
10121 test_101b() {
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10124
10125         local STRIPE_SIZE=1048576
10126         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10127
10128         if [ $SLOW == "yes" ]; then
10129                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10130         else
10131                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10132         fi
10133
10134         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10135
10136         # prepare the read-ahead file
10137         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10138         cancel_lru_locks osc
10139         for BIDX in 2 4 8 16 32 64 128 256
10140         do
10141                 local BSIZE=$((BIDX*4096))
10142                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10143                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10144                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10145                 $LCTL set_param -n llite.*.read_ahead_stats=0
10146                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10147                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10148                 cancel_lru_locks osc
10149                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10150         done
10151         cleanup_test101bc
10152         true
10153 }
10154 run_test 101b "check stride-io mode read-ahead ================="
10155
10156 test_101c() {
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10158
10159         local STRIPE_SIZE=1048576
10160         local FILE_LENGTH=$((STRIPE_SIZE*100))
10161         local nreads=10000
10162         local rsize=65536
10163         local osc_rpc_stats
10164
10165         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10166
10167         cancel_lru_locks osc
10168         $LCTL set_param osc.*.rpc_stats=0
10169         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10170         $LCTL get_param osc.*.rpc_stats
10171         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10172                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10173                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10174                 local size
10175
10176                 if [ $lines -le 20 ]; then
10177                         echo "continue debug"
10178                         continue
10179                 fi
10180                 for size in 1 2 4 8; do
10181                         local rpc=$(echo "$stats" |
10182                                     awk '($1 == "'$size':") {print $2; exit; }')
10183                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10184                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10185                 done
10186                 echo "$osc_rpc_stats check passed!"
10187         done
10188         cleanup_test101bc
10189         true
10190 }
10191 run_test 101c "check stripe_size aligned read-ahead"
10192
10193 test_101d() {
10194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10195
10196         local file=$DIR/$tfile
10197         local sz_MB=${FILESIZE_101d:-80}
10198         local ra_MB=${READAHEAD_MB:-40}
10199
10200         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10201         [ $free_MB -lt $sz_MB ] &&
10202                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10203
10204         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10205         $LFS setstripe -c -1 $file || error "setstripe failed"
10206
10207         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10208         echo Cancel LRU locks on lustre client to flush the client cache
10209         cancel_lru_locks osc
10210
10211         echo Disable read-ahead
10212         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10213         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10214         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10215         $LCTL get_param -n llite.*.max_read_ahead_mb
10216
10217         echo "Reading the test file $file with read-ahead disabled"
10218         local sz_KB=$((sz_MB * 1024 / 4))
10219         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10220         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10221         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10222                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10223
10224         echo "Cancel LRU locks on lustre client to flush the client cache"
10225         cancel_lru_locks osc
10226         echo Enable read-ahead with ${ra_MB}MB
10227         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10228
10229         echo "Reading the test file $file with read-ahead enabled"
10230         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10231                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10232
10233         echo "read-ahead disabled time read $raOFF"
10234         echo "read-ahead enabled time read $raON"
10235
10236         rm -f $file
10237         wait_delete_completed
10238
10239         # use awk for this check instead of bash because it handles decimals
10240         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10241                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10242 }
10243 run_test 101d "file read with and without read-ahead enabled"
10244
10245 test_101e() {
10246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10247
10248         local file=$DIR/$tfile
10249         local size_KB=500  #KB
10250         local count=100
10251         local bsize=1024
10252
10253         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10254         local need_KB=$((count * size_KB))
10255         [[ $free_KB -le $need_KB ]] &&
10256                 skip_env "Need free space $need_KB, have $free_KB"
10257
10258         echo "Creating $count ${size_KB}K test files"
10259         for ((i = 0; i < $count; i++)); do
10260                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10261         done
10262
10263         echo "Cancel LRU locks on lustre client to flush the client cache"
10264         cancel_lru_locks $OSC
10265
10266         echo "Reset readahead stats"
10267         $LCTL set_param -n llite.*.read_ahead_stats=0
10268
10269         for ((i = 0; i < $count; i++)); do
10270                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10271         done
10272
10273         $LCTL get_param llite.*.max_cached_mb
10274         $LCTL get_param llite.*.read_ahead_stats
10275         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10276                      get_named_value 'misses' | calc_total)
10277
10278         for ((i = 0; i < $count; i++)); do
10279                 rm -rf $file.$i 2>/dev/null
10280         done
10281
10282         #10000 means 20% reads are missing in readahead
10283         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10284 }
10285 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10286
10287 test_101f() {
10288         which iozone || skip_env "no iozone installed"
10289
10290         local old_debug=$($LCTL get_param debug)
10291         old_debug=${old_debug#*=}
10292         $LCTL set_param debug="reada mmap"
10293
10294         # create a test file
10295         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10296
10297         echo Cancel LRU locks on lustre client to flush the client cache
10298         cancel_lru_locks osc
10299
10300         echo Reset readahead stats
10301         $LCTL set_param -n llite.*.read_ahead_stats=0
10302
10303         echo mmap read the file with small block size
10304         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10305                 > /dev/null 2>&1
10306
10307         echo checking missing pages
10308         $LCTL get_param llite.*.read_ahead_stats
10309         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10310                         get_named_value 'misses' | calc_total)
10311
10312         $LCTL set_param debug="$old_debug"
10313         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10314         rm -f $DIR/$tfile
10315 }
10316 run_test 101f "check mmap read performance"
10317
10318 test_101g_brw_size_test() {
10319         local mb=$1
10320         local pages=$((mb * 1048576 / PAGE_SIZE))
10321         local file=$DIR/$tfile
10322
10323         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10324                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10325         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10326                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10327                         return 2
10328         done
10329
10330         stack_trap "rm -f $file" EXIT
10331         $LCTL set_param -n osc.*.rpc_stats=0
10332
10333         # 10 RPCs should be enough for the test
10334         local count=10
10335         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10336                 { error "dd write ${mb} MB blocks failed"; return 3; }
10337         cancel_lru_locks osc
10338         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10339                 { error "dd write ${mb} MB blocks failed"; return 4; }
10340
10341         # calculate number of full-sized read and write RPCs
10342         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10343                 sed -n '/pages per rpc/,/^$/p' |
10344                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10345                 END { print reads,writes }'))
10346         # allow one extra full-sized read RPC for async readahead
10347         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10348                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10349         [[ ${rpcs[1]} == $count ]] ||
10350                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10351 }
10352
10353 test_101g() {
10354         remote_ost_nodsh && skip "remote OST with nodsh"
10355
10356         local rpcs
10357         local osts=$(get_facets OST)
10358         local list=$(comma_list $(osts_nodes))
10359         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10360         local brw_size="obdfilter.*.brw_size"
10361
10362         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10363
10364         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10365
10366         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10367                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10368                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10369            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10370                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10371                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10372
10373                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10374                         suffix="M"
10375
10376                 if [[ $orig_mb -lt 16 ]]; then
10377                         save_lustre_params $osts "$brw_size" > $p
10378                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10379                                 error "set 16MB RPC size failed"
10380
10381                         echo "remount client to enable new RPC size"
10382                         remount_client $MOUNT || error "remount_client failed"
10383                 fi
10384
10385                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10386                 # should be able to set brw_size=12, but no rpc_stats for that
10387                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10388         fi
10389
10390         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10391
10392         if [[ $orig_mb -lt 16 ]]; then
10393                 restore_lustre_params < $p
10394                 remount_client $MOUNT || error "remount_client restore failed"
10395         fi
10396
10397         rm -f $p $DIR/$tfile
10398 }
10399 run_test 101g "Big bulk(4/16 MiB) readahead"
10400
10401 test_101h() {
10402         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10403
10404         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10405                 error "dd 70M file failed"
10406         echo Cancel LRU locks on lustre client to flush the client cache
10407         cancel_lru_locks osc
10408
10409         echo "Reset readahead stats"
10410         $LCTL set_param -n llite.*.read_ahead_stats 0
10411
10412         echo "Read 10M of data but cross 64M bundary"
10413         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10414         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10415                      get_named_value 'misses' | calc_total)
10416         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10417         rm -f $p $DIR/$tfile
10418 }
10419 run_test 101h "Readahead should cover current read window"
10420
10421 test_101i() {
10422         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10423                 error "dd 10M file failed"
10424
10425         local max_per_file_mb=$($LCTL get_param -n \
10426                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10427         cancel_lru_locks osc
10428         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10429         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10430                 error "set max_read_ahead_per_file_mb to 1 failed"
10431
10432         echo "Reset readahead stats"
10433         $LCTL set_param llite.*.read_ahead_stats=0
10434
10435         dd if=$DIR/$tfile of=/dev/null bs=2M
10436
10437         $LCTL get_param llite.*.read_ahead_stats
10438         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10439                      awk '/misses/ { print $2 }')
10440         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10441         rm -f $DIR/$tfile
10442 }
10443 run_test 101i "allow current readahead to exceed reservation"
10444
10445 test_101j() {
10446         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10447                 error "setstripe $DIR/$tfile failed"
10448         local file_size=$((1048576 * 16))
10449         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10450         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10451
10452         echo Disable read-ahead
10453         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10454
10455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10456         for blk in $PAGE_SIZE 1048576 $file_size; do
10457                 cancel_lru_locks osc
10458                 echo "Reset readahead stats"
10459                 $LCTL set_param -n llite.*.read_ahead_stats=0
10460                 local count=$(($file_size / $blk))
10461                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10462                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10463                              get_named_value 'failed.to.fast.read' | calc_total)
10464                 $LCTL get_param -n llite.*.read_ahead_stats
10465                 [ $miss -eq $count ] || error "expected $count got $miss"
10466         done
10467
10468         rm -f $p $DIR/$tfile
10469 }
10470 run_test 101j "A complete read block should be submitted when no RA"
10471
10472 setup_test102() {
10473         test_mkdir $DIR/$tdir
10474         chown $RUNAS_ID $DIR/$tdir
10475         STRIPE_SIZE=65536
10476         STRIPE_OFFSET=1
10477         STRIPE_COUNT=$OSTCOUNT
10478         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10479
10480         trap cleanup_test102 EXIT
10481         cd $DIR
10482         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10483         cd $DIR/$tdir
10484         for num in 1 2 3 4; do
10485                 for count in $(seq 1 $STRIPE_COUNT); do
10486                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10487                                 local size=`expr $STRIPE_SIZE \* $num`
10488                                 local file=file"$num-$idx-$count"
10489                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10490                         done
10491                 done
10492         done
10493
10494         cd $DIR
10495         $1 tar cf $TMP/f102.tar $tdir --xattrs
10496 }
10497
10498 cleanup_test102() {
10499         trap 0
10500         rm -f $TMP/f102.tar
10501         rm -rf $DIR/d0.sanity/d102
10502 }
10503
10504 test_102a() {
10505         [ "$UID" != 0 ] && skip "must run as root"
10506         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10507                 skip_env "must have user_xattr"
10508
10509         [ -z "$(which setfattr 2>/dev/null)" ] &&
10510                 skip_env "could not find setfattr"
10511
10512         local testfile=$DIR/$tfile
10513
10514         touch $testfile
10515         echo "set/get xattr..."
10516         setfattr -n trusted.name1 -v value1 $testfile ||
10517                 error "setfattr -n trusted.name1=value1 $testfile failed"
10518         getfattr -n trusted.name1 $testfile 2> /dev/null |
10519           grep "trusted.name1=.value1" ||
10520                 error "$testfile missing trusted.name1=value1"
10521
10522         setfattr -n user.author1 -v author1 $testfile ||
10523                 error "setfattr -n user.author1=author1 $testfile failed"
10524         getfattr -n user.author1 $testfile 2> /dev/null |
10525           grep "user.author1=.author1" ||
10526                 error "$testfile missing trusted.author1=author1"
10527
10528         echo "listxattr..."
10529         setfattr -n trusted.name2 -v value2 $testfile ||
10530                 error "$testfile unable to set trusted.name2"
10531         setfattr -n trusted.name3 -v value3 $testfile ||
10532                 error "$testfile unable to set trusted.name3"
10533         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10534             grep "trusted.name" | wc -l) -eq 3 ] ||
10535                 error "$testfile missing 3 trusted.name xattrs"
10536
10537         setfattr -n user.author2 -v author2 $testfile ||
10538                 error "$testfile unable to set user.author2"
10539         setfattr -n user.author3 -v author3 $testfile ||
10540                 error "$testfile unable to set user.author3"
10541         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10542             grep "user.author" | wc -l) -eq 3 ] ||
10543                 error "$testfile missing 3 user.author xattrs"
10544
10545         echo "remove xattr..."
10546         setfattr -x trusted.name1 $testfile ||
10547                 error "$testfile error deleting trusted.name1"
10548         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10549                 error "$testfile did not delete trusted.name1 xattr"
10550
10551         setfattr -x user.author1 $testfile ||
10552                 error "$testfile error deleting user.author1"
10553         echo "set lustre special xattr ..."
10554         $LFS setstripe -c1 $testfile
10555         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10556                 awk -F "=" '/trusted.lov/ { print $2 }' )
10557         setfattr -n "trusted.lov" -v $lovea $testfile ||
10558                 error "$testfile doesn't ignore setting trusted.lov again"
10559         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10560                 error "$testfile allow setting invalid trusted.lov"
10561         rm -f $testfile
10562 }
10563 run_test 102a "user xattr test =================================="
10564
10565 check_102b_layout() {
10566         local layout="$*"
10567         local testfile=$DIR/$tfile
10568
10569         echo "test layout '$layout'"
10570         $LFS setstripe $layout $testfile || error "setstripe failed"
10571         $LFS getstripe -y $testfile
10572
10573         echo "get/set/list trusted.lov xattr ..." # b=10930
10574         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10575         [[ "$value" =~ "trusted.lov" ]] ||
10576                 error "can't get trusted.lov from $testfile"
10577         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10578                 error "getstripe failed"
10579
10580         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10581
10582         value=$(cut -d= -f2 <<<$value)
10583         # LU-13168: truncated xattr should fail if short lov_user_md header
10584         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10585                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10586         for len in $lens; do
10587                 echo "setfattr $len $testfile.2"
10588                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10589                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10590         done
10591         local stripe_size=$($LFS getstripe -S $testfile.2)
10592         local stripe_count=$($LFS getstripe -c $testfile.2)
10593         [[ $stripe_size -eq 65536 ]] ||
10594                 error "stripe size $stripe_size != 65536"
10595         [[ $stripe_count -eq $stripe_count_orig ]] ||
10596                 error "stripe count $stripe_count != $stripe_count_orig"
10597         rm $testfile $testfile.2
10598 }
10599
10600 test_102b() {
10601         [ -z "$(which setfattr 2>/dev/null)" ] &&
10602                 skip_env "could not find setfattr"
10603         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10604
10605         # check plain layout
10606         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10607
10608         # and also check composite layout
10609         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10610
10611 }
10612 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10613
10614 test_102c() {
10615         [ -z "$(which setfattr 2>/dev/null)" ] &&
10616                 skip_env "could not find setfattr"
10617         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10618
10619         # b10930: get/set/list lustre.lov xattr
10620         echo "get/set/list lustre.lov xattr ..."
10621         test_mkdir $DIR/$tdir
10622         chown $RUNAS_ID $DIR/$tdir
10623         local testfile=$DIR/$tdir/$tfile
10624         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10625                 error "setstripe failed"
10626         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10627                 error "getstripe failed"
10628         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10629         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10630
10631         local testfile2=${testfile}2
10632         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10633                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10634
10635         $RUNAS $MCREATE $testfile2
10636         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10637         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10638         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10639         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10640         [ $stripe_count -eq $STRIPECOUNT ] ||
10641                 error "stripe count $stripe_count != $STRIPECOUNT"
10642 }
10643 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10644
10645 compare_stripe_info1() {
10646         local stripe_index_all_zero=true
10647
10648         for num in 1 2 3 4; do
10649                 for count in $(seq 1 $STRIPE_COUNT); do
10650                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10651                                 local size=$((STRIPE_SIZE * num))
10652                                 local file=file"$num-$offset-$count"
10653                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10654                                 [[ $stripe_size -ne $size ]] &&
10655                                     error "$file: size $stripe_size != $size"
10656                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10657                                 # allow fewer stripes to be created, ORI-601
10658                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10659                                     error "$file: count $stripe_count != $count"
10660                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10661                                 [[ $stripe_index -ne 0 ]] &&
10662                                         stripe_index_all_zero=false
10663                         done
10664                 done
10665         done
10666         $stripe_index_all_zero &&
10667                 error "all files are being extracted starting from OST index 0"
10668         return 0
10669 }
10670
10671 have_xattrs_include() {
10672         tar --help | grep -q xattrs-include &&
10673                 echo --xattrs-include="lustre.*"
10674 }
10675
10676 test_102d() {
10677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10678         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10679
10680         XINC=$(have_xattrs_include)
10681         setup_test102
10682         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10683         cd $DIR/$tdir/$tdir
10684         compare_stripe_info1
10685 }
10686 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10687
10688 test_102f() {
10689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10690         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10691
10692         XINC=$(have_xattrs_include)
10693         setup_test102
10694         test_mkdir $DIR/$tdir.restore
10695         cd $DIR
10696         tar cf - --xattrs $tdir | tar xf - \
10697                 -C $DIR/$tdir.restore --xattrs $XINC
10698         cd $DIR/$tdir.restore/$tdir
10699         compare_stripe_info1
10700 }
10701 run_test 102f "tar copy files, not keep osts"
10702
10703 grow_xattr() {
10704         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10705                 skip "must have user_xattr"
10706         [ -z "$(which setfattr 2>/dev/null)" ] &&
10707                 skip_env "could not find setfattr"
10708         [ -z "$(which getfattr 2>/dev/null)" ] &&
10709                 skip_env "could not find getfattr"
10710
10711         local xsize=${1:-1024}  # in bytes
10712         local file=$DIR/$tfile
10713         local value="$(generate_string $xsize)"
10714         local xbig=trusted.big
10715         local toobig=$2
10716
10717         touch $file
10718         log "save $xbig on $file"
10719         if [ -z "$toobig" ]
10720         then
10721                 setfattr -n $xbig -v $value $file ||
10722                         error "saving $xbig on $file failed"
10723         else
10724                 setfattr -n $xbig -v $value $file &&
10725                         error "saving $xbig on $file succeeded"
10726                 return 0
10727         fi
10728
10729         local orig=$(get_xattr_value $xbig $file)
10730         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10731
10732         local xsml=trusted.sml
10733         log "save $xsml on $file"
10734         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10735
10736         local new=$(get_xattr_value $xbig $file)
10737         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10738
10739         log "grow $xsml on $file"
10740         setfattr -n $xsml -v "$value" $file ||
10741                 error "growing $xsml on $file failed"
10742
10743         new=$(get_xattr_value $xbig $file)
10744         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10745         log "$xbig still valid after growing $xsml"
10746
10747         rm -f $file
10748 }
10749
10750 test_102h() { # bug 15777
10751         grow_xattr 1024
10752 }
10753 run_test 102h "grow xattr from inside inode to external block"
10754
10755 test_102ha() {
10756         large_xattr_enabled || skip_env "ea_inode feature disabled"
10757
10758         echo "setting xattr of max xattr size: $(max_xattr_size)"
10759         grow_xattr $(max_xattr_size)
10760
10761         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10762         echo "This should fail:"
10763         grow_xattr $(($(max_xattr_size) + 10)) 1
10764 }
10765 run_test 102ha "grow xattr from inside inode to external inode"
10766
10767 test_102i() { # bug 17038
10768         [ -z "$(which getfattr 2>/dev/null)" ] &&
10769                 skip "could not find getfattr"
10770
10771         touch $DIR/$tfile
10772         ln -s $DIR/$tfile $DIR/${tfile}link
10773         getfattr -n trusted.lov $DIR/$tfile ||
10774                 error "lgetxattr on $DIR/$tfile failed"
10775         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10776                 grep -i "no such attr" ||
10777                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10778         rm -f $DIR/$tfile $DIR/${tfile}link
10779 }
10780 run_test 102i "lgetxattr test on symbolic link ============"
10781
10782 test_102j() {
10783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10784         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10785
10786         XINC=$(have_xattrs_include)
10787         setup_test102 "$RUNAS"
10788         chown $RUNAS_ID $DIR/$tdir
10789         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10790         cd $DIR/$tdir/$tdir
10791         compare_stripe_info1 "$RUNAS"
10792 }
10793 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10794
10795 test_102k() {
10796         [ -z "$(which setfattr 2>/dev/null)" ] &&
10797                 skip "could not find setfattr"
10798
10799         touch $DIR/$tfile
10800         # b22187 just check that does not crash for regular file.
10801         setfattr -n trusted.lov $DIR/$tfile
10802         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10803         local test_kdir=$DIR/$tdir
10804         test_mkdir $test_kdir
10805         local default_size=$($LFS getstripe -S $test_kdir)
10806         local default_count=$($LFS getstripe -c $test_kdir)
10807         local default_offset=$($LFS getstripe -i $test_kdir)
10808         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10809                 error 'dir setstripe failed'
10810         setfattr -n trusted.lov $test_kdir
10811         local stripe_size=$($LFS getstripe -S $test_kdir)
10812         local stripe_count=$($LFS getstripe -c $test_kdir)
10813         local stripe_offset=$($LFS getstripe -i $test_kdir)
10814         [ $stripe_size -eq $default_size ] ||
10815                 error "stripe size $stripe_size != $default_size"
10816         [ $stripe_count -eq $default_count ] ||
10817                 error "stripe count $stripe_count != $default_count"
10818         [ $stripe_offset -eq $default_offset ] ||
10819                 error "stripe offset $stripe_offset != $default_offset"
10820         rm -rf $DIR/$tfile $test_kdir
10821 }
10822 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10823
10824 test_102l() {
10825         [ -z "$(which getfattr 2>/dev/null)" ] &&
10826                 skip "could not find getfattr"
10827
10828         # LU-532 trusted. xattr is invisible to non-root
10829         local testfile=$DIR/$tfile
10830
10831         touch $testfile
10832
10833         echo "listxattr as user..."
10834         chown $RUNAS_ID $testfile
10835         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10836             grep -q "trusted" &&
10837                 error "$testfile trusted xattrs are user visible"
10838
10839         return 0;
10840 }
10841 run_test 102l "listxattr size test =================================="
10842
10843 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10844         local path=$DIR/$tfile
10845         touch $path
10846
10847         listxattr_size_check $path || error "listattr_size_check $path failed"
10848 }
10849 run_test 102m "Ensure listxattr fails on small bufffer ========"
10850
10851 cleanup_test102
10852
10853 getxattr() { # getxattr path name
10854         # Return the base64 encoding of the value of xattr name on path.
10855         local path=$1
10856         local name=$2
10857
10858         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10859         # file: $path
10860         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10861         #
10862         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10863
10864         getfattr --absolute-names --encoding=base64 --name=$name $path |
10865                 awk -F= -v name=$name '$1 == name {
10866                         print substr($0, index($0, "=") + 1);
10867         }'
10868 }
10869
10870 test_102n() { # LU-4101 mdt: protect internal xattrs
10871         [ -z "$(which setfattr 2>/dev/null)" ] &&
10872                 skip "could not find setfattr"
10873         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10874         then
10875                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10876         fi
10877
10878         local file0=$DIR/$tfile.0
10879         local file1=$DIR/$tfile.1
10880         local xattr0=$TMP/$tfile.0
10881         local xattr1=$TMP/$tfile.1
10882         local namelist="lov lma lmv link fid version som hsm"
10883         local name
10884         local value
10885
10886         rm -rf $file0 $file1 $xattr0 $xattr1
10887         touch $file0 $file1
10888
10889         # Get 'before' xattrs of $file1.
10890         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10891
10892         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10893                 namelist+=" lfsck_namespace"
10894         for name in $namelist; do
10895                 # Try to copy xattr from $file0 to $file1.
10896                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10897
10898                 setfattr --name=trusted.$name --value="$value" $file1 ||
10899                         error "setxattr 'trusted.$name' failed"
10900
10901                 # Try to set a garbage xattr.
10902                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10903
10904                 if [[ x$name == "xlov" ]]; then
10905                         setfattr --name=trusted.lov --value="$value" $file1 &&
10906                         error "setxattr invalid 'trusted.lov' success"
10907                 else
10908                         setfattr --name=trusted.$name --value="$value" $file1 ||
10909                                 error "setxattr invalid 'trusted.$name' failed"
10910                 fi
10911
10912                 # Try to remove the xattr from $file1. We don't care if this
10913                 # appears to succeed or fail, we just don't want there to be
10914                 # any changes or crashes.
10915                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10916         done
10917
10918         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10919         then
10920                 name="lfsck_ns"
10921                 # Try to copy xattr from $file0 to $file1.
10922                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10923
10924                 setfattr --name=trusted.$name --value="$value" $file1 ||
10925                         error "setxattr 'trusted.$name' failed"
10926
10927                 # Try to set a garbage xattr.
10928                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10929
10930                 setfattr --name=trusted.$name --value="$value" $file1 ||
10931                         error "setxattr 'trusted.$name' failed"
10932
10933                 # Try to remove the xattr from $file1. We don't care if this
10934                 # appears to succeed or fail, we just don't want there to be
10935                 # any changes or crashes.
10936                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10937         fi
10938
10939         # Get 'after' xattrs of file1.
10940         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10941
10942         if ! diff $xattr0 $xattr1; then
10943                 error "before and after xattrs of '$file1' differ"
10944         fi
10945
10946         rm -rf $file0 $file1 $xattr0 $xattr1
10947
10948         return 0
10949 }
10950 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10951
10952 test_102p() { # LU-4703 setxattr did not check ownership
10953         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10954                 skip "MDS needs to be at least 2.5.56"
10955
10956         local testfile=$DIR/$tfile
10957
10958         touch $testfile
10959
10960         echo "setfacl as user..."
10961         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10962         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10963
10964         echo "setfattr as user..."
10965         setfacl -m "u:$RUNAS_ID:---" $testfile
10966         $RUNAS setfattr -x system.posix_acl_access $testfile
10967         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10968 }
10969 run_test 102p "check setxattr(2) correctly fails without permission"
10970
10971 test_102q() {
10972         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10973                 skip "MDS needs to be at least 2.6.92"
10974
10975         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10976 }
10977 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10978
10979 test_102r() {
10980         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10981                 skip "MDS needs to be at least 2.6.93"
10982
10983         touch $DIR/$tfile || error "touch"
10984         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10985         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10986         rm $DIR/$tfile || error "rm"
10987
10988         #normal directory
10989         mkdir -p $DIR/$tdir || error "mkdir"
10990         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10991         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10992         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10993                 error "$testfile error deleting user.author1"
10994         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10995                 grep "user.$(basename $tdir)" &&
10996                 error "$tdir did not delete user.$(basename $tdir)"
10997         rmdir $DIR/$tdir || error "rmdir"
10998
10999         #striped directory
11000         test_mkdir $DIR/$tdir
11001         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11002         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11003         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11004                 error "$testfile error deleting user.author1"
11005         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11006                 grep "user.$(basename $tdir)" &&
11007                 error "$tdir did not delete user.$(basename $tdir)"
11008         rmdir $DIR/$tdir || error "rm striped dir"
11009 }
11010 run_test 102r "set EAs with empty values"
11011
11012 test_102s() {
11013         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11014                 skip "MDS needs to be at least 2.11.52"
11015
11016         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11017
11018         save_lustre_params client "llite.*.xattr_cache" > $save
11019
11020         for cache in 0 1; do
11021                 lctl set_param llite.*.xattr_cache=$cache
11022
11023                 rm -f $DIR/$tfile
11024                 touch $DIR/$tfile || error "touch"
11025                 for prefix in lustre security system trusted user; do
11026                         # Note getxattr() may fail with 'Operation not
11027                         # supported' or 'No such attribute' depending
11028                         # on prefix and cache.
11029                         getfattr -n $prefix.n102s $DIR/$tfile &&
11030                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11031                 done
11032         done
11033
11034         restore_lustre_params < $save
11035 }
11036 run_test 102s "getting nonexistent xattrs should fail"
11037
11038 test_102t() {
11039         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11040                 skip "MDS needs to be at least 2.11.52"
11041
11042         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11043
11044         save_lustre_params client "llite.*.xattr_cache" > $save
11045
11046         for cache in 0 1; do
11047                 lctl set_param llite.*.xattr_cache=$cache
11048
11049                 for buf_size in 0 256; do
11050                         rm -f $DIR/$tfile
11051                         touch $DIR/$tfile || error "touch"
11052                         setfattr -n user.multiop $DIR/$tfile
11053                         $MULTIOP $DIR/$tfile oa$buf_size ||
11054                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11055                 done
11056         done
11057
11058         restore_lustre_params < $save
11059 }
11060 run_test 102t "zero length xattr values handled correctly"
11061
11062 run_acl_subtest()
11063 {
11064     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11065     return $?
11066 }
11067
11068 test_103a() {
11069         [ "$UID" != 0 ] && skip "must run as root"
11070         $GSS && skip_env "could not run under gss"
11071         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11072                 skip_env "must have acl enabled"
11073         [ -z "$(which setfacl 2>/dev/null)" ] &&
11074                 skip_env "could not find setfacl"
11075         remote_mds_nodsh && skip "remote MDS with nodsh"
11076
11077         gpasswd -a daemon bin                           # LU-5641
11078         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11079
11080         declare -a identity_old
11081
11082         for num in $(seq $MDSCOUNT); do
11083                 switch_identity $num true || identity_old[$num]=$?
11084         done
11085
11086         SAVE_UMASK=$(umask)
11087         umask 0022
11088         mkdir -p $DIR/$tdir
11089         cd $DIR/$tdir
11090
11091         echo "performing cp ..."
11092         run_acl_subtest cp || error "run_acl_subtest cp failed"
11093         echo "performing getfacl-noacl..."
11094         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11095         echo "performing misc..."
11096         run_acl_subtest misc || error  "misc test failed"
11097         echo "performing permissions..."
11098         run_acl_subtest permissions || error "permissions failed"
11099         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11100         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11101                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11102                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11103         then
11104                 echo "performing permissions xattr..."
11105                 run_acl_subtest permissions_xattr ||
11106                         error "permissions_xattr failed"
11107         fi
11108         echo "performing setfacl..."
11109         run_acl_subtest setfacl || error  "setfacl test failed"
11110
11111         # inheritance test got from HP
11112         echo "performing inheritance..."
11113         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11114         chmod +x make-tree || error "chmod +x failed"
11115         run_acl_subtest inheritance || error "inheritance test failed"
11116         rm -f make-tree
11117
11118         echo "LU-974 ignore umask when acl is enabled..."
11119         run_acl_subtest 974 || error "LU-974 umask test failed"
11120         if [ $MDSCOUNT -ge 2 ]; then
11121                 run_acl_subtest 974_remote ||
11122                         error "LU-974 umask test failed under remote dir"
11123         fi
11124
11125         echo "LU-2561 newly created file is same size as directory..."
11126         if [ "$mds1_FSTYPE" != "zfs" ]; then
11127                 run_acl_subtest 2561 || error "LU-2561 test failed"
11128         else
11129                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11130         fi
11131
11132         run_acl_subtest 4924 || error "LU-4924 test failed"
11133
11134         cd $SAVE_PWD
11135         umask $SAVE_UMASK
11136
11137         for num in $(seq $MDSCOUNT); do
11138                 if [ "${identity_old[$num]}" = 1 ]; then
11139                         switch_identity $num false || identity_old[$num]=$?
11140                 fi
11141         done
11142 }
11143 run_test 103a "acl test"
11144
11145 test_103b() {
11146         declare -a pids
11147         local U
11148
11149         for U in {0..511}; do
11150                 {
11151                 local O=$(printf "%04o" $U)
11152
11153                 umask $(printf "%04o" $((511 ^ $O)))
11154                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11155                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11156
11157                 (( $S == ($O & 0666) )) ||
11158                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11159
11160                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11161                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11162                 (( $S == ($O & 0666) )) ||
11163                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11164
11165                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11166                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11167                 (( $S == ($O & 0666) )) ||
11168                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11169                 rm -f $DIR/$tfile.[smp]$0
11170                 } &
11171                 local pid=$!
11172
11173                 # limit the concurrently running threads to 64. LU-11878
11174                 local idx=$((U % 64))
11175                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11176                 pids[idx]=$pid
11177         done
11178         wait
11179 }
11180 run_test 103b "umask lfs setstripe"
11181
11182 test_103c() {
11183         mkdir -p $DIR/$tdir
11184         cp -rp $DIR/$tdir $DIR/$tdir.bak
11185
11186         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11187                 error "$DIR/$tdir shouldn't contain default ACL"
11188         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11189                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11190         true
11191 }
11192 run_test 103c "'cp -rp' won't set empty acl"
11193
11194 test_103e() {
11195         local numacl
11196         local fileacl
11197         local saved_debug=$($LCTL get_param -n debug)
11198
11199         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11200                 skip "MDS needs to be at least 2.14.0"
11201
11202         large_xattr_enabled || skip_env "ea_inode feature disabled"
11203
11204         mkdir -p $DIR/$tdir
11205         # add big LOV EA to cause reply buffer overflow earlier
11206         $LFS setstripe -C 1000 $DIR/$tdir
11207         lctl set_param mdc.*-mdc*.stats=clear
11208
11209         $LCTL set_param debug=0
11210         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11211         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11212
11213         # add a large number of default ACLs (expect 8000+ for 2.13+)
11214         for U in {2..7000}; do
11215                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11216                         error "Able to add just $U default ACLs"
11217         done
11218         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11219         echo "$numacl default ACLs created"
11220
11221         stat $DIR/$tdir || error "Cannot stat directory"
11222         # check file creation
11223         touch $DIR/$tdir/$tfile ||
11224                 error "failed to create $tfile with $numacl default ACLs"
11225         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11226         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11227         echo "$fileacl ACLs were inherited"
11228         (( $fileacl == $numacl )) ||
11229                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11230         # check that new ACLs creation adds new ACLs to inherited ACLs
11231         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11232                 error "Cannot set new ACL"
11233         numacl=$((numacl + 1))
11234         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11235         (( $fileacl == $numacl )) ||
11236                 error "failed to add new ACL: $fileacl != $numacl as expected"
11237         # adds more ACLs to a file to reach their maximum at 8000+
11238         numacl=0
11239         for U in {20000..25000}; do
11240                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11241                 numacl=$((numacl + 1))
11242         done
11243         echo "Added $numacl more ACLs to the file"
11244         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11245         echo "Total $fileacl ACLs in file"
11246         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11247         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11248         rmdir $DIR/$tdir || error "Cannot remove directory"
11249 }
11250 run_test 103e "inheritance of big amount of default ACLs"
11251
11252 test_103f() {
11253         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11254                 skip "MDS needs to be at least 2.14.51"
11255
11256         large_xattr_enabled || skip_env "ea_inode feature disabled"
11257
11258         # enable changelog to consume more internal MDD buffers
11259         changelog_register
11260
11261         mkdir -p $DIR/$tdir
11262         # add big LOV EA
11263         $LFS setstripe -C 1000 $DIR/$tdir
11264         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11265         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11266         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11267         rmdir $DIR/$tdir || error "Cannot remove directory"
11268 }
11269 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11270
11271 test_104a() {
11272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11273
11274         touch $DIR/$tfile
11275         lfs df || error "lfs df failed"
11276         lfs df -ih || error "lfs df -ih failed"
11277         lfs df -h $DIR || error "lfs df -h $DIR failed"
11278         lfs df -i $DIR || error "lfs df -i $DIR failed"
11279         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11280         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11281
11282         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11283         lctl --device %$OSC deactivate
11284         lfs df || error "lfs df with deactivated OSC failed"
11285         lctl --device %$OSC activate
11286         # wait the osc back to normal
11287         wait_osc_import_ready client ost
11288
11289         lfs df || error "lfs df with reactivated OSC failed"
11290         rm -f $DIR/$tfile
11291 }
11292 run_test 104a "lfs df [-ih] [path] test ========================="
11293
11294 test_104b() {
11295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11296         [ $RUNAS_ID -eq $UID ] &&
11297                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11298
11299         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11300                         grep "Permission denied" | wc -l)))
11301         if [ $denied_cnt -ne 0 ]; then
11302                 error "lfs check servers test failed"
11303         fi
11304 }
11305 run_test 104b "$RUNAS lfs check servers test ===================="
11306
11307 #
11308 # Verify $1 is within range of $2.
11309 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11310 # $1 is <= 2% of $2. Else Fail.
11311 #
11312 value_in_range() {
11313         # Strip all units (M, G, T)
11314         actual=$(echo $1 | tr -d A-Z)
11315         expect=$(echo $2 | tr -d A-Z)
11316
11317         expect_lo=$(($expect * 98 / 100)) # 2% below
11318         expect_hi=$(($expect * 102 / 100)) # 2% above
11319
11320         # permit 2% drift above and below
11321         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11322 }
11323
11324 test_104c() {
11325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11326         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11327
11328         local ost_param="osd-zfs.$FSNAME-OST0000."
11329         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11330         local ofacets=$(get_facets OST)
11331         local mfacets=$(get_facets MDS)
11332         local saved_ost_blocks=
11333         local saved_mdt_blocks=
11334
11335         echo "Before recordsize change"
11336         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11337         df=($(df -h | grep "/mnt/lustre"$))
11338
11339         # For checking.
11340         echo "lfs output : ${lfs_df[*]}"
11341         echo "df  output : ${df[*]}"
11342
11343         for facet in ${ofacets//,/ }; do
11344                 if [ -z $saved_ost_blocks ]; then
11345                         saved_ost_blocks=$(do_facet $facet \
11346                                 lctl get_param -n $ost_param.blocksize)
11347                         echo "OST Blocksize: $saved_ost_blocks"
11348                 fi
11349                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11350                 do_facet $facet zfs set recordsize=32768 $ost
11351         done
11352
11353         # BS too small. Sufficient for functional testing.
11354         for facet in ${mfacets//,/ }; do
11355                 if [ -z $saved_mdt_blocks ]; then
11356                         saved_mdt_blocks=$(do_facet $facet \
11357                                 lctl get_param -n $mdt_param.blocksize)
11358                         echo "MDT Blocksize: $saved_mdt_blocks"
11359                 fi
11360                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11361                 do_facet $facet zfs set recordsize=32768 $mdt
11362         done
11363
11364         # Give new values chance to reflect change
11365         sleep 2
11366
11367         echo "After recordsize change"
11368         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11369         df_after=($(df -h | grep "/mnt/lustre"$))
11370
11371         # For checking.
11372         echo "lfs output : ${lfs_df_after[*]}"
11373         echo "df  output : ${df_after[*]}"
11374
11375         # Verify lfs df
11376         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11377                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11378         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11379                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11380         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11381                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11382
11383         # Verify df
11384         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11385                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11386         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11387                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11388         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11389                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11390
11391         # Restore MDT recordize back to original
11392         for facet in ${mfacets//,/ }; do
11393                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11394                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11395         done
11396
11397         # Restore OST recordize back to original
11398         for facet in ${ofacets//,/ }; do
11399                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11400                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11401         done
11402
11403         return 0
11404 }
11405 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11406
11407 test_105a() {
11408         # doesn't work on 2.4 kernels
11409         touch $DIR/$tfile
11410         if $(flock_is_enabled); then
11411                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11412         else
11413                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11414         fi
11415         rm -f $DIR/$tfile
11416 }
11417 run_test 105a "flock when mounted without -o flock test ========"
11418
11419 test_105b() {
11420         touch $DIR/$tfile
11421         if $(flock_is_enabled); then
11422                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11423         else
11424                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11425         fi
11426         rm -f $DIR/$tfile
11427 }
11428 run_test 105b "fcntl when mounted without -o flock test ========"
11429
11430 test_105c() {
11431         touch $DIR/$tfile
11432         if $(flock_is_enabled); then
11433                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11434         else
11435                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11436         fi
11437         rm -f $DIR/$tfile
11438 }
11439 run_test 105c "lockf when mounted without -o flock test"
11440
11441 test_105d() { # bug 15924
11442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11443
11444         test_mkdir $DIR/$tdir
11445         flock_is_enabled || skip_env "mount w/o flock enabled"
11446         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11447         $LCTL set_param fail_loc=0x80000315
11448         flocks_test 2 $DIR/$tdir
11449 }
11450 run_test 105d "flock race (should not freeze) ========"
11451
11452 test_105e() { # bug 22660 && 22040
11453         flock_is_enabled || skip_env "mount w/o flock enabled"
11454
11455         touch $DIR/$tfile
11456         flocks_test 3 $DIR/$tfile
11457 }
11458 run_test 105e "Two conflicting flocks from same process"
11459
11460 test_106() { #bug 10921
11461         test_mkdir $DIR/$tdir
11462         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11463         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11464 }
11465 run_test 106 "attempt exec of dir followed by chown of that dir"
11466
11467 test_107() {
11468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11469
11470         CDIR=`pwd`
11471         local file=core
11472
11473         cd $DIR
11474         rm -f $file
11475
11476         local save_pattern=$(sysctl -n kernel.core_pattern)
11477         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11478         sysctl -w kernel.core_pattern=$file
11479         sysctl -w kernel.core_uses_pid=0
11480
11481         ulimit -c unlimited
11482         sleep 60 &
11483         SLEEPPID=$!
11484
11485         sleep 1
11486
11487         kill -s 11 $SLEEPPID
11488         wait $SLEEPPID
11489         if [ -e $file ]; then
11490                 size=`stat -c%s $file`
11491                 [ $size -eq 0 ] && error "Fail to create core file $file"
11492         else
11493                 error "Fail to create core file $file"
11494         fi
11495         rm -f $file
11496         sysctl -w kernel.core_pattern=$save_pattern
11497         sysctl -w kernel.core_uses_pid=$save_uses_pid
11498         cd $CDIR
11499 }
11500 run_test 107 "Coredump on SIG"
11501
11502 test_110() {
11503         test_mkdir $DIR/$tdir
11504         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11505         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11506                 error "mkdir with 256 char should fail, but did not"
11507         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11508                 error "create with 255 char failed"
11509         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11510                 error "create with 256 char should fail, but did not"
11511
11512         ls -l $DIR/$tdir
11513         rm -rf $DIR/$tdir
11514 }
11515 run_test 110 "filename length checking"
11516
11517 #
11518 # Purpose: To verify dynamic thread (OSS) creation.
11519 #
11520 test_115() {
11521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11522         remote_ost_nodsh && skip "remote OST with nodsh"
11523
11524         # Lustre does not stop service threads once they are started.
11525         # Reset number of running threads to default.
11526         stopall
11527         setupall
11528
11529         local OSTIO_pre
11530         local save_params="$TMP/sanity-$TESTNAME.parameters"
11531
11532         # Get ll_ost_io count before I/O
11533         OSTIO_pre=$(do_facet ost1 \
11534                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11535         # Exit if lustre is not running (ll_ost_io not running).
11536         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11537
11538         echo "Starting with $OSTIO_pre threads"
11539         local thread_max=$((OSTIO_pre * 2))
11540         local rpc_in_flight=$((thread_max * 2))
11541         # Number of I/O Process proposed to be started.
11542         local nfiles
11543         local facets=$(get_facets OST)
11544
11545         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11546         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11547
11548         # Set in_flight to $rpc_in_flight
11549         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11550                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11551         nfiles=${rpc_in_flight}
11552         # Set ost thread_max to $thread_max
11553         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11554
11555         # 5 Minutes should be sufficient for max number of OSS
11556         # threads(thread_max) to be created.
11557         local timeout=300
11558
11559         # Start I/O.
11560         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11561         test_mkdir $DIR/$tdir
11562         for i in $(seq $nfiles); do
11563                 local file=$DIR/$tdir/${tfile}-$i
11564                 $LFS setstripe -c -1 -i 0 $file
11565                 ($WTL $file $timeout)&
11566         done
11567
11568         # I/O Started - Wait for thread_started to reach thread_max or report
11569         # error if thread_started is more than thread_max.
11570         echo "Waiting for thread_started to reach thread_max"
11571         local thread_started=0
11572         local end_time=$((SECONDS + timeout))
11573
11574         while [ $SECONDS -le $end_time ] ; do
11575                 echo -n "."
11576                 # Get ost i/o thread_started count.
11577                 thread_started=$(do_facet ost1 \
11578                         "$LCTL get_param \
11579                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11580                 # Break out if thread_started is equal/greater than thread_max
11581                 if [[ $thread_started -ge $thread_max ]]; then
11582                         echo ll_ost_io thread_started $thread_started, \
11583                                 equal/greater than thread_max $thread_max
11584                         break
11585                 fi
11586                 sleep 1
11587         done
11588
11589         # Cleanup - We have the numbers, Kill i/o jobs if running.
11590         jobcount=($(jobs -p))
11591         for i in $(seq 0 $((${#jobcount[@]}-1)))
11592         do
11593                 kill -9 ${jobcount[$i]}
11594                 if [ $? -ne 0 ] ; then
11595                         echo Warning: \
11596                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11597                 fi
11598         done
11599
11600         # Cleanup files left by WTL binary.
11601         for i in $(seq $nfiles); do
11602                 local file=$DIR/$tdir/${tfile}-$i
11603                 rm -rf $file
11604                 if [ $? -ne 0 ] ; then
11605                         echo "Warning: Failed to delete file $file"
11606                 fi
11607         done
11608
11609         restore_lustre_params <$save_params
11610         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11611
11612         # Error out if no new thread has started or Thread started is greater
11613         # than thread max.
11614         if [[ $thread_started -le $OSTIO_pre ||
11615                         $thread_started -gt $thread_max ]]; then
11616                 error "ll_ost_io: thread_started $thread_started" \
11617                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11618                       "No new thread started or thread started greater " \
11619                       "than thread_max."
11620         fi
11621 }
11622 run_test 115 "verify dynamic thread creation===================="
11623
11624 free_min_max () {
11625         wait_delete_completed
11626         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11627         echo "OST kbytes available: ${AVAIL[@]}"
11628         MAXV=${AVAIL[0]}
11629         MAXI=0
11630         MINV=${AVAIL[0]}
11631         MINI=0
11632         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11633                 #echo OST $i: ${AVAIL[i]}kb
11634                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11635                         MAXV=${AVAIL[i]}
11636                         MAXI=$i
11637                 fi
11638                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11639                         MINV=${AVAIL[i]}
11640                         MINI=$i
11641                 fi
11642         done
11643         echo "Min free space: OST $MINI: $MINV"
11644         echo "Max free space: OST $MAXI: $MAXV"
11645 }
11646
11647 test_116a() { # was previously test_116()
11648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11649         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11650         remote_mds_nodsh && skip "remote MDS with nodsh"
11651
11652         echo -n "Free space priority "
11653         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11654                 head -n1
11655         declare -a AVAIL
11656         free_min_max
11657
11658         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11659         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11660         trap simple_cleanup_common EXIT
11661
11662         # Check if we need to generate uneven OSTs
11663         test_mkdir -p $DIR/$tdir/OST${MINI}
11664         local FILL=$((MINV / 4))
11665         local DIFF=$((MAXV - MINV))
11666         local DIFF2=$((DIFF * 100 / MINV))
11667
11668         local threshold=$(do_facet $SINGLEMDS \
11669                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11670         threshold=${threshold%%%}
11671         echo -n "Check for uneven OSTs: "
11672         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11673
11674         if [[ $DIFF2 -gt $threshold ]]; then
11675                 echo "ok"
11676                 echo "Don't need to fill OST$MINI"
11677         else
11678                 # generate uneven OSTs. Write 2% over the QOS threshold value
11679                 echo "no"
11680                 DIFF=$((threshold - DIFF2 + 2))
11681                 DIFF2=$((MINV * DIFF / 100))
11682                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11683                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11684                         error "setstripe failed"
11685                 DIFF=$((DIFF2 / 2048))
11686                 i=0
11687                 while [ $i -lt $DIFF ]; do
11688                         i=$((i + 1))
11689                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11690                                 bs=2M count=1 2>/dev/null
11691                         echo -n .
11692                 done
11693                 echo .
11694                 sync
11695                 sleep_maxage
11696                 free_min_max
11697         fi
11698
11699         DIFF=$((MAXV - MINV))
11700         DIFF2=$((DIFF * 100 / MINV))
11701         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11702         if [ $DIFF2 -gt $threshold ]; then
11703                 echo "ok"
11704         else
11705                 echo "failed - QOS mode won't be used"
11706                 simple_cleanup_common
11707                 skip "QOS imbalance criteria not met"
11708         fi
11709
11710         MINI1=$MINI
11711         MINV1=$MINV
11712         MAXI1=$MAXI
11713         MAXV1=$MAXV
11714
11715         # now fill using QOS
11716         $LFS setstripe -c 1 $DIR/$tdir
11717         FILL=$((FILL / 200))
11718         if [ $FILL -gt 600 ]; then
11719                 FILL=600
11720         fi
11721         echo "writing $FILL files to QOS-assigned OSTs"
11722         i=0
11723         while [ $i -lt $FILL ]; do
11724                 i=$((i + 1))
11725                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11726                         count=1 2>/dev/null
11727                 echo -n .
11728         done
11729         echo "wrote $i 200k files"
11730         sync
11731         sleep_maxage
11732
11733         echo "Note: free space may not be updated, so measurements might be off"
11734         free_min_max
11735         DIFF2=$((MAXV - MINV))
11736         echo "free space delta: orig $DIFF final $DIFF2"
11737         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11738         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11739         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11740         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11741         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11742         if [[ $DIFF -gt 0 ]]; then
11743                 FILL=$((DIFF2 * 100 / DIFF - 100))
11744                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11745         fi
11746
11747         # Figure out which files were written where
11748         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11749                awk '/'$MINI1': / {print $2; exit}')
11750         echo $UUID
11751         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11752         echo "$MINC files created on smaller OST $MINI1"
11753         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11754                awk '/'$MAXI1': / {print $2; exit}')
11755         echo $UUID
11756         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11757         echo "$MAXC files created on larger OST $MAXI1"
11758         if [[ $MINC -gt 0 ]]; then
11759                 FILL=$((MAXC * 100 / MINC - 100))
11760                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11761         fi
11762         [[ $MAXC -gt $MINC ]] ||
11763                 error_ignore LU-9 "stripe QOS didn't balance free space"
11764         simple_cleanup_common
11765 }
11766 run_test 116a "stripe QOS: free space balance ==================="
11767
11768 test_116b() { # LU-2093
11769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11770         remote_mds_nodsh && skip "remote MDS with nodsh"
11771
11772 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11773         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11774                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11775         [ -z "$old_rr" ] && skip "no QOS"
11776         do_facet $SINGLEMDS lctl set_param \
11777                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11778         mkdir -p $DIR/$tdir
11779         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11780         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11781         do_facet $SINGLEMDS lctl set_param fail_loc=0
11782         rm -rf $DIR/$tdir
11783         do_facet $SINGLEMDS lctl set_param \
11784                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11785 }
11786 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11787
11788 test_117() # bug 10891
11789 {
11790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11791
11792         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11793         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11794         lctl set_param fail_loc=0x21e
11795         > $DIR/$tfile || error "truncate failed"
11796         lctl set_param fail_loc=0
11797         echo "Truncate succeeded."
11798         rm -f $DIR/$tfile
11799 }
11800 run_test 117 "verify osd extend =========="
11801
11802 NO_SLOW_RESENDCOUNT=4
11803 export OLD_RESENDCOUNT=""
11804 set_resend_count () {
11805         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11806         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11807         lctl set_param -n $PROC_RESENDCOUNT $1
11808         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11809 }
11810
11811 # for reduce test_118* time (b=14842)
11812 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11813
11814 # Reset async IO behavior after error case
11815 reset_async() {
11816         FILE=$DIR/reset_async
11817
11818         # Ensure all OSCs are cleared
11819         $LFS setstripe -c -1 $FILE
11820         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11821         sync
11822         rm $FILE
11823 }
11824
11825 test_118a() #bug 11710
11826 {
11827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11828
11829         reset_async
11830
11831         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11832         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11833         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11834
11835         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11836                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11837                 return 1;
11838         fi
11839         rm -f $DIR/$tfile
11840 }
11841 run_test 118a "verify O_SYNC works =========="
11842
11843 test_118b()
11844 {
11845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11846         remote_ost_nodsh && skip "remote OST with nodsh"
11847
11848         reset_async
11849
11850         #define OBD_FAIL_SRV_ENOENT 0x217
11851         set_nodes_failloc "$(osts_nodes)" 0x217
11852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11853         RC=$?
11854         set_nodes_failloc "$(osts_nodes)" 0
11855         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11856         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11857                     grep -c writeback)
11858
11859         if [[ $RC -eq 0 ]]; then
11860                 error "Must return error due to dropped pages, rc=$RC"
11861                 return 1;
11862         fi
11863
11864         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11865                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11866                 return 1;
11867         fi
11868
11869         echo "Dirty pages not leaked on ENOENT"
11870
11871         # Due to the above error the OSC will issue all RPCs syncronously
11872         # until a subsequent RPC completes successfully without error.
11873         $MULTIOP $DIR/$tfile Ow4096yc
11874         rm -f $DIR/$tfile
11875
11876         return 0
11877 }
11878 run_test 118b "Reclaim dirty pages on fatal error =========="
11879
11880 test_118c()
11881 {
11882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11883
11884         # for 118c, restore the original resend count, LU-1940
11885         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11886                                 set_resend_count $OLD_RESENDCOUNT
11887         remote_ost_nodsh && skip "remote OST with nodsh"
11888
11889         reset_async
11890
11891         #define OBD_FAIL_OST_EROFS               0x216
11892         set_nodes_failloc "$(osts_nodes)" 0x216
11893
11894         # multiop should block due to fsync until pages are written
11895         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11896         MULTIPID=$!
11897         sleep 1
11898
11899         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11900                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11901         fi
11902
11903         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11904                     grep -c writeback)
11905         if [[ $WRITEBACK -eq 0 ]]; then
11906                 error "No page in writeback, writeback=$WRITEBACK"
11907         fi
11908
11909         set_nodes_failloc "$(osts_nodes)" 0
11910         wait $MULTIPID
11911         RC=$?
11912         if [[ $RC -ne 0 ]]; then
11913                 error "Multiop fsync failed, rc=$RC"
11914         fi
11915
11916         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11917         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11918                     grep -c writeback)
11919         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11920                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11921         fi
11922
11923         rm -f $DIR/$tfile
11924         echo "Dirty pages flushed via fsync on EROFS"
11925         return 0
11926 }
11927 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11928
11929 # continue to use small resend count to reduce test_118* time (b=14842)
11930 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11931
11932 test_118d()
11933 {
11934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11935         remote_ost_nodsh && skip "remote OST with nodsh"
11936
11937         reset_async
11938
11939         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11940         set_nodes_failloc "$(osts_nodes)" 0x214
11941         # multiop should block due to fsync until pages are written
11942         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11943         MULTIPID=$!
11944         sleep 1
11945
11946         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11947                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11948         fi
11949
11950         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11951                     grep -c writeback)
11952         if [[ $WRITEBACK -eq 0 ]]; then
11953                 error "No page in writeback, writeback=$WRITEBACK"
11954         fi
11955
11956         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11957         set_nodes_failloc "$(osts_nodes)" 0
11958
11959         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11960         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11961                     grep -c writeback)
11962         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11963                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11964         fi
11965
11966         rm -f $DIR/$tfile
11967         echo "Dirty pages gaurenteed flushed via fsync"
11968         return 0
11969 }
11970 run_test 118d "Fsync validation inject a delay of the bulk =========="
11971
11972 test_118f() {
11973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11974
11975         reset_async
11976
11977         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11978         lctl set_param fail_loc=0x8000040a
11979
11980         # Should simulate EINVAL error which is fatal
11981         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11982         RC=$?
11983         if [[ $RC -eq 0 ]]; then
11984                 error "Must return error due to dropped pages, rc=$RC"
11985         fi
11986
11987         lctl set_param fail_loc=0x0
11988
11989         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11990         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11991         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11992                     grep -c writeback)
11993         if [[ $LOCKED -ne 0 ]]; then
11994                 error "Locked pages remain in cache, locked=$LOCKED"
11995         fi
11996
11997         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11998                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11999         fi
12000
12001         rm -f $DIR/$tfile
12002         echo "No pages locked after fsync"
12003
12004         reset_async
12005         return 0
12006 }
12007 run_test 118f "Simulate unrecoverable OSC side error =========="
12008
12009 test_118g() {
12010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12011
12012         reset_async
12013
12014         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12015         lctl set_param fail_loc=0x406
12016
12017         # simulate local -ENOMEM
12018         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12019         RC=$?
12020
12021         lctl set_param fail_loc=0
12022         if [[ $RC -eq 0 ]]; then
12023                 error "Must return error due to dropped pages, rc=$RC"
12024         fi
12025
12026         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12027         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12028         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12029                         grep -c writeback)
12030         if [[ $LOCKED -ne 0 ]]; then
12031                 error "Locked pages remain in cache, locked=$LOCKED"
12032         fi
12033
12034         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12035                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12036         fi
12037
12038         rm -f $DIR/$tfile
12039         echo "No pages locked after fsync"
12040
12041         reset_async
12042         return 0
12043 }
12044 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12045
12046 test_118h() {
12047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12048         remote_ost_nodsh && skip "remote OST with nodsh"
12049
12050         reset_async
12051
12052         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12053         set_nodes_failloc "$(osts_nodes)" 0x20e
12054         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12055         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12056         RC=$?
12057
12058         set_nodes_failloc "$(osts_nodes)" 0
12059         if [[ $RC -eq 0 ]]; then
12060                 error "Must return error due to dropped pages, rc=$RC"
12061         fi
12062
12063         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12064         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12065         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12066                     grep -c writeback)
12067         if [[ $LOCKED -ne 0 ]]; then
12068                 error "Locked pages remain in cache, locked=$LOCKED"
12069         fi
12070
12071         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12072                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12073         fi
12074
12075         rm -f $DIR/$tfile
12076         echo "No pages locked after fsync"
12077
12078         return 0
12079 }
12080 run_test 118h "Verify timeout in handling recoverables errors  =========="
12081
12082 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12083
12084 test_118i() {
12085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12086         remote_ost_nodsh && skip "remote OST with nodsh"
12087
12088         reset_async
12089
12090         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12091         set_nodes_failloc "$(osts_nodes)" 0x20e
12092
12093         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12094         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12095         PID=$!
12096         sleep 5
12097         set_nodes_failloc "$(osts_nodes)" 0
12098
12099         wait $PID
12100         RC=$?
12101         if [[ $RC -ne 0 ]]; then
12102                 error "got error, but should be not, rc=$RC"
12103         fi
12104
12105         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12106         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12107         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | 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 118i "Fix error before timeout in recoverable error  =========="
12122
12123 [ "$SLOW" = "no" ] && set_resend_count 4
12124
12125 test_118j() {
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_BULK2     0x220
12132         set_nodes_failloc "$(osts_nodes)" 0x220
12133
12134         # return -EIO from OST
12135         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12136         RC=$?
12137         set_nodes_failloc "$(osts_nodes)" 0x0
12138         if [[ $RC -eq 0 ]]; then
12139                 error "Must return error due to dropped pages, rc=$RC"
12140         fi
12141
12142         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12143         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12144         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12145         if [[ $LOCKED -ne 0 ]]; then
12146                 error "Locked pages remain in cache, locked=$LOCKED"
12147         fi
12148
12149         # in recoverable error on OST we want resend and stay until it finished
12150         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12151                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12152         fi
12153
12154         rm -f $DIR/$tfile
12155         echo "No pages locked after fsync"
12156
12157         return 0
12158 }
12159 run_test 118j "Simulate unrecoverable OST side error =========="
12160
12161 test_118k()
12162 {
12163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12164         remote_ost_nodsh && skip "remote OSTs with nodsh"
12165
12166         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12167         set_nodes_failloc "$(osts_nodes)" 0x20e
12168         test_mkdir $DIR/$tdir
12169
12170         for ((i=0;i<10;i++)); do
12171                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12172                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12173                 SLEEPPID=$!
12174                 sleep 0.500s
12175                 kill $SLEEPPID
12176                 wait $SLEEPPID
12177         done
12178
12179         set_nodes_failloc "$(osts_nodes)" 0
12180         rm -rf $DIR/$tdir
12181 }
12182 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12183
12184 test_118l() # LU-646
12185 {
12186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12187
12188         test_mkdir $DIR/$tdir
12189         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12190         rm -rf $DIR/$tdir
12191 }
12192 run_test 118l "fsync dir"
12193
12194 test_118m() # LU-3066
12195 {
12196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12197
12198         test_mkdir $DIR/$tdir
12199         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12200         rm -rf $DIR/$tdir
12201 }
12202 run_test 118m "fdatasync dir ========="
12203
12204 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12205
12206 test_118n()
12207 {
12208         local begin
12209         local end
12210
12211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12212         remote_ost_nodsh && skip "remote OSTs with nodsh"
12213
12214         # Sleep to avoid a cached response.
12215         #define OBD_STATFS_CACHE_SECONDS 1
12216         sleep 2
12217
12218         # Inject a 10 second delay in the OST_STATFS handler.
12219         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12220         set_nodes_failloc "$(osts_nodes)" 0x242
12221
12222         begin=$SECONDS
12223         stat --file-system $MOUNT > /dev/null
12224         end=$SECONDS
12225
12226         set_nodes_failloc "$(osts_nodes)" 0
12227
12228         if ((end - begin > 20)); then
12229             error "statfs took $((end - begin)) seconds, expected 10"
12230         fi
12231 }
12232 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12233
12234 test_119a() # bug 11737
12235 {
12236         BSIZE=$((512 * 1024))
12237         directio write $DIR/$tfile 0 1 $BSIZE
12238         # We ask to read two blocks, which is more than a file size.
12239         # directio will indicate an error when requested and actual
12240         # sizes aren't equeal (a normal situation in this case) and
12241         # print actual read amount.
12242         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12243         if [ "$NOB" != "$BSIZE" ]; then
12244                 error "read $NOB bytes instead of $BSIZE"
12245         fi
12246         rm -f $DIR/$tfile
12247 }
12248 run_test 119a "Short directIO read must return actual read amount"
12249
12250 test_119b() # bug 11737
12251 {
12252         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12253
12254         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12255         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12256         sync
12257         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12258                 error "direct read failed"
12259         rm -f $DIR/$tfile
12260 }
12261 run_test 119b "Sparse directIO read must return actual read amount"
12262
12263 test_119c() # bug 13099
12264 {
12265         BSIZE=1048576
12266         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12267         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12268         rm -f $DIR/$tfile
12269 }
12270 run_test 119c "Testing for direct read hitting hole"
12271
12272 test_119d() # bug 15950
12273 {
12274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12275
12276         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12277         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12278         BSIZE=1048576
12279         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12280         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12281         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12282         lctl set_param fail_loc=0x40d
12283         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12284         pid_dio=$!
12285         sleep 1
12286         cat $DIR/$tfile > /dev/null &
12287         lctl set_param fail_loc=0
12288         pid_reads=$!
12289         wait $pid_dio
12290         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12291         sleep 2
12292         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12293         error "the read rpcs have not completed in 2s"
12294         rm -f $DIR/$tfile
12295         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12296 }
12297 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12298
12299 test_120a() {
12300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12301         remote_mds_nodsh && skip "remote MDS with nodsh"
12302         test_mkdir -i0 -c1 $DIR/$tdir
12303         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12304                 skip_env "no early lock cancel on server"
12305
12306         lru_resize_disable mdc
12307         lru_resize_disable osc
12308         cancel_lru_locks mdc
12309         # asynchronous object destroy at MDT could cause bl ast to client
12310         cancel_lru_locks osc
12311
12312         stat $DIR/$tdir > /dev/null
12313         can1=$(do_facet mds1 \
12314                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12315                awk '/ldlm_cancel/ {print $2}')
12316         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12317                awk '/ldlm_bl_callback/ {print $2}')
12318         test_mkdir -i0 -c1 $DIR/$tdir/d1
12319         can2=$(do_facet mds1 \
12320                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12321                awk '/ldlm_cancel/ {print $2}')
12322         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12323                awk '/ldlm_bl_callback/ {print $2}')
12324         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12325         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12326         lru_resize_enable mdc
12327         lru_resize_enable osc
12328 }
12329 run_test 120a "Early Lock Cancel: mkdir test"
12330
12331 test_120b() {
12332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12333         remote_mds_nodsh && skip "remote MDS with nodsh"
12334         test_mkdir $DIR/$tdir
12335         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12336                 skip_env "no early lock cancel on server"
12337
12338         lru_resize_disable mdc
12339         lru_resize_disable osc
12340         cancel_lru_locks mdc
12341         stat $DIR/$tdir > /dev/null
12342         can1=$(do_facet $SINGLEMDS \
12343                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12344                awk '/ldlm_cancel/ {print $2}')
12345         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12346                awk '/ldlm_bl_callback/ {print $2}')
12347         touch $DIR/$tdir/f1
12348         can2=$(do_facet $SINGLEMDS \
12349                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12350                awk '/ldlm_cancel/ {print $2}')
12351         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12352                awk '/ldlm_bl_callback/ {print $2}')
12353         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12354         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12355         lru_resize_enable mdc
12356         lru_resize_enable osc
12357 }
12358 run_test 120b "Early Lock Cancel: create test"
12359
12360 test_120c() {
12361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12362         remote_mds_nodsh && skip "remote MDS with nodsh"
12363         test_mkdir -i0 -c1 $DIR/$tdir
12364         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12365                 skip "no early lock cancel on server"
12366
12367         lru_resize_disable mdc
12368         lru_resize_disable osc
12369         test_mkdir -i0 -c1 $DIR/$tdir/d1
12370         test_mkdir -i0 -c1 $DIR/$tdir/d2
12371         touch $DIR/$tdir/d1/f1
12372         cancel_lru_locks mdc
12373         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12374         can1=$(do_facet mds1 \
12375                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12376                awk '/ldlm_cancel/ {print $2}')
12377         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12378                awk '/ldlm_bl_callback/ {print $2}')
12379         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12380         can2=$(do_facet mds1 \
12381                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12382                awk '/ldlm_cancel/ {print $2}')
12383         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12384                awk '/ldlm_bl_callback/ {print $2}')
12385         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12386         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12387         lru_resize_enable mdc
12388         lru_resize_enable osc
12389 }
12390 run_test 120c "Early Lock Cancel: link test"
12391
12392 test_120d() {
12393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12394         remote_mds_nodsh && skip "remote MDS with nodsh"
12395         test_mkdir -i0 -c1 $DIR/$tdir
12396         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12397                 skip_env "no early lock cancel on server"
12398
12399         lru_resize_disable mdc
12400         lru_resize_disable osc
12401         touch $DIR/$tdir
12402         cancel_lru_locks mdc
12403         stat $DIR/$tdir > /dev/null
12404         can1=$(do_facet mds1 \
12405                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12406                awk '/ldlm_cancel/ {print $2}')
12407         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12408                awk '/ldlm_bl_callback/ {print $2}')
12409         chmod a+x $DIR/$tdir
12410         can2=$(do_facet mds1 \
12411                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12412                awk '/ldlm_cancel/ {print $2}')
12413         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12414                awk '/ldlm_bl_callback/ {print $2}')
12415         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12416         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12417         lru_resize_enable mdc
12418         lru_resize_enable osc
12419 }
12420 run_test 120d "Early Lock Cancel: setattr test"
12421
12422 test_120e() {
12423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12424         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12425                 skip_env "no early lock cancel on server"
12426         remote_mds_nodsh && skip "remote MDS with nodsh"
12427
12428         local dlmtrace_set=false
12429
12430         test_mkdir -i0 -c1 $DIR/$tdir
12431         lru_resize_disable mdc
12432         lru_resize_disable osc
12433         ! $LCTL get_param debug | grep -q dlmtrace &&
12434                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12435         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12436         cancel_lru_locks mdc
12437         cancel_lru_locks osc
12438         dd if=$DIR/$tdir/f1 of=/dev/null
12439         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12440         # XXX client can not do early lock cancel of OST lock
12441         # during unlink (LU-4206), so cancel osc lock now.
12442         sleep 2
12443         cancel_lru_locks osc
12444         can1=$(do_facet mds1 \
12445                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12446                awk '/ldlm_cancel/ {print $2}')
12447         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12448                awk '/ldlm_bl_callback/ {print $2}')
12449         unlink $DIR/$tdir/f1
12450         sleep 5
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 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12457                 $LCTL dk $TMP/cancel.debug.txt
12458         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12459                 $LCTL dk $TMP/blocking.debug.txt
12460         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12461         lru_resize_enable mdc
12462         lru_resize_enable osc
12463 }
12464 run_test 120e "Early Lock Cancel: unlink test"
12465
12466 test_120f() {
12467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12468         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12469                 skip_env "no early lock cancel on server"
12470         remote_mds_nodsh && skip "remote MDS with nodsh"
12471
12472         test_mkdir -i0 -c1 $DIR/$tdir
12473         lru_resize_disable mdc
12474         lru_resize_disable osc
12475         test_mkdir -i0 -c1 $DIR/$tdir/d1
12476         test_mkdir -i0 -c1 $DIR/$tdir/d2
12477         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12478         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12479         cancel_lru_locks mdc
12480         cancel_lru_locks osc
12481         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12482         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12483         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12484         # XXX client can not do early lock cancel of OST lock
12485         # during rename (LU-4206), so cancel osc lock now.
12486         sleep 2
12487         cancel_lru_locks osc
12488         can1=$(do_facet mds1 \
12489                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12490                awk '/ldlm_cancel/ {print $2}')
12491         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12492                awk '/ldlm_bl_callback/ {print $2}')
12493         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12494         sleep 5
12495         can2=$(do_facet mds1 \
12496                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12497                awk '/ldlm_cancel/ {print $2}')
12498         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12499                awk '/ldlm_bl_callback/ {print $2}')
12500         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12501         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12502         lru_resize_enable mdc
12503         lru_resize_enable osc
12504 }
12505 run_test 120f "Early Lock Cancel: rename test"
12506
12507 test_120g() {
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         lru_resize_disable mdc
12514         lru_resize_disable osc
12515         count=10000
12516         echo create $count files
12517         test_mkdir $DIR/$tdir
12518         cancel_lru_locks mdc
12519         cancel_lru_locks osc
12520         t0=$(date +%s)
12521
12522         can0=$(do_facet $SINGLEMDS \
12523                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12524                awk '/ldlm_cancel/ {print $2}')
12525         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12526                awk '/ldlm_bl_callback/ {print $2}')
12527         createmany -o $DIR/$tdir/f $count
12528         sync
12529         can1=$(do_facet $SINGLEMDS \
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         t1=$(date +%s)
12535         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12536         echo rm $count files
12537         rm -r $DIR/$tdir
12538         sync
12539         can2=$(do_facet $SINGLEMDS \
12540                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12541                awk '/ldlm_cancel/ {print $2}')
12542         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12543                awk '/ldlm_bl_callback/ {print $2}')
12544         t2=$(date +%s)
12545         echo total: $count removes in $((t2-t1))
12546         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12547         sleep 2
12548         # wait for commitment of removal
12549         lru_resize_enable mdc
12550         lru_resize_enable osc
12551 }
12552 run_test 120g "Early Lock Cancel: performance test"
12553
12554 test_121() { #bug #10589
12555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12556
12557         rm -rf $DIR/$tfile
12558         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12559 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12560         lctl set_param fail_loc=0x310
12561         cancel_lru_locks osc > /dev/null
12562         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12563         lctl set_param fail_loc=0
12564         [[ $reads -eq $writes ]] ||
12565                 error "read $reads blocks, must be $writes blocks"
12566 }
12567 run_test 121 "read cancel race ========="
12568
12569 test_123a_base() { # was test 123, statahead(bug 11401)
12570         local lsx="$1"
12571
12572         SLOWOK=0
12573         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12574                 log "testing UP system. Performance may be lower than expected."
12575                 SLOWOK=1
12576         fi
12577
12578         rm -rf $DIR/$tdir
12579         test_mkdir $DIR/$tdir
12580         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12581         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12582         MULT=10
12583         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12584                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12585
12586                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12587                 lctl set_param -n llite.*.statahead_max 0
12588                 lctl get_param llite.*.statahead_max
12589                 cancel_lru_locks mdc
12590                 cancel_lru_locks osc
12591                 stime=$(date +%s)
12592                 time $lsx $DIR/$tdir | wc -l
12593                 etime=$(date +%s)
12594                 delta=$((etime - stime))
12595                 log "$lsx $i files without statahead: $delta sec"
12596                 lctl set_param llite.*.statahead_max=$max
12597
12598                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12599                         grep "statahead wrong:" | awk '{print $3}')
12600                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12601                 cancel_lru_locks mdc
12602                 cancel_lru_locks osc
12603                 stime=$(date +%s)
12604                 time $lsx $DIR/$tdir | wc -l
12605                 etime=$(date +%s)
12606                 delta_sa=$((etime - stime))
12607                 log "$lsx $i files with statahead: $delta_sa sec"
12608                 lctl get_param -n llite.*.statahead_stats
12609                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12610                         grep "statahead wrong:" | awk '{print $3}')
12611
12612                 [[ $swrong -lt $ewrong ]] &&
12613                         log "statahead was stopped, maybe too many locks held!"
12614                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12615
12616                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12617                         max=$(lctl get_param -n llite.*.statahead_max |
12618                                 head -n 1)
12619                         lctl set_param -n llite.*.statahead_max 0
12620                         lctl get_param llite.*.statahead_max
12621                         cancel_lru_locks mdc
12622                         cancel_lru_locks osc
12623                         stime=$(date +%s)
12624                         time $lsx $DIR/$tdir | wc -l
12625                         etime=$(date +%s)
12626                         delta=$((etime - stime))
12627                         log "$lsx $i files again without statahead: $delta sec"
12628                         lctl set_param llite.*.statahead_max=$max
12629                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12630                                 if [  $SLOWOK -eq 0 ]; then
12631                                         error "$lsx $i files is slower with statahead!"
12632                                 else
12633                                         log "$lsx $i files is slower with statahead!"
12634                                 fi
12635                                 break
12636                         fi
12637                 fi
12638
12639                 [ $delta -gt 20 ] && break
12640                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12641                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12642         done
12643         log "$lsx done"
12644
12645         stime=$(date +%s)
12646         rm -r $DIR/$tdir
12647         sync
12648         etime=$(date +%s)
12649         delta=$((etime - stime))
12650         log "rm -r $DIR/$tdir/: $delta seconds"
12651         log "rm done"
12652         lctl get_param -n llite.*.statahead_stats
12653 }
12654
12655 test_123aa() {
12656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12657
12658         test_123a_base "ls -l"
12659 }
12660 run_test 123aa "verify statahead work"
12661
12662 test_123ab() {
12663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12664
12665         statx_supported || skip_env "Test must be statx() syscall supported"
12666
12667         test_123a_base "$STATX -l"
12668 }
12669 run_test 123ab "verify statahead work by using statx"
12670
12671 test_123ac() {
12672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12673
12674         statx_supported || skip_env "Test must be statx() syscall supported"
12675
12676         local rpcs_before
12677         local rpcs_after
12678         local agl_before
12679         local agl_after
12680
12681         cancel_lru_locks $OSC
12682         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12683         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12684                 awk '/agl.total:/ {print $3}')
12685         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12686         test_123a_base "$STATX --cached=always -D"
12687         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12688                 awk '/agl.total:/ {print $3}')
12689         [ $agl_before -eq $agl_after ] ||
12690                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12691         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12692         [ $rpcs_after -eq $rpcs_before ] ||
12693                 error "$STATX should not send glimpse RPCs to $OSC"
12694 }
12695 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12696
12697 test_123b () { # statahead(bug 15027)
12698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12699
12700         test_mkdir $DIR/$tdir
12701         createmany -o $DIR/$tdir/$tfile-%d 1000
12702
12703         cancel_lru_locks mdc
12704         cancel_lru_locks osc
12705
12706 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12707         lctl set_param fail_loc=0x80000803
12708         ls -lR $DIR/$tdir > /dev/null
12709         log "ls done"
12710         lctl set_param fail_loc=0x0
12711         lctl get_param -n llite.*.statahead_stats
12712         rm -r $DIR/$tdir
12713         sync
12714
12715 }
12716 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12717
12718 test_123c() {
12719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12720
12721         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12722         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12723         touch $DIR/$tdir.1/{1..3}
12724         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12725
12726         remount_client $MOUNT
12727
12728         $MULTIOP $DIR/$tdir.0 Q
12729
12730         # let statahead to complete
12731         ls -l $DIR/$tdir.0 > /dev/null
12732
12733         testid=$(echo $TESTNAME | tr '_' ' ')
12734         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12735                 error "statahead warning" || true
12736 }
12737 run_test 123c "Can not initialize inode warning on DNE statahead"
12738
12739 test_124a() {
12740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12741         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12742                 skip_env "no lru resize on server"
12743
12744         local NR=2000
12745
12746         test_mkdir $DIR/$tdir
12747
12748         log "create $NR files at $DIR/$tdir"
12749         createmany -o $DIR/$tdir/f $NR ||
12750                 error "failed to create $NR files in $DIR/$tdir"
12751
12752         cancel_lru_locks mdc
12753         ls -l $DIR/$tdir > /dev/null
12754
12755         local NSDIR=""
12756         local LRU_SIZE=0
12757         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12758                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12759                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12760                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12761                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12762                         log "NSDIR=$NSDIR"
12763                         log "NS=$(basename $NSDIR)"
12764                         break
12765                 fi
12766         done
12767
12768         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12769                 skip "Not enough cached locks created!"
12770         fi
12771         log "LRU=$LRU_SIZE"
12772
12773         local SLEEP=30
12774
12775         # We know that lru resize allows one client to hold $LIMIT locks
12776         # for 10h. After that locks begin to be killed by client.
12777         local MAX_HRS=10
12778         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12779         log "LIMIT=$LIMIT"
12780         if [ $LIMIT -lt $LRU_SIZE ]; then
12781                 skip "Limit is too small $LIMIT"
12782         fi
12783
12784         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12785         # killing locks. Some time was spent for creating locks. This means
12786         # that up to the moment of sleep finish we must have killed some of
12787         # them (10-100 locks). This depends on how fast ther were created.
12788         # Many of them were touched in almost the same moment and thus will
12789         # be killed in groups.
12790         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12791
12792         # Use $LRU_SIZE_B here to take into account real number of locks
12793         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12794         local LRU_SIZE_B=$LRU_SIZE
12795         log "LVF=$LVF"
12796         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12797         log "OLD_LVF=$OLD_LVF"
12798         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12799
12800         # Let's make sure that we really have some margin. Client checks
12801         # cached locks every 10 sec.
12802         SLEEP=$((SLEEP+20))
12803         log "Sleep ${SLEEP} sec"
12804         local SEC=0
12805         while ((SEC<$SLEEP)); do
12806                 echo -n "..."
12807                 sleep 5
12808                 SEC=$((SEC+5))
12809                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12810                 echo -n "$LRU_SIZE"
12811         done
12812         echo ""
12813         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12814         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12815
12816         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12817                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12818                 unlinkmany $DIR/$tdir/f $NR
12819                 return
12820         }
12821
12822         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12823         log "unlink $NR files at $DIR/$tdir"
12824         unlinkmany $DIR/$tdir/f $NR
12825 }
12826 run_test 124a "lru resize ======================================="
12827
12828 get_max_pool_limit()
12829 {
12830         local limit=$($LCTL get_param \
12831                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12832         local max=0
12833         for l in $limit; do
12834                 if [[ $l -gt $max ]]; then
12835                         max=$l
12836                 fi
12837         done
12838         echo $max
12839 }
12840
12841 test_124b() {
12842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12843         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12844                 skip_env "no lru resize on server"
12845
12846         LIMIT=$(get_max_pool_limit)
12847
12848         NR=$(($(default_lru_size)*20))
12849         if [[ $NR -gt $LIMIT ]]; then
12850                 log "Limit lock number by $LIMIT locks"
12851                 NR=$LIMIT
12852         fi
12853
12854         IFree=$(mdsrate_inodes_available)
12855         if [ $IFree -lt $NR ]; then
12856                 log "Limit lock number by $IFree inodes"
12857                 NR=$IFree
12858         fi
12859
12860         lru_resize_disable mdc
12861         test_mkdir -p $DIR/$tdir/disable_lru_resize
12862
12863         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12864         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12865         cancel_lru_locks mdc
12866         stime=`date +%s`
12867         PID=""
12868         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12869         PID="$PID $!"
12870         sleep 2
12871         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12872         PID="$PID $!"
12873         sleep 2
12874         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12875         PID="$PID $!"
12876         wait $PID
12877         etime=`date +%s`
12878         nolruresize_delta=$((etime-stime))
12879         log "ls -la time: $nolruresize_delta seconds"
12880         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12881         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12882
12883         lru_resize_enable mdc
12884         test_mkdir -p $DIR/$tdir/enable_lru_resize
12885
12886         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12887         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12888         cancel_lru_locks mdc
12889         stime=`date +%s`
12890         PID=""
12891         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12892         PID="$PID $!"
12893         sleep 2
12894         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12895         PID="$PID $!"
12896         sleep 2
12897         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12898         PID="$PID $!"
12899         wait $PID
12900         etime=`date +%s`
12901         lruresize_delta=$((etime-stime))
12902         log "ls -la time: $lruresize_delta seconds"
12903         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12904
12905         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12906                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12907         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12908                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12909         else
12910                 log "lru resize performs the same with no lru resize"
12911         fi
12912         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12913 }
12914 run_test 124b "lru resize (performance test) ======================="
12915
12916 test_124c() {
12917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12918         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12919                 skip_env "no lru resize on server"
12920
12921         # cache ununsed locks on client
12922         local nr=100
12923         cancel_lru_locks mdc
12924         test_mkdir $DIR/$tdir
12925         createmany -o $DIR/$tdir/f $nr ||
12926                 error "failed to create $nr files in $DIR/$tdir"
12927         ls -l $DIR/$tdir > /dev/null
12928
12929         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12930         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12931         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12932         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12933         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12934
12935         # set lru_max_age to 1 sec
12936         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12937         echo "sleep $((recalc_p * 2)) seconds..."
12938         sleep $((recalc_p * 2))
12939
12940         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12941         # restore lru_max_age
12942         $LCTL set_param -n $nsdir.lru_max_age $max_age
12943         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12944         unlinkmany $DIR/$tdir/f $nr
12945 }
12946 run_test 124c "LRUR cancel very aged locks"
12947
12948 test_124d() {
12949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12950         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12951                 skip_env "no lru resize on server"
12952
12953         # cache ununsed locks on client
12954         local nr=100
12955
12956         lru_resize_disable mdc
12957         stack_trap "lru_resize_enable mdc" EXIT
12958
12959         cancel_lru_locks mdc
12960
12961         # asynchronous object destroy at MDT could cause bl ast to client
12962         test_mkdir $DIR/$tdir
12963         createmany -o $DIR/$tdir/f $nr ||
12964                 error "failed to create $nr files in $DIR/$tdir"
12965         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12966
12967         ls -l $DIR/$tdir > /dev/null
12968
12969         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12970         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12971         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12972         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12973
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         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12979
12980         echo "sleep $((recalc_p * 2)) seconds..."
12981         sleep $((recalc_p * 2))
12982
12983         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12984
12985         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12986 }
12987 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12988
12989 test_125() { # 13358
12990         $LCTL get_param -n llite.*.client_type | grep -q local ||
12991                 skip "must run as local client"
12992         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12993                 skip_env "must have acl enabled"
12994         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12995
12996         test_mkdir $DIR/$tdir
12997         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12998         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12999         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13000 }
13001 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13002
13003 test_126() { # bug 12829/13455
13004         $GSS && skip_env "must run as gss disabled"
13005         $LCTL get_param -n llite.*.client_type | grep -q local ||
13006                 skip "must run as local client"
13007         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13008
13009         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13010         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13011         rm -f $DIR/$tfile
13012         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13013 }
13014 run_test 126 "check that the fsgid provided by the client is taken into account"
13015
13016 test_127a() { # bug 15521
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018         local name count samp unit min max sum sumsq
13019
13020         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13021         echo "stats before reset"
13022         $LCTL get_param osc.*.stats
13023         $LCTL set_param osc.*.stats=0
13024         local fsize=$((2048 * 1024))
13025
13026         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13027         cancel_lru_locks osc
13028         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13029
13030         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13031         stack_trap "rm -f $TMP/$tfile.tmp"
13032         while read name count samp unit min max sum sumsq; do
13033                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13034                 [ ! $min ] && error "Missing min value for $name proc entry"
13035                 eval $name=$count || error "Wrong proc format"
13036
13037                 case $name in
13038                 read_bytes|write_bytes)
13039                         [[ "$unit" =~ "bytes" ]] ||
13040                                 error "unit is not 'bytes': $unit"
13041                         (( $min >= 4096 )) || error "min is too small: $min"
13042                         (( $min <= $fsize )) || error "min is too big: $min"
13043                         (( $max >= 4096 )) || error "max is too small: $max"
13044                         (( $max <= $fsize )) || error "max is too big: $max"
13045                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13046                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13047                                 error "sumsquare is too small: $sumsq"
13048                         (( $sumsq <= $fsize * $fsize )) ||
13049                                 error "sumsquare is too big: $sumsq"
13050                         ;;
13051                 ost_read|ost_write)
13052                         [[ "$unit" =~ "usec" ]] ||
13053                                 error "unit is not 'usec': $unit"
13054                         ;;
13055                 *)      ;;
13056                 esac
13057         done < $DIR/$tfile.tmp
13058
13059         #check that we actually got some stats
13060         [ "$read_bytes" ] || error "Missing read_bytes stats"
13061         [ "$write_bytes" ] || error "Missing write_bytes stats"
13062         [ "$read_bytes" != 0 ] || error "no read done"
13063         [ "$write_bytes" != 0 ] || error "no write done"
13064 }
13065 run_test 127a "verify the client stats are sane"
13066
13067 test_127b() { # bug LU-333
13068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13069         local name count samp unit min max sum sumsq
13070
13071         echo "stats before reset"
13072         $LCTL get_param llite.*.stats
13073         $LCTL set_param llite.*.stats=0
13074
13075         # perform 2 reads and writes so MAX is different from SUM.
13076         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13077         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13078         cancel_lru_locks osc
13079         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13080         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13081
13082         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13083         stack_trap "rm -f $TMP/$tfile.tmp"
13084         while read name count samp unit min max sum sumsq; do
13085                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13086                 eval $name=$count || error "Wrong proc format"
13087
13088                 case $name in
13089                 read_bytes|write_bytes)
13090                         [[ "$unit" =~ "bytes" ]] ||
13091                                 error "unit is not 'bytes': $unit"
13092                         (( $count == 2 )) || error "count is not 2: $count"
13093                         (( $min == $PAGE_SIZE )) ||
13094                                 error "min is not $PAGE_SIZE: $min"
13095                         (( $max == $PAGE_SIZE )) ||
13096                                 error "max is not $PAGE_SIZE: $max"
13097                         (( $sum == $PAGE_SIZE * 2 )) ||
13098                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13099                         ;;
13100                 read|write)
13101                         [[ "$unit" =~ "usec" ]] ||
13102                                 error "unit is not 'usec': $unit"
13103                         ;;
13104                 *)      ;;
13105                 esac
13106         done < $TMP/$tfile.tmp
13107
13108         #check that we actually got some stats
13109         [ "$read_bytes" ] || error "Missing read_bytes stats"
13110         [ "$write_bytes" ] || error "Missing write_bytes stats"
13111         [ "$read_bytes" != 0 ] || error "no read done"
13112         [ "$write_bytes" != 0 ] || error "no write done"
13113 }
13114 run_test 127b "verify the llite client stats are sane"
13115
13116 test_127c() { # LU-12394
13117         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13118         local size
13119         local bsize
13120         local reads
13121         local writes
13122         local count
13123
13124         $LCTL set_param llite.*.extents_stats=1
13125         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13126
13127         # Use two stripes so there is enough space in default config
13128         $LFS setstripe -c 2 $DIR/$tfile
13129
13130         # Extent stats start at 0-4K and go in power of two buckets
13131         # LL_HIST_START = 12 --> 2^12 = 4K
13132         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13133         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13134         # small configs
13135         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13136                 do
13137                 # Write and read, 2x each, second time at a non-zero offset
13138                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13139                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13140                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13141                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13142                 rm -f $DIR/$tfile
13143         done
13144
13145         $LCTL get_param llite.*.extents_stats
13146
13147         count=2
13148         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13149                 do
13150                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13151                                 grep -m 1 $bsize)
13152                 reads=$(echo $bucket | awk '{print $5}')
13153                 writes=$(echo $bucket | awk '{print $9}')
13154                 [ "$reads" -eq $count ] ||
13155                         error "$reads reads in < $bsize bucket, expect $count"
13156                 [ "$writes" -eq $count ] ||
13157                         error "$writes writes in < $bsize bucket, expect $count"
13158         done
13159
13160         # Test mmap write and read
13161         $LCTL set_param llite.*.extents_stats=c
13162         size=512
13163         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13164         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13165         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13166
13167         $LCTL get_param llite.*.extents_stats
13168
13169         count=$(((size*1024) / PAGE_SIZE))
13170
13171         bsize=$((2 * PAGE_SIZE / 1024))K
13172
13173         bucket=$($LCTL get_param -n llite.*.extents_stats |
13174                         grep -m 1 $bsize)
13175         reads=$(echo $bucket | awk '{print $5}')
13176         writes=$(echo $bucket | awk '{print $9}')
13177         # mmap writes fault in the page first, creating an additonal read
13178         [ "$reads" -eq $((2 * count)) ] ||
13179                 error "$reads reads in < $bsize bucket, expect $count"
13180         [ "$writes" -eq $count ] ||
13181                 error "$writes writes in < $bsize bucket, expect $count"
13182 }
13183 run_test 127c "test llite extent stats with regular & mmap i/o"
13184
13185 test_128() { # bug 15212
13186         touch $DIR/$tfile
13187         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13188                 find $DIR/$tfile
13189                 find $DIR/$tfile
13190         EOF
13191
13192         result=$(grep error $TMP/$tfile.log)
13193         rm -f $DIR/$tfile $TMP/$tfile.log
13194         [ -z "$result" ] ||
13195                 error "consecutive find's under interactive lfs failed"
13196 }
13197 run_test 128 "interactive lfs for 2 consecutive find's"
13198
13199 set_dir_limits () {
13200         local mntdev
13201         local canondev
13202         local node
13203
13204         local ldproc=/proc/fs/ldiskfs
13205         local facets=$(get_facets MDS)
13206
13207         for facet in ${facets//,/ }; do
13208                 canondev=$(ldiskfs_canon \
13209                            *.$(convert_facet2label $facet).mntdev $facet)
13210                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13211                         ldproc=/sys/fs/ldiskfs
13212                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13213                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13214         done
13215 }
13216
13217 check_mds_dmesg() {
13218         local facets=$(get_facets MDS)
13219         for facet in ${facets//,/ }; do
13220                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13221         done
13222         return 1
13223 }
13224
13225 test_129() {
13226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13227         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13228                 skip "Need MDS version with at least 2.5.56"
13229         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13230                 skip_env "ldiskfs only test"
13231         fi
13232         remote_mds_nodsh && skip "remote MDS with nodsh"
13233
13234         local ENOSPC=28
13235         local has_warning=false
13236
13237         rm -rf $DIR/$tdir
13238         mkdir -p $DIR/$tdir
13239
13240         # block size of mds1
13241         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13242         set_dir_limits $maxsize $((maxsize * 6 / 8))
13243         stack_trap "set_dir_limits 0 0"
13244         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13245         local dirsize=$(stat -c%s "$DIR/$tdir")
13246         local nfiles=0
13247         while (( $dirsize <= $maxsize )); do
13248                 $MCREATE $DIR/$tdir/file_base_$nfiles
13249                 rc=$?
13250                 # check two errors:
13251                 # ENOSPC for ext4 max_dir_size, which has been used since
13252                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13253                 if (( rc == ENOSPC )); then
13254                         set_dir_limits 0 0
13255                         echo "rc=$rc returned as expected after $nfiles files"
13256
13257                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13258                                 error "create failed w/o dir size limit"
13259
13260                         # messages may be rate limited if test is run repeatedly
13261                         check_mds_dmesg '"is approaching max"' ||
13262                                 echo "warning message should be output"
13263                         check_mds_dmesg '"has reached max"' ||
13264                                 echo "reached message should be output"
13265
13266                         dirsize=$(stat -c%s "$DIR/$tdir")
13267
13268                         [[ $dirsize -ge $maxsize ]] && return 0
13269                         error "dirsize $dirsize < $maxsize after $nfiles files"
13270                 elif (( rc != 0 )); then
13271                         break
13272                 fi
13273                 nfiles=$((nfiles + 1))
13274                 dirsize=$(stat -c%s "$DIR/$tdir")
13275         done
13276
13277         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13278 }
13279 run_test 129 "test directory size limit ========================"
13280
13281 OLDIFS="$IFS"
13282 cleanup_130() {
13283         trap 0
13284         IFS="$OLDIFS"
13285 }
13286
13287 test_130a() {
13288         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13289         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13290
13291         trap cleanup_130 EXIT RETURN
13292
13293         local fm_file=$DIR/$tfile
13294         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13295         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13296                 error "dd failed for $fm_file"
13297
13298         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13299         filefrag -ves $fm_file
13300         RC=$?
13301         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13302                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13303         [ $RC != 0 ] && error "filefrag $fm_file failed"
13304
13305         filefrag_op=$(filefrag -ve -k $fm_file |
13306                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13307         lun=$($LFS getstripe -i $fm_file)
13308
13309         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13310         IFS=$'\n'
13311         tot_len=0
13312         for line in $filefrag_op
13313         do
13314                 frag_lun=`echo $line | cut -d: -f5`
13315                 ext_len=`echo $line | cut -d: -f4`
13316                 if (( $frag_lun != $lun )); then
13317                         cleanup_130
13318                         error "FIEMAP on 1-stripe file($fm_file) failed"
13319                         return
13320                 fi
13321                 (( tot_len += ext_len ))
13322         done
13323
13324         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13325                 cleanup_130
13326                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13327                 return
13328         fi
13329
13330         cleanup_130
13331
13332         echo "FIEMAP on single striped file succeeded"
13333 }
13334 run_test 130a "FIEMAP (1-stripe file)"
13335
13336 test_130b() {
13337         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13338
13339         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13340         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13341
13342         trap cleanup_130 EXIT RETURN
13343
13344         local fm_file=$DIR/$tfile
13345         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13346                         error "setstripe on $fm_file"
13347         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13348                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13349
13350         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13351                 error "dd failed on $fm_file"
13352
13353         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13354         filefrag_op=$(filefrag -ve -k $fm_file |
13355                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13356
13357         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13358                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13359
13360         IFS=$'\n'
13361         tot_len=0
13362         num_luns=1
13363         for line in $filefrag_op
13364         do
13365                 frag_lun=$(echo $line | cut -d: -f5 |
13366                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13367                 ext_len=$(echo $line | cut -d: -f4)
13368                 if (( $frag_lun != $last_lun )); then
13369                         if (( tot_len != 1024 )); then
13370                                 cleanup_130
13371                                 error "FIEMAP on $fm_file failed; returned " \
13372                                 "len $tot_len for OST $last_lun instead of 1024"
13373                                 return
13374                         else
13375                                 (( num_luns += 1 ))
13376                                 tot_len=0
13377                         fi
13378                 fi
13379                 (( tot_len += ext_len ))
13380                 last_lun=$frag_lun
13381         done
13382         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13383                 cleanup_130
13384                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13385                         "luns or wrong len for OST $last_lun"
13386                 return
13387         fi
13388
13389         cleanup_130
13390
13391         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13392 }
13393 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13394
13395 test_130c() {
13396         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13397
13398         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13399         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13400
13401         trap cleanup_130 EXIT RETURN
13402
13403         local fm_file=$DIR/$tfile
13404         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13405         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13406                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13407
13408         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13409                         error "dd failed on $fm_file"
13410
13411         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13412         filefrag_op=$(filefrag -ve -k $fm_file |
13413                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13414
13415         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13416                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13417
13418         IFS=$'\n'
13419         tot_len=0
13420         num_luns=1
13421         for line in $filefrag_op
13422         do
13423                 frag_lun=$(echo $line | cut -d: -f5 |
13424                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13425                 ext_len=$(echo $line | cut -d: -f4)
13426                 if (( $frag_lun != $last_lun )); then
13427                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13428                         if (( logical != 512 )); then
13429                                 cleanup_130
13430                                 error "FIEMAP on $fm_file failed; returned " \
13431                                 "logical start for lun $logical instead of 512"
13432                                 return
13433                         fi
13434                         if (( tot_len != 512 )); then
13435                                 cleanup_130
13436                                 error "FIEMAP on $fm_file failed; returned " \
13437                                 "len $tot_len for OST $last_lun instead of 1024"
13438                                 return
13439                         else
13440                                 (( num_luns += 1 ))
13441                                 tot_len=0
13442                         fi
13443                 fi
13444                 (( tot_len += ext_len ))
13445                 last_lun=$frag_lun
13446         done
13447         if (( num_luns != 2 || tot_len != 512 )); then
13448                 cleanup_130
13449                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13450                         "luns or wrong len for OST $last_lun"
13451                 return
13452         fi
13453
13454         cleanup_130
13455
13456         echo "FIEMAP on 2-stripe file with hole succeeded"
13457 }
13458 run_test 130c "FIEMAP (2-stripe file with hole)"
13459
13460 test_130d() {
13461         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13462
13463         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13464         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13465
13466         trap cleanup_130 EXIT RETURN
13467
13468         local fm_file=$DIR/$tfile
13469         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13470                         error "setstripe on $fm_file"
13471         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13472                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13473
13474         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13475         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13476                 error "dd failed on $fm_file"
13477
13478         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13479         filefrag_op=$(filefrag -ve -k $fm_file |
13480                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13481
13482         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13483                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13484
13485         IFS=$'\n'
13486         tot_len=0
13487         num_luns=1
13488         for line in $filefrag_op
13489         do
13490                 frag_lun=$(echo $line | cut -d: -f5 |
13491                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13492                 ext_len=$(echo $line | cut -d: -f4)
13493                 if (( $frag_lun != $last_lun )); then
13494                         if (( tot_len != 1024 )); then
13495                                 cleanup_130
13496                                 error "FIEMAP on $fm_file failed; returned " \
13497                                 "len $tot_len for OST $last_lun instead of 1024"
13498                                 return
13499                         else
13500                                 (( num_luns += 1 ))
13501                                 tot_len=0
13502                         fi
13503                 fi
13504                 (( tot_len += ext_len ))
13505                 last_lun=$frag_lun
13506         done
13507         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13508                 cleanup_130
13509                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13510                         "luns or wrong len for OST $last_lun"
13511                 return
13512         fi
13513
13514         cleanup_130
13515
13516         echo "FIEMAP on N-stripe file succeeded"
13517 }
13518 run_test 130d "FIEMAP (N-stripe file)"
13519
13520 test_130e() {
13521         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13522
13523         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13524         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13525
13526         trap cleanup_130 EXIT RETURN
13527
13528         local fm_file=$DIR/$tfile
13529         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13530
13531         NUM_BLKS=512
13532         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13533         for ((i = 0; i < $NUM_BLKS; i++)); do
13534                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13535                         conv=notrunc > /dev/null 2>&1
13536         done
13537
13538         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13539         filefrag_op=$(filefrag -ve -k $fm_file |
13540                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13541
13542         last_lun=$(echo $filefrag_op | cut -d: -f5)
13543
13544         IFS=$'\n'
13545         tot_len=0
13546         num_luns=1
13547         for line in $filefrag_op; do
13548                 frag_lun=$(echo $line | cut -d: -f5)
13549                 ext_len=$(echo $line | cut -d: -f4)
13550                 if [[ "$frag_lun" != "$last_lun" ]]; then
13551                         if (( tot_len != $EXPECTED_LEN )); then
13552                                 cleanup_130
13553                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13554                         else
13555                                 (( num_luns += 1 ))
13556                                 tot_len=0
13557                         fi
13558                 fi
13559                 (( tot_len += ext_len ))
13560                 last_lun=$frag_lun
13561         done
13562         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13563                 cleanup_130
13564                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13565         fi
13566
13567         echo "FIEMAP with continuation calls succeeded"
13568 }
13569 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13570
13571 test_130f() {
13572         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13573         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13574
13575         local fm_file=$DIR/$tfile
13576         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13577                 error "multiop create with lov_delay_create on $fm_file"
13578
13579         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13580         filefrag_extents=$(filefrag -vek $fm_file |
13581                            awk '/extents? found/ { print $2 }')
13582         if [[ "$filefrag_extents" != "0" ]]; then
13583                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13584         fi
13585
13586         rm -f $fm_file
13587 }
13588 run_test 130f "FIEMAP (unstriped file)"
13589
13590 test_130g() {
13591         local file=$DIR/$tfile
13592         local nr=$((OSTCOUNT * 100))
13593
13594         $LFS setstripe -C $nr $file ||
13595                 error "failed to setstripe -C $nr $file"
13596
13597         dd if=/dev/zero of=$file count=$nr bs=1M
13598         sync
13599         nr=$($LFS getstripe -c $file)
13600
13601         local extents=$(filefrag -v $file |
13602                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13603
13604         echo "filefrag list $extents extents in file with stripecount $nr"
13605         if (( extents < nr )); then
13606                 $LFS getstripe $file
13607                 filefrag -v $file
13608                 error "filefrag printed $extents < $nr extents"
13609         fi
13610
13611         rm -f $file
13612 }
13613 run_test 130g "FIEMAP (overstripe file)"
13614
13615 # Test for writev/readv
13616 test_131a() {
13617         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13618                 error "writev test failed"
13619         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13620                 error "readv failed"
13621         rm -f $DIR/$tfile
13622 }
13623 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13624
13625 test_131b() {
13626         local fsize=$((524288 + 1048576 + 1572864))
13627         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13628                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13629                         error "append writev test failed"
13630
13631         ((fsize += 1572864 + 1048576))
13632         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13633                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13634                         error "append writev test failed"
13635         rm -f $DIR/$tfile
13636 }
13637 run_test 131b "test append writev"
13638
13639 test_131c() {
13640         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13641         error "NOT PASS"
13642 }
13643 run_test 131c "test read/write on file w/o objects"
13644
13645 test_131d() {
13646         rwv -f $DIR/$tfile -w -n 1 1572864
13647         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13648         if [ "$NOB" != 1572864 ]; then
13649                 error "Short read filed: read $NOB bytes instead of 1572864"
13650         fi
13651         rm -f $DIR/$tfile
13652 }
13653 run_test 131d "test short read"
13654
13655 test_131e() {
13656         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13657         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13658         error "read hitting hole failed"
13659         rm -f $DIR/$tfile
13660 }
13661 run_test 131e "test read hitting hole"
13662
13663 check_stats() {
13664         local facet=$1
13665         local op=$2
13666         local want=${3:-0}
13667         local res
13668
13669         case $facet in
13670         mds*) res=$(do_facet $facet \
13671                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13672                  ;;
13673         ost*) res=$(do_facet $facet \
13674                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13675                  ;;
13676         *) error "Wrong facet '$facet'" ;;
13677         esac
13678         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13679         # if the argument $3 is zero, it means any stat increment is ok.
13680         if [[ $want -gt 0 ]]; then
13681                 local count=$(echo $res | awk '{ print $2 }')
13682                 [[ $count -ne $want ]] &&
13683                         error "The $op counter on $facet is $count, not $want"
13684         fi
13685 }
13686
13687 test_133a() {
13688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13689         remote_ost_nodsh && skip "remote OST with nodsh"
13690         remote_mds_nodsh && skip "remote MDS with nodsh"
13691         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13692                 skip_env "MDS doesn't support rename stats"
13693
13694         local testdir=$DIR/${tdir}/stats_testdir
13695
13696         mkdir -p $DIR/${tdir}
13697
13698         # clear stats.
13699         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13700         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13701
13702         # verify mdt stats first.
13703         mkdir ${testdir} || error "mkdir failed"
13704         check_stats $SINGLEMDS "mkdir" 1
13705         touch ${testdir}/${tfile} || error "touch failed"
13706         check_stats $SINGLEMDS "open" 1
13707         check_stats $SINGLEMDS "close" 1
13708         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13709                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13710                 check_stats $SINGLEMDS "mknod" 2
13711         }
13712         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13713         check_stats $SINGLEMDS "unlink" 1
13714         rm -f ${testdir}/${tfile} || error "file remove failed"
13715         check_stats $SINGLEMDS "unlink" 2
13716
13717         # remove working dir and check mdt stats again.
13718         rmdir ${testdir} || error "rmdir failed"
13719         check_stats $SINGLEMDS "rmdir" 1
13720
13721         local testdir1=$DIR/${tdir}/stats_testdir1
13722         mkdir -p ${testdir}
13723         mkdir -p ${testdir1}
13724         touch ${testdir1}/test1
13725         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13726         check_stats $SINGLEMDS "crossdir_rename" 1
13727
13728         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13729         check_stats $SINGLEMDS "samedir_rename" 1
13730
13731         rm -rf $DIR/${tdir}
13732 }
13733 run_test 133a "Verifying MDT stats ========================================"
13734
13735 test_133b() {
13736         local res
13737
13738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13739         remote_ost_nodsh && skip "remote OST with nodsh"
13740         remote_mds_nodsh && skip "remote MDS with nodsh"
13741
13742         local testdir=$DIR/${tdir}/stats_testdir
13743
13744         mkdir -p ${testdir} || error "mkdir failed"
13745         touch ${testdir}/${tfile} || error "touch failed"
13746         cancel_lru_locks mdc
13747
13748         # clear stats.
13749         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13750         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13751
13752         # extra mdt stats verification.
13753         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13754         check_stats $SINGLEMDS "setattr" 1
13755         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13756         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13757         then            # LU-1740
13758                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13759                 check_stats $SINGLEMDS "getattr" 1
13760         fi
13761         rm -rf $DIR/${tdir}
13762
13763         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13764         # so the check below is not reliable
13765         [ $MDSCOUNT -eq 1 ] || return 0
13766
13767         # Sleep to avoid a cached response.
13768         #define OBD_STATFS_CACHE_SECONDS 1
13769         sleep 2
13770         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13771         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13772         $LFS df || error "lfs failed"
13773         check_stats $SINGLEMDS "statfs" 1
13774
13775         # check aggregated statfs (LU-10018)
13776         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13777                 return 0
13778         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13779                 return 0
13780         sleep 2
13781         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13782         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13783         df $DIR
13784         check_stats $SINGLEMDS "statfs" 1
13785
13786         # We want to check that the client didn't send OST_STATFS to
13787         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13788         # extra care is needed here.
13789         if remote_mds; then
13790                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13791                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13792
13793                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13794                 [ "$res" ] && error "OST got STATFS"
13795         fi
13796
13797         return 0
13798 }
13799 run_test 133b "Verifying extra MDT stats =================================="
13800
13801 test_133c() {
13802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13803         remote_ost_nodsh && skip "remote OST with nodsh"
13804         remote_mds_nodsh && skip "remote MDS with nodsh"
13805
13806         local testdir=$DIR/$tdir/stats_testdir
13807
13808         test_mkdir -p $testdir
13809
13810         # verify obdfilter stats.
13811         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13812         sync
13813         cancel_lru_locks osc
13814         wait_delete_completed
13815
13816         # clear stats.
13817         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13818         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13819
13820         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13821                 error "dd failed"
13822         sync
13823         cancel_lru_locks osc
13824         check_stats ost1 "write" 1
13825
13826         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13827         check_stats ost1 "read" 1
13828
13829         > $testdir/$tfile || error "truncate failed"
13830         check_stats ost1 "punch" 1
13831
13832         rm -f $testdir/$tfile || error "file remove failed"
13833         wait_delete_completed
13834         check_stats ost1 "destroy" 1
13835
13836         rm -rf $DIR/$tdir
13837 }
13838 run_test 133c "Verifying OST stats ========================================"
13839
13840 order_2() {
13841         local value=$1
13842         local orig=$value
13843         local order=1
13844
13845         while [ $value -ge 2 ]; do
13846                 order=$((order*2))
13847                 value=$((value/2))
13848         done
13849
13850         if [ $orig -gt $order ]; then
13851                 order=$((order*2))
13852         fi
13853         echo $order
13854 }
13855
13856 size_in_KMGT() {
13857     local value=$1
13858     local size=('K' 'M' 'G' 'T');
13859     local i=0
13860     local size_string=$value
13861
13862     while [ $value -ge 1024 ]; do
13863         if [ $i -gt 3 ]; then
13864             #T is the biggest unit we get here, if that is bigger,
13865             #just return XXXT
13866             size_string=${value}T
13867             break
13868         fi
13869         value=$((value >> 10))
13870         if [ $value -lt 1024 ]; then
13871             size_string=${value}${size[$i]}
13872             break
13873         fi
13874         i=$((i + 1))
13875     done
13876
13877     echo $size_string
13878 }
13879
13880 get_rename_size() {
13881         local size=$1
13882         local context=${2:-.}
13883         local sample=$(do_facet $SINGLEMDS $LCTL \
13884                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13885                 grep -A1 $context |
13886                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13887         echo $sample
13888 }
13889
13890 test_133d() {
13891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13892         remote_ost_nodsh && skip "remote OST with nodsh"
13893         remote_mds_nodsh && skip "remote MDS with nodsh"
13894         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13895                 skip_env "MDS doesn't support rename stats"
13896
13897         local testdir1=$DIR/${tdir}/stats_testdir1
13898         local testdir2=$DIR/${tdir}/stats_testdir2
13899         mkdir -p $DIR/${tdir}
13900
13901         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13902
13903         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13904         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13905
13906         createmany -o $testdir1/test 512 || error "createmany failed"
13907
13908         # check samedir rename size
13909         mv ${testdir1}/test0 ${testdir1}/test_0
13910
13911         local testdir1_size=$(ls -l $DIR/${tdir} |
13912                 awk '/stats_testdir1/ {print $5}')
13913         local testdir2_size=$(ls -l $DIR/${tdir} |
13914                 awk '/stats_testdir2/ {print $5}')
13915
13916         testdir1_size=$(order_2 $testdir1_size)
13917         testdir2_size=$(order_2 $testdir2_size)
13918
13919         testdir1_size=$(size_in_KMGT $testdir1_size)
13920         testdir2_size=$(size_in_KMGT $testdir2_size)
13921
13922         echo "source rename dir size: ${testdir1_size}"
13923         echo "target rename dir size: ${testdir2_size}"
13924
13925         local cmd="do_facet $SINGLEMDS $LCTL "
13926         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13927
13928         eval $cmd || error "$cmd failed"
13929         local samedir=$($cmd | grep 'same_dir')
13930         local same_sample=$(get_rename_size $testdir1_size)
13931         [ -z "$samedir" ] && error "samedir_rename_size count error"
13932         [[ $same_sample -eq 1 ]] ||
13933                 error "samedir_rename_size error $same_sample"
13934         echo "Check same dir rename stats success"
13935
13936         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13937
13938         # check crossdir rename size
13939         mv ${testdir1}/test_0 ${testdir2}/test_0
13940
13941         testdir1_size=$(ls -l $DIR/${tdir} |
13942                 awk '/stats_testdir1/ {print $5}')
13943         testdir2_size=$(ls -l $DIR/${tdir} |
13944                 awk '/stats_testdir2/ {print $5}')
13945
13946         testdir1_size=$(order_2 $testdir1_size)
13947         testdir2_size=$(order_2 $testdir2_size)
13948
13949         testdir1_size=$(size_in_KMGT $testdir1_size)
13950         testdir2_size=$(size_in_KMGT $testdir2_size)
13951
13952         echo "source rename dir size: ${testdir1_size}"
13953         echo "target rename dir size: ${testdir2_size}"
13954
13955         eval $cmd || error "$cmd failed"
13956         local crossdir=$($cmd | grep 'crossdir')
13957         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13958         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13959         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13960         [[ $src_sample -eq 1 ]] ||
13961                 error "crossdir_rename_size error $src_sample"
13962         [[ $tgt_sample -eq 1 ]] ||
13963                 error "crossdir_rename_size error $tgt_sample"
13964         echo "Check cross dir rename stats success"
13965         rm -rf $DIR/${tdir}
13966 }
13967 run_test 133d "Verifying rename_stats ========================================"
13968
13969 test_133e() {
13970         remote_mds_nodsh && skip "remote MDS with nodsh"
13971         remote_ost_nodsh && skip "remote OST with nodsh"
13972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13973
13974         local testdir=$DIR/${tdir}/stats_testdir
13975         local ctr f0 f1 bs=32768 count=42 sum
13976
13977         mkdir -p ${testdir} || error "mkdir failed"
13978
13979         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13980
13981         for ctr in {write,read}_bytes; do
13982                 sync
13983                 cancel_lru_locks osc
13984
13985                 do_facet ost1 $LCTL set_param -n \
13986                         "obdfilter.*.exports.clear=clear"
13987
13988                 if [ $ctr = write_bytes ]; then
13989                         f0=/dev/zero
13990                         f1=${testdir}/${tfile}
13991                 else
13992                         f0=${testdir}/${tfile}
13993                         f1=/dev/null
13994                 fi
13995
13996                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13997                         error "dd failed"
13998                 sync
13999                 cancel_lru_locks osc
14000
14001                 sum=$(do_facet ost1 $LCTL get_param \
14002                         "obdfilter.*.exports.*.stats" |
14003                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14004                                 $1 == ctr { sum += $7 }
14005                                 END { printf("%0.0f", sum) }')
14006
14007                 if ((sum != bs * count)); then
14008                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14009                 fi
14010         done
14011
14012         rm -rf $DIR/${tdir}
14013 }
14014 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14015
14016 test_133f() {
14017         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14018                 skip "too old lustre for get_param -R ($facet_ver)"
14019
14020         # verifying readability.
14021         $LCTL get_param -R '*' &> /dev/null
14022
14023         # Verifing writability with badarea_io.
14024         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14025         local skipped_params='force_lbug|changelog_mask|daemon_file'
14026         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14027                 egrep -v "$skipped_params" |
14028                 xargs -n 1 find $proc_dirs -name |
14029                 xargs -n 1 badarea_io ||
14030                 error "client badarea_io failed"
14031
14032         # remount the FS in case writes/reads /proc break the FS
14033         cleanup || error "failed to unmount"
14034         setup || error "failed to setup"
14035 }
14036 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14037
14038 test_133g() {
14039         remote_mds_nodsh && skip "remote MDS with nodsh"
14040         remote_ost_nodsh && skip "remote OST with nodsh"
14041
14042         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14043         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14044         local facet
14045         for facet in mds1 ost1; do
14046                 local facet_ver=$(lustre_version_code $facet)
14047                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14048                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14049                 else
14050                         log "$facet: too old lustre for get_param -R"
14051                 fi
14052                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14053                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14054                                 tr -d = | egrep -v $skipped_params |
14055                                 xargs -n 1 find $proc_dirs -name |
14056                                 xargs -n 1 badarea_io" ||
14057                                         error "$facet badarea_io failed"
14058                 else
14059                         skip_noexit "$facet: too old lustre for get_param -R"
14060                 fi
14061         done
14062
14063         # remount the FS in case writes/reads /proc break the FS
14064         cleanup || error "failed to unmount"
14065         setup || error "failed to setup"
14066 }
14067 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14068
14069 test_133h() {
14070         remote_mds_nodsh && skip "remote MDS with nodsh"
14071         remote_ost_nodsh && skip "remote OST with nodsh"
14072         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14073                 skip "Need MDS version at least 2.9.54"
14074
14075         local facet
14076         for facet in client mds1 ost1; do
14077                 # Get the list of files that are missing the terminating newline
14078                 local plist=$(do_facet $facet
14079                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14080                 local ent
14081                 for ent in $plist; do
14082                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14083                                 awk -v FS='\v' -v RS='\v\v' \
14084                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14085                                         print FILENAME}'" 2>/dev/null)
14086                         [ -z $missing ] || {
14087                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14088                                 error "file does not end with newline: $facet-$ent"
14089                         }
14090                 done
14091         done
14092 }
14093 run_test 133h "Proc files should end with newlines"
14094
14095 test_134a() {
14096         remote_mds_nodsh && skip "remote MDS with nodsh"
14097         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14098                 skip "Need MDS version at least 2.7.54"
14099
14100         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14101         cancel_lru_locks mdc
14102
14103         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14104         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14105         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14106
14107         local nr=1000
14108         createmany -o $DIR/$tdir/f $nr ||
14109                 error "failed to create $nr files in $DIR/$tdir"
14110         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14111
14112         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14113         do_facet mds1 $LCTL set_param fail_loc=0x327
14114         do_facet mds1 $LCTL set_param fail_val=500
14115         touch $DIR/$tdir/m
14116
14117         echo "sleep 10 seconds ..."
14118         sleep 10
14119         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14120
14121         do_facet mds1 $LCTL set_param fail_loc=0
14122         do_facet mds1 $LCTL set_param fail_val=0
14123         [ $lck_cnt -lt $unused ] ||
14124                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14125
14126         rm $DIR/$tdir/m
14127         unlinkmany $DIR/$tdir/f $nr
14128 }
14129 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14130
14131 test_134b() {
14132         remote_mds_nodsh && skip "remote MDS with nodsh"
14133         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14134                 skip "Need MDS version at least 2.7.54"
14135
14136         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14137         cancel_lru_locks mdc
14138
14139         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14140                         ldlm.lock_reclaim_threshold_mb)
14141         # disable reclaim temporarily
14142         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14143
14144         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14145         do_facet mds1 $LCTL set_param fail_loc=0x328
14146         do_facet mds1 $LCTL set_param fail_val=500
14147
14148         $LCTL set_param debug=+trace
14149
14150         local nr=600
14151         createmany -o $DIR/$tdir/f $nr &
14152         local create_pid=$!
14153
14154         echo "Sleep $TIMEOUT seconds ..."
14155         sleep $TIMEOUT
14156         if ! ps -p $create_pid  > /dev/null 2>&1; then
14157                 do_facet mds1 $LCTL set_param fail_loc=0
14158                 do_facet mds1 $LCTL set_param fail_val=0
14159                 do_facet mds1 $LCTL set_param \
14160                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14161                 error "createmany finished incorrectly!"
14162         fi
14163         do_facet mds1 $LCTL set_param fail_loc=0
14164         do_facet mds1 $LCTL set_param fail_val=0
14165         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14166         wait $create_pid || return 1
14167
14168         unlinkmany $DIR/$tdir/f $nr
14169 }
14170 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14171
14172 test_135() {
14173         remote_mds_nodsh && skip "remote MDS with nodsh"
14174         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14175                 skip "Need MDS version at least 2.13.50"
14176         local fname
14177
14178         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14179
14180 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14181         #set only one record at plain llog
14182         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14183
14184         #fill already existed plain llog each 64767
14185         #wrapping whole catalog
14186         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14187
14188         createmany -o $DIR/$tdir/$tfile_ 64700
14189         for (( i = 0; i < 64700; i = i + 2 ))
14190         do
14191                 rm $DIR/$tdir/$tfile_$i &
14192                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14193                 local pid=$!
14194                 wait $pid
14195         done
14196
14197         #waiting osp synchronization
14198         wait_delete_completed
14199 }
14200 run_test 135 "Race catalog processing"
14201
14202 test_136() {
14203         remote_mds_nodsh && skip "remote MDS with nodsh"
14204         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14205                 skip "Need MDS version at least 2.13.50"
14206         local fname
14207
14208         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14209         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14210         #set only one record at plain llog
14211 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14212         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14213
14214         #fill already existed 2 plain llogs each 64767
14215         #wrapping whole catalog
14216         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14217         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14218         wait_delete_completed
14219
14220         createmany -o $DIR/$tdir/$tfile_ 10
14221         sleep 25
14222
14223         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14224         for (( i = 0; i < 10; i = i + 3 ))
14225         do
14226                 rm $DIR/$tdir/$tfile_$i &
14227                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14228                 local pid=$!
14229                 wait $pid
14230                 sleep 7
14231                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14232         done
14233
14234         #waiting osp synchronization
14235         wait_delete_completed
14236 }
14237 run_test 136 "Race catalog processing 2"
14238
14239 test_140() { #bug-17379
14240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14241
14242         test_mkdir $DIR/$tdir
14243         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14244         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14245
14246         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14247         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14248         local i=0
14249         while i=$((i + 1)); do
14250                 test_mkdir $i
14251                 cd $i || error "Changing to $i"
14252                 ln -s ../stat stat || error "Creating stat symlink"
14253                 # Read the symlink until ELOOP present,
14254                 # not LBUGing the system is considered success,
14255                 # we didn't overrun the stack.
14256                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14257                 if [ $ret -ne 0 ]; then
14258                         if [ $ret -eq 40 ]; then
14259                                 break  # -ELOOP
14260                         else
14261                                 error "Open stat symlink"
14262                                         return
14263                         fi
14264                 fi
14265         done
14266         i=$((i - 1))
14267         echo "The symlink depth = $i"
14268         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14269                 error "Invalid symlink depth"
14270
14271         # Test recursive symlink
14272         ln -s symlink_self symlink_self
14273         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14274         echo "open symlink_self returns $ret"
14275         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14276 }
14277 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14278
14279 test_150a() {
14280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14281
14282         local TF="$TMP/$tfile"
14283
14284         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14285         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14286         cp $TF $DIR/$tfile
14287         cancel_lru_locks $OSC
14288         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14289         remount_client $MOUNT
14290         df -P $MOUNT
14291         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14292
14293         $TRUNCATE $TF 6000
14294         $TRUNCATE $DIR/$tfile 6000
14295         cancel_lru_locks $OSC
14296         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14297
14298         echo "12345" >>$TF
14299         echo "12345" >>$DIR/$tfile
14300         cancel_lru_locks $OSC
14301         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14302
14303         echo "12345" >>$TF
14304         echo "12345" >>$DIR/$tfile
14305         cancel_lru_locks $OSC
14306         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14307 }
14308 run_test 150a "truncate/append tests"
14309
14310 test_150b() {
14311         check_set_fallocate_or_skip
14312
14313         touch $DIR/$tfile
14314         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14315         check_fallocate $DIR/$tfile || error "fallocate failed"
14316 }
14317 run_test 150b "Verify fallocate (prealloc) functionality"
14318
14319 test_150bb() {
14320         check_set_fallocate_or_skip
14321
14322         touch $DIR/$tfile
14323         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14324         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14325         > $DIR/$tfile
14326         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14327         # precomputed md5sum for 20MB of zeroes
14328         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14329         local sum=($(md5sum $DIR/$tfile))
14330
14331         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14332
14333         check_set_fallocate 1
14334
14335         > $DIR/$tfile
14336         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14337         sum=($(md5sum $DIR/$tfile))
14338
14339         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14340 }
14341 run_test 150bb "Verify fallocate modes both zero space"
14342
14343 test_150c() {
14344         check_set_fallocate_or_skip
14345         local striping="-c2"
14346
14347         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14348         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14349         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14350         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14351         local want=$((OSTCOUNT * 1048576))
14352
14353         # Must allocate all requested space, not more than 5% extra
14354         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14355                 error "bytes $bytes is not $want"
14356
14357         rm -f $DIR/$tfile
14358
14359         echo "verify fallocate on PFL file"
14360
14361         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14362
14363         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14364                 error "Create $DIR/$tfile failed"
14365         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14366                         error "fallocate failed"
14367         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14368         want=$((512 * 1048576))
14369
14370         # Must allocate all requested space, not more than 5% extra
14371         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14372                 error "bytes $bytes is not $want"
14373 }
14374 run_test 150c "Verify fallocate Size and Blocks"
14375
14376 test_150d() {
14377         check_set_fallocate_or_skip
14378         local striping="-c2"
14379
14380         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14381
14382         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14383         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14384                 error "setstripe failed"
14385         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14386         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14387         local want=$((OSTCOUNT * 1048576))
14388
14389         # Must allocate all requested space, not more than 5% extra
14390         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14391                 error "bytes $bytes is not $want"
14392 }
14393 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14394
14395 test_150e() {
14396         check_set_fallocate_or_skip
14397
14398         echo "df before:"
14399         $LFS df
14400         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14401         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14402                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14403
14404         # Find OST with Minimum Size
14405         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14406                        sort -un | head -1)
14407
14408         # Get 100MB per OST of the available space to reduce run time
14409         # else 60% of the available space if we are running SLOW tests
14410         if [ $SLOW == "no" ]; then
14411                 local space=$((1024 * 100 * OSTCOUNT))
14412         else
14413                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14414         fi
14415
14416         fallocate -l${space}k $DIR/$tfile ||
14417                 error "fallocate ${space}k $DIR/$tfile failed"
14418         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14419
14420         # get size immediately after fallocate. This should be correctly
14421         # updated
14422         local size=$(stat -c '%s' $DIR/$tfile)
14423         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14424
14425         # Sleep for a while for statfs to get updated. And not pull from cache.
14426         sleep 2
14427
14428         echo "df after fallocate:"
14429         $LFS df
14430
14431         (( size / 1024 == space )) || error "size $size != requested $space"
14432         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14433                 error "used $used < space $space"
14434
14435         rm $DIR/$tfile || error "rm failed"
14436         sync
14437         wait_delete_completed
14438
14439         echo "df after unlink:"
14440         $LFS df
14441 }
14442 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14443
14444 test_150f() {
14445         local size
14446         local blocks
14447         local want_size_before=20480 # in bytes
14448         local want_blocks_before=40 # 512 sized blocks
14449         local want_blocks_after=24  # 512 sized blocks
14450         local length=$(((want_blocks_before - want_blocks_after) * 512))
14451
14452         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14453                 skip "need at least 2.14.0 for fallocate punch"
14454
14455         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14456                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14457         fi
14458
14459         check_set_fallocate_or_skip
14460         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14461
14462         [[ "x$DOM" == "xyes" ]] &&
14463                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14464
14465         echo "Verify fallocate punch: Range within the file range"
14466         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14467                 error "dd failed for bs 4096 and count 5"
14468
14469         # Call fallocate with punch range which is within the file range
14470         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14471                 error "fallocate failed: offset 4096 and length $length"
14472         # client must see changes immediately after fallocate
14473         size=$(stat -c '%s' $DIR/$tfile)
14474         blocks=$(stat -c '%b' $DIR/$tfile)
14475
14476         # Verify punch worked.
14477         (( blocks == want_blocks_after )) ||
14478                 error "punch failed: blocks $blocks != $want_blocks_after"
14479
14480         (( size == want_size_before )) ||
14481                 error "punch failed: size $size != $want_size_before"
14482
14483         # Verify there is hole in file
14484         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14485         # precomputed md5sum
14486         local expect="4a9a834a2db02452929c0a348273b4aa"
14487
14488         cksum=($(md5sum $DIR/$tfile))
14489         [[ "${cksum[0]}" == "$expect" ]] ||
14490                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14491
14492         # Start second sub-case for fallocate punch.
14493         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14494         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14495                 error "dd failed for bs 4096 and count 5"
14496
14497         # Punch range less than block size will have no change in block count
14498         want_blocks_after=40  # 512 sized blocks
14499
14500         # Punch overlaps two blocks and less than blocksize
14501         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14502                 error "fallocate failed: offset 4000 length 3000"
14503         size=$(stat -c '%s' $DIR/$tfile)
14504         blocks=$(stat -c '%b' $DIR/$tfile)
14505
14506         # Verify punch worked.
14507         (( blocks == want_blocks_after )) ||
14508                 error "punch failed: blocks $blocks != $want_blocks_after"
14509
14510         (( size == want_size_before )) ||
14511                 error "punch failed: size $size != $want_size_before"
14512
14513         # Verify if range is really zero'ed out. We expect Zeros.
14514         # precomputed md5sum
14515         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14516         cksum=($(md5sum $DIR/$tfile))
14517         [[ "${cksum[0]}" == "$expect" ]] ||
14518                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14519 }
14520 run_test 150f "Verify fallocate punch functionality"
14521
14522 test_150g() {
14523         local space
14524         local size
14525         local blocks
14526         local blocks_after
14527         local size_after
14528         local BS=4096 # Block size in bytes
14529
14530         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14531                 skip "need at least 2.14.0 for fallocate punch"
14532
14533         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14534                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14535         fi
14536
14537         check_set_fallocate_or_skip
14538         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14539
14540         if [[ "x$DOM" == "xyes" ]]; then
14541                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14542                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14543         else
14544                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14545                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14546         fi
14547
14548         # Get 100MB per OST of the available space to reduce run time
14549         # else 60% of the available space if we are running SLOW tests
14550         if [ $SLOW == "no" ]; then
14551                 space=$((1024 * 100 * OSTCOUNT))
14552         else
14553                 # Find OST with Minimum Size
14554                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14555                         sort -un | head -1)
14556                 echo "min size OST: $space"
14557                 space=$(((space * 60)/100 * OSTCOUNT))
14558         fi
14559         # space in 1k units, round to 4k blocks
14560         local blkcount=$((space * 1024 / $BS))
14561
14562         echo "Verify fallocate punch: Very large Range"
14563         fallocate -l${space}k $DIR/$tfile ||
14564                 error "fallocate ${space}k $DIR/$tfile failed"
14565         # write 1M at the end, start and in the middle
14566         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14567                 error "dd failed: bs $BS count 256"
14568         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14569                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14570         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14571                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14572
14573         # Gather stats.
14574         size=$(stat -c '%s' $DIR/$tfile)
14575
14576         # gather punch length.
14577         local punch_size=$((size - (BS * 2)))
14578
14579         echo "punch_size = $punch_size"
14580         echo "size - punch_size: $((size - punch_size))"
14581         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14582
14583         # Call fallocate to punch all except 2 blocks. We leave the
14584         # first and the last block
14585         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14586         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14587                 error "fallocate failed: offset $BS length $punch_size"
14588
14589         size_after=$(stat -c '%s' $DIR/$tfile)
14590         blocks_after=$(stat -c '%b' $DIR/$tfile)
14591
14592         # Verify punch worked.
14593         # Size should be kept
14594         (( size == size_after )) ||
14595                 error "punch failed: size $size != $size_after"
14596
14597         # two 4k data blocks to remain plus possible 1 extra extent block
14598         (( blocks_after <= ((BS / 512) * 3) )) ||
14599                 error "too many blocks remains: $blocks_after"
14600
14601         # Verify that file has hole between the first and the last blocks
14602         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14603         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14604
14605         echo "Hole at [$hole_start, $hole_end)"
14606         (( hole_start == BS )) ||
14607                 error "no hole at offset $BS after punch"
14608
14609         (( hole_end == BS + punch_size )) ||
14610                 error "data at offset $hole_end < $((BS + punch_size))"
14611 }
14612 run_test 150g "Verify fallocate punch on large range"
14613
14614 #LU-2902 roc_hit was not able to read all values from lproc
14615 function roc_hit_init() {
14616         local list=$(comma_list $(osts_nodes))
14617         local dir=$DIR/$tdir-check
14618         local file=$dir/$tfile
14619         local BEFORE
14620         local AFTER
14621         local idx
14622
14623         test_mkdir $dir
14624         #use setstripe to do a write to every ost
14625         for i in $(seq 0 $((OSTCOUNT-1))); do
14626                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14627                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14628                 idx=$(printf %04x $i)
14629                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14630                         awk '$1 == "cache_access" {sum += $7}
14631                                 END { printf("%0.0f", sum) }')
14632
14633                 cancel_lru_locks osc
14634                 cat $file >/dev/null
14635
14636                 AFTER=$(get_osd_param $list *OST*$idx stats |
14637                         awk '$1 == "cache_access" {sum += $7}
14638                                 END { printf("%0.0f", sum) }')
14639
14640                 echo BEFORE:$BEFORE AFTER:$AFTER
14641                 if ! let "AFTER - BEFORE == 4"; then
14642                         rm -rf $dir
14643                         error "roc_hit is not safe to use"
14644                 fi
14645                 rm $file
14646         done
14647
14648         rm -rf $dir
14649 }
14650
14651 function roc_hit() {
14652         local list=$(comma_list $(osts_nodes))
14653         echo $(get_osd_param $list '' stats |
14654                 awk '$1 == "cache_hit" {sum += $7}
14655                         END { printf("%0.0f", sum) }')
14656 }
14657
14658 function set_cache() {
14659         local on=1
14660
14661         if [ "$2" == "off" ]; then
14662                 on=0;
14663         fi
14664         local list=$(comma_list $(osts_nodes))
14665         set_osd_param $list '' $1_cache_enable $on
14666
14667         cancel_lru_locks osc
14668 }
14669
14670 test_151() {
14671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14672         remote_ost_nodsh && skip "remote OST with nodsh"
14673
14674         local CPAGES=3
14675         local list=$(comma_list $(osts_nodes))
14676
14677         # check whether obdfilter is cache capable at all
14678         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14679                 skip "not cache-capable obdfilter"
14680         fi
14681
14682         # check cache is enabled on all obdfilters
14683         if get_osd_param $list '' read_cache_enable | grep 0; then
14684                 skip "oss cache is disabled"
14685         fi
14686
14687         set_osd_param $list '' writethrough_cache_enable 1
14688
14689         # check write cache is enabled on all obdfilters
14690         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14691                 skip "oss write cache is NOT enabled"
14692         fi
14693
14694         roc_hit_init
14695
14696         #define OBD_FAIL_OBD_NO_LRU  0x609
14697         do_nodes $list $LCTL set_param fail_loc=0x609
14698
14699         # pages should be in the case right after write
14700         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14701                 error "dd failed"
14702
14703         local BEFORE=$(roc_hit)
14704         cancel_lru_locks osc
14705         cat $DIR/$tfile >/dev/null
14706         local AFTER=$(roc_hit)
14707
14708         do_nodes $list $LCTL set_param fail_loc=0
14709
14710         if ! let "AFTER - BEFORE == CPAGES"; then
14711                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14712         fi
14713
14714         cancel_lru_locks osc
14715         # invalidates OST cache
14716         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14717         set_osd_param $list '' read_cache_enable 0
14718         cat $DIR/$tfile >/dev/null
14719
14720         # now data shouldn't be found in the cache
14721         BEFORE=$(roc_hit)
14722         cancel_lru_locks osc
14723         cat $DIR/$tfile >/dev/null
14724         AFTER=$(roc_hit)
14725         if let "AFTER - BEFORE != 0"; then
14726                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14727         fi
14728
14729         set_osd_param $list '' read_cache_enable 1
14730         rm -f $DIR/$tfile
14731 }
14732 run_test 151 "test cache on oss and controls ==============================="
14733
14734 test_152() {
14735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14736
14737         local TF="$TMP/$tfile"
14738
14739         # simulate ENOMEM during write
14740 #define OBD_FAIL_OST_NOMEM      0x226
14741         lctl set_param fail_loc=0x80000226
14742         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14743         cp $TF $DIR/$tfile
14744         sync || error "sync failed"
14745         lctl set_param fail_loc=0
14746
14747         # discard client's cache
14748         cancel_lru_locks osc
14749
14750         # simulate ENOMEM during read
14751         lctl set_param fail_loc=0x80000226
14752         cmp $TF $DIR/$tfile || error "cmp failed"
14753         lctl set_param fail_loc=0
14754
14755         rm -f $TF
14756 }
14757 run_test 152 "test read/write with enomem ============================"
14758
14759 test_153() {
14760         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14761 }
14762 run_test 153 "test if fdatasync does not crash ======================="
14763
14764 dot_lustre_fid_permission_check() {
14765         local fid=$1
14766         local ffid=$MOUNT/.lustre/fid/$fid
14767         local test_dir=$2
14768
14769         echo "stat fid $fid"
14770         stat $ffid > /dev/null || error "stat $ffid failed."
14771         echo "touch fid $fid"
14772         touch $ffid || error "touch $ffid failed."
14773         echo "write to fid $fid"
14774         cat /etc/hosts > $ffid || error "write $ffid failed."
14775         echo "read fid $fid"
14776         diff /etc/hosts $ffid || error "read $ffid failed."
14777         echo "append write to fid $fid"
14778         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14779         echo "rename fid $fid"
14780         mv $ffid $test_dir/$tfile.1 &&
14781                 error "rename $ffid to $tfile.1 should fail."
14782         touch $test_dir/$tfile.1
14783         mv $test_dir/$tfile.1 $ffid &&
14784                 error "rename $tfile.1 to $ffid should fail."
14785         rm -f $test_dir/$tfile.1
14786         echo "truncate fid $fid"
14787         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14788         echo "link fid $fid"
14789         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14790         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14791                 echo "setfacl fid $fid"
14792                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14793                 echo "getfacl fid $fid"
14794                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14795         fi
14796         echo "unlink fid $fid"
14797         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14798         echo "mknod fid $fid"
14799         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14800
14801         fid=[0xf00000400:0x1:0x0]
14802         ffid=$MOUNT/.lustre/fid/$fid
14803
14804         echo "stat non-exist fid $fid"
14805         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14806         echo "write to non-exist fid $fid"
14807         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14808         echo "link new fid $fid"
14809         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14810
14811         mkdir -p $test_dir/$tdir
14812         touch $test_dir/$tdir/$tfile
14813         fid=$($LFS path2fid $test_dir/$tdir)
14814         rc=$?
14815         [ $rc -ne 0 ] &&
14816                 error "error: could not get fid for $test_dir/$dir/$tfile."
14817
14818         ffid=$MOUNT/.lustre/fid/$fid
14819
14820         echo "ls $fid"
14821         ls $ffid > /dev/null || error "ls $ffid failed."
14822         echo "touch $fid/$tfile.1"
14823         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14824
14825         echo "touch $MOUNT/.lustre/fid/$tfile"
14826         touch $MOUNT/.lustre/fid/$tfile && \
14827                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14828
14829         echo "setxattr to $MOUNT/.lustre/fid"
14830         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14831
14832         echo "listxattr for $MOUNT/.lustre/fid"
14833         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14834
14835         echo "delxattr from $MOUNT/.lustre/fid"
14836         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14837
14838         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14839         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14840                 error "touch invalid fid should fail."
14841
14842         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14843         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14844                 error "touch non-normal fid should fail."
14845
14846         echo "rename $tdir to $MOUNT/.lustre/fid"
14847         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14848                 error "rename to $MOUNT/.lustre/fid should fail."
14849
14850         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14851         then            # LU-3547
14852                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14853                 local new_obf_mode=777
14854
14855                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14856                 chmod $new_obf_mode $DIR/.lustre/fid ||
14857                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14858
14859                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14860                 [ $obf_mode -eq $new_obf_mode ] ||
14861                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14862
14863                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14864                 chmod $old_obf_mode $DIR/.lustre/fid ||
14865                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14866         fi
14867
14868         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14869         fid=$($LFS path2fid $test_dir/$tfile-2)
14870
14871         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14872         then # LU-5424
14873                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14874                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14875                         error "create lov data thru .lustre failed"
14876         fi
14877         echo "cp /etc/passwd $test_dir/$tfile-2"
14878         cp /etc/passwd $test_dir/$tfile-2 ||
14879                 error "copy to $test_dir/$tfile-2 failed."
14880         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14881         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14882                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14883
14884         rm -rf $test_dir/tfile.lnk
14885         rm -rf $test_dir/$tfile-2
14886 }
14887
14888 test_154A() {
14889         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14890                 skip "Need MDS version at least 2.4.1"
14891
14892         local tf=$DIR/$tfile
14893         touch $tf
14894
14895         local fid=$($LFS path2fid $tf)
14896         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14897
14898         # check that we get the same pathname back
14899         local rootpath
14900         local found
14901         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14902                 echo "$rootpath $fid"
14903                 found=$($LFS fid2path $rootpath "$fid")
14904                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14905                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14906         done
14907
14908         # check wrong root path format
14909         rootpath=$MOUNT"_wrong"
14910         found=$($LFS fid2path $rootpath "$fid")
14911         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14912 }
14913 run_test 154A "lfs path2fid and fid2path basic checks"
14914
14915 test_154B() {
14916         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14917                 skip "Need MDS version at least 2.4.1"
14918
14919         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14920         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14921         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14922         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14923
14924         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14925         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14926
14927         # check that we get the same pathname
14928         echo "PFID: $PFID, name: $name"
14929         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14930         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14931         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14932                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14933
14934         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14935 }
14936 run_test 154B "verify the ll_decode_linkea tool"
14937
14938 test_154a() {
14939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14940         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14941         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14942                 skip "Need MDS version at least 2.2.51"
14943         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14944
14945         cp /etc/hosts $DIR/$tfile
14946
14947         fid=$($LFS path2fid $DIR/$tfile)
14948         rc=$?
14949         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14950
14951         dot_lustre_fid_permission_check "$fid" $DIR ||
14952                 error "dot lustre permission check $fid failed"
14953
14954         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14955
14956         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14957
14958         touch $MOUNT/.lustre/file &&
14959                 error "creation is not allowed under .lustre"
14960
14961         mkdir $MOUNT/.lustre/dir &&
14962                 error "mkdir is not allowed under .lustre"
14963
14964         rm -rf $DIR/$tfile
14965 }
14966 run_test 154a "Open-by-FID"
14967
14968 test_154b() {
14969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14970         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14971         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14972         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14973                 skip "Need MDS version at least 2.2.51"
14974
14975         local remote_dir=$DIR/$tdir/remote_dir
14976         local MDTIDX=1
14977         local rc=0
14978
14979         mkdir -p $DIR/$tdir
14980         $LFS mkdir -i $MDTIDX $remote_dir ||
14981                 error "create remote directory failed"
14982
14983         cp /etc/hosts $remote_dir/$tfile
14984
14985         fid=$($LFS path2fid $remote_dir/$tfile)
14986         rc=$?
14987         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14988
14989         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14990                 error "dot lustre permission check $fid failed"
14991         rm -rf $DIR/$tdir
14992 }
14993 run_test 154b "Open-by-FID for remote directory"
14994
14995 test_154c() {
14996         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14997                 skip "Need MDS version at least 2.4.1"
14998
14999         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15000         local FID1=$($LFS path2fid $DIR/$tfile.1)
15001         local FID2=$($LFS path2fid $DIR/$tfile.2)
15002         local FID3=$($LFS path2fid $DIR/$tfile.3)
15003
15004         local N=1
15005         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15006                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15007                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15008                 local want=FID$N
15009                 [ "$FID" = "${!want}" ] ||
15010                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15011                 N=$((N + 1))
15012         done
15013
15014         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15015         do
15016                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15017                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15018                 N=$((N + 1))
15019         done
15020 }
15021 run_test 154c "lfs path2fid and fid2path multiple arguments"
15022
15023 test_154d() {
15024         remote_mds_nodsh && skip "remote MDS with nodsh"
15025         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15026                 skip "Need MDS version at least 2.5.53"
15027
15028         if remote_mds; then
15029                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15030         else
15031                 nid="0@lo"
15032         fi
15033         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15034         local fd
15035         local cmd
15036
15037         rm -f $DIR/$tfile
15038         touch $DIR/$tfile
15039
15040         local fid=$($LFS path2fid $DIR/$tfile)
15041         # Open the file
15042         fd=$(free_fd)
15043         cmd="exec $fd<$DIR/$tfile"
15044         eval $cmd
15045         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15046         echo "$fid_list" | grep "$fid"
15047         rc=$?
15048
15049         cmd="exec $fd>/dev/null"
15050         eval $cmd
15051         if [ $rc -ne 0 ]; then
15052                 error "FID $fid not found in open files list $fid_list"
15053         fi
15054 }
15055 run_test 154d "Verify open file fid"
15056
15057 test_154e()
15058 {
15059         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15060                 skip "Need MDS version at least 2.6.50"
15061
15062         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15063                 error ".lustre returned by readdir"
15064         fi
15065 }
15066 run_test 154e ".lustre is not returned by readdir"
15067
15068 test_154f() {
15069         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15070
15071         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15072         mkdir_on_mdt0 $DIR/$tdir
15073         # test dirs inherit from its stripe
15074         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15075         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15076         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15077         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15078         touch $DIR/f
15079
15080         # get fid of parents
15081         local FID0=$($LFS path2fid $DIR/$tdir)
15082         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15083         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15084         local FID3=$($LFS path2fid $DIR)
15085
15086         # check that path2fid --parents returns expected <parent_fid>/name
15087         # 1) test for a directory (single parent)
15088         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15089         [ "$parent" == "$FID0/foo1" ] ||
15090                 error "expected parent: $FID0/foo1, got: $parent"
15091
15092         # 2) test for a file with nlink > 1 (multiple parents)
15093         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15094         echo "$parent" | grep -F "$FID1/$tfile" ||
15095                 error "$FID1/$tfile not returned in parent list"
15096         echo "$parent" | grep -F "$FID2/link" ||
15097                 error "$FID2/link not returned in parent list"
15098
15099         # 3) get parent by fid
15100         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15101         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15102         echo "$parent" | grep -F "$FID1/$tfile" ||
15103                 error "$FID1/$tfile not returned in parent list (by fid)"
15104         echo "$parent" | grep -F "$FID2/link" ||
15105                 error "$FID2/link not returned in parent list (by fid)"
15106
15107         # 4) test for entry in root directory
15108         parent=$($LFS path2fid --parents $DIR/f)
15109         echo "$parent" | grep -F "$FID3/f" ||
15110                 error "$FID3/f not returned in parent list"
15111
15112         # 5) test it on root directory
15113         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15114                 error "$MOUNT should not have parents"
15115
15116         # enable xattr caching and check that linkea is correctly updated
15117         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15118         save_lustre_params client "llite.*.xattr_cache" > $save
15119         lctl set_param llite.*.xattr_cache 1
15120
15121         # 6.1) linkea update on rename
15122         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15123
15124         # get parents by fid
15125         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15126         # foo1 should no longer be returned in parent list
15127         echo "$parent" | grep -F "$FID1" &&
15128                 error "$FID1 should no longer be in parent list"
15129         # the new path should appear
15130         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15131                 error "$FID2/$tfile.moved is not in parent list"
15132
15133         # 6.2) linkea update on unlink
15134         rm -f $DIR/$tdir/foo2/link
15135         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15136         # foo2/link should no longer be returned in parent list
15137         echo "$parent" | grep -F "$FID2/link" &&
15138                 error "$FID2/link should no longer be in parent list"
15139         true
15140
15141         rm -f $DIR/f
15142         restore_lustre_params < $save
15143         rm -f $save
15144 }
15145 run_test 154f "get parent fids by reading link ea"
15146
15147 test_154g()
15148 {
15149         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15150         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15151            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15152                 skip "Need MDS version at least 2.6.92"
15153
15154         mkdir_on_mdt0 $DIR/$tdir
15155         llapi_fid_test -d $DIR/$tdir
15156 }
15157 run_test 154g "various llapi FID tests"
15158
15159 test_155_small_load() {
15160     local temp=$TMP/$tfile
15161     local file=$DIR/$tfile
15162
15163     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15164         error "dd of=$temp bs=6096 count=1 failed"
15165     cp $temp $file
15166     cancel_lru_locks $OSC
15167     cmp $temp $file || error "$temp $file differ"
15168
15169     $TRUNCATE $temp 6000
15170     $TRUNCATE $file 6000
15171     cmp $temp $file || error "$temp $file differ (truncate1)"
15172
15173     echo "12345" >>$temp
15174     echo "12345" >>$file
15175     cmp $temp $file || error "$temp $file differ (append1)"
15176
15177     echo "12345" >>$temp
15178     echo "12345" >>$file
15179     cmp $temp $file || error "$temp $file differ (append2)"
15180
15181     rm -f $temp $file
15182     true
15183 }
15184
15185 test_155_big_load() {
15186         remote_ost_nodsh && skip "remote OST with nodsh"
15187
15188         local temp=$TMP/$tfile
15189         local file=$DIR/$tfile
15190
15191         free_min_max
15192         local cache_size=$(do_facet ost$((MAXI+1)) \
15193                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15194         local large_file_size=$((cache_size * 2))
15195
15196         echo "OSS cache size: $cache_size KB"
15197         echo "Large file size: $large_file_size KB"
15198
15199         [ $MAXV -le $large_file_size ] &&
15200                 skip_env "max available OST size needs > $large_file_size KB"
15201
15202         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15203
15204         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15205                 error "dd of=$temp bs=$large_file_size count=1k failed"
15206         cp $temp $file
15207         ls -lh $temp $file
15208         cancel_lru_locks osc
15209         cmp $temp $file || error "$temp $file differ"
15210
15211         rm -f $temp $file
15212         true
15213 }
15214
15215 save_writethrough() {
15216         local facets=$(get_facets OST)
15217
15218         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15219 }
15220
15221 test_155a() {
15222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15223
15224         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15225
15226         save_writethrough $p
15227
15228         set_cache read on
15229         set_cache writethrough on
15230         test_155_small_load
15231         restore_lustre_params < $p
15232         rm -f $p
15233 }
15234 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15235
15236 test_155b() {
15237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15238
15239         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15240
15241         save_writethrough $p
15242
15243         set_cache read on
15244         set_cache writethrough off
15245         test_155_small_load
15246         restore_lustre_params < $p
15247         rm -f $p
15248 }
15249 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15250
15251 test_155c() {
15252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15253
15254         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15255
15256         save_writethrough $p
15257
15258         set_cache read off
15259         set_cache writethrough on
15260         test_155_small_load
15261         restore_lustre_params < $p
15262         rm -f $p
15263 }
15264 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15265
15266 test_155d() {
15267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15268
15269         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15270
15271         save_writethrough $p
15272
15273         set_cache read off
15274         set_cache writethrough off
15275         test_155_small_load
15276         restore_lustre_params < $p
15277         rm -f $p
15278 }
15279 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15280
15281 test_155e() {
15282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15283
15284         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15285
15286         save_writethrough $p
15287
15288         set_cache read on
15289         set_cache writethrough on
15290         test_155_big_load
15291         restore_lustre_params < $p
15292         rm -f $p
15293 }
15294 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15295
15296 test_155f() {
15297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15298
15299         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15300
15301         save_writethrough $p
15302
15303         set_cache read on
15304         set_cache writethrough off
15305         test_155_big_load
15306         restore_lustre_params < $p
15307         rm -f $p
15308 }
15309 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15310
15311 test_155g() {
15312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15313
15314         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15315
15316         save_writethrough $p
15317
15318         set_cache read off
15319         set_cache writethrough on
15320         test_155_big_load
15321         restore_lustre_params < $p
15322         rm -f $p
15323 }
15324 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15325
15326 test_155h() {
15327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15328
15329         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15330
15331         save_writethrough $p
15332
15333         set_cache read off
15334         set_cache writethrough off
15335         test_155_big_load
15336         restore_lustre_params < $p
15337         rm -f $p
15338 }
15339 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15340
15341 test_156() {
15342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15343         remote_ost_nodsh && skip "remote OST with nodsh"
15344         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15345                 skip "stats not implemented on old servers"
15346         [ "$ost1_FSTYPE" = "zfs" ] &&
15347                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15348
15349         local CPAGES=3
15350         local BEFORE
15351         local AFTER
15352         local file="$DIR/$tfile"
15353         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15354
15355         save_writethrough $p
15356         roc_hit_init
15357
15358         log "Turn on read and write cache"
15359         set_cache read on
15360         set_cache writethrough on
15361
15362         log "Write data and read it back."
15363         log "Read should be satisfied from the cache."
15364         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15365         BEFORE=$(roc_hit)
15366         cancel_lru_locks osc
15367         cat $file >/dev/null
15368         AFTER=$(roc_hit)
15369         if ! let "AFTER - BEFORE == CPAGES"; then
15370                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15371         else
15372                 log "cache hits: before: $BEFORE, after: $AFTER"
15373         fi
15374
15375         log "Read again; it should be satisfied from the cache."
15376         BEFORE=$AFTER
15377         cancel_lru_locks osc
15378         cat $file >/dev/null
15379         AFTER=$(roc_hit)
15380         if ! let "AFTER - BEFORE == CPAGES"; then
15381                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15382         else
15383                 log "cache hits:: before: $BEFORE, after: $AFTER"
15384         fi
15385
15386         log "Turn off the read cache and turn on the write cache"
15387         set_cache read off
15388         set_cache writethrough on
15389
15390         log "Read again; it should be satisfied from the cache."
15391         BEFORE=$(roc_hit)
15392         cancel_lru_locks osc
15393         cat $file >/dev/null
15394         AFTER=$(roc_hit)
15395         if ! let "AFTER - BEFORE == CPAGES"; then
15396                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15397         else
15398                 log "cache hits:: before: $BEFORE, after: $AFTER"
15399         fi
15400
15401         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15402                 # > 2.12.56 uses pagecache if cached
15403                 log "Read again; it should not be satisfied from the cache."
15404                 BEFORE=$AFTER
15405                 cancel_lru_locks osc
15406                 cat $file >/dev/null
15407                 AFTER=$(roc_hit)
15408                 if ! let "AFTER - BEFORE == 0"; then
15409                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15410                 else
15411                         log "cache hits:: before: $BEFORE, after: $AFTER"
15412                 fi
15413         fi
15414
15415         log "Write data and read it back."
15416         log "Read should be satisfied from the cache."
15417         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15418         BEFORE=$(roc_hit)
15419         cancel_lru_locks osc
15420         cat $file >/dev/null
15421         AFTER=$(roc_hit)
15422         if ! let "AFTER - BEFORE == CPAGES"; then
15423                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15424         else
15425                 log "cache hits:: before: $BEFORE, after: $AFTER"
15426         fi
15427
15428         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15429                 # > 2.12.56 uses pagecache if cached
15430                 log "Read again; it should not be satisfied from the cache."
15431                 BEFORE=$AFTER
15432                 cancel_lru_locks osc
15433                 cat $file >/dev/null
15434                 AFTER=$(roc_hit)
15435                 if ! let "AFTER - BEFORE == 0"; then
15436                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15437                 else
15438                         log "cache hits:: before: $BEFORE, after: $AFTER"
15439                 fi
15440         fi
15441
15442         log "Turn off read and write cache"
15443         set_cache read off
15444         set_cache writethrough off
15445
15446         log "Write data and read it back"
15447         log "It should not be satisfied from the cache."
15448         rm -f $file
15449         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15450         cancel_lru_locks osc
15451         BEFORE=$(roc_hit)
15452         cat $file >/dev/null
15453         AFTER=$(roc_hit)
15454         if ! let "AFTER - BEFORE == 0"; then
15455                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15456         else
15457                 log "cache hits:: before: $BEFORE, after: $AFTER"
15458         fi
15459
15460         log "Turn on the read cache and turn off the write cache"
15461         set_cache read on
15462         set_cache writethrough off
15463
15464         log "Write data and read it back"
15465         log "It should not be satisfied from the cache."
15466         rm -f $file
15467         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15468         BEFORE=$(roc_hit)
15469         cancel_lru_locks osc
15470         cat $file >/dev/null
15471         AFTER=$(roc_hit)
15472         if ! let "AFTER - BEFORE == 0"; then
15473                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15474         else
15475                 log "cache hits:: before: $BEFORE, after: $AFTER"
15476         fi
15477
15478         log "Read again; it should be satisfied from the cache."
15479         BEFORE=$(roc_hit)
15480         cancel_lru_locks osc
15481         cat $file >/dev/null
15482         AFTER=$(roc_hit)
15483         if ! let "AFTER - BEFORE == CPAGES"; then
15484                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15485         else
15486                 log "cache hits:: before: $BEFORE, after: $AFTER"
15487         fi
15488
15489         restore_lustre_params < $p
15490         rm -f $p $file
15491 }
15492 run_test 156 "Verification of tunables"
15493
15494 test_160a() {
15495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15496         remote_mds_nodsh && skip "remote MDS with nodsh"
15497         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15498                 skip "Need MDS version at least 2.2.0"
15499
15500         changelog_register || error "changelog_register failed"
15501         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15502         changelog_users $SINGLEMDS | grep -q $cl_user ||
15503                 error "User $cl_user not found in changelog_users"
15504
15505         mkdir_on_mdt0 $DIR/$tdir
15506
15507         # change something
15508         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15509         changelog_clear 0 || error "changelog_clear failed"
15510         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15511         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15512         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15513         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15514         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15515         rm $DIR/$tdir/pics/desktop.jpg
15516
15517         echo "verifying changelog mask"
15518         changelog_chmask "-MKDIR"
15519         changelog_chmask "-CLOSE"
15520
15521         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15522         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15523
15524         changelog_chmask "+MKDIR"
15525         changelog_chmask "+CLOSE"
15526
15527         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15528         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15529
15530         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15531         CLOSES=$(changelog_dump | grep -c "CLOSE")
15532         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15533         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15534
15535         # verify contents
15536         echo "verifying target fid"
15537         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15538         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15539         [ "$fidc" == "$fidf" ] ||
15540                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15541         echo "verifying parent fid"
15542         # The FID returned from the Changelog may be the directory shard on
15543         # a different MDT, and not the FID returned by path2fid on the parent.
15544         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15545         # since this is what will matter when recreating this file in the tree.
15546         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15547         local pathp=$($LFS fid2path $MOUNT "$fidp")
15548         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15549                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15550
15551         echo "getting records for $cl_user"
15552         changelog_users $SINGLEMDS
15553         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15554         local nclr=3
15555         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15556                 error "changelog_clear failed"
15557         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15558         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15559         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15560                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15561
15562         local min0_rec=$(changelog_users $SINGLEMDS |
15563                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15564         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15565                           awk '{ print $1; exit; }')
15566
15567         changelog_dump | tail -n 5
15568         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15569         [ $first_rec == $((min0_rec + 1)) ] ||
15570                 error "first index should be $min0_rec + 1 not $first_rec"
15571
15572         # LU-3446 changelog index reset on MDT restart
15573         local cur_rec1=$(changelog_users $SINGLEMDS |
15574                          awk '/^current.index:/ { print $NF }')
15575         changelog_clear 0 ||
15576                 error "clear all changelog records for $cl_user failed"
15577         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15578         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15579                 error "Fail to start $SINGLEMDS"
15580         local cur_rec2=$(changelog_users $SINGLEMDS |
15581                          awk '/^current.index:/ { print $NF }')
15582         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15583         [ $cur_rec1 == $cur_rec2 ] ||
15584                 error "current index should be $cur_rec1 not $cur_rec2"
15585
15586         echo "verifying users from this test are deregistered"
15587         changelog_deregister || error "changelog_deregister failed"
15588         changelog_users $SINGLEMDS | grep -q $cl_user &&
15589                 error "User '$cl_user' still in changelog_users"
15590
15591         # lctl get_param -n mdd.*.changelog_users
15592         # current_index: 144
15593         # ID    index (idle seconds)
15594         # cl3   144   (2) mask=<list>
15595         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15596                 # this is the normal case where all users were deregistered
15597                 # make sure no new records are added when no users are present
15598                 local last_rec1=$(changelog_users $SINGLEMDS |
15599                                   awk '/^current.index:/ { print $NF }')
15600                 touch $DIR/$tdir/chloe
15601                 local last_rec2=$(changelog_users $SINGLEMDS |
15602                                   awk '/^current.index:/ { print $NF }')
15603                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15604                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15605         else
15606                 # any changelog users must be leftovers from a previous test
15607                 changelog_users $SINGLEMDS
15608                 echo "other changelog users; can't verify off"
15609         fi
15610 }
15611 run_test 160a "changelog sanity"
15612
15613 test_160b() { # LU-3587
15614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15615         remote_mds_nodsh && skip "remote MDS with nodsh"
15616         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15617                 skip "Need MDS version at least 2.2.0"
15618
15619         changelog_register || error "changelog_register failed"
15620         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15621         changelog_users $SINGLEMDS | grep -q $cl_user ||
15622                 error "User '$cl_user' not found in changelog_users"
15623
15624         local longname1=$(str_repeat a 255)
15625         local longname2=$(str_repeat b 255)
15626
15627         cd $DIR
15628         echo "creating very long named file"
15629         touch $longname1 || error "create of '$longname1' failed"
15630         echo "renaming very long named file"
15631         mv $longname1 $longname2
15632
15633         changelog_dump | grep RENME | tail -n 5
15634         rm -f $longname2
15635 }
15636 run_test 160b "Verify that very long rename doesn't crash in changelog"
15637
15638 test_160c() {
15639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15640         remote_mds_nodsh && skip "remote MDS with nodsh"
15641
15642         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15643                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15644                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15645                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15646
15647         local rc=0
15648
15649         # Registration step
15650         changelog_register || error "changelog_register failed"
15651
15652         rm -rf $DIR/$tdir
15653         mkdir -p $DIR/$tdir
15654         $MCREATE $DIR/$tdir/foo_160c
15655         changelog_chmask "-TRUNC"
15656         $TRUNCATE $DIR/$tdir/foo_160c 200
15657         changelog_chmask "+TRUNC"
15658         $TRUNCATE $DIR/$tdir/foo_160c 199
15659         changelog_dump | tail -n 5
15660         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15661         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15662 }
15663 run_test 160c "verify that changelog log catch the truncate event"
15664
15665 test_160d() {
15666         remote_mds_nodsh && skip "remote MDS with nodsh"
15667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15669         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15670                 skip "Need MDS version at least 2.7.60"
15671
15672         # Registration step
15673         changelog_register || error "changelog_register failed"
15674
15675         mkdir -p $DIR/$tdir/migrate_dir
15676         changelog_clear 0 || error "changelog_clear failed"
15677
15678         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15679         changelog_dump | tail -n 5
15680         local migrates=$(changelog_dump | grep -c "MIGRT")
15681         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15682 }
15683 run_test 160d "verify that changelog log catch the migrate event"
15684
15685 test_160e() {
15686         remote_mds_nodsh && skip "remote MDS with nodsh"
15687
15688         # Create a user
15689         changelog_register || error "changelog_register failed"
15690
15691         local MDT0=$(facet_svc $SINGLEMDS)
15692         local rc
15693
15694         # No user (expect fail)
15695         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15696         rc=$?
15697         if [ $rc -eq 0 ]; then
15698                 error "Should fail without user"
15699         elif [ $rc -ne 4 ]; then
15700                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15701         fi
15702
15703         # Delete a future user (expect fail)
15704         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15705         rc=$?
15706         if [ $rc -eq 0 ]; then
15707                 error "Deleted non-existant user cl77"
15708         elif [ $rc -ne 2 ]; then
15709                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15710         fi
15711
15712         # Clear to a bad index (1 billion should be safe)
15713         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15714         rc=$?
15715
15716         if [ $rc -eq 0 ]; then
15717                 error "Successfully cleared to invalid CL index"
15718         elif [ $rc -ne 22 ]; then
15719                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15720         fi
15721 }
15722 run_test 160e "changelog negative testing (should return errors)"
15723
15724 test_160f() {
15725         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15726         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15727                 skip "Need MDS version at least 2.10.56"
15728
15729         local mdts=$(comma_list $(mdts_nodes))
15730
15731         # Create a user
15732         changelog_register || error "first changelog_register failed"
15733         changelog_register || error "second changelog_register failed"
15734         local cl_users
15735         declare -A cl_user1
15736         declare -A cl_user2
15737         local user_rec1
15738         local user_rec2
15739         local i
15740
15741         # generate some changelog records to accumulate on each MDT
15742         # use all_char because created files should be evenly distributed
15743         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15744                 error "test_mkdir $tdir failed"
15745         log "$(date +%s): creating first files"
15746         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15747                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15748                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15749         done
15750
15751         # check changelogs have been generated
15752         local start=$SECONDS
15753         local idle_time=$((MDSCOUNT * 5 + 5))
15754         local nbcl=$(changelog_dump | wc -l)
15755         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15756
15757         for param in "changelog_max_idle_time=$idle_time" \
15758                      "changelog_gc=1" \
15759                      "changelog_min_gc_interval=2" \
15760                      "changelog_min_free_cat_entries=3"; do
15761                 local MDT0=$(facet_svc $SINGLEMDS)
15762                 local var="${param%=*}"
15763                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15764
15765                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15766                 do_nodes $mdts $LCTL set_param mdd.*.$param
15767         done
15768
15769         # force cl_user2 to be idle (1st part), but also cancel the
15770         # cl_user1 records so that it is not evicted later in the test.
15771         local sleep1=$((idle_time / 2))
15772         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15773         sleep $sleep1
15774
15775         # simulate changelog catalog almost full
15776         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15777         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15778
15779         for i in $(seq $MDSCOUNT); do
15780                 cl_users=(${CL_USERS[mds$i]})
15781                 cl_user1[mds$i]="${cl_users[0]}"
15782                 cl_user2[mds$i]="${cl_users[1]}"
15783
15784                 [ -n "${cl_user1[mds$i]}" ] ||
15785                         error "mds$i: no user registered"
15786                 [ -n "${cl_user2[mds$i]}" ] ||
15787                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15788
15789                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15790                 [ -n "$user_rec1" ] ||
15791                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15792                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15793                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15794                 [ -n "$user_rec2" ] ||
15795                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15796                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15797                      "$user_rec1 + 2 == $user_rec2"
15798                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15799                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15800                               "$user_rec1 + 2, but is $user_rec2"
15801                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15802                 [ -n "$user_rec2" ] ||
15803                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15804                 [ $user_rec1 == $user_rec2 ] ||
15805                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15806                               "$user_rec1, but is $user_rec2"
15807         done
15808
15809         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15810         local sleep2=$((idle_time - (SECONDS - start) + 1))
15811         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15812         sleep $sleep2
15813
15814         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15815         # cl_user1 should be OK because it recently processed records.
15816         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15817         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15818                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15819                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15820         done
15821
15822         # ensure gc thread is done
15823         for i in $(mdts_nodes); do
15824                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15825                         error "$i: GC-thread not done"
15826         done
15827
15828         local first_rec
15829         for (( i = 1; i <= MDSCOUNT; i++ )); do
15830                 # check cl_user1 still registered
15831                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15832                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15833                 # check cl_user2 unregistered
15834                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15835                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15836
15837                 # check changelogs are present and starting at $user_rec1 + 1
15838                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15839                 [ -n "$user_rec1" ] ||
15840                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15841                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15842                             awk '{ print $1; exit; }')
15843
15844                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15845                 [ $((user_rec1 + 1)) == $first_rec ] ||
15846                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15847         done
15848 }
15849 run_test 160f "changelog garbage collect (timestamped users)"
15850
15851 test_160g() {
15852         remote_mds_nodsh && skip "remote MDS with nodsh"
15853         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15854                 skip "Need MDS version at least 2.10.56"
15855
15856         local mdts=$(comma_list $(mdts_nodes))
15857
15858         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15859         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15860
15861         # Create a user
15862         changelog_register || error "first changelog_register failed"
15863         changelog_register || error "second changelog_register failed"
15864         local cl_users
15865         declare -A cl_user1
15866         declare -A cl_user2
15867         local user_rec1
15868         local user_rec2
15869         local i
15870
15871         # generate some changelog records to accumulate on each MDT
15872         # use all_char because created files should be evenly distributed
15873         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15874                 error "test_mkdir $tdir failed"
15875         for ((i = 0; i < MDSCOUNT; i++)); do
15876                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15877                         error "create $DIR/$tdir/d$i.1 failed"
15878         done
15879
15880         # check changelogs have been generated
15881         local nbcl=$(changelog_dump | wc -l)
15882         (( $nbcl > 0 )) || error "no changelogs found"
15883
15884         # reduce the max_idle_indexes value to make sure we exceed it
15885         for param in "changelog_max_idle_indexes=1" \
15886                      "changelog_gc=1" \
15887                      "changelog_min_gc_interval=2" \
15888                      "changelog_min_free_cat_entries=3"; do
15889                 local MDT0=$(facet_svc $SINGLEMDS)
15890                 local var="${param%=*}"
15891                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15892
15893                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15894                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15895                         error "unable to set mdd.*.$param"
15896         done
15897
15898         # simulate changelog catalog almost full
15899         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15900         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15901
15902         local start=$SECONDS
15903         for i in $(seq $MDSCOUNT); do
15904                 cl_users=(${CL_USERS[mds$i]})
15905                 cl_user1[mds$i]="${cl_users[0]}"
15906                 cl_user2[mds$i]="${cl_users[1]}"
15907
15908                 [ -n "${cl_user1[mds$i]}" ] ||
15909                         error "mds$i: no user registered"
15910                 [ -n "${cl_user2[mds$i]}" ] ||
15911                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15912
15913                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15914                 [ -n "$user_rec1" ] ||
15915                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15916                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15917                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15918                 [ -n "$user_rec2" ] ||
15919                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15920                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15921                      "$user_rec1 + 2 == $user_rec2"
15922                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15923                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15924                               "$user_rec1 + 2, but is $user_rec2"
15925                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15926                 [ -n "$user_rec2" ] ||
15927                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15928                 [ $user_rec1 == $user_rec2 ] ||
15929                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15930                               "$user_rec1, but is $user_rec2"
15931         done
15932
15933         # ensure we are past the previous changelog_min_gc_interval set above
15934         local sleep2=$((start + 2 - SECONDS))
15935         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15936
15937         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15938         # cl_user1 should be OK because it recently processed records.
15939         for ((i = 0; i < MDSCOUNT; i++)); do
15940                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15941                         error "create $DIR/$tdir/d$i.3 failed"
15942         done
15943
15944         # ensure gc thread is done
15945         for i in $(mdts_nodes); do
15946                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15947                         error "$i: GC-thread not done"
15948         done
15949
15950         local first_rec
15951         for (( i = 1; i <= MDSCOUNT; i++ )); do
15952                 # check cl_user1 still registered
15953                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15954                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15955                 # check cl_user2 unregistered
15956                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15957                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15958
15959                 # check changelogs are present and starting at $user_rec1 + 1
15960                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15961                 [ -n "$user_rec1" ] ||
15962                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15963                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15964                             awk '{ print $1; exit; }')
15965
15966                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15967                 [ $((user_rec1 + 1)) == $first_rec ] ||
15968                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15969         done
15970 }
15971 run_test 160g "changelog garbage collect (old users)"
15972
15973 test_160h() {
15974         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15975         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15976                 skip "Need MDS version at least 2.10.56"
15977
15978         local mdts=$(comma_list $(mdts_nodes))
15979
15980         # Create a user
15981         changelog_register || error "first changelog_register failed"
15982         changelog_register || error "second changelog_register failed"
15983         local cl_users
15984         declare -A cl_user1
15985         declare -A cl_user2
15986         local user_rec1
15987         local user_rec2
15988         local i
15989
15990         # generate some changelog records to accumulate on each MDT
15991         # use all_char because created files should be evenly distributed
15992         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15993                 error "test_mkdir $tdir failed"
15994         for ((i = 0; i < MDSCOUNT; i++)); do
15995                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15996                         error "create $DIR/$tdir/d$i.1 failed"
15997         done
15998
15999         # check changelogs have been generated
16000         local nbcl=$(changelog_dump | wc -l)
16001         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16002
16003         for param in "changelog_max_idle_time=10" \
16004                      "changelog_gc=1" \
16005                      "changelog_min_gc_interval=2"; do
16006                 local MDT0=$(facet_svc $SINGLEMDS)
16007                 local var="${param%=*}"
16008                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16009
16010                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16011                 do_nodes $mdts $LCTL set_param mdd.*.$param
16012         done
16013
16014         # force cl_user2 to be idle (1st part)
16015         sleep 9
16016
16017         for i in $(seq $MDSCOUNT); do
16018                 cl_users=(${CL_USERS[mds$i]})
16019                 cl_user1[mds$i]="${cl_users[0]}"
16020                 cl_user2[mds$i]="${cl_users[1]}"
16021
16022                 [ -n "${cl_user1[mds$i]}" ] ||
16023                         error "mds$i: no user registered"
16024                 [ -n "${cl_user2[mds$i]}" ] ||
16025                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16026
16027                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16028                 [ -n "$user_rec1" ] ||
16029                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16030                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16031                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16032                 [ -n "$user_rec2" ] ||
16033                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16034                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16035                      "$user_rec1 + 2 == $user_rec2"
16036                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16037                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16038                               "$user_rec1 + 2, but is $user_rec2"
16039                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16040                 [ -n "$user_rec2" ] ||
16041                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16042                 [ $user_rec1 == $user_rec2 ] ||
16043                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16044                               "$user_rec1, but is $user_rec2"
16045         done
16046
16047         # force cl_user2 to be idle (2nd part) and to reach
16048         # changelog_max_idle_time
16049         sleep 2
16050
16051         # force each GC-thread start and block then
16052         # one per MDT/MDD, set fail_val accordingly
16053         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16054         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16055
16056         # generate more changelogs to trigger fail_loc
16057         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16058                 error "create $DIR/$tdir/${tfile}bis failed"
16059
16060         # stop MDT to stop GC-thread, should be done in back-ground as it will
16061         # block waiting for the thread to be released and exit
16062         declare -A stop_pids
16063         for i in $(seq $MDSCOUNT); do
16064                 stop mds$i &
16065                 stop_pids[mds$i]=$!
16066         done
16067
16068         for i in $(mdts_nodes); do
16069                 local facet
16070                 local nb=0
16071                 local facets=$(facets_up_on_host $i)
16072
16073                 for facet in ${facets//,/ }; do
16074                         if [[ $facet == mds* ]]; then
16075                                 nb=$((nb + 1))
16076                         fi
16077                 done
16078                 # ensure each MDS's gc threads are still present and all in "R"
16079                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16080                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16081                         error "$i: expected $nb GC-thread"
16082                 wait_update $i \
16083                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16084                         "R" 20 ||
16085                         error "$i: GC-thread not found in R-state"
16086                 # check umounts of each MDT on MDS have reached kthread_stop()
16087                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16088                         error "$i: expected $nb umount"
16089                 wait_update $i \
16090                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16091                         error "$i: umount not found in D-state"
16092         done
16093
16094         # release all GC-threads
16095         do_nodes $mdts $LCTL set_param fail_loc=0
16096
16097         # wait for MDT stop to complete
16098         for i in $(seq $MDSCOUNT); do
16099                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16100         done
16101
16102         # XXX
16103         # may try to check if any orphan changelog records are present
16104         # via ldiskfs/zfs and llog_reader...
16105
16106         # re-start/mount MDTs
16107         for i in $(seq $MDSCOUNT); do
16108                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16109                         error "Fail to start mds$i"
16110         done
16111
16112         local first_rec
16113         for i in $(seq $MDSCOUNT); do
16114                 # check cl_user1 still registered
16115                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16116                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16117                 # check cl_user2 unregistered
16118                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16119                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16120
16121                 # check changelogs are present and starting at $user_rec1 + 1
16122                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16123                 [ -n "$user_rec1" ] ||
16124                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16125                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16126                             awk '{ print $1; exit; }')
16127
16128                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16129                 [ $((user_rec1 + 1)) == $first_rec ] ||
16130                         error "mds$i: first index should be $user_rec1 + 1, " \
16131                               "but is $first_rec"
16132         done
16133 }
16134 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16135               "during mount"
16136
16137 test_160i() {
16138
16139         local mdts=$(comma_list $(mdts_nodes))
16140
16141         changelog_register || error "first changelog_register failed"
16142
16143         # generate some changelog records to accumulate on each MDT
16144         # use all_char because created files should be evenly distributed
16145         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16146                 error "test_mkdir $tdir failed"
16147         for ((i = 0; i < MDSCOUNT; i++)); do
16148                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16149                         error "create $DIR/$tdir/d$i.1 failed"
16150         done
16151
16152         # check changelogs have been generated
16153         local nbcl=$(changelog_dump | wc -l)
16154         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16155
16156         # simulate race between register and unregister
16157         # XXX as fail_loc is set per-MDS, with DNE configs the race
16158         # simulation will only occur for one MDT per MDS and for the
16159         # others the normal race scenario will take place
16160         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16161         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16162         do_nodes $mdts $LCTL set_param fail_val=1
16163
16164         # unregister 1st user
16165         changelog_deregister &
16166         local pid1=$!
16167         # wait some time for deregister work to reach race rdv
16168         sleep 2
16169         # register 2nd user
16170         changelog_register || error "2nd user register failed"
16171
16172         wait $pid1 || error "1st user deregister failed"
16173
16174         local i
16175         local last_rec
16176         declare -A LAST_REC
16177         for i in $(seq $MDSCOUNT); do
16178                 if changelog_users mds$i | grep "^cl"; then
16179                         # make sure new records are added with one user present
16180                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16181                                           awk '/^current.index:/ { print $NF }')
16182                 else
16183                         error "mds$i has no user registered"
16184                 fi
16185         done
16186
16187         # generate more changelog records to accumulate on each MDT
16188         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16189                 error "create $DIR/$tdir/${tfile}bis failed"
16190
16191         for i in $(seq $MDSCOUNT); do
16192                 last_rec=$(changelog_users $SINGLEMDS |
16193                            awk '/^current.index:/ { print $NF }')
16194                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16195                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16196                         error "changelogs are off on mds$i"
16197         done
16198 }
16199 run_test 160i "changelog user register/unregister race"
16200
16201 test_160j() {
16202         remote_mds_nodsh && skip "remote MDS with nodsh"
16203         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16204                 skip "Need MDS version at least 2.12.56"
16205
16206         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16207         stack_trap "umount $MOUNT2" EXIT
16208
16209         changelog_register || error "first changelog_register failed"
16210         stack_trap "changelog_deregister" EXIT
16211
16212         # generate some changelog
16213         # use all_char because created files should be evenly distributed
16214         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16215                 error "mkdir $tdir failed"
16216         for ((i = 0; i < MDSCOUNT; i++)); do
16217                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16218                         error "create $DIR/$tdir/d$i.1 failed"
16219         done
16220
16221         # open the changelog device
16222         exec 3>/dev/changelog-$FSNAME-MDT0000
16223         stack_trap "exec 3>&-" EXIT
16224         exec 4</dev/changelog-$FSNAME-MDT0000
16225         stack_trap "exec 4<&-" EXIT
16226
16227         # umount the first lustre mount
16228         umount $MOUNT
16229         stack_trap "mount_client $MOUNT" EXIT
16230
16231         # read changelog, which may or may not fail, but should not crash
16232         cat <&4 >/dev/null
16233
16234         # clear changelog
16235         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16236         changelog_users $SINGLEMDS | grep -q $cl_user ||
16237                 error "User $cl_user not found in changelog_users"
16238
16239         printf 'clear:'$cl_user':0' >&3
16240 }
16241 run_test 160j "client can be umounted while its chanangelog is being used"
16242
16243 test_160k() {
16244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16245         remote_mds_nodsh && skip "remote MDS with nodsh"
16246
16247         mkdir -p $DIR/$tdir/1/1
16248
16249         changelog_register || error "changelog_register failed"
16250         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16251
16252         changelog_users $SINGLEMDS | grep -q $cl_user ||
16253                 error "User '$cl_user' not found in changelog_users"
16254 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16255         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16256         rmdir $DIR/$tdir/1/1 & sleep 1
16257         mkdir $DIR/$tdir/2
16258         touch $DIR/$tdir/2/2
16259         rm -rf $DIR/$tdir/2
16260
16261         wait
16262         sleep 4
16263
16264         changelog_dump | grep rmdir || error "rmdir not recorded"
16265 }
16266 run_test 160k "Verify that changelog records are not lost"
16267
16268 # Verifies that a file passed as a parameter has recently had an operation
16269 # performed on it that has generated an MTIME changelog which contains the
16270 # correct parent FID. As files might reside on a different MDT from the
16271 # parent directory in DNE configurations, the FIDs are translated to paths
16272 # before being compared, which should be identical
16273 compare_mtime_changelog() {
16274         local file="${1}"
16275         local mdtidx
16276         local mtime
16277         local cl_fid
16278         local pdir
16279         local dir
16280
16281         mdtidx=$($LFS getstripe --mdt-index $file)
16282         mdtidx=$(printf "%04x" $mdtidx)
16283
16284         # Obtain the parent FID from the MTIME changelog
16285         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16286         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16287
16288         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16289         [ -z "$cl_fid" ] && error "parent FID not present"
16290
16291         # Verify that the path for the parent FID is the same as the path for
16292         # the test directory
16293         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16294
16295         dir=$(dirname $1)
16296
16297         [[ "${pdir%/}" == "$dir" ]] ||
16298                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16299 }
16300
16301 test_160l() {
16302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16303
16304         remote_mds_nodsh && skip "remote MDS with nodsh"
16305         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16306                 skip "Need MDS version at least 2.13.55"
16307
16308         local cl_user
16309
16310         changelog_register || error "changelog_register failed"
16311         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16312
16313         changelog_users $SINGLEMDS | grep -q $cl_user ||
16314                 error "User '$cl_user' not found in changelog_users"
16315
16316         # Clear some types so that MTIME changelogs are generated
16317         changelog_chmask "-CREAT"
16318         changelog_chmask "-CLOSE"
16319
16320         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16321
16322         # Test CL_MTIME during setattr
16323         touch $DIR/$tdir/$tfile
16324         compare_mtime_changelog $DIR/$tdir/$tfile
16325
16326         # Test CL_MTIME during close
16327         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16328         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16329 }
16330 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16331
16332 test_160m() {
16333         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16334         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16335                 skip "Need MDS version at least 2.14.51"
16336         local cl_users
16337         local cl_user1
16338         local cl_user2
16339         local pid1
16340
16341         # Create a user
16342         changelog_register || error "first changelog_register failed"
16343         changelog_register || error "second changelog_register failed"
16344
16345         cl_users=(${CL_USERS[mds1]})
16346         cl_user1="${cl_users[0]}"
16347         cl_user2="${cl_users[1]}"
16348         # generate some changelog records to accumulate on MDT0
16349         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16350         createmany -m $DIR/$tdir/$tfile 50 ||
16351                 error "create $DIR/$tdir/$tfile failed"
16352         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16353         rm -f $DIR/$tdir
16354
16355         # check changelogs have been generated
16356         local nbcl=$(changelog_dump | wc -l)
16357         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16358
16359 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16360         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16361
16362         __changelog_clear mds1 $cl_user1 +10
16363         __changelog_clear mds1 $cl_user2 0 &
16364         pid1=$!
16365         sleep 2
16366         __changelog_clear mds1 $cl_user1 0 ||
16367                 error "fail to cancel record for $cl_user1"
16368         wait $pid1
16369         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16370 }
16371 run_test 160m "Changelog clear race"
16372
16373 test_160n() {
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         local first_rec
16382         local last_rec=0
16383
16384         # Create a user
16385         changelog_register || error "first changelog_register failed"
16386
16387         cl_users=(${CL_USERS[mds1]})
16388         cl_user1="${cl_users[0]}"
16389
16390         # generate some changelog records to accumulate on MDT0
16391         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16392         first_rec=$(changelog_users $SINGLEMDS |
16393                         awk '/^current.index:/ { print $NF }')
16394         while (( last_rec < (( first_rec + 65000)) )); do
16395                 createmany -m $DIR/$tdir/$tfile 10000 ||
16396                         error "create $DIR/$tdir/$tfile failed"
16397
16398                 for i in $(seq 0 10000); do
16399                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16400                                 > /dev/null
16401                 done
16402
16403                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16404                         error "unlinkmany failed unlink"
16405                 last_rec=$(changelog_users $SINGLEMDS |
16406                         awk '/^current.index:/ { print $NF }')
16407                 echo last record $last_rec
16408                 (( last_rec == 0 )) && error "no changelog found"
16409         done
16410
16411 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16412         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16413
16414         __changelog_clear mds1 $cl_user1 0 &
16415         pid1=$!
16416         sleep 2
16417         __changelog_clear mds1 $cl_user1 0 ||
16418                 error "fail to cancel record for $cl_user1"
16419         wait $pid1
16420         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16421 }
16422 run_test 160n "Changelog destroy race"
16423
16424 test_160o() {
16425         local mdt="$(facet_svc $SINGLEMDS)"
16426
16427         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16428         remote_mds_nodsh && skip "remote MDS with nodsh"
16429         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16430                 skip "Need MDS version at least 2.14.52"
16431
16432         changelog_register --user test_160o -m unlnk+close+open ||
16433                 error "changelog_register failed"
16434
16435         do_facet $SINGLEMDS $LCTL --device $mdt \
16436                                 changelog_register -u "Tt3_-#" &&
16437                 error "bad symbols in name should fail"
16438
16439         do_facet $SINGLEMDS $LCTL --device $mdt \
16440                                 changelog_register -u test_160o &&
16441                 error "the same name registration should fail"
16442
16443         do_facet $SINGLEMDS $LCTL --device $mdt \
16444                         changelog_register -u test_160toolongname &&
16445                 error "too long name registration should fail"
16446
16447         changelog_chmask "MARK+HSM"
16448         lctl get_param mdd.*.changelog*mask
16449         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16450         changelog_users $SINGLEMDS | grep -q $cl_user ||
16451                 error "User $cl_user not found in changelog_users"
16452         #verify username
16453         echo $cl_user | grep -q test_160o ||
16454                 error "User $cl_user has no specific name 'test160o'"
16455
16456         # change something
16457         changelog_clear 0 || error "changelog_clear failed"
16458         # generate some changelog records to accumulate on MDT0
16459         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16460         touch $DIR/$tdir/$tfile                 # open 1
16461
16462         OPENS=$(changelog_dump | grep -c "OPEN")
16463         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16464
16465         # must be no MKDIR it wasn't set as user mask
16466         MKDIR=$(changelog_dump | grep -c "MKDIR")
16467         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16468
16469         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16470                                 mdd.$mdt.changelog_current_mask -n)
16471         # register maskless user
16472         changelog_register || error "changelog_register failed"
16473         # effective mask should be not changed because it is not minimal
16474         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16475                                 mdd.$mdt.changelog_current_mask -n)
16476         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16477         # set server mask to minimal value
16478         changelog_chmask "MARK"
16479         # check effective mask again, should be treated as DEFMASK now
16480         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16481                                 mdd.$mdt.changelog_current_mask -n)
16482         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16483
16484         do_facet $SINGLEMDS $LCTL --device $mdt \
16485                                 changelog_deregister -u test_160o ||
16486                 error "cannot deregister by name"
16487 }
16488 run_test 160o "changelog user name and mask"
16489
16490 test_160p() {
16491         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16492         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16493                 skip "Need MDS version at least 2.14.51"
16494         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16495         local cl_users
16496         local cl_user1
16497         local entry_count
16498
16499         # Create a user
16500         changelog_register || error "first changelog_register failed"
16501
16502         cl_users=(${CL_USERS[mds1]})
16503         cl_user1="${cl_users[0]}"
16504
16505         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16506         createmany -m $DIR/$tdir/$tfile 50 ||
16507                 error "create $DIR/$tdir/$tfile failed"
16508         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16509         rm -rf $DIR/$tdir
16510
16511         # check changelogs have been generated
16512         entry_count=$(changelog_dump | wc -l)
16513         ((entry_count != 0)) || error "no changelog entries found"
16514
16515         # remove changelog_users and check that orphan entries are removed
16516         stop mds1
16517         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16518         start mds1 || error "cannot start mdt"
16519         entry_count=$(changelog_dump | wc -l)
16520         ((entry_count == 0)) ||
16521                 error "found $entry_count changelog entries, expected none"
16522 }
16523 run_test 160p "Changelog orphan cleanup with no users"
16524
16525 test_160q() {
16526         local mdt="$(facet_svc $SINGLEMDS)"
16527         local clu
16528
16529         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16530         remote_mds_nodsh && skip "remote MDS with nodsh"
16531         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16532                 skip "Need MDS version at least 2.14.54"
16533
16534         # set server mask to minimal value like server init does
16535         changelog_chmask "MARK"
16536         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16537                 error "changelog_register failed"
16538         # check effective mask again, should be treated as DEFMASK now
16539         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16540                                 mdd.$mdt.changelog_current_mask -n)
16541         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16542                 error "changelog_deregister failed"
16543         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16544 }
16545 run_test 160q "changelog effective mask is DEFMASK if not set"
16546
16547 test_161a() {
16548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16549
16550         test_mkdir -c1 $DIR/$tdir
16551         cp /etc/hosts $DIR/$tdir/$tfile
16552         test_mkdir -c1 $DIR/$tdir/foo1
16553         test_mkdir -c1 $DIR/$tdir/foo2
16554         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16555         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16556         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16557         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16558         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16559         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16560                 $LFS fid2path $DIR $FID
16561                 error "bad link ea"
16562         fi
16563         # middle
16564         rm $DIR/$tdir/foo2/zachary
16565         # last
16566         rm $DIR/$tdir/foo2/thor
16567         # first
16568         rm $DIR/$tdir/$tfile
16569         # rename
16570         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16571         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16572                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16573         rm $DIR/$tdir/foo2/maggie
16574
16575         # overflow the EA
16576         local longname=$tfile.avg_len_is_thirty_two_
16577         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16578                 error_noexit 'failed to unlink many hardlinks'" EXIT
16579         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16580                 error "failed to hardlink many files"
16581         links=$($LFS fid2path $DIR $FID | wc -l)
16582         echo -n "${links}/1000 links in link EA"
16583         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16584 }
16585 run_test 161a "link ea sanity"
16586
16587 test_161b() {
16588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16589         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16590
16591         local MDTIDX=1
16592         local remote_dir=$DIR/$tdir/remote_dir
16593
16594         mkdir -p $DIR/$tdir
16595         $LFS mkdir -i $MDTIDX $remote_dir ||
16596                 error "create remote directory failed"
16597
16598         cp /etc/hosts $remote_dir/$tfile
16599         mkdir -p $remote_dir/foo1
16600         mkdir -p $remote_dir/foo2
16601         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16602         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16603         ln $remote_dir/$tfile $remote_dir/foo1/luna
16604         ln $remote_dir/$tfile $remote_dir/foo2/thor
16605
16606         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16607                      tr -d ']')
16608         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16609                 $LFS fid2path $DIR $FID
16610                 error "bad link ea"
16611         fi
16612         # middle
16613         rm $remote_dir/foo2/zachary
16614         # last
16615         rm $remote_dir/foo2/thor
16616         # first
16617         rm $remote_dir/$tfile
16618         # rename
16619         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16620         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16621         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16622                 $LFS fid2path $DIR $FID
16623                 error "bad link rename"
16624         fi
16625         rm $remote_dir/foo2/maggie
16626
16627         # overflow the EA
16628         local longname=filename_avg_len_is_thirty_two_
16629         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16630                 error "failed to hardlink many files"
16631         links=$($LFS fid2path $DIR $FID | wc -l)
16632         echo -n "${links}/1000 links in link EA"
16633         [[ ${links} -gt 60 ]] ||
16634                 error "expected at least 60 links in link EA"
16635         unlinkmany $remote_dir/foo2/$longname 1000 ||
16636         error "failed to unlink many hardlinks"
16637 }
16638 run_test 161b "link ea sanity under remote directory"
16639
16640 test_161c() {
16641         remote_mds_nodsh && skip "remote MDS with nodsh"
16642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16643         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16644                 skip "Need MDS version at least 2.1.5"
16645
16646         # define CLF_RENAME_LAST 0x0001
16647         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16648         changelog_register || error "changelog_register failed"
16649
16650         rm -rf $DIR/$tdir
16651         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16652         touch $DIR/$tdir/foo_161c
16653         touch $DIR/$tdir/bar_161c
16654         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16655         changelog_dump | grep RENME | tail -n 5
16656         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16657         changelog_clear 0 || error "changelog_clear failed"
16658         if [ x$flags != "x0x1" ]; then
16659                 error "flag $flags is not 0x1"
16660         fi
16661
16662         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16663         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16664         touch $DIR/$tdir/foo_161c
16665         touch $DIR/$tdir/bar_161c
16666         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16667         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16668         changelog_dump | grep RENME | tail -n 5
16669         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16670         changelog_clear 0 || error "changelog_clear failed"
16671         if [ x$flags != "x0x0" ]; then
16672                 error "flag $flags is not 0x0"
16673         fi
16674         echo "rename overwrite a target having nlink > 1," \
16675                 "changelog record has flags of $flags"
16676
16677         # rename doesn't overwrite a target (changelog flag 0x0)
16678         touch $DIR/$tdir/foo_161c
16679         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16680         changelog_dump | grep RENME | tail -n 5
16681         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16682         changelog_clear 0 || error "changelog_clear failed"
16683         if [ x$flags != "x0x0" ]; then
16684                 error "flag $flags is not 0x0"
16685         fi
16686         echo "rename doesn't overwrite a target," \
16687                 "changelog record has flags of $flags"
16688
16689         # define CLF_UNLINK_LAST 0x0001
16690         # unlink a file having nlink = 1 (changelog flag 0x1)
16691         rm -f $DIR/$tdir/foo2_161c
16692         changelog_dump | grep UNLNK | tail -n 5
16693         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16694         changelog_clear 0 || error "changelog_clear failed"
16695         if [ x$flags != "x0x1" ]; then
16696                 error "flag $flags is not 0x1"
16697         fi
16698         echo "unlink a file having nlink = 1," \
16699                 "changelog record has flags of $flags"
16700
16701         # unlink a file having nlink > 1 (changelog flag 0x0)
16702         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16703         rm -f $DIR/$tdir/foobar_161c
16704         changelog_dump | grep UNLNK | tail -n 5
16705         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16706         changelog_clear 0 || error "changelog_clear failed"
16707         if [ x$flags != "x0x0" ]; then
16708                 error "flag $flags is not 0x0"
16709         fi
16710         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16711 }
16712 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16713
16714 test_161d() {
16715         remote_mds_nodsh && skip "remote MDS with nodsh"
16716         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16717
16718         local pid
16719         local fid
16720
16721         changelog_register || error "changelog_register failed"
16722
16723         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16724         # interfer with $MOUNT/.lustre/fid/ access
16725         mkdir $DIR/$tdir
16726         [[ $? -eq 0 ]] || error "mkdir failed"
16727
16728         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16729         $LCTL set_param fail_loc=0x8000140c
16730         # 5s pause
16731         $LCTL set_param fail_val=5
16732
16733         # create file
16734         echo foofoo > $DIR/$tdir/$tfile &
16735         pid=$!
16736
16737         # wait for create to be delayed
16738         sleep 2
16739
16740         ps -p $pid
16741         [[ $? -eq 0 ]] || error "create should be blocked"
16742
16743         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16744         stack_trap "rm -f $tempfile"
16745         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16746         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16747         # some delay may occur during ChangeLog publishing and file read just
16748         # above, that could allow file write to happen finally
16749         [[ -s $tempfile ]] && echo "file should be empty"
16750
16751         $LCTL set_param fail_loc=0
16752
16753         wait $pid
16754         [[ $? -eq 0 ]] || error "create failed"
16755 }
16756 run_test 161d "create with concurrent .lustre/fid access"
16757
16758 check_path() {
16759         local expected="$1"
16760         shift
16761         local fid="$2"
16762
16763         local path
16764         path=$($LFS fid2path "$@")
16765         local rc=$?
16766
16767         if [ $rc -ne 0 ]; then
16768                 error "path looked up of '$expected' failed: rc=$rc"
16769         elif [ "$path" != "$expected" ]; then
16770                 error "path looked up '$path' instead of '$expected'"
16771         else
16772                 echo "FID '$fid' resolves to path '$path' as expected"
16773         fi
16774 }
16775
16776 test_162a() { # was test_162
16777         test_mkdir -p -c1 $DIR/$tdir/d2
16778         touch $DIR/$tdir/d2/$tfile
16779         touch $DIR/$tdir/d2/x1
16780         touch $DIR/$tdir/d2/x2
16781         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16782         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16783         # regular file
16784         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16785         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16786
16787         # softlink
16788         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16789         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16790         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16791
16792         # softlink to wrong file
16793         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16794         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16795         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16796
16797         # hardlink
16798         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16799         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16800         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16801         # fid2path dir/fsname should both work
16802         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16803         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16804
16805         # hardlink count: check that there are 2 links
16806         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16807         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16808
16809         # hardlink indexing: remove the first link
16810         rm $DIR/$tdir/d2/p/q/r/hlink
16811         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16812 }
16813 run_test 162a "path lookup sanity"
16814
16815 test_162b() {
16816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16818
16819         mkdir $DIR/$tdir
16820         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16821                                 error "create striped dir failed"
16822
16823         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16824                                         tail -n 1 | awk '{print $2}')
16825         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16826
16827         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16828         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16829
16830         # regular file
16831         for ((i=0;i<5;i++)); do
16832                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16833                         error "get fid for f$i failed"
16834                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16835
16836                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16837                         error "get fid for d$i failed"
16838                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16839         done
16840
16841         return 0
16842 }
16843 run_test 162b "striped directory path lookup sanity"
16844
16845 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16846 test_162c() {
16847         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16848                 skip "Need MDS version at least 2.7.51"
16849
16850         local lpath=$tdir.local
16851         local rpath=$tdir.remote
16852
16853         test_mkdir $DIR/$lpath
16854         test_mkdir $DIR/$rpath
16855
16856         for ((i = 0; i <= 101; i++)); do
16857                 lpath="$lpath/$i"
16858                 mkdir $DIR/$lpath
16859                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16860                         error "get fid for local directory $DIR/$lpath failed"
16861                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16862
16863                 rpath="$rpath/$i"
16864                 test_mkdir $DIR/$rpath
16865                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16866                         error "get fid for remote directory $DIR/$rpath failed"
16867                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16868         done
16869
16870         return 0
16871 }
16872 run_test 162c "fid2path works with paths 100 or more directories deep"
16873
16874 oalr_event_count() {
16875         local event="${1}"
16876         local trace="${2}"
16877
16878         awk -v name="${FSNAME}-OST0000" \
16879             -v event="${event}" \
16880             '$1 == "TRACE" && $2 == event && $3 == name' \
16881             "${trace}" |
16882         wc -l
16883 }
16884
16885 oalr_expect_event_count() {
16886         local event="${1}"
16887         local trace="${2}"
16888         local expect="${3}"
16889         local count
16890
16891         count=$(oalr_event_count "${event}" "${trace}")
16892         if ((count == expect)); then
16893                 return 0
16894         fi
16895
16896         error_noexit "${event} event count was '${count}', expected ${expect}"
16897         cat "${trace}" >&2
16898         exit 1
16899 }
16900
16901 cleanup_165() {
16902         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16903         stop ost1
16904         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16905 }
16906
16907 setup_165() {
16908         sync # Flush previous IOs so we can count log entries.
16909         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16910         stack_trap cleanup_165 EXIT
16911 }
16912
16913 test_165a() {
16914         local trace="/tmp/${tfile}.trace"
16915         local rc
16916         local count
16917
16918         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16919                 skip "OFD access log unsupported"
16920
16921         setup_165
16922         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16923         sleep 5
16924
16925         do_facet ost1 ofd_access_log_reader --list
16926         stop ost1
16927
16928         do_facet ost1 killall -TERM ofd_access_log_reader
16929         wait
16930         rc=$?
16931
16932         if ((rc != 0)); then
16933                 error "ofd_access_log_reader exited with rc = '${rc}'"
16934         fi
16935
16936         # Parse trace file for discovery events:
16937         oalr_expect_event_count alr_log_add "${trace}" 1
16938         oalr_expect_event_count alr_log_eof "${trace}" 1
16939         oalr_expect_event_count alr_log_free "${trace}" 1
16940 }
16941 run_test 165a "ofd access log discovery"
16942
16943 test_165b() {
16944         local trace="/tmp/${tfile}.trace"
16945         local file="${DIR}/${tfile}"
16946         local pfid1
16947         local pfid2
16948         local -a entry
16949         local rc
16950         local count
16951         local size
16952         local flags
16953
16954         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16955                 skip "OFD access log unsupported"
16956
16957         setup_165
16958         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16959         sleep 5
16960
16961         do_facet ost1 ofd_access_log_reader --list
16962
16963         lfs setstripe -c 1 -i 0 "${file}"
16964         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16965                 error "cannot create '${file}'"
16966
16967         sleep 5
16968         do_facet ost1 killall -TERM ofd_access_log_reader
16969         wait
16970         rc=$?
16971
16972         if ((rc != 0)); then
16973                 error "ofd_access_log_reader exited with rc = '${rc}'"
16974         fi
16975
16976         oalr_expect_event_count alr_log_entry "${trace}" 1
16977
16978         pfid1=$($LFS path2fid "${file}")
16979
16980         # 1     2             3   4    5     6   7    8    9     10
16981         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16982         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16983
16984         echo "entry = '${entry[*]}'" >&2
16985
16986         pfid2=${entry[4]}
16987         if [[ "${pfid1}" != "${pfid2}" ]]; then
16988                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16989         fi
16990
16991         size=${entry[8]}
16992         if ((size != 1048576)); then
16993                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16994         fi
16995
16996         flags=${entry[10]}
16997         if [[ "${flags}" != "w" ]]; then
16998                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16999         fi
17000
17001         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17002         sleep 5
17003
17004         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17005                 error "cannot read '${file}'"
17006         sleep 5
17007
17008         do_facet ost1 killall -TERM ofd_access_log_reader
17009         wait
17010         rc=$?
17011
17012         if ((rc != 0)); then
17013                 error "ofd_access_log_reader exited with rc = '${rc}'"
17014         fi
17015
17016         oalr_expect_event_count alr_log_entry "${trace}" 1
17017
17018         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17019         echo "entry = '${entry[*]}'" >&2
17020
17021         pfid2=${entry[4]}
17022         if [[ "${pfid1}" != "${pfid2}" ]]; then
17023                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17024         fi
17025
17026         size=${entry[8]}
17027         if ((size != 524288)); then
17028                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17029         fi
17030
17031         flags=${entry[10]}
17032         if [[ "${flags}" != "r" ]]; then
17033                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17034         fi
17035 }
17036 run_test 165b "ofd access log entries are produced and consumed"
17037
17038 test_165c() {
17039         local trace="/tmp/${tfile}.trace"
17040         local file="${DIR}/${tdir}/${tfile}"
17041
17042         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17043                 skip "OFD access log unsupported"
17044
17045         test_mkdir "${DIR}/${tdir}"
17046
17047         setup_165
17048         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17049         sleep 5
17050
17051         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17052
17053         # 4096 / 64 = 64. Create twice as many entries.
17054         for ((i = 0; i < 128; i++)); do
17055                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17056                         error "cannot create file"
17057         done
17058
17059         sync
17060
17061         do_facet ost1 killall -TERM ofd_access_log_reader
17062         wait
17063         rc=$?
17064         if ((rc != 0)); then
17065                 error "ofd_access_log_reader exited with rc = '${rc}'"
17066         fi
17067
17068         unlinkmany  "${file}-%d" 128
17069 }
17070 run_test 165c "full ofd access logs do not block IOs"
17071
17072 oal_get_read_count() {
17073         local stats="$1"
17074
17075         # STATS lustre-OST0001 alr_read_count 1
17076
17077         do_facet ost1 cat "${stats}" |
17078         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17079              END { print count; }'
17080 }
17081
17082 oal_expect_read_count() {
17083         local stats="$1"
17084         local count
17085         local expect="$2"
17086
17087         # Ask ofd_access_log_reader to write stats.
17088         do_facet ost1 killall -USR1 ofd_access_log_reader
17089
17090         # Allow some time for things to happen.
17091         sleep 1
17092
17093         count=$(oal_get_read_count "${stats}")
17094         if ((count == expect)); then
17095                 return 0
17096         fi
17097
17098         error_noexit "bad read count, got ${count}, expected ${expect}"
17099         do_facet ost1 cat "${stats}" >&2
17100         exit 1
17101 }
17102
17103 test_165d() {
17104         local stats="/tmp/${tfile}.stats"
17105         local file="${DIR}/${tdir}/${tfile}"
17106         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17107
17108         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17109                 skip "OFD access log unsupported"
17110
17111         test_mkdir "${DIR}/${tdir}"
17112
17113         setup_165
17114         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17115         sleep 5
17116
17117         lfs setstripe -c 1 -i 0 "${file}"
17118
17119         do_facet ost1 lctl set_param "${param}=rw"
17120         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17121                 error "cannot create '${file}'"
17122         oal_expect_read_count "${stats}" 1
17123
17124         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17125                 error "cannot read '${file}'"
17126         oal_expect_read_count "${stats}" 2
17127
17128         do_facet ost1 lctl set_param "${param}=r"
17129         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17130                 error "cannot create '${file}'"
17131         oal_expect_read_count "${stats}" 2
17132
17133         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17134                 error "cannot read '${file}'"
17135         oal_expect_read_count "${stats}" 3
17136
17137         do_facet ost1 lctl set_param "${param}=w"
17138         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17139                 error "cannot create '${file}'"
17140         oal_expect_read_count "${stats}" 4
17141
17142         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17143                 error "cannot read '${file}'"
17144         oal_expect_read_count "${stats}" 4
17145
17146         do_facet ost1 lctl set_param "${param}=0"
17147         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17148                 error "cannot create '${file}'"
17149         oal_expect_read_count "${stats}" 4
17150
17151         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17152                 error "cannot read '${file}'"
17153         oal_expect_read_count "${stats}" 4
17154
17155         do_facet ost1 killall -TERM ofd_access_log_reader
17156         wait
17157         rc=$?
17158         if ((rc != 0)); then
17159                 error "ofd_access_log_reader exited with rc = '${rc}'"
17160         fi
17161 }
17162 run_test 165d "ofd_access_log mask works"
17163
17164 test_165e() {
17165         local stats="/tmp/${tfile}.stats"
17166         local file0="${DIR}/${tdir}-0/${tfile}"
17167         local file1="${DIR}/${tdir}-1/${tfile}"
17168
17169         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17170                 skip "OFD access log unsupported"
17171
17172         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17173
17174         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17175         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17176
17177         lfs setstripe -c 1 -i 0 "${file0}"
17178         lfs setstripe -c 1 -i 0 "${file1}"
17179
17180         setup_165
17181         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17182         sleep 5
17183
17184         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17185                 error "cannot create '${file0}'"
17186         sync
17187         oal_expect_read_count "${stats}" 0
17188
17189         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17190                 error "cannot create '${file1}'"
17191         sync
17192         oal_expect_read_count "${stats}" 1
17193
17194         do_facet ost1 killall -TERM ofd_access_log_reader
17195         wait
17196         rc=$?
17197         if ((rc != 0)); then
17198                 error "ofd_access_log_reader exited with rc = '${rc}'"
17199         fi
17200 }
17201 run_test 165e "ofd_access_log MDT index filter works"
17202
17203 test_165f() {
17204         local trace="/tmp/${tfile}.trace"
17205         local rc
17206         local count
17207
17208         setup_165
17209         do_facet ost1 timeout 60 ofd_access_log_reader \
17210                 --exit-on-close --debug=- --trace=- > "${trace}" &
17211         sleep 5
17212         stop ost1
17213
17214         wait
17215         rc=$?
17216
17217         if ((rc != 0)); then
17218                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17219                 cat "${trace}"
17220                 exit 1
17221         fi
17222 }
17223 run_test 165f "ofd_access_log_reader --exit-on-close works"
17224
17225 test_169() {
17226         # do directio so as not to populate the page cache
17227         log "creating a 10 Mb file"
17228         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17229                 error "multiop failed while creating a file"
17230         log "starting reads"
17231         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17232         log "truncating the file"
17233         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17234                 error "multiop failed while truncating the file"
17235         log "killing dd"
17236         kill %+ || true # reads might have finished
17237         echo "wait until dd is finished"
17238         wait
17239         log "removing the temporary file"
17240         rm -rf $DIR/$tfile || error "tmp file removal failed"
17241 }
17242 run_test 169 "parallel read and truncate should not deadlock"
17243
17244 test_170() {
17245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17246
17247         $LCTL clear     # bug 18514
17248         $LCTL debug_daemon start $TMP/${tfile}_log_good
17249         touch $DIR/$tfile
17250         $LCTL debug_daemon stop
17251         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17252                 error "sed failed to read log_good"
17253
17254         $LCTL debug_daemon start $TMP/${tfile}_log_good
17255         rm -rf $DIR/$tfile
17256         $LCTL debug_daemon stop
17257
17258         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17259                error "lctl df log_bad failed"
17260
17261         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17262         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17263
17264         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17265         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17266
17267         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17268                 error "bad_line good_line1 good_line2 are empty"
17269
17270         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17271         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17272         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17273
17274         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17275         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17276         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17277
17278         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17279                 error "bad_line_new good_line_new are empty"
17280
17281         local expected_good=$((good_line1 + good_line2*2))
17282
17283         rm -f $TMP/${tfile}*
17284         # LU-231, short malformed line may not be counted into bad lines
17285         if [ $bad_line -ne $bad_line_new ] &&
17286                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17287                 error "expected $bad_line bad lines, but got $bad_line_new"
17288                 return 1
17289         fi
17290
17291         if [ $expected_good -ne $good_line_new ]; then
17292                 error "expected $expected_good good lines, but got $good_line_new"
17293                 return 2
17294         fi
17295         true
17296 }
17297 run_test 170 "test lctl df to handle corrupted log ====================="
17298
17299 test_171() { # bug20592
17300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17301
17302         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17303         $LCTL set_param fail_loc=0x50e
17304         $LCTL set_param fail_val=3000
17305         multiop_bg_pause $DIR/$tfile O_s || true
17306         local MULTIPID=$!
17307         kill -USR1 $MULTIPID
17308         # cause log dump
17309         sleep 3
17310         wait $MULTIPID
17311         if dmesg | grep "recursive fault"; then
17312                 error "caught a recursive fault"
17313         fi
17314         $LCTL set_param fail_loc=0
17315         true
17316 }
17317 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17318
17319 # it would be good to share it with obdfilter-survey/iokit-libecho code
17320 setup_obdecho_osc () {
17321         local rc=0
17322         local ost_nid=$1
17323         local obdfilter_name=$2
17324         echo "Creating new osc for $obdfilter_name on $ost_nid"
17325         # make sure we can find loopback nid
17326         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17327
17328         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17329                            ${obdfilter_name}_osc_UUID || rc=2; }
17330         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17331                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17332         return $rc
17333 }
17334
17335 cleanup_obdecho_osc () {
17336         local obdfilter_name=$1
17337         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17338         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17339         return 0
17340 }
17341
17342 obdecho_test() {
17343         local OBD=$1
17344         local node=$2
17345         local pages=${3:-64}
17346         local rc=0
17347         local id
17348
17349         local count=10
17350         local obd_size=$(get_obd_size $node $OBD)
17351         local page_size=$(get_page_size $node)
17352         if [[ -n "$obd_size" ]]; then
17353                 local new_count=$((obd_size / (pages * page_size / 1024)))
17354                 [[ $new_count -ge $count ]] || count=$new_count
17355         fi
17356
17357         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17358         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17359                            rc=2; }
17360         if [ $rc -eq 0 ]; then
17361             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17362             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17363         fi
17364         echo "New object id is $id"
17365         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17366                            rc=4; }
17367         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17368                            "test_brw $count w v $pages $id" || rc=4; }
17369         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17370                            rc=4; }
17371         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17372                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17373         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17374                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17375         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17376         return $rc
17377 }
17378
17379 test_180a() {
17380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17381
17382         if ! [ -d /sys/fs/lustre/echo_client ] &&
17383            ! module_loaded obdecho; then
17384                 load_module obdecho/obdecho &&
17385                         stack_trap "rmmod obdecho" EXIT ||
17386                         error "unable to load obdecho on client"
17387         fi
17388
17389         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17390         local host=$($LCTL get_param -n osc.$osc.import |
17391                      awk '/current_connection:/ { print $2 }' )
17392         local target=$($LCTL get_param -n osc.$osc.import |
17393                        awk '/target:/ { print $2 }' )
17394         target=${target%_UUID}
17395
17396         if [ -n "$target" ]; then
17397                 setup_obdecho_osc $host $target &&
17398                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17399                         { error "obdecho setup failed with $?"; return; }
17400
17401                 obdecho_test ${target}_osc client ||
17402                         error "obdecho_test failed on ${target}_osc"
17403         else
17404                 $LCTL get_param osc.$osc.import
17405                 error "there is no osc.$osc.import target"
17406         fi
17407 }
17408 run_test 180a "test obdecho on osc"
17409
17410 test_180b() {
17411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17412         remote_ost_nodsh && skip "remote OST with nodsh"
17413
17414         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17415                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17416                 error "failed to load module obdecho"
17417
17418         local target=$(do_facet ost1 $LCTL dl |
17419                        awk '/obdfilter/ { print $4; exit; }')
17420
17421         if [ -n "$target" ]; then
17422                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17423         else
17424                 do_facet ost1 $LCTL dl
17425                 error "there is no obdfilter target on ost1"
17426         fi
17427 }
17428 run_test 180b "test obdecho directly on obdfilter"
17429
17430 test_180c() { # LU-2598
17431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17432         remote_ost_nodsh && skip "remote OST with nodsh"
17433         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17434                 skip "Need MDS version at least 2.4.0"
17435
17436         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17437                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17438                 error "failed to load module obdecho"
17439
17440         local target=$(do_facet ost1 $LCTL dl |
17441                        awk '/obdfilter/ { print $4; exit; }')
17442
17443         if [ -n "$target" ]; then
17444                 local pages=16384 # 64MB bulk I/O RPC size
17445
17446                 obdecho_test "$target" ost1 "$pages" ||
17447                         error "obdecho_test with pages=$pages failed with $?"
17448         else
17449                 do_facet ost1 $LCTL dl
17450                 error "there is no obdfilter target on ost1"
17451         fi
17452 }
17453 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17454
17455 test_181() { # bug 22177
17456         test_mkdir $DIR/$tdir
17457         # create enough files to index the directory
17458         createmany -o $DIR/$tdir/foobar 4000
17459         # print attributes for debug purpose
17460         lsattr -d .
17461         # open dir
17462         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17463         MULTIPID=$!
17464         # remove the files & current working dir
17465         unlinkmany $DIR/$tdir/foobar 4000
17466         rmdir $DIR/$tdir
17467         kill -USR1 $MULTIPID
17468         wait $MULTIPID
17469         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17470         return 0
17471 }
17472 run_test 181 "Test open-unlinked dir ========================"
17473
17474 test_182() {
17475         local fcount=1000
17476         local tcount=10
17477
17478         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17479
17480         $LCTL set_param mdc.*.rpc_stats=clear
17481
17482         for (( i = 0; i < $tcount; i++ )) ; do
17483                 mkdir $DIR/$tdir/$i
17484         done
17485
17486         for (( i = 0; i < $tcount; i++ )) ; do
17487                 createmany -o $DIR/$tdir/$i/f- $fcount &
17488         done
17489         wait
17490
17491         for (( i = 0; i < $tcount; i++ )) ; do
17492                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17493         done
17494         wait
17495
17496         $LCTL get_param mdc.*.rpc_stats
17497
17498         rm -rf $DIR/$tdir
17499 }
17500 run_test 182 "Test parallel modify metadata operations ================"
17501
17502 test_183() { # LU-2275
17503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17504         remote_mds_nodsh && skip "remote MDS with nodsh"
17505         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17506                 skip "Need MDS version at least 2.3.56"
17507
17508         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17509         echo aaa > $DIR/$tdir/$tfile
17510
17511 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17512         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17513
17514         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17515         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17516
17517         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17518
17519         # Flush negative dentry cache
17520         touch $DIR/$tdir/$tfile
17521
17522         # We are not checking for any leaked references here, they'll
17523         # become evident next time we do cleanup with module unload.
17524         rm -rf $DIR/$tdir
17525 }
17526 run_test 183 "No crash or request leak in case of strange dispositions ========"
17527
17528 # test suite 184 is for LU-2016, LU-2017
17529 test_184a() {
17530         check_swap_layouts_support
17531
17532         dir0=$DIR/$tdir/$testnum
17533         test_mkdir -p -c1 $dir0
17534         ref1=/etc/passwd
17535         ref2=/etc/group
17536         file1=$dir0/f1
17537         file2=$dir0/f2
17538         $LFS setstripe -c1 $file1
17539         cp $ref1 $file1
17540         $LFS setstripe -c2 $file2
17541         cp $ref2 $file2
17542         gen1=$($LFS getstripe -g $file1)
17543         gen2=$($LFS getstripe -g $file2)
17544
17545         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17546         gen=$($LFS getstripe -g $file1)
17547         [[ $gen1 != $gen ]] ||
17548                 "Layout generation on $file1 does not change"
17549         gen=$($LFS getstripe -g $file2)
17550         [[ $gen2 != $gen ]] ||
17551                 "Layout generation on $file2 does not change"
17552
17553         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17554         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17555
17556         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17557 }
17558 run_test 184a "Basic layout swap"
17559
17560 test_184b() {
17561         check_swap_layouts_support
17562
17563         dir0=$DIR/$tdir/$testnum
17564         mkdir -p $dir0 || error "creating dir $dir0"
17565         file1=$dir0/f1
17566         file2=$dir0/f2
17567         file3=$dir0/f3
17568         dir1=$dir0/d1
17569         dir2=$dir0/d2
17570         mkdir $dir1 $dir2
17571         $LFS setstripe -c1 $file1
17572         $LFS setstripe -c2 $file2
17573         $LFS setstripe -c1 $file3
17574         chown $RUNAS_ID $file3
17575         gen1=$($LFS getstripe -g $file1)
17576         gen2=$($LFS getstripe -g $file2)
17577
17578         $LFS swap_layouts $dir1 $dir2 &&
17579                 error "swap of directories layouts should fail"
17580         $LFS swap_layouts $dir1 $file1 &&
17581                 error "swap of directory and file layouts should fail"
17582         $RUNAS $LFS swap_layouts $file1 $file2 &&
17583                 error "swap of file we cannot write should fail"
17584         $LFS swap_layouts $file1 $file3 &&
17585                 error "swap of file with different owner should fail"
17586         /bin/true # to clear error code
17587 }
17588 run_test 184b "Forbidden layout swap (will generate errors)"
17589
17590 test_184c() {
17591         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17592         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17593         check_swap_layouts_support
17594         check_swap_layout_no_dom $DIR
17595
17596         local dir0=$DIR/$tdir/$testnum
17597         mkdir -p $dir0 || error "creating dir $dir0"
17598
17599         local ref1=$dir0/ref1
17600         local ref2=$dir0/ref2
17601         local file1=$dir0/file1
17602         local file2=$dir0/file2
17603         # create a file large enough for the concurrent test
17604         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17605         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17606         echo "ref file size: ref1($(stat -c %s $ref1))," \
17607              "ref2($(stat -c %s $ref2))"
17608
17609         cp $ref2 $file2
17610         dd if=$ref1 of=$file1 bs=16k &
17611         local DD_PID=$!
17612
17613         # Make sure dd starts to copy file, but wait at most 5 seconds
17614         local loops=0
17615         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17616
17617         $LFS swap_layouts $file1 $file2
17618         local rc=$?
17619         wait $DD_PID
17620         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17621         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17622
17623         # how many bytes copied before swapping layout
17624         local copied=$(stat -c %s $file2)
17625         local remaining=$(stat -c %s $ref1)
17626         remaining=$((remaining - copied))
17627         echo "Copied $copied bytes before swapping layout..."
17628
17629         cmp -n $copied $file1 $ref2 | grep differ &&
17630                 error "Content mismatch [0, $copied) of ref2 and file1"
17631         cmp -n $copied $file2 $ref1 ||
17632                 error "Content mismatch [0, $copied) of ref1 and file2"
17633         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17634                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17635
17636         # clean up
17637         rm -f $ref1 $ref2 $file1 $file2
17638 }
17639 run_test 184c "Concurrent write and layout swap"
17640
17641 test_184d() {
17642         check_swap_layouts_support
17643         check_swap_layout_no_dom $DIR
17644         [ -z "$(which getfattr 2>/dev/null)" ] &&
17645                 skip_env "no getfattr command"
17646
17647         local file1=$DIR/$tdir/$tfile-1
17648         local file2=$DIR/$tdir/$tfile-2
17649         local file3=$DIR/$tdir/$tfile-3
17650         local lovea1
17651         local lovea2
17652
17653         mkdir -p $DIR/$tdir
17654         touch $file1 || error "create $file1 failed"
17655         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17656                 error "create $file2 failed"
17657         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17658                 error "create $file3 failed"
17659         lovea1=$(get_layout_param $file1)
17660
17661         $LFS swap_layouts $file2 $file3 ||
17662                 error "swap $file2 $file3 layouts failed"
17663         $LFS swap_layouts $file1 $file2 ||
17664                 error "swap $file1 $file2 layouts failed"
17665
17666         lovea2=$(get_layout_param $file2)
17667         echo "$lovea1"
17668         echo "$lovea2"
17669         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17670
17671         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17672         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17673 }
17674 run_test 184d "allow stripeless layouts swap"
17675
17676 test_184e() {
17677         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17678                 skip "Need MDS version at least 2.6.94"
17679         check_swap_layouts_support
17680         check_swap_layout_no_dom $DIR
17681         [ -z "$(which getfattr 2>/dev/null)" ] &&
17682                 skip_env "no getfattr command"
17683
17684         local file1=$DIR/$tdir/$tfile-1
17685         local file2=$DIR/$tdir/$tfile-2
17686         local file3=$DIR/$tdir/$tfile-3
17687         local lovea
17688
17689         mkdir -p $DIR/$tdir
17690         touch $file1 || error "create $file1 failed"
17691         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17692                 error "create $file2 failed"
17693         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17694                 error "create $file3 failed"
17695
17696         $LFS swap_layouts $file1 $file2 ||
17697                 error "swap $file1 $file2 layouts failed"
17698
17699         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17700         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17701
17702         echo 123 > $file1 || error "Should be able to write into $file1"
17703
17704         $LFS swap_layouts $file1 $file3 ||
17705                 error "swap $file1 $file3 layouts failed"
17706
17707         echo 123 > $file1 || error "Should be able to write into $file1"
17708
17709         rm -rf $file1 $file2 $file3
17710 }
17711 run_test 184e "Recreate layout after stripeless layout swaps"
17712
17713 test_184f() {
17714         # Create a file with name longer than sizeof(struct stat) ==
17715         # 144 to see if we can get chars from the file name to appear
17716         # in the returned striping. Note that 'f' == 0x66.
17717         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17718
17719         mkdir -p $DIR/$tdir
17720         mcreate $DIR/$tdir/$file
17721         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17722                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17723         fi
17724 }
17725 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17726
17727 test_185() { # LU-2441
17728         # LU-3553 - no volatile file support in old servers
17729         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17730                 skip "Need MDS version at least 2.3.60"
17731
17732         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17733         touch $DIR/$tdir/spoo
17734         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17735         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17736                 error "cannot create/write a volatile file"
17737         [ "$FILESET" == "" ] &&
17738         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17739                 error "FID is still valid after close"
17740
17741         multiop_bg_pause $DIR/$tdir vVw4096_c
17742         local multi_pid=$!
17743
17744         local OLD_IFS=$IFS
17745         IFS=":"
17746         local fidv=($fid)
17747         IFS=$OLD_IFS
17748         # assume that the next FID for this client is sequential, since stdout
17749         # is unfortunately eaten by multiop_bg_pause
17750         local n=$((${fidv[1]} + 1))
17751         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17752         if [ "$FILESET" == "" ]; then
17753                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17754                         error "FID is missing before close"
17755         fi
17756         kill -USR1 $multi_pid
17757         # 1 second delay, so if mtime change we will see it
17758         sleep 1
17759         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17760         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17761 }
17762 run_test 185 "Volatile file support"
17763
17764 function create_check_volatile() {
17765         local idx=$1
17766         local tgt
17767
17768         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17769         local PID=$!
17770         sleep 1
17771         local FID=$(cat /tmp/${tfile}.fid)
17772         [ "$FID" == "" ] && error "can't get FID for volatile"
17773         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17774         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17775         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17776         kill -USR1 $PID
17777         wait
17778         sleep 1
17779         cancel_lru_locks mdc # flush opencache
17780         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17781         return 0
17782 }
17783
17784 test_185a(){
17785         # LU-12516 - volatile creation via .lustre
17786         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17787                 skip "Need MDS version at least 2.3.55"
17788
17789         create_check_volatile 0
17790         [ $MDSCOUNT -lt 2 ] && return 0
17791
17792         # DNE case
17793         create_check_volatile 1
17794
17795         return 0
17796 }
17797 run_test 185a "Volatile file creation in .lustre/fid/"
17798
17799 test_187a() {
17800         remote_mds_nodsh && skip "remote MDS with nodsh"
17801         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17802                 skip "Need MDS version at least 2.3.0"
17803
17804         local dir0=$DIR/$tdir/$testnum
17805         mkdir -p $dir0 || error "creating dir $dir0"
17806
17807         local file=$dir0/file1
17808         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17809         local dv1=$($LFS data_version $file)
17810         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17811         local dv2=$($LFS data_version $file)
17812         [[ $dv1 != $dv2 ]] ||
17813                 error "data version did not change on write $dv1 == $dv2"
17814
17815         # clean up
17816         rm -f $file1
17817 }
17818 run_test 187a "Test data version change"
17819
17820 test_187b() {
17821         remote_mds_nodsh && skip "remote MDS with nodsh"
17822         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17823                 skip "Need MDS version at least 2.3.0"
17824
17825         local dir0=$DIR/$tdir/$testnum
17826         mkdir -p $dir0 || error "creating dir $dir0"
17827
17828         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17829         [[ ${DV[0]} != ${DV[1]} ]] ||
17830                 error "data version did not change on write"\
17831                       " ${DV[0]} == ${DV[1]}"
17832
17833         # clean up
17834         rm -f $file1
17835 }
17836 run_test 187b "Test data version change on volatile file"
17837
17838 test_200() {
17839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17840         remote_mgs_nodsh && skip "remote MGS with nodsh"
17841         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17842
17843         local POOL=${POOL:-cea1}
17844         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17845         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17846         # Pool OST targets
17847         local first_ost=0
17848         local last_ost=$(($OSTCOUNT - 1))
17849         local ost_step=2
17850         local ost_list=$(seq $first_ost $ost_step $last_ost)
17851         local ost_range="$first_ost $last_ost $ost_step"
17852         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17853         local file_dir=$POOL_ROOT/file_tst
17854         local subdir=$test_path/subdir
17855         local rc=0
17856
17857         while : ; do
17858                 # former test_200a test_200b
17859                 pool_add $POOL                          || { rc=$? ; break; }
17860                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17861                 # former test_200c test_200d
17862                 mkdir -p $test_path
17863                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17864                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17865                 mkdir -p $subdir
17866                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17867                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17868                                                         || { rc=$? ; break; }
17869                 # former test_200e test_200f
17870                 local files=$((OSTCOUNT*3))
17871                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17872                                                         || { rc=$? ; break; }
17873                 pool_create_files $POOL $file_dir $files "$ost_list" \
17874                                                         || { rc=$? ; break; }
17875                 # former test_200g test_200h
17876                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17877                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17878
17879                 # former test_201a test_201b test_201c
17880                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17881
17882                 local f=$test_path/$tfile
17883                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17884                 pool_remove $POOL $f                    || { rc=$? ; break; }
17885                 break
17886         done
17887
17888         destroy_test_pools
17889
17890         return $rc
17891 }
17892 run_test 200 "OST pools"
17893
17894 # usage: default_attr <count | size | offset>
17895 default_attr() {
17896         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17897 }
17898
17899 # usage: check_default_stripe_attr
17900 check_default_stripe_attr() {
17901         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17902         case $1 in
17903         --stripe-count|-c)
17904                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17905         --stripe-size|-S)
17906                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17907         --stripe-index|-i)
17908                 EXPECTED=-1;;
17909         *)
17910                 error "unknown getstripe attr '$1'"
17911         esac
17912
17913         [ $ACTUAL == $EXPECTED ] ||
17914                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17915 }
17916
17917 test_204a() {
17918         test_mkdir $DIR/$tdir
17919         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17920
17921         check_default_stripe_attr --stripe-count
17922         check_default_stripe_attr --stripe-size
17923         check_default_stripe_attr --stripe-index
17924 }
17925 run_test 204a "Print default stripe attributes"
17926
17927 test_204b() {
17928         test_mkdir $DIR/$tdir
17929         $LFS setstripe --stripe-count 1 $DIR/$tdir
17930
17931         check_default_stripe_attr --stripe-size
17932         check_default_stripe_attr --stripe-index
17933 }
17934 run_test 204b "Print default stripe size and offset"
17935
17936 test_204c() {
17937         test_mkdir $DIR/$tdir
17938         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17939
17940         check_default_stripe_attr --stripe-count
17941         check_default_stripe_attr --stripe-index
17942 }
17943 run_test 204c "Print default stripe count and offset"
17944
17945 test_204d() {
17946         test_mkdir $DIR/$tdir
17947         $LFS setstripe --stripe-index 0 $DIR/$tdir
17948
17949         check_default_stripe_attr --stripe-count
17950         check_default_stripe_attr --stripe-size
17951 }
17952 run_test 204d "Print default stripe count and size"
17953
17954 test_204e() {
17955         test_mkdir $DIR/$tdir
17956         $LFS setstripe -d $DIR/$tdir
17957
17958         check_default_stripe_attr --stripe-count --raw
17959         check_default_stripe_attr --stripe-size --raw
17960         check_default_stripe_attr --stripe-index --raw
17961 }
17962 run_test 204e "Print raw stripe attributes"
17963
17964 test_204f() {
17965         test_mkdir $DIR/$tdir
17966         $LFS setstripe --stripe-count 1 $DIR/$tdir
17967
17968         check_default_stripe_attr --stripe-size --raw
17969         check_default_stripe_attr --stripe-index --raw
17970 }
17971 run_test 204f "Print raw stripe size and offset"
17972
17973 test_204g() {
17974         test_mkdir $DIR/$tdir
17975         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17976
17977         check_default_stripe_attr --stripe-count --raw
17978         check_default_stripe_attr --stripe-index --raw
17979 }
17980 run_test 204g "Print raw stripe count and offset"
17981
17982 test_204h() {
17983         test_mkdir $DIR/$tdir
17984         $LFS setstripe --stripe-index 0 $DIR/$tdir
17985
17986         check_default_stripe_attr --stripe-count --raw
17987         check_default_stripe_attr --stripe-size --raw
17988 }
17989 run_test 204h "Print raw stripe count and size"
17990
17991 # Figure out which job scheduler is being used, if any,
17992 # or use a fake one
17993 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17994         JOBENV=SLURM_JOB_ID
17995 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17996         JOBENV=LSB_JOBID
17997 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17998         JOBENV=PBS_JOBID
17999 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18000         JOBENV=LOADL_STEP_ID
18001 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18002         JOBENV=JOB_ID
18003 else
18004         $LCTL list_param jobid_name > /dev/null 2>&1
18005         if [ $? -eq 0 ]; then
18006                 JOBENV=nodelocal
18007         else
18008                 JOBENV=FAKE_JOBID
18009         fi
18010 fi
18011 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18012
18013 verify_jobstats() {
18014         local cmd=($1)
18015         shift
18016         local facets="$@"
18017
18018 # we don't really need to clear the stats for this test to work, since each
18019 # command has a unique jobid, but it makes debugging easier if needed.
18020 #       for facet in $facets; do
18021 #               local dev=$(convert_facet2label $facet)
18022 #               # clear old jobstats
18023 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18024 #       done
18025
18026         # use a new JobID for each test, or we might see an old one
18027         [ "$JOBENV" = "FAKE_JOBID" ] &&
18028                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18029
18030         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18031
18032         [ "$JOBENV" = "nodelocal" ] && {
18033                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18034                 $LCTL set_param jobid_name=$FAKE_JOBID
18035                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18036         }
18037
18038         log "Test: ${cmd[*]}"
18039         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18040
18041         if [ $JOBENV = "FAKE_JOBID" ]; then
18042                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18043         else
18044                 ${cmd[*]}
18045         fi
18046
18047         # all files are created on OST0000
18048         for facet in $facets; do
18049                 local stats="*.$(convert_facet2label $facet).job_stats"
18050
18051                 # strip out libtool wrappers for in-tree executables
18052                 if [ $(do_facet $facet lctl get_param $stats |
18053                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18054                         do_facet $facet lctl get_param $stats
18055                         error "No jobstats for $JOBVAL found on $facet::$stats"
18056                 fi
18057         done
18058 }
18059
18060 jobstats_set() {
18061         local new_jobenv=$1
18062
18063         set_persistent_param_and_check client "jobid_var" \
18064                 "$FSNAME.sys.jobid_var" $new_jobenv
18065 }
18066
18067 test_205a() { # Job stats
18068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18069         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18070                 skip "Need MDS version with at least 2.7.1"
18071         remote_mgs_nodsh && skip "remote MGS with nodsh"
18072         remote_mds_nodsh && skip "remote MDS with nodsh"
18073         remote_ost_nodsh && skip "remote OST with nodsh"
18074         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18075                 skip "Server doesn't support jobstats"
18076         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18077
18078         local old_jobenv=$($LCTL get_param -n jobid_var)
18079         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18080
18081         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18082                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18083         else
18084                 stack_trap "do_facet mgs $PERM_CMD \
18085                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18086         fi
18087         changelog_register
18088
18089         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18090                                 mdt.*.job_cleanup_interval | head -n 1)
18091         local new_interval=5
18092         do_facet $SINGLEMDS \
18093                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18094         stack_trap "do_facet $SINGLEMDS \
18095                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18096         local start=$SECONDS
18097
18098         local cmd
18099         # mkdir
18100         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18101         verify_jobstats "$cmd" "$SINGLEMDS"
18102         # rmdir
18103         cmd="rmdir $DIR/$tdir"
18104         verify_jobstats "$cmd" "$SINGLEMDS"
18105         # mkdir on secondary MDT
18106         if [ $MDSCOUNT -gt 1 ]; then
18107                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18108                 verify_jobstats "$cmd" "mds2"
18109         fi
18110         # mknod
18111         cmd="mknod $DIR/$tfile c 1 3"
18112         verify_jobstats "$cmd" "$SINGLEMDS"
18113         # unlink
18114         cmd="rm -f $DIR/$tfile"
18115         verify_jobstats "$cmd" "$SINGLEMDS"
18116         # create all files on OST0000 so verify_jobstats can find OST stats
18117         # open & close
18118         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18119         verify_jobstats "$cmd" "$SINGLEMDS"
18120         # setattr
18121         cmd="touch $DIR/$tfile"
18122         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18123         # write
18124         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18125         verify_jobstats "$cmd" "ost1"
18126         # read
18127         cancel_lru_locks osc
18128         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18129         verify_jobstats "$cmd" "ost1"
18130         # truncate
18131         cmd="$TRUNCATE $DIR/$tfile 0"
18132         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18133         # rename
18134         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18135         verify_jobstats "$cmd" "$SINGLEMDS"
18136         # jobstats expiry - sleep until old stats should be expired
18137         local left=$((new_interval + 5 - (SECONDS - start)))
18138         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18139                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18140                         "0" $left
18141         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18142         verify_jobstats "$cmd" "$SINGLEMDS"
18143         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18144             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18145
18146         # Ensure that jobid are present in changelog (if supported by MDS)
18147         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18148                 changelog_dump | tail -10
18149                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18150                 [ $jobids -eq 9 ] ||
18151                         error "Wrong changelog jobid count $jobids != 9"
18152
18153                 # LU-5862
18154                 JOBENV="disable"
18155                 jobstats_set $JOBENV
18156                 touch $DIR/$tfile
18157                 changelog_dump | grep $tfile
18158                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18159                 [ $jobids -eq 0 ] ||
18160                         error "Unexpected jobids when jobid_var=$JOBENV"
18161         fi
18162
18163         # test '%j' access to environment variable - if supported
18164         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18165                 JOBENV="JOBCOMPLEX"
18166                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18167
18168                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18169         fi
18170
18171         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18172                 JOBENV="JOBCOMPLEX"
18173                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18174
18175                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18176         fi
18177
18178         # test '%j' access to per-session jobid - if supported
18179         if lctl list_param jobid_this_session > /dev/null 2>&1
18180         then
18181                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18182                 lctl set_param jobid_this_session=$USER
18183
18184                 JOBENV="JOBCOMPLEX"
18185                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18186
18187                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18188         fi
18189 }
18190 run_test 205a "Verify job stats"
18191
18192 # LU-13117, LU-13597
18193 test_205b() {
18194         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18195                 skip "Need MDS version at least 2.13.54.91"
18196
18197         job_stats="mdt.*.job_stats"
18198         $LCTL set_param $job_stats=clear
18199         # Setting jobid_var to USER might not be supported
18200         $LCTL set_param jobid_var=USER || true
18201         $LCTL set_param jobid_name="%e.%u"
18202         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18203         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18204                 grep "job_id:.*foolish" &&
18205                         error "Unexpected jobid found"
18206         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18207                 grep "open:.*min.*max.*sum" ||
18208                         error "wrong job_stats format found"
18209 }
18210 run_test 205b "Verify job stats jobid and output format"
18211
18212 # LU-13733
18213 test_205c() {
18214         $LCTL set_param llite.*.stats=0
18215         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18216         $LCTL get_param llite.*.stats
18217         $LCTL get_param llite.*.stats | grep \
18218                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18219                         error "wrong client stats format found"
18220 }
18221 run_test 205c "Verify client stats format"
18222
18223 # LU-1480, LU-1773 and LU-1657
18224 test_206() {
18225         mkdir -p $DIR/$tdir
18226         $LFS setstripe -c -1 $DIR/$tdir
18227 #define OBD_FAIL_LOV_INIT 0x1403
18228         $LCTL set_param fail_loc=0xa0001403
18229         $LCTL set_param fail_val=1
18230         touch $DIR/$tdir/$tfile || true
18231 }
18232 run_test 206 "fail lov_init_raid0() doesn't lbug"
18233
18234 test_207a() {
18235         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18236         local fsz=`stat -c %s $DIR/$tfile`
18237         cancel_lru_locks mdc
18238
18239         # do not return layout in getattr intent
18240 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18241         $LCTL set_param fail_loc=0x170
18242         local sz=`stat -c %s $DIR/$tfile`
18243
18244         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18245
18246         rm -rf $DIR/$tfile
18247 }
18248 run_test 207a "can refresh layout at glimpse"
18249
18250 test_207b() {
18251         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18252         local cksum=`md5sum $DIR/$tfile`
18253         local fsz=`stat -c %s $DIR/$tfile`
18254         cancel_lru_locks mdc
18255         cancel_lru_locks osc
18256
18257         # do not return layout in getattr intent
18258 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18259         $LCTL set_param fail_loc=0x171
18260
18261         # it will refresh layout after the file is opened but before read issues
18262         echo checksum is "$cksum"
18263         echo "$cksum" |md5sum -c --quiet || error "file differs"
18264
18265         rm -rf $DIR/$tfile
18266 }
18267 run_test 207b "can refresh layout at open"
18268
18269 test_208() {
18270         # FIXME: in this test suite, only RD lease is used. This is okay
18271         # for now as only exclusive open is supported. After generic lease
18272         # is done, this test suite should be revised. - Jinshan
18273
18274         remote_mds_nodsh && skip "remote MDS with nodsh"
18275         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18276                 skip "Need MDS version at least 2.4.52"
18277
18278         echo "==== test 1: verify get lease work"
18279         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18280
18281         echo "==== test 2: verify lease can be broken by upcoming open"
18282         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18283         local PID=$!
18284         sleep 1
18285
18286         $MULTIOP $DIR/$tfile oO_RDWR:c
18287         kill -USR1 $PID && wait $PID || error "break lease error"
18288
18289         echo "==== test 3: verify lease can't be granted if an open already exists"
18290         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18291         local PID=$!
18292         sleep 1
18293
18294         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18295         kill -USR1 $PID && wait $PID || error "open file error"
18296
18297         echo "==== test 4: lease can sustain over recovery"
18298         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18299         PID=$!
18300         sleep 1
18301
18302         fail mds1
18303
18304         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18305
18306         echo "==== test 5: lease broken can't be regained by replay"
18307         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18308         PID=$!
18309         sleep 1
18310
18311         # open file to break lease and then recovery
18312         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18313         fail mds1
18314
18315         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18316
18317         rm -f $DIR/$tfile
18318 }
18319 run_test 208 "Exclusive open"
18320
18321 test_209() {
18322         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18323                 skip_env "must have disp_stripe"
18324
18325         touch $DIR/$tfile
18326         sync; sleep 5; sync;
18327
18328         echo 3 > /proc/sys/vm/drop_caches
18329         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18330                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18331         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18332
18333         # open/close 500 times
18334         for i in $(seq 500); do
18335                 cat $DIR/$tfile
18336         done
18337
18338         echo 3 > /proc/sys/vm/drop_caches
18339         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18340                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18341         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18342
18343         echo "before: $req_before, after: $req_after"
18344         [ $((req_after - req_before)) -ge 300 ] &&
18345                 error "open/close requests are not freed"
18346         return 0
18347 }
18348 run_test 209 "read-only open/close requests should be freed promptly"
18349
18350 test_210() {
18351         local pid
18352
18353         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18354         pid=$!
18355         sleep 1
18356
18357         $LFS getstripe $DIR/$tfile
18358         kill -USR1 $pid
18359         wait $pid || error "multiop failed"
18360
18361         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18362         pid=$!
18363         sleep 1
18364
18365         $LFS getstripe $DIR/$tfile
18366         kill -USR1 $pid
18367         wait $pid || error "multiop failed"
18368 }
18369 run_test 210 "lfs getstripe does not break leases"
18370
18371 test_212() {
18372         size=`date +%s`
18373         size=$((size % 8192 + 1))
18374         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18375         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18376         rm -f $DIR/f212 $DIR/f212.xyz
18377 }
18378 run_test 212 "Sendfile test ============================================"
18379
18380 test_213() {
18381         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18382         cancel_lru_locks osc
18383         lctl set_param fail_loc=0x8000040f
18384         # generate a read lock
18385         cat $DIR/$tfile > /dev/null
18386         # write to the file, it will try to cancel the above read lock.
18387         cat /etc/hosts >> $DIR/$tfile
18388 }
18389 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18390
18391 test_214() { # for bug 20133
18392         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18393         for (( i=0; i < 340; i++ )) ; do
18394                 touch $DIR/$tdir/d214c/a$i
18395         done
18396
18397         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18398         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18399         ls $DIR/d214c || error "ls $DIR/d214c failed"
18400         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18401         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18402 }
18403 run_test 214 "hash-indexed directory test - bug 20133"
18404
18405 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18406 create_lnet_proc_files() {
18407         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18408 }
18409
18410 # counterpart of create_lnet_proc_files
18411 remove_lnet_proc_files() {
18412         rm -f $TMP/lnet_$1.sys
18413 }
18414
18415 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18416 # 3rd arg as regexp for body
18417 check_lnet_proc_stats() {
18418         local l=$(cat "$TMP/lnet_$1" |wc -l)
18419         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18420
18421         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18422 }
18423
18424 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18425 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18426 # optional and can be regexp for 2nd line (lnet.routes case)
18427 check_lnet_proc_entry() {
18428         local blp=2          # blp stands for 'position of 1st line of body'
18429         [ -z "$5" ] || blp=3 # lnet.routes case
18430
18431         local l=$(cat "$TMP/lnet_$1" |wc -l)
18432         # subtracting one from $blp because the body can be empty
18433         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18434
18435         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18436                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18437
18438         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18439                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18440
18441         # bail out if any unexpected line happened
18442         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18443         [ "$?" != 0 ] || error "$2 misformatted"
18444 }
18445
18446 test_215() { # for bugs 18102, 21079, 21517
18447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18448
18449         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18450         local P='[1-9][0-9]*'           # positive numeric
18451         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18452         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18453         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18454         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18455
18456         local L1 # regexp for 1st line
18457         local L2 # regexp for 2nd line (optional)
18458         local BR # regexp for the rest (body)
18459
18460         # lnet.stats should look as 11 space-separated non-negative numerics
18461         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18462         create_lnet_proc_files "stats"
18463         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18464         remove_lnet_proc_files "stats"
18465
18466         # lnet.routes should look like this:
18467         # Routing disabled/enabled
18468         # net hops priority state router
18469         # where net is a string like tcp0, hops > 0, priority >= 0,
18470         # state is up/down,
18471         # router is a string like 192.168.1.1@tcp2
18472         L1="^Routing (disabled|enabled)$"
18473         L2="^net +hops +priority +state +router$"
18474         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18475         create_lnet_proc_files "routes"
18476         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18477         remove_lnet_proc_files "routes"
18478
18479         # lnet.routers should look like this:
18480         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18481         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18482         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18483         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18484         L1="^ref +rtr_ref +alive +router$"
18485         BR="^$P +$P +(up|down) +$NID$"
18486         create_lnet_proc_files "routers"
18487         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18488         remove_lnet_proc_files "routers"
18489
18490         # lnet.peers should look like this:
18491         # nid refs state last max rtr min tx min queue
18492         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18493         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18494         # numeric (0 or >0 or <0), queue >= 0.
18495         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18496         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18497         create_lnet_proc_files "peers"
18498         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18499         remove_lnet_proc_files "peers"
18500
18501         # lnet.buffers  should look like this:
18502         # pages count credits min
18503         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18504         L1="^pages +count +credits +min$"
18505         BR="^ +$N +$N +$I +$I$"
18506         create_lnet_proc_files "buffers"
18507         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18508         remove_lnet_proc_files "buffers"
18509
18510         # lnet.nis should look like this:
18511         # nid status alive refs peer rtr max tx min
18512         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18513         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18514         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18515         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18516         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18517         create_lnet_proc_files "nis"
18518         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18519         remove_lnet_proc_files "nis"
18520
18521         # can we successfully write to lnet.stats?
18522         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18523 }
18524 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18525
18526 test_216() { # bug 20317
18527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18528         remote_ost_nodsh && skip "remote OST with nodsh"
18529
18530         local node
18531         local facets=$(get_facets OST)
18532         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18533
18534         save_lustre_params client "osc.*.contention_seconds" > $p
18535         save_lustre_params $facets \
18536                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18537         save_lustre_params $facets \
18538                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18539         save_lustre_params $facets \
18540                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18541         clear_stats osc.*.osc_stats
18542
18543         # agressive lockless i/o settings
18544         do_nodes $(comma_list $(osts_nodes)) \
18545                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18546                         ldlm.namespaces.filter-*.contended_locks=0 \
18547                         ldlm.namespaces.filter-*.contention_seconds=60"
18548         lctl set_param -n osc.*.contention_seconds=60
18549
18550         $DIRECTIO write $DIR/$tfile 0 10 4096
18551         $CHECKSTAT -s 40960 $DIR/$tfile
18552
18553         # disable lockless i/o
18554         do_nodes $(comma_list $(osts_nodes)) \
18555                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18556                         ldlm.namespaces.filter-*.contended_locks=32 \
18557                         ldlm.namespaces.filter-*.contention_seconds=0"
18558         lctl set_param -n osc.*.contention_seconds=0
18559         clear_stats osc.*.osc_stats
18560
18561         dd if=/dev/zero of=$DIR/$tfile count=0
18562         $CHECKSTAT -s 0 $DIR/$tfile
18563
18564         restore_lustre_params <$p
18565         rm -f $p
18566         rm $DIR/$tfile
18567 }
18568 run_test 216 "check lockless direct write updates file size and kms correctly"
18569
18570 test_217() { # bug 22430
18571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18572
18573         local node
18574         local nid
18575
18576         for node in $(nodes_list); do
18577                 nid=$(host_nids_address $node $NETTYPE)
18578                 if [[ $nid = *-* ]] ; then
18579                         echo "lctl ping $(h2nettype $nid)"
18580                         lctl ping $(h2nettype $nid)
18581                 else
18582                         echo "skipping $node (no hyphen detected)"
18583                 fi
18584         done
18585 }
18586 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18587
18588 test_218() {
18589        # do directio so as not to populate the page cache
18590        log "creating a 10 Mb file"
18591        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18592        log "starting reads"
18593        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18594        log "truncating the file"
18595        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18596        log "killing dd"
18597        kill %+ || true # reads might have finished
18598        echo "wait until dd is finished"
18599        wait
18600        log "removing the temporary file"
18601        rm -rf $DIR/$tfile || error "tmp file removal failed"
18602 }
18603 run_test 218 "parallel read and truncate should not deadlock"
18604
18605 test_219() {
18606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18607
18608         # write one partial page
18609         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18610         # set no grant so vvp_io_commit_write will do sync write
18611         $LCTL set_param fail_loc=0x411
18612         # write a full page at the end of file
18613         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18614
18615         $LCTL set_param fail_loc=0
18616         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18617         $LCTL set_param fail_loc=0x411
18618         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18619
18620         # LU-4201
18621         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18622         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18623 }
18624 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18625
18626 test_220() { #LU-325
18627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18628         remote_ost_nodsh && skip "remote OST with nodsh"
18629         remote_mds_nodsh && skip "remote MDS with nodsh"
18630         remote_mgs_nodsh && skip "remote MGS with nodsh"
18631
18632         local OSTIDX=0
18633
18634         # create on MDT0000 so the last_id and next_id are correct
18635         mkdir_on_mdt0 $DIR/$tdir
18636         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18637         OST=${OST%_UUID}
18638
18639         # on the mdt's osc
18640         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18641         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18642                         osp.$mdtosc_proc1.prealloc_last_id)
18643         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18644                         osp.$mdtosc_proc1.prealloc_next_id)
18645
18646         $LFS df -i
18647
18648         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18649         #define OBD_FAIL_OST_ENOINO              0x229
18650         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18651         create_pool $FSNAME.$TESTNAME || return 1
18652         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18653
18654         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18655
18656         MDSOBJS=$((last_id - next_id))
18657         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18658
18659         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18660         echo "OST still has $count kbytes free"
18661
18662         echo "create $MDSOBJS files @next_id..."
18663         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18664
18665         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18666                         osp.$mdtosc_proc1.prealloc_last_id)
18667         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18668                         osp.$mdtosc_proc1.prealloc_next_id)
18669
18670         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18671         $LFS df -i
18672
18673         echo "cleanup..."
18674
18675         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18676         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18677
18678         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18679                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18680         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18681                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18682         echo "unlink $MDSOBJS files @$next_id..."
18683         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18684 }
18685 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18686
18687 test_221() {
18688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18689
18690         dd if=`which date` of=$MOUNT/date oflag=sync
18691         chmod +x $MOUNT/date
18692
18693         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18694         $LCTL set_param fail_loc=0x80001401
18695
18696         $MOUNT/date > /dev/null
18697         rm -f $MOUNT/date
18698 }
18699 run_test 221 "make sure fault and truncate race to not cause OOM"
18700
18701 test_222a () {
18702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18703
18704         rm -rf $DIR/$tdir
18705         test_mkdir $DIR/$tdir
18706         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18707         createmany -o $DIR/$tdir/$tfile 10
18708         cancel_lru_locks mdc
18709         cancel_lru_locks osc
18710         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18711         $LCTL set_param fail_loc=0x31a
18712         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18713         $LCTL set_param fail_loc=0
18714         rm -r $DIR/$tdir
18715 }
18716 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18717
18718 test_222b () {
18719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18720
18721         rm -rf $DIR/$tdir
18722         test_mkdir $DIR/$tdir
18723         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18724         createmany -o $DIR/$tdir/$tfile 10
18725         cancel_lru_locks mdc
18726         cancel_lru_locks osc
18727         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18728         $LCTL set_param fail_loc=0x31a
18729         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18730         $LCTL set_param fail_loc=0
18731 }
18732 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18733
18734 test_223 () {
18735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18736
18737         rm -rf $DIR/$tdir
18738         test_mkdir $DIR/$tdir
18739         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18740         createmany -o $DIR/$tdir/$tfile 10
18741         cancel_lru_locks mdc
18742         cancel_lru_locks osc
18743         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18744         $LCTL set_param fail_loc=0x31b
18745         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18746         $LCTL set_param fail_loc=0
18747         rm -r $DIR/$tdir
18748 }
18749 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18750
18751 test_224a() { # LU-1039, MRP-303
18752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18753
18754         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18755         $LCTL set_param fail_loc=0x508
18756         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18757         $LCTL set_param fail_loc=0
18758         df $DIR
18759 }
18760 run_test 224a "Don't panic on bulk IO failure"
18761
18762 test_224b() { # LU-1039, MRP-303
18763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18764
18765         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18766         cancel_lru_locks osc
18767         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18768         $LCTL set_param fail_loc=0x515
18769         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18770         $LCTL set_param fail_loc=0
18771         df $DIR
18772 }
18773 run_test 224b "Don't panic on bulk IO failure"
18774
18775 test_224c() { # LU-6441
18776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18777         remote_mds_nodsh && skip "remote MDS with nodsh"
18778
18779         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18780         save_writethrough $p
18781         set_cache writethrough on
18782
18783         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18784         local at_max=$($LCTL get_param -n at_max)
18785         local timeout=$($LCTL get_param -n timeout)
18786         local test_at="at_max"
18787         local param_at="$FSNAME.sys.at_max"
18788         local test_timeout="timeout"
18789         local param_timeout="$FSNAME.sys.timeout"
18790
18791         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18792
18793         set_persistent_param_and_check client "$test_at" "$param_at" 0
18794         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18795
18796         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18797         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18798         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18799         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18800         sync
18801         do_facet ost1 "$LCTL set_param fail_loc=0"
18802
18803         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18804         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18805                 $timeout
18806
18807         $LCTL set_param -n $pages_per_rpc
18808         restore_lustre_params < $p
18809         rm -f $p
18810 }
18811 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18812
18813 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18814 test_225a () {
18815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18816         if [ -z ${MDSSURVEY} ]; then
18817                 skip_env "mds-survey not found"
18818         fi
18819         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18820                 skip "Need MDS version at least 2.2.51"
18821
18822         local mds=$(facet_host $SINGLEMDS)
18823         local target=$(do_nodes $mds 'lctl dl' |
18824                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18825
18826         local cmd1="file_count=1000 thrhi=4"
18827         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18828         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18829         local cmd="$cmd1 $cmd2 $cmd3"
18830
18831         rm -f ${TMP}/mds_survey*
18832         echo + $cmd
18833         eval $cmd || error "mds-survey with zero-stripe failed"
18834         cat ${TMP}/mds_survey*
18835         rm -f ${TMP}/mds_survey*
18836 }
18837 run_test 225a "Metadata survey sanity with zero-stripe"
18838
18839 test_225b () {
18840         if [ -z ${MDSSURVEY} ]; then
18841                 skip_env "mds-survey not found"
18842         fi
18843         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18844                 skip "Need MDS version at least 2.2.51"
18845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18846         remote_mds_nodsh && skip "remote MDS with nodsh"
18847         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18848                 skip_env "Need to mount OST to test"
18849         fi
18850
18851         local mds=$(facet_host $SINGLEMDS)
18852         local target=$(do_nodes $mds 'lctl dl' |
18853                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18854
18855         local cmd1="file_count=1000 thrhi=4"
18856         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18857         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18858         local cmd="$cmd1 $cmd2 $cmd3"
18859
18860         rm -f ${TMP}/mds_survey*
18861         echo + $cmd
18862         eval $cmd || error "mds-survey with stripe_count failed"
18863         cat ${TMP}/mds_survey*
18864         rm -f ${TMP}/mds_survey*
18865 }
18866 run_test 225b "Metadata survey sanity with stripe_count = 1"
18867
18868 mcreate_path2fid () {
18869         local mode=$1
18870         local major=$2
18871         local minor=$3
18872         local name=$4
18873         local desc=$5
18874         local path=$DIR/$tdir/$name
18875         local fid
18876         local rc
18877         local fid_path
18878
18879         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18880                 error "cannot create $desc"
18881
18882         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18883         rc=$?
18884         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18885
18886         fid_path=$($LFS fid2path $MOUNT $fid)
18887         rc=$?
18888         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18889
18890         [ "$path" == "$fid_path" ] ||
18891                 error "fid2path returned $fid_path, expected $path"
18892
18893         echo "pass with $path and $fid"
18894 }
18895
18896 test_226a () {
18897         rm -rf $DIR/$tdir
18898         mkdir -p $DIR/$tdir
18899
18900         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18901         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18902         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18903         mcreate_path2fid 0040666 0 0 dir "directory"
18904         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18905         mcreate_path2fid 0100666 0 0 file "regular file"
18906         mcreate_path2fid 0120666 0 0 link "symbolic link"
18907         mcreate_path2fid 0140666 0 0 sock "socket"
18908 }
18909 run_test 226a "call path2fid and fid2path on files of all type"
18910
18911 test_226b () {
18912         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18913
18914         local MDTIDX=1
18915
18916         rm -rf $DIR/$tdir
18917         mkdir -p $DIR/$tdir
18918         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18919                 error "create remote directory failed"
18920         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18921         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18922                                 "character special file (null)"
18923         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18924                                 "character special file (no device)"
18925         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18926         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18927                                 "block special file (loop)"
18928         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18929         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18930         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18931 }
18932 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18933
18934 test_226c () {
18935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18936         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18937                 skip "Need MDS version at least 2.13.55"
18938
18939         local submnt=/mnt/submnt
18940         local srcfile=/etc/passwd
18941         local dstfile=$submnt/passwd
18942         local path
18943         local fid
18944
18945         rm -rf $DIR/$tdir
18946         rm -rf $submnt
18947         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18948                 error "create remote directory failed"
18949         mkdir -p $submnt || error "create $submnt failed"
18950         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18951                 error "mount $submnt failed"
18952         stack_trap "umount $submnt" EXIT
18953
18954         cp $srcfile $dstfile
18955         fid=$($LFS path2fid $dstfile)
18956         path=$($LFS fid2path $submnt "$fid")
18957         [ "$path" = "$dstfile" ] ||
18958                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18959 }
18960 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18961
18962 # LU-1299 Executing or running ldd on a truncated executable does not
18963 # cause an out-of-memory condition.
18964 test_227() {
18965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18966         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18967
18968         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18969         chmod +x $MOUNT/date
18970
18971         $MOUNT/date > /dev/null
18972         ldd $MOUNT/date > /dev/null
18973         rm -f $MOUNT/date
18974 }
18975 run_test 227 "running truncated executable does not cause OOM"
18976
18977 # LU-1512 try to reuse idle OI blocks
18978 test_228a() {
18979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18980         remote_mds_nodsh && skip "remote MDS with nodsh"
18981         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18982
18983         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18984         local myDIR=$DIR/$tdir
18985
18986         mkdir -p $myDIR
18987         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18988         $LCTL set_param fail_loc=0x80001002
18989         createmany -o $myDIR/t- 10000
18990         $LCTL set_param fail_loc=0
18991         # The guard is current the largest FID holder
18992         touch $myDIR/guard
18993         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18994                     tr -d '[')
18995         local IDX=$(($SEQ % 64))
18996
18997         do_facet $SINGLEMDS sync
18998         # Make sure journal flushed.
18999         sleep 6
19000         local blk1=$(do_facet $SINGLEMDS \
19001                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19002                      grep Blockcount | awk '{print $4}')
19003
19004         # Remove old files, some OI blocks will become idle.
19005         unlinkmany $myDIR/t- 10000
19006         # Create new files, idle OI blocks should be reused.
19007         createmany -o $myDIR/t- 2000
19008         do_facet $SINGLEMDS sync
19009         # Make sure journal flushed.
19010         sleep 6
19011         local blk2=$(do_facet $SINGLEMDS \
19012                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19013                      grep Blockcount | awk '{print $4}')
19014
19015         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19016 }
19017 run_test 228a "try to reuse idle OI blocks"
19018
19019 test_228b() {
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
19048         # stop the MDT
19049         stop $SINGLEMDS || error "Fail to stop MDT."
19050         # remount the MDT
19051         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19052
19053         df $MOUNT || error "Fail to df."
19054         # Create new files, idle OI blocks should be reused.
19055         createmany -o $myDIR/t- 2000
19056         do_facet $SINGLEMDS sync
19057         # Make sure journal flushed.
19058         sleep 6
19059         local blk2=$(do_facet $SINGLEMDS \
19060                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19061                      grep Blockcount | awk '{print $4}')
19062
19063         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19064 }
19065 run_test 228b "idle OI blocks can be reused after MDT restart"
19066
19067 #LU-1881
19068 test_228c() {
19069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19070         remote_mds_nodsh && skip "remote MDS with nodsh"
19071         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19072
19073         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19074         local myDIR=$DIR/$tdir
19075
19076         mkdir -p $myDIR
19077         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19078         $LCTL set_param fail_loc=0x80001002
19079         # 20000 files can guarantee there are index nodes in the OI file
19080         createmany -o $myDIR/t- 20000
19081         $LCTL set_param fail_loc=0
19082         # The guard is current the largest FID holder
19083         touch $myDIR/guard
19084         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19085                     tr -d '[')
19086         local IDX=$(($SEQ % 64))
19087
19088         do_facet $SINGLEMDS sync
19089         # Make sure journal flushed.
19090         sleep 6
19091         local blk1=$(do_facet $SINGLEMDS \
19092                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19093                      grep Blockcount | awk '{print $4}')
19094
19095         # Remove old files, some OI blocks will become idle.
19096         unlinkmany $myDIR/t- 20000
19097         rm -f $myDIR/guard
19098         # The OI file should become empty now
19099
19100         # Create new files, idle OI blocks should be reused.
19101         createmany -o $myDIR/t- 2000
19102         do_facet $SINGLEMDS sync
19103         # Make sure journal flushed.
19104         sleep 6
19105         local blk2=$(do_facet $SINGLEMDS \
19106                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19107                      grep Blockcount | awk '{print $4}')
19108
19109         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19110 }
19111 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19112
19113 test_229() { # LU-2482, LU-3448
19114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19115         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19116         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19117                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19118
19119         rm -f $DIR/$tfile
19120
19121         # Create a file with a released layout and stripe count 2.
19122         $MULTIOP $DIR/$tfile H2c ||
19123                 error "failed to create file with released layout"
19124
19125         $LFS getstripe -v $DIR/$tfile
19126
19127         local pattern=$($LFS getstripe -L $DIR/$tfile)
19128         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19129
19130         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19131                 error "getstripe"
19132         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19133         stat $DIR/$tfile || error "failed to stat released file"
19134
19135         chown $RUNAS_ID $DIR/$tfile ||
19136                 error "chown $RUNAS_ID $DIR/$tfile failed"
19137
19138         chgrp $RUNAS_ID $DIR/$tfile ||
19139                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19140
19141         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19142         rm $DIR/$tfile || error "failed to remove released file"
19143 }
19144 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19145
19146 test_230a() {
19147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19148         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19149         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19150                 skip "Need MDS version at least 2.11.52"
19151
19152         local MDTIDX=1
19153
19154         test_mkdir $DIR/$tdir
19155         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19156         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19157         [ $mdt_idx -ne 0 ] &&
19158                 error "create local directory on wrong MDT $mdt_idx"
19159
19160         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19161                         error "create remote directory failed"
19162         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19163         [ $mdt_idx -ne $MDTIDX ] &&
19164                 error "create remote directory on wrong MDT $mdt_idx"
19165
19166         createmany -o $DIR/$tdir/test_230/t- 10 ||
19167                 error "create files on remote directory failed"
19168         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19169         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19170         rm -r $DIR/$tdir || error "unlink remote directory failed"
19171 }
19172 run_test 230a "Create remote directory and files under the remote directory"
19173
19174 test_230b() {
19175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19177         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19178                 skip "Need MDS version at least 2.11.52"
19179
19180         local MDTIDX=1
19181         local mdt_index
19182         local i
19183         local file
19184         local pid
19185         local stripe_count
19186         local migrate_dir=$DIR/$tdir/migrate_dir
19187         local other_dir=$DIR/$tdir/other_dir
19188
19189         test_mkdir $DIR/$tdir
19190         test_mkdir -i0 -c1 $migrate_dir
19191         test_mkdir -i0 -c1 $other_dir
19192         for ((i=0; i<10; i++)); do
19193                 mkdir -p $migrate_dir/dir_${i}
19194                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19195                         error "create files under remote dir failed $i"
19196         done
19197
19198         cp /etc/passwd $migrate_dir/$tfile
19199         cp /etc/passwd $other_dir/$tfile
19200         chattr +SAD $migrate_dir
19201         chattr +SAD $migrate_dir/$tfile
19202
19203         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19204         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19205         local old_dir_mode=$(stat -c%f $migrate_dir)
19206         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19207
19208         mkdir -p $migrate_dir/dir_default_stripe2
19209         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19210         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19211
19212         mkdir -p $other_dir
19213         ln $migrate_dir/$tfile $other_dir/luna
19214         ln $migrate_dir/$tfile $migrate_dir/sofia
19215         ln $other_dir/$tfile $migrate_dir/david
19216         ln -s $migrate_dir/$tfile $other_dir/zachary
19217         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19218         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19219
19220         local len
19221         local lnktgt
19222
19223         # inline symlink
19224         for len in 58 59 60; do
19225                 lnktgt=$(str_repeat 'l' $len)
19226                 touch $migrate_dir/$lnktgt
19227                 ln -s $lnktgt $migrate_dir/${len}char_ln
19228         done
19229
19230         # PATH_MAX
19231         for len in 4094 4095; do
19232                 lnktgt=$(str_repeat 'l' $len)
19233                 ln -s $lnktgt $migrate_dir/${len}char_ln
19234         done
19235
19236         # NAME_MAX
19237         for len in 254 255; do
19238                 touch $migrate_dir/$(str_repeat 'l' $len)
19239         done
19240
19241         $LFS migrate -m $MDTIDX $migrate_dir ||
19242                 error "fails on migrating remote dir to MDT1"
19243
19244         echo "migratate to MDT1, then checking.."
19245         for ((i = 0; i < 10; i++)); do
19246                 for file in $(find $migrate_dir/dir_${i}); do
19247                         mdt_index=$($LFS getstripe -m $file)
19248                         # broken symlink getstripe will fail
19249                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19250                                 error "$file is not on MDT${MDTIDX}"
19251                 done
19252         done
19253
19254         # the multiple link file should still in MDT0
19255         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19256         [ $mdt_index == 0 ] ||
19257                 error "$file is not on MDT${MDTIDX}"
19258
19259         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19260         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19261                 error " expect $old_dir_flag get $new_dir_flag"
19262
19263         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19264         [ "$old_file_flag" = "$new_file_flag" ] ||
19265                 error " expect $old_file_flag get $new_file_flag"
19266
19267         local new_dir_mode=$(stat -c%f $migrate_dir)
19268         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19269                 error "expect mode $old_dir_mode get $new_dir_mode"
19270
19271         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19272         [ "$old_file_mode" = "$new_file_mode" ] ||
19273                 error "expect mode $old_file_mode get $new_file_mode"
19274
19275         diff /etc/passwd $migrate_dir/$tfile ||
19276                 error "$tfile different after migration"
19277
19278         diff /etc/passwd $other_dir/luna ||
19279                 error "luna different after migration"
19280
19281         diff /etc/passwd $migrate_dir/sofia ||
19282                 error "sofia different after migration"
19283
19284         diff /etc/passwd $migrate_dir/david ||
19285                 error "david different after migration"
19286
19287         diff /etc/passwd $other_dir/zachary ||
19288                 error "zachary different after migration"
19289
19290         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19291                 error "${tfile}_ln different after migration"
19292
19293         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19294                 error "${tfile}_ln_other different after migration"
19295
19296         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19297         [ $stripe_count = 2 ] ||
19298                 error "dir strpe_count $d != 2 after migration."
19299
19300         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19301         [ $stripe_count = 2 ] ||
19302                 error "file strpe_count $d != 2 after migration."
19303
19304         #migrate back to MDT0
19305         MDTIDX=0
19306
19307         $LFS migrate -m $MDTIDX $migrate_dir ||
19308                 error "fails on migrating remote dir to MDT0"
19309
19310         echo "migrate back to MDT0, checking.."
19311         for file in $(find $migrate_dir); do
19312                 mdt_index=$($LFS getstripe -m $file)
19313                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19314                         error "$file is not on MDT${MDTIDX}"
19315         done
19316
19317         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19318         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19319                 error " expect $old_dir_flag get $new_dir_flag"
19320
19321         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19322         [ "$old_file_flag" = "$new_file_flag" ] ||
19323                 error " expect $old_file_flag get $new_file_flag"
19324
19325         local new_dir_mode=$(stat -c%f $migrate_dir)
19326         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19327                 error "expect mode $old_dir_mode get $new_dir_mode"
19328
19329         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19330         [ "$old_file_mode" = "$new_file_mode" ] ||
19331                 error "expect mode $old_file_mode get $new_file_mode"
19332
19333         diff /etc/passwd ${migrate_dir}/$tfile ||
19334                 error "$tfile different after migration"
19335
19336         diff /etc/passwd ${other_dir}/luna ||
19337                 error "luna different after migration"
19338
19339         diff /etc/passwd ${migrate_dir}/sofia ||
19340                 error "sofia different after migration"
19341
19342         diff /etc/passwd ${other_dir}/zachary ||
19343                 error "zachary different after migration"
19344
19345         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19346                 error "${tfile}_ln different after migration"
19347
19348         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19349                 error "${tfile}_ln_other different after migration"
19350
19351         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19352         [ $stripe_count = 2 ] ||
19353                 error "dir strpe_count $d != 2 after migration."
19354
19355         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19356         [ $stripe_count = 2 ] ||
19357                 error "file strpe_count $d != 2 after migration."
19358
19359         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19360 }
19361 run_test 230b "migrate directory"
19362
19363 test_230c() {
19364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19366         remote_mds_nodsh && skip "remote MDS with nodsh"
19367         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19368                 skip "Need MDS version at least 2.11.52"
19369
19370         local MDTIDX=1
19371         local total=3
19372         local mdt_index
19373         local file
19374         local migrate_dir=$DIR/$tdir/migrate_dir
19375
19376         #If migrating directory fails in the middle, all entries of
19377         #the directory is still accessiable.
19378         test_mkdir $DIR/$tdir
19379         test_mkdir -i0 -c1 $migrate_dir
19380         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19381         stat $migrate_dir
19382         createmany -o $migrate_dir/f $total ||
19383                 error "create files under ${migrate_dir} failed"
19384
19385         # fail after migrating top dir, and this will fail only once, so the
19386         # first sub file migration will fail (currently f3), others succeed.
19387         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19388         do_facet mds1 lctl set_param fail_loc=0x1801
19389         local t=$(ls $migrate_dir | wc -l)
19390         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19391                 error "migrate should fail"
19392         local u=$(ls $migrate_dir | wc -l)
19393         [ "$u" == "$t" ] || error "$u != $t during migration"
19394
19395         # add new dir/file should succeed
19396         mkdir $migrate_dir/dir ||
19397                 error "mkdir failed under migrating directory"
19398         touch $migrate_dir/file ||
19399                 error "create file failed under migrating directory"
19400
19401         # add file with existing name should fail
19402         for file in $migrate_dir/f*; do
19403                 stat $file > /dev/null || error "stat $file failed"
19404                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19405                         error "open(O_CREAT|O_EXCL) $file should fail"
19406                 $MULTIOP $file m && error "create $file should fail"
19407                 touch $DIR/$tdir/remote_dir/$tfile ||
19408                         error "touch $tfile failed"
19409                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19410                         error "link $file should fail"
19411                 mdt_index=$($LFS getstripe -m $file)
19412                 if [ $mdt_index == 0 ]; then
19413                         # file failed to migrate is not allowed to rename to
19414                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19415                                 error "rename to $file should fail"
19416                 else
19417                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19418                                 error "rename to $file failed"
19419                 fi
19420                 echo hello >> $file || error "write $file failed"
19421         done
19422
19423         # resume migration with different options should fail
19424         $LFS migrate -m 0 $migrate_dir &&
19425                 error "migrate -m 0 $migrate_dir should fail"
19426
19427         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19428                 error "migrate -c 2 $migrate_dir should fail"
19429
19430         # resume migration should succeed
19431         $LFS migrate -m $MDTIDX $migrate_dir ||
19432                 error "migrate $migrate_dir failed"
19433
19434         echo "Finish migration, then checking.."
19435         for file in $(find $migrate_dir); do
19436                 mdt_index=$($LFS getstripe -m $file)
19437                 [ $mdt_index == $MDTIDX ] ||
19438                         error "$file is not on MDT${MDTIDX}"
19439         done
19440
19441         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19442 }
19443 run_test 230c "check directory accessiblity if migration failed"
19444
19445 test_230d() {
19446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19448         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19449                 skip "Need MDS version at least 2.11.52"
19450         # LU-11235
19451         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19452
19453         local migrate_dir=$DIR/$tdir/migrate_dir
19454         local old_index
19455         local new_index
19456         local old_count
19457         local new_count
19458         local new_hash
19459         local mdt_index
19460         local i
19461         local j
19462
19463         old_index=$((RANDOM % MDSCOUNT))
19464         old_count=$((MDSCOUNT - old_index))
19465         new_index=$((RANDOM % MDSCOUNT))
19466         new_count=$((MDSCOUNT - new_index))
19467         new_hash=1 # for all_char
19468
19469         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19470         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19471
19472         test_mkdir $DIR/$tdir
19473         test_mkdir -i $old_index -c $old_count $migrate_dir
19474
19475         for ((i=0; i<100; i++)); do
19476                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19477                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19478                         error "create files under remote dir failed $i"
19479         done
19480
19481         echo -n "Migrate from MDT$old_index "
19482         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19483         echo -n "to MDT$new_index"
19484         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19485         echo
19486
19487         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19488         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19489                 error "migrate remote dir error"
19490
19491         echo "Finish migration, then checking.."
19492         for file in $(find $migrate_dir); do
19493                 mdt_index=$($LFS getstripe -m $file)
19494                 if [ $mdt_index -lt $new_index ] ||
19495                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19496                         error "$file is on MDT$mdt_index"
19497                 fi
19498         done
19499
19500         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19501 }
19502 run_test 230d "check migrate big directory"
19503
19504 test_230e() {
19505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19507         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19508                 skip "Need MDS version at least 2.11.52"
19509
19510         local i
19511         local j
19512         local a_fid
19513         local b_fid
19514
19515         mkdir_on_mdt0 $DIR/$tdir
19516         mkdir $DIR/$tdir/migrate_dir
19517         mkdir $DIR/$tdir/other_dir
19518         touch $DIR/$tdir/migrate_dir/a
19519         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19520         ls $DIR/$tdir/other_dir
19521
19522         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19523                 error "migrate dir fails"
19524
19525         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19526         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19527
19528         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19529         [ $mdt_index == 0 ] || error "a is not on MDT0"
19530
19531         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19532                 error "migrate dir fails"
19533
19534         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19535         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19536
19537         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19538         [ $mdt_index == 1 ] || error "a is not on MDT1"
19539
19540         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19541         [ $mdt_index == 1 ] || error "b is not on MDT1"
19542
19543         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19544         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19545
19546         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19547
19548         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19549 }
19550 run_test 230e "migrate mulitple local link files"
19551
19552 test_230f() {
19553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19555         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19556                 skip "Need MDS version at least 2.11.52"
19557
19558         local a_fid
19559         local ln_fid
19560
19561         mkdir -p $DIR/$tdir
19562         mkdir $DIR/$tdir/migrate_dir
19563         $LFS mkdir -i1 $DIR/$tdir/other_dir
19564         touch $DIR/$tdir/migrate_dir/a
19565         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19566         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19567         ls $DIR/$tdir/other_dir
19568
19569         # a should be migrated to MDT1, since no other links on MDT0
19570         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19571                 error "#1 migrate dir fails"
19572         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19573         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19574         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19575         [ $mdt_index == 1 ] || error "a is not on MDT1"
19576
19577         # a should stay on MDT1, because it is a mulitple link file
19578         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19579                 error "#2 migrate dir fails"
19580         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19581         [ $mdt_index == 1 ] || error "a is not on MDT1"
19582
19583         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19584                 error "#3 migrate dir fails"
19585
19586         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19587         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19588         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19589
19590         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19591         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19592
19593         # a should be migrated to MDT0, since no other links on MDT1
19594         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19595                 error "#4 migrate dir fails"
19596         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19597         [ $mdt_index == 0 ] || error "a is not on MDT0"
19598
19599         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19600 }
19601 run_test 230f "migrate mulitple remote link files"
19602
19603 test_230g() {
19604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19605         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19606         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19607                 skip "Need MDS version at least 2.11.52"
19608
19609         mkdir -p $DIR/$tdir/migrate_dir
19610
19611         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19612                 error "migrating dir to non-exist MDT succeeds"
19613         true
19614 }
19615 run_test 230g "migrate dir to non-exist MDT"
19616
19617 test_230h() {
19618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19620         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19621                 skip "Need MDS version at least 2.11.52"
19622
19623         local mdt_index
19624
19625         mkdir -p $DIR/$tdir/migrate_dir
19626
19627         $LFS migrate -m1 $DIR &&
19628                 error "migrating mountpoint1 should fail"
19629
19630         $LFS migrate -m1 $DIR/$tdir/.. &&
19631                 error "migrating mountpoint2 should fail"
19632
19633         # same as mv
19634         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19635                 error "migrating $tdir/migrate_dir/.. should fail"
19636
19637         true
19638 }
19639 run_test 230h "migrate .. and root"
19640
19641 test_230i() {
19642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19643         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19644         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19645                 skip "Need MDS version at least 2.11.52"
19646
19647         mkdir -p $DIR/$tdir/migrate_dir
19648
19649         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19650                 error "migration fails with a tailing slash"
19651
19652         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19653                 error "migration fails with two tailing slashes"
19654 }
19655 run_test 230i "lfs migrate -m tolerates trailing slashes"
19656
19657 test_230j() {
19658         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19659         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19660                 skip "Need MDS version at least 2.11.52"
19661
19662         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19663         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19664                 error "create $tfile failed"
19665         cat /etc/passwd > $DIR/$tdir/$tfile
19666
19667         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19668
19669         cmp /etc/passwd $DIR/$tdir/$tfile ||
19670                 error "DoM file mismatch after migration"
19671 }
19672 run_test 230j "DoM file data not changed after dir migration"
19673
19674 test_230k() {
19675         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19676         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19677                 skip "Need MDS version at least 2.11.56"
19678
19679         local total=20
19680         local files_on_starting_mdt=0
19681
19682         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19683         $LFS getdirstripe $DIR/$tdir
19684         for i in $(seq $total); do
19685                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19686                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19687                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19688         done
19689
19690         echo "$files_on_starting_mdt files on MDT0"
19691
19692         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19693         $LFS getdirstripe $DIR/$tdir
19694
19695         files_on_starting_mdt=0
19696         for i in $(seq $total); do
19697                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19698                         error "file $tfile.$i mismatch after migration"
19699                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19700                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19701         done
19702
19703         echo "$files_on_starting_mdt files on MDT1 after migration"
19704         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19705
19706         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19707         $LFS getdirstripe $DIR/$tdir
19708
19709         files_on_starting_mdt=0
19710         for i in $(seq $total); do
19711                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19712                         error "file $tfile.$i mismatch after 2nd migration"
19713                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19714                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19715         done
19716
19717         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19718         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19719
19720         true
19721 }
19722 run_test 230k "file data not changed after dir migration"
19723
19724 test_230l() {
19725         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19726         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19727                 skip "Need MDS version at least 2.11.56"
19728
19729         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19730         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19731                 error "create files under remote dir failed $i"
19732         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19733 }
19734 run_test 230l "readdir between MDTs won't crash"
19735
19736 test_230m() {
19737         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19738         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19739                 skip "Need MDS version at least 2.11.56"
19740
19741         local MDTIDX=1
19742         local mig_dir=$DIR/$tdir/migrate_dir
19743         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19744         local shortstr="b"
19745         local val
19746
19747         echo "Creating files and dirs with xattrs"
19748         test_mkdir $DIR/$tdir
19749         test_mkdir -i0 -c1 $mig_dir
19750         mkdir $mig_dir/dir
19751         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19752                 error "cannot set xattr attr1 on dir"
19753         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19754                 error "cannot set xattr attr2 on dir"
19755         touch $mig_dir/dir/f0
19756         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19757                 error "cannot set xattr attr1 on file"
19758         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19759                 error "cannot set xattr attr2 on file"
19760         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19761         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19762         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19763         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19764         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19765         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19766         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19767         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19768         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19769
19770         echo "Migrating to MDT1"
19771         $LFS migrate -m $MDTIDX $mig_dir ||
19772                 error "fails on migrating dir to MDT1"
19773
19774         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19775         echo "Checking xattrs"
19776         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19777         [ "$val" = $longstr ] ||
19778                 error "expecting xattr1 $longstr on dir, found $val"
19779         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19780         [ "$val" = $shortstr ] ||
19781                 error "expecting xattr2 $shortstr on dir, found $val"
19782         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19783         [ "$val" = $longstr ] ||
19784                 error "expecting xattr1 $longstr on file, found $val"
19785         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19786         [ "$val" = $shortstr ] ||
19787                 error "expecting xattr2 $shortstr on file, found $val"
19788 }
19789 run_test 230m "xattrs not changed after dir migration"
19790
19791 test_230n() {
19792         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19793         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19794                 skip "Need MDS version at least 2.13.53"
19795
19796         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19797         cat /etc/hosts > $DIR/$tdir/$tfile
19798         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19799         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19800
19801         cmp /etc/hosts $DIR/$tdir/$tfile ||
19802                 error "File data mismatch after migration"
19803 }
19804 run_test 230n "Dir migration with mirrored file"
19805
19806 test_230o() {
19807         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19808         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19809                 skip "Need MDS version at least 2.13.52"
19810
19811         local mdts=$(comma_list $(mdts_nodes))
19812         local timeout=100
19813         local restripe_status
19814         local delta
19815         local i
19816
19817         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19818
19819         # in case "crush" hash type is not set
19820         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19821
19822         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19823                            mdt.*MDT0000.enable_dir_restripe)
19824         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19825         stack_trap "do_nodes $mdts $LCTL set_param \
19826                     mdt.*.enable_dir_restripe=$restripe_status"
19827
19828         mkdir $DIR/$tdir
19829         createmany -m $DIR/$tdir/f 100 ||
19830                 error "create files under remote dir failed $i"
19831         createmany -d $DIR/$tdir/d 100 ||
19832                 error "create dirs under remote dir failed $i"
19833
19834         for i in $(seq 2 $MDSCOUNT); do
19835                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19836                 $LFS setdirstripe -c $i $DIR/$tdir ||
19837                         error "split -c $i $tdir failed"
19838                 wait_update $HOSTNAME \
19839                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19840                         error "dir split not finished"
19841                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19842                         awk '/migrate/ {sum += $2} END { print sum }')
19843                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19844                 # delta is around total_files/stripe_count
19845                 (( $delta < 200 / (i - 1) + 4 )) ||
19846                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19847         done
19848 }
19849 run_test 230o "dir split"
19850
19851 test_230p() {
19852         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19853         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19854                 skip "Need MDS version at least 2.13.52"
19855
19856         local mdts=$(comma_list $(mdts_nodes))
19857         local timeout=100
19858         local restripe_status
19859         local delta
19860         local c
19861
19862         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19863
19864         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19865
19866         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19867                            mdt.*MDT0000.enable_dir_restripe)
19868         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19869         stack_trap "do_nodes $mdts $LCTL set_param \
19870                     mdt.*.enable_dir_restripe=$restripe_status"
19871
19872         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19873         createmany -m $DIR/$tdir/f 100 ||
19874                 error "create files under remote dir failed"
19875         createmany -d $DIR/$tdir/d 100 ||
19876                 error "create dirs under remote dir failed"
19877
19878         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19879                 local mdt_hash="crush"
19880
19881                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19882                 $LFS setdirstripe -c $c $DIR/$tdir ||
19883                         error "split -c $c $tdir failed"
19884                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19885                         mdt_hash="$mdt_hash,fixed"
19886                 elif [ $c -eq 1 ]; then
19887                         mdt_hash="none"
19888                 fi
19889                 wait_update $HOSTNAME \
19890                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19891                         error "dir merge not finished"
19892                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19893                         awk '/migrate/ {sum += $2} END { print sum }')
19894                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19895                 # delta is around total_files/stripe_count
19896                 (( delta < 200 / c + 4 )) ||
19897                         error "$delta files migrated >= $((200 / c + 4))"
19898         done
19899 }
19900 run_test 230p "dir merge"
19901
19902 test_230q() {
19903         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19904         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19905                 skip "Need MDS version at least 2.13.52"
19906
19907         local mdts=$(comma_list $(mdts_nodes))
19908         local saved_threshold=$(do_facet mds1 \
19909                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19910         local saved_delta=$(do_facet mds1 \
19911                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19912         local threshold=100
19913         local delta=2
19914         local total=0
19915         local stripe_count=0
19916         local stripe_index
19917         local nr_files
19918         local create
19919
19920         # test with fewer files on ZFS
19921         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19922
19923         stack_trap "do_nodes $mdts $LCTL set_param \
19924                     mdt.*.dir_split_count=$saved_threshold"
19925         stack_trap "do_nodes $mdts $LCTL set_param \
19926                     mdt.*.dir_split_delta=$saved_delta"
19927         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19928         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19929         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19930         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19931         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19932         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19933
19934         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19935         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19936
19937         create=$((threshold * 3 / 2))
19938         while [ $stripe_count -lt $MDSCOUNT ]; do
19939                 createmany -m $DIR/$tdir/f $total $create ||
19940                         error "create sub files failed"
19941                 stat $DIR/$tdir > /dev/null
19942                 total=$((total + create))
19943                 stripe_count=$((stripe_count + delta))
19944                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19945
19946                 wait_update $HOSTNAME \
19947                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19948                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19949
19950                 wait_update $HOSTNAME \
19951                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19952                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19953
19954                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19955                 echo "$nr_files/$total files on MDT$stripe_index after split"
19956                 # allow 10% margin of imbalance with crush hash
19957                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19958                         error "$nr_files files on MDT$stripe_index after split"
19959
19960                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19961                 [ $nr_files -eq $total ] ||
19962                         error "total sub files $nr_files != $total"
19963         done
19964
19965         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19966
19967         echo "fixed layout directory won't auto split"
19968         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19969         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19970                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19971         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19972                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19973 }
19974 run_test 230q "dir auto split"
19975
19976 test_230r() {
19977         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19978         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19979         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19980                 skip "Need MDS version at least 2.13.54"
19981
19982         # maximum amount of local locks:
19983         # parent striped dir - 2 locks
19984         # new stripe in parent to migrate to - 1 lock
19985         # source and target - 2 locks
19986         # Total 5 locks for regular file
19987         mkdir -p $DIR/$tdir
19988         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19989         touch $DIR/$tdir/dir1/eee
19990
19991         # create 4 hardlink for 4 more locks
19992         # Total: 9 locks > RS_MAX_LOCKS (8)
19993         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19994         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19995         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19996         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19997         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19998         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19999         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20000         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20001
20002         cancel_lru_locks mdc
20003
20004         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20005                 error "migrate dir fails"
20006
20007         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20008 }
20009 run_test 230r "migrate with too many local locks"
20010
20011 test_230s() {
20012         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20013                 skip "Need MDS version at least 2.13.57"
20014
20015         local mdts=$(comma_list $(mdts_nodes))
20016         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20017                                 mdt.*MDT0000.enable_dir_restripe)
20018
20019         stack_trap "do_nodes $mdts $LCTL set_param \
20020                     mdt.*.enable_dir_restripe=$restripe_status"
20021
20022         local st
20023         for st in 0 1; do
20024                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20025                 test_mkdir $DIR/$tdir
20026                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20027                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20028                 rmdir $DIR/$tdir
20029         done
20030 }
20031 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20032
20033 test_230t()
20034 {
20035         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20036         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20037                 skip "Need MDS version at least 2.14.50"
20038
20039         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20040         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20041         $LFS project -p 1 -s $DIR/$tdir ||
20042                 error "set $tdir project id failed"
20043         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20044                 error "set subdir project id failed"
20045         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20046 }
20047 run_test 230t "migrate directory with project ID set"
20048
20049 test_231a()
20050 {
20051         # For simplicity this test assumes that max_pages_per_rpc
20052         # is the same across all OSCs
20053         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20054         local bulk_size=$((max_pages * PAGE_SIZE))
20055         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20056                                        head -n 1)
20057
20058         mkdir -p $DIR/$tdir
20059         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20060                 error "failed to set stripe with -S ${brw_size}M option"
20061
20062         # clear the OSC stats
20063         $LCTL set_param osc.*.stats=0 &>/dev/null
20064         stop_writeback
20065
20066         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20067         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20068                 oflag=direct &>/dev/null || error "dd failed"
20069
20070         sync; sleep 1; sync # just to be safe
20071         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20072         if [ x$nrpcs != "x1" ]; then
20073                 $LCTL get_param osc.*.stats
20074                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20075         fi
20076
20077         start_writeback
20078         # Drop the OSC cache, otherwise we will read from it
20079         cancel_lru_locks osc
20080
20081         # clear the OSC stats
20082         $LCTL set_param osc.*.stats=0 &>/dev/null
20083
20084         # Client reads $bulk_size.
20085         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20086                 iflag=direct &>/dev/null || error "dd failed"
20087
20088         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20089         if [ x$nrpcs != "x1" ]; then
20090                 $LCTL get_param osc.*.stats
20091                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20092         fi
20093 }
20094 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20095
20096 test_231b() {
20097         mkdir -p $DIR/$tdir
20098         local i
20099         for i in {0..1023}; do
20100                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20101                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20102                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20103         done
20104         sync
20105 }
20106 run_test 231b "must not assert on fully utilized OST request buffer"
20107
20108 test_232a() {
20109         mkdir -p $DIR/$tdir
20110         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20111
20112         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20113         do_facet ost1 $LCTL set_param fail_loc=0x31c
20114
20115         # ignore dd failure
20116         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20117
20118         do_facet ost1 $LCTL set_param fail_loc=0
20119         umount_client $MOUNT || error "umount failed"
20120         mount_client $MOUNT || error "mount failed"
20121         stop ost1 || error "cannot stop ost1"
20122         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20123 }
20124 run_test 232a "failed lock should not block umount"
20125
20126 test_232b() {
20127         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20128                 skip "Need MDS version at least 2.10.58"
20129
20130         mkdir -p $DIR/$tdir
20131         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20132         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20133         sync
20134         cancel_lru_locks osc
20135
20136         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20137         do_facet ost1 $LCTL set_param fail_loc=0x31c
20138
20139         # ignore failure
20140         $LFS data_version $DIR/$tdir/$tfile || true
20141
20142         do_facet ost1 $LCTL set_param fail_loc=0
20143         umount_client $MOUNT || error "umount failed"
20144         mount_client $MOUNT || error "mount failed"
20145         stop ost1 || error "cannot stop ost1"
20146         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20147 }
20148 run_test 232b "failed data version lock should not block umount"
20149
20150 test_233a() {
20151         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20152                 skip "Need MDS version at least 2.3.64"
20153         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20154
20155         local fid=$($LFS path2fid $MOUNT)
20156
20157         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20158                 error "cannot access $MOUNT using its FID '$fid'"
20159 }
20160 run_test 233a "checking that OBF of the FS root succeeds"
20161
20162 test_233b() {
20163         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20164                 skip "Need MDS version at least 2.5.90"
20165         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20166
20167         local fid=$($LFS path2fid $MOUNT/.lustre)
20168
20169         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20170                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20171
20172         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20173         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20174                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20175 }
20176 run_test 233b "checking that OBF of the FS .lustre succeeds"
20177
20178 test_234() {
20179         local p="$TMP/sanityN-$TESTNAME.parameters"
20180         save_lustre_params client "llite.*.xattr_cache" > $p
20181         lctl set_param llite.*.xattr_cache 1 ||
20182                 skip_env "xattr cache is not supported"
20183
20184         mkdir -p $DIR/$tdir || error "mkdir failed"
20185         touch $DIR/$tdir/$tfile || error "touch failed"
20186         # OBD_FAIL_LLITE_XATTR_ENOMEM
20187         $LCTL set_param fail_loc=0x1405
20188         getfattr -n user.attr $DIR/$tdir/$tfile &&
20189                 error "getfattr should have failed with ENOMEM"
20190         $LCTL set_param fail_loc=0x0
20191         rm -rf $DIR/$tdir
20192
20193         restore_lustre_params < $p
20194         rm -f $p
20195 }
20196 run_test 234 "xattr cache should not crash on ENOMEM"
20197
20198 test_235() {
20199         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20200                 skip "Need MDS version at least 2.4.52"
20201
20202         flock_deadlock $DIR/$tfile
20203         local RC=$?
20204         case $RC in
20205                 0)
20206                 ;;
20207                 124) error "process hangs on a deadlock"
20208                 ;;
20209                 *) error "error executing flock_deadlock $DIR/$tfile"
20210                 ;;
20211         esac
20212 }
20213 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20214
20215 #LU-2935
20216 test_236() {
20217         check_swap_layouts_support
20218
20219         local ref1=/etc/passwd
20220         local ref2=/etc/group
20221         local file1=$DIR/$tdir/f1
20222         local file2=$DIR/$tdir/f2
20223
20224         test_mkdir -c1 $DIR/$tdir
20225         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20226         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20227         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20228         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20229         local fd=$(free_fd)
20230         local cmd="exec $fd<>$file2"
20231         eval $cmd
20232         rm $file2
20233         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20234                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20235         cmd="exec $fd>&-"
20236         eval $cmd
20237         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20238
20239         #cleanup
20240         rm -rf $DIR/$tdir
20241 }
20242 run_test 236 "Layout swap on open unlinked file"
20243
20244 # LU-4659 linkea consistency
20245 test_238() {
20246         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20247                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20248                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20249                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20250
20251         touch $DIR/$tfile
20252         ln $DIR/$tfile $DIR/$tfile.lnk
20253         touch $DIR/$tfile.new
20254         mv $DIR/$tfile.new $DIR/$tfile
20255         local fid1=$($LFS path2fid $DIR/$tfile)
20256         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20257         local path1=$($LFS fid2path $FSNAME "$fid1")
20258         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20259         local path2=$($LFS fid2path $FSNAME "$fid2")
20260         [ $tfile.lnk == $path2 ] ||
20261                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20262         rm -f $DIR/$tfile*
20263 }
20264 run_test 238 "Verify linkea consistency"
20265
20266 test_239A() { # was test_239
20267         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20268                 skip "Need MDS version at least 2.5.60"
20269
20270         local list=$(comma_list $(mdts_nodes))
20271
20272         mkdir -p $DIR/$tdir
20273         createmany -o $DIR/$tdir/f- 5000
20274         unlinkmany $DIR/$tdir/f- 5000
20275         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20276                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20277         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20278                         osp.*MDT*.sync_in_flight" | calc_sum)
20279         [ "$changes" -eq 0 ] || error "$changes not synced"
20280 }
20281 run_test 239A "osp_sync test"
20282
20283 test_239a() { #LU-5297
20284         remote_mds_nodsh && skip "remote MDS with nodsh"
20285
20286         touch $DIR/$tfile
20287         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20288         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20289         chgrp $RUNAS_GID $DIR/$tfile
20290         wait_delete_completed
20291 }
20292 run_test 239a "process invalid osp sync record correctly"
20293
20294 test_239b() { #LU-5297
20295         remote_mds_nodsh && skip "remote MDS with nodsh"
20296
20297         touch $DIR/$tfile1
20298         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20299         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20300         chgrp $RUNAS_GID $DIR/$tfile1
20301         wait_delete_completed
20302         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20303         touch $DIR/$tfile2
20304         chgrp $RUNAS_GID $DIR/$tfile2
20305         wait_delete_completed
20306 }
20307 run_test 239b "process osp sync record with ENOMEM error correctly"
20308
20309 test_240() {
20310         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20311         remote_mds_nodsh && skip "remote MDS with nodsh"
20312
20313         mkdir -p $DIR/$tdir
20314
20315         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20316                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20317         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20318                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20319
20320         umount_client $MOUNT || error "umount failed"
20321         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20322         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20323         mount_client $MOUNT || error "failed to mount client"
20324
20325         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20326         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20327 }
20328 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20329
20330 test_241_bio() {
20331         local count=$1
20332         local bsize=$2
20333
20334         for LOOP in $(seq $count); do
20335                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20336                 cancel_lru_locks $OSC || true
20337         done
20338 }
20339
20340 test_241_dio() {
20341         local count=$1
20342         local bsize=$2
20343
20344         for LOOP in $(seq $1); do
20345                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20346                         2>/dev/null
20347         done
20348 }
20349
20350 test_241a() { # was test_241
20351         local bsize=$PAGE_SIZE
20352
20353         (( bsize < 40960 )) && bsize=40960
20354         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20355         ls -la $DIR/$tfile
20356         cancel_lru_locks $OSC
20357         test_241_bio 1000 $bsize &
20358         PID=$!
20359         test_241_dio 1000 $bsize
20360         wait $PID
20361 }
20362 run_test 241a "bio vs dio"
20363
20364 test_241b() {
20365         local bsize=$PAGE_SIZE
20366
20367         (( bsize < 40960 )) && bsize=40960
20368         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20369         ls -la $DIR/$tfile
20370         test_241_dio 1000 $bsize &
20371         PID=$!
20372         test_241_dio 1000 $bsize
20373         wait $PID
20374 }
20375 run_test 241b "dio vs dio"
20376
20377 test_242() {
20378         remote_mds_nodsh && skip "remote MDS with nodsh"
20379
20380         mkdir_on_mdt0 $DIR/$tdir
20381         touch $DIR/$tdir/$tfile
20382
20383         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20384         do_facet mds1 lctl set_param fail_loc=0x105
20385         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20386
20387         do_facet mds1 lctl set_param fail_loc=0
20388         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20389 }
20390 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20391
20392 test_243()
20393 {
20394         test_mkdir $DIR/$tdir
20395         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20396 }
20397 run_test 243 "various group lock tests"
20398
20399 test_244a()
20400 {
20401         test_mkdir $DIR/$tdir
20402         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20403         sendfile_grouplock $DIR/$tdir/$tfile || \
20404                 error "sendfile+grouplock failed"
20405         rm -rf $DIR/$tdir
20406 }
20407 run_test 244a "sendfile with group lock tests"
20408
20409 test_244b()
20410 {
20411         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20412
20413         local threads=50
20414         local size=$((1024*1024))
20415
20416         test_mkdir $DIR/$tdir
20417         for i in $(seq 1 $threads); do
20418                 local file=$DIR/$tdir/file_$((i / 10))
20419                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20420                 local pids[$i]=$!
20421         done
20422         for i in $(seq 1 $threads); do
20423                 wait ${pids[$i]}
20424         done
20425 }
20426 run_test 244b "multi-threaded write with group lock"
20427
20428 test_245() {
20429         local flagname="multi_mod_rpcs"
20430         local connect_data_name="max_mod_rpcs"
20431         local out
20432
20433         # check if multiple modify RPCs flag is set
20434         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20435                 grep "connect_flags:")
20436         echo "$out"
20437
20438         echo "$out" | grep -qw $flagname
20439         if [ $? -ne 0 ]; then
20440                 echo "connect flag $flagname is not set"
20441                 return
20442         fi
20443
20444         # check if multiple modify RPCs data is set
20445         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20446         echo "$out"
20447
20448         echo "$out" | grep -qw $connect_data_name ||
20449                 error "import should have connect data $connect_data_name"
20450 }
20451 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20452
20453 cleanup_247() {
20454         local submount=$1
20455
20456         trap 0
20457         umount_client $submount
20458         rmdir $submount
20459 }
20460
20461 test_247a() {
20462         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20463                 grep -q subtree ||
20464                 skip_env "Fileset feature is not supported"
20465
20466         local submount=${MOUNT}_$tdir
20467
20468         mkdir $MOUNT/$tdir
20469         mkdir -p $submount || error "mkdir $submount failed"
20470         FILESET="$FILESET/$tdir" mount_client $submount ||
20471                 error "mount $submount failed"
20472         trap "cleanup_247 $submount" EXIT
20473         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20474         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20475                 error "read $MOUNT/$tdir/$tfile failed"
20476         cleanup_247 $submount
20477 }
20478 run_test 247a "mount subdir as fileset"
20479
20480 test_247b() {
20481         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20482                 skip_env "Fileset feature is not supported"
20483
20484         local submount=${MOUNT}_$tdir
20485
20486         rm -rf $MOUNT/$tdir
20487         mkdir -p $submount || error "mkdir $submount failed"
20488         SKIP_FILESET=1
20489         FILESET="$FILESET/$tdir" mount_client $submount &&
20490                 error "mount $submount should fail"
20491         rmdir $submount
20492 }
20493 run_test 247b "mount subdir that dose not exist"
20494
20495 test_247c() {
20496         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20497                 skip_env "Fileset feature is not supported"
20498
20499         local submount=${MOUNT}_$tdir
20500
20501         mkdir -p $MOUNT/$tdir/dir1
20502         mkdir -p $submount || error "mkdir $submount failed"
20503         trap "cleanup_247 $submount" EXIT
20504         FILESET="$FILESET/$tdir" mount_client $submount ||
20505                 error "mount $submount failed"
20506         local fid=$($LFS path2fid $MOUNT/)
20507         $LFS fid2path $submount $fid && error "fid2path should fail"
20508         cleanup_247 $submount
20509 }
20510 run_test 247c "running fid2path outside subdirectory root"
20511
20512 test_247d() {
20513         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20514                 skip "Fileset feature is not supported"
20515
20516         local submount=${MOUNT}_$tdir
20517
20518         mkdir -p $MOUNT/$tdir/dir1
20519         mkdir -p $submount || error "mkdir $submount failed"
20520         FILESET="$FILESET/$tdir" mount_client $submount ||
20521                 error "mount $submount failed"
20522         trap "cleanup_247 $submount" EXIT
20523
20524         local td=$submount/dir1
20525         local fid=$($LFS path2fid $td)
20526         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20527
20528         # check that we get the same pathname back
20529         local rootpath
20530         local found
20531         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20532                 echo "$rootpath $fid"
20533                 found=$($LFS fid2path $rootpath "$fid")
20534                 [ -n "found" ] || error "fid2path should succeed"
20535                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20536         done
20537         # check wrong root path format
20538         rootpath=$submount"_wrong"
20539         found=$($LFS fid2path $rootpath "$fid")
20540         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20541
20542         cleanup_247 $submount
20543 }
20544 run_test 247d "running fid2path inside subdirectory root"
20545
20546 # LU-8037
20547 test_247e() {
20548         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20549                 grep -q subtree ||
20550                 skip "Fileset feature is not supported"
20551
20552         local submount=${MOUNT}_$tdir
20553
20554         mkdir $MOUNT/$tdir
20555         mkdir -p $submount || error "mkdir $submount failed"
20556         FILESET="$FILESET/.." mount_client $submount &&
20557                 error "mount $submount should fail"
20558         rmdir $submount
20559 }
20560 run_test 247e "mount .. as fileset"
20561
20562 test_247f() {
20563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20564         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20565                 skip "Need at least version 2.13.52"
20566         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20567                 skip "Need at least version 2.14.50"
20568         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20569                 grep -q subtree ||
20570                 skip "Fileset feature is not supported"
20571
20572         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20573         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20574                 error "mkdir remote failed"
20575         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20576                 error "mkdir remote/subdir failed"
20577         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20578                 error "mkdir striped failed"
20579         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20580
20581         local submount=${MOUNT}_$tdir
20582
20583         mkdir -p $submount || error "mkdir $submount failed"
20584         stack_trap "rmdir $submount"
20585
20586         local dir
20587         local stat
20588         local fileset=$FILESET
20589         local mdts=$(comma_list $(mdts_nodes))
20590
20591         stat=$(do_facet mds1 $LCTL get_param -n \
20592                 mdt.*MDT0000.enable_remote_subdir_mount)
20593         stack_trap "do_nodes $mdts $LCTL set_param \
20594                 mdt.*.enable_remote_subdir_mount=$stat"
20595
20596         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20597         stack_trap "umount_client $submount"
20598         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20599                 error "mount remote dir $dir should fail"
20600
20601         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20602                 $tdir/striped/. ; do
20603                 FILESET="$fileset/$dir" mount_client $submount ||
20604                         error "mount $dir failed"
20605                 umount_client $submount
20606         done
20607
20608         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20609         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20610                 error "mount $tdir/remote failed"
20611 }
20612 run_test 247f "mount striped or remote directory as fileset"
20613
20614 test_247g() {
20615         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20616         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20617                 skip "Need at least version 2.14.50"
20618
20619         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20620                 error "mkdir $tdir failed"
20621         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20622
20623         local submount=${MOUNT}_$tdir
20624
20625         mkdir -p $submount || error "mkdir $submount failed"
20626         stack_trap "rmdir $submount"
20627
20628         FILESET="$fileset/$tdir" mount_client $submount ||
20629                 error "mount $dir failed"
20630         stack_trap "umount $submount"
20631
20632         local mdts=$(comma_list $(mdts_nodes))
20633
20634         local nrpcs
20635
20636         stat $submount > /dev/null
20637         cancel_lru_locks $MDC
20638         stat $submount > /dev/null
20639         stat $submount/$tfile > /dev/null
20640         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20641         stat $submount/$tfile > /dev/null
20642         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20643                 awk '/getattr/ {sum += $2} END {print sum}')
20644
20645         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20646 }
20647 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20648
20649 test_248a() {
20650         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20651         [ -z "$fast_read_sav" ] && skip "no fast read support"
20652
20653         # create a large file for fast read verification
20654         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20655
20656         # make sure the file is created correctly
20657         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20658                 { rm -f $DIR/$tfile; skip "file creation error"; }
20659
20660         echo "Test 1: verify that fast read is 4 times faster on cache read"
20661
20662         # small read with fast read enabled
20663         $LCTL set_param -n llite.*.fast_read=1
20664         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20665                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20666                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20667         # small read with fast read disabled
20668         $LCTL set_param -n llite.*.fast_read=0
20669         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20670                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20671                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20672
20673         # verify that fast read is 4 times faster for cache read
20674         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20675                 error_not_in_vm "fast read was not 4 times faster: " \
20676                            "$t_fast vs $t_slow"
20677
20678         echo "Test 2: verify the performance between big and small read"
20679         $LCTL set_param -n llite.*.fast_read=1
20680
20681         # 1k non-cache read
20682         cancel_lru_locks osc
20683         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20684                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20685                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20686
20687         # 1M non-cache read
20688         cancel_lru_locks osc
20689         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20690                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20691                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20692
20693         # verify that big IO is not 4 times faster than small IO
20694         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20695                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20696
20697         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20698         rm -f $DIR/$tfile
20699 }
20700 run_test 248a "fast read verification"
20701
20702 test_248b() {
20703         # Default short_io_bytes=16384, try both smaller and larger sizes.
20704         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20705         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20706         echo "bs=53248 count=113 normal buffered write"
20707         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20708                 error "dd of initial data file failed"
20709         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20710
20711         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20712         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20713                 error "dd with sync normal writes failed"
20714         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20715
20716         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20717         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20718                 error "dd with sync small writes failed"
20719         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20720
20721         cancel_lru_locks osc
20722
20723         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20724         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20725         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20726         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20727                 iflag=direct || error "dd with O_DIRECT small read failed"
20728         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20729         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20730                 error "compare $TMP/$tfile.1 failed"
20731
20732         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20733         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20734
20735         # just to see what the maximum tunable value is, and test parsing
20736         echo "test invalid parameter 2MB"
20737         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20738                 error "too-large short_io_bytes allowed"
20739         echo "test maximum parameter 512KB"
20740         # if we can set a larger short_io_bytes, run test regardless of version
20741         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20742                 # older clients may not allow setting it this large, that's OK
20743                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20744                         skip "Need at least client version 2.13.50"
20745                 error "medium short_io_bytes failed"
20746         fi
20747         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20748         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20749
20750         echo "test large parameter 64KB"
20751         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20752         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20753
20754         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20755         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20756                 error "dd with sync large writes failed"
20757         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20758
20759         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20760         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20761         num=$((113 * 4096 / PAGE_SIZE))
20762         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20763         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20764                 error "dd with O_DIRECT large writes failed"
20765         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20766                 error "compare $DIR/$tfile.3 failed"
20767
20768         cancel_lru_locks osc
20769
20770         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20771         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20772                 error "dd with O_DIRECT large read failed"
20773         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20774                 error "compare $TMP/$tfile.2 failed"
20775
20776         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20777         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20778                 error "dd with O_DIRECT large read failed"
20779         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20780                 error "compare $TMP/$tfile.3 failed"
20781 }
20782 run_test 248b "test short_io read and write for both small and large sizes"
20783
20784 test_249() { # LU-7890
20785         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20786                 skip "Need at least version 2.8.54"
20787
20788         rm -f $DIR/$tfile
20789         $LFS setstripe -c 1 $DIR/$tfile
20790         # Offset 2T == 4k * 512M
20791         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20792                 error "dd to 2T offset failed"
20793 }
20794 run_test 249 "Write above 2T file size"
20795
20796 test_250() {
20797         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20798          && skip "no 16TB file size limit on ZFS"
20799
20800         $LFS setstripe -c 1 $DIR/$tfile
20801         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20802         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20803         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20804         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20805                 conv=notrunc,fsync && error "append succeeded"
20806         return 0
20807 }
20808 run_test 250 "Write above 16T limit"
20809
20810 test_251() {
20811         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20812
20813         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20814         #Skip once - writing the first stripe will succeed
20815         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20816         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20817                 error "short write happened"
20818
20819         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20820         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20821                 error "short read happened"
20822
20823         rm -f $DIR/$tfile
20824 }
20825 run_test 251 "Handling short read and write correctly"
20826
20827 test_252() {
20828         remote_mds_nodsh && skip "remote MDS with nodsh"
20829         remote_ost_nodsh && skip "remote OST with nodsh"
20830         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20831                 skip_env "ldiskfs only test"
20832         fi
20833
20834         local tgt
20835         local dev
20836         local out
20837         local uuid
20838         local num
20839         local gen
20840
20841         # check lr_reader on OST0000
20842         tgt=ost1
20843         dev=$(facet_device $tgt)
20844         out=$(do_facet $tgt $LR_READER $dev)
20845         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20846         echo "$out"
20847         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20848         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20849                 error "Invalid uuid returned by $LR_READER on target $tgt"
20850         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20851
20852         # check lr_reader -c on MDT0000
20853         tgt=mds1
20854         dev=$(facet_device $tgt)
20855         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20856                 skip "$LR_READER does not support additional options"
20857         fi
20858         out=$(do_facet $tgt $LR_READER -c $dev)
20859         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20860         echo "$out"
20861         num=$(echo "$out" | grep -c "mdtlov")
20862         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20863                 error "Invalid number of mdtlov clients returned by $LR_READER"
20864         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20865
20866         # check lr_reader -cr on MDT0000
20867         out=$(do_facet $tgt $LR_READER -cr $dev)
20868         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20869         echo "$out"
20870         echo "$out" | grep -q "^reply_data:$" ||
20871                 error "$LR_READER should have returned 'reply_data' section"
20872         num=$(echo "$out" | grep -c "client_generation")
20873         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20874 }
20875 run_test 252 "check lr_reader tool"
20876
20877 test_253() {
20878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20879         remote_mds_nodsh && skip "remote MDS with nodsh"
20880         remote_mgs_nodsh && skip "remote MGS with nodsh"
20881
20882         local ostidx=0
20883         local rc=0
20884         local ost_name=$(ostname_from_index $ostidx)
20885
20886         # on the mdt's osc
20887         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20888         do_facet $SINGLEMDS $LCTL get_param -n \
20889                 osp.$mdtosc_proc1.reserved_mb_high ||
20890                 skip  "remote MDS does not support reserved_mb_high"
20891
20892         rm -rf $DIR/$tdir
20893         wait_mds_ost_sync
20894         wait_delete_completed
20895         mkdir $DIR/$tdir
20896
20897         pool_add $TESTNAME || error "Pool creation failed"
20898         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20899
20900         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20901                 error "Setstripe failed"
20902
20903         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20904
20905         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20906                     grep "watermarks")
20907         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20908
20909         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20910                         osp.$mdtosc_proc1.prealloc_status)
20911         echo "prealloc_status $oa_status"
20912
20913         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20914                 error "File creation should fail"
20915
20916         #object allocation was stopped, but we still able to append files
20917         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20918                 oflag=append || error "Append failed"
20919
20920         rm -f $DIR/$tdir/$tfile.0
20921
20922         # For this test, we want to delete the files we created to go out of
20923         # space but leave the watermark, so we remain nearly out of space
20924         ost_watermarks_enospc_delete_files $tfile $ostidx
20925
20926         wait_delete_completed
20927
20928         sleep_maxage
20929
20930         for i in $(seq 10 12); do
20931                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20932                         2>/dev/null || error "File creation failed after rm"
20933         done
20934
20935         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20936                         osp.$mdtosc_proc1.prealloc_status)
20937         echo "prealloc_status $oa_status"
20938
20939         if (( oa_status != 0 )); then
20940                 error "Object allocation still disable after rm"
20941         fi
20942 }
20943 run_test 253 "Check object allocation limit"
20944
20945 test_254() {
20946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20947         remote_mds_nodsh && skip "remote MDS with nodsh"
20948         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20949                 skip "MDS does not support changelog_size"
20950
20951         local cl_user
20952         local MDT0=$(facet_svc $SINGLEMDS)
20953
20954         changelog_register || error "changelog_register failed"
20955
20956         changelog_clear 0 || error "changelog_clear failed"
20957
20958         local size1=$(do_facet $SINGLEMDS \
20959                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20960         echo "Changelog size $size1"
20961
20962         rm -rf $DIR/$tdir
20963         $LFS mkdir -i 0 $DIR/$tdir
20964         # change something
20965         mkdir -p $DIR/$tdir/pics/2008/zachy
20966         touch $DIR/$tdir/pics/2008/zachy/timestamp
20967         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20968         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20969         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20970         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20971         rm $DIR/$tdir/pics/desktop.jpg
20972
20973         local size2=$(do_facet $SINGLEMDS \
20974                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20975         echo "Changelog size after work $size2"
20976
20977         (( $size2 > $size1 )) ||
20978                 error "new Changelog size=$size2 less than old size=$size1"
20979 }
20980 run_test 254 "Check changelog size"
20981
20982 ladvise_no_type()
20983 {
20984         local type=$1
20985         local file=$2
20986
20987         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20988                 awk -F: '{print $2}' | grep $type > /dev/null
20989         if [ $? -ne 0 ]; then
20990                 return 0
20991         fi
20992         return 1
20993 }
20994
20995 ladvise_no_ioctl()
20996 {
20997         local file=$1
20998
20999         lfs ladvise -a willread $file > /dev/null 2>&1
21000         if [ $? -eq 0 ]; then
21001                 return 1
21002         fi
21003
21004         lfs ladvise -a willread $file 2>&1 |
21005                 grep "Inappropriate ioctl for device" > /dev/null
21006         if [ $? -eq 0 ]; then
21007                 return 0
21008         fi
21009         return 1
21010 }
21011
21012 percent() {
21013         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21014 }
21015
21016 # run a random read IO workload
21017 # usage: random_read_iops <filename> <filesize> <iosize>
21018 random_read_iops() {
21019         local file=$1
21020         local fsize=$2
21021         local iosize=${3:-4096}
21022
21023         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21024                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21025 }
21026
21027 drop_file_oss_cache() {
21028         local file="$1"
21029         local nodes="$2"
21030
21031         $LFS ladvise -a dontneed $file 2>/dev/null ||
21032                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21033 }
21034
21035 ladvise_willread_performance()
21036 {
21037         local repeat=10
21038         local average_origin=0
21039         local average_cache=0
21040         local average_ladvise=0
21041
21042         for ((i = 1; i <= $repeat; i++)); do
21043                 echo "Iter $i/$repeat: reading without willread hint"
21044                 cancel_lru_locks osc
21045                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21046                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21047                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21048                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21049
21050                 cancel_lru_locks osc
21051                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21052                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21053                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21054
21055                 cancel_lru_locks osc
21056                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21057                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21058                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21059                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21060                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21061         done
21062         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21063         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21064         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21065
21066         speedup_cache=$(percent $average_cache $average_origin)
21067         speedup_ladvise=$(percent $average_ladvise $average_origin)
21068
21069         echo "Average uncached read: $average_origin"
21070         echo "Average speedup with OSS cached read: " \
21071                 "$average_cache = +$speedup_cache%"
21072         echo "Average speedup with ladvise willread: " \
21073                 "$average_ladvise = +$speedup_ladvise%"
21074
21075         local lowest_speedup=20
21076         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21077                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21078                         "got $average_cache%. Skipping ladvise willread check."
21079                 return 0
21080         fi
21081
21082         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21083         # it is still good to run until then to exercise 'ladvise willread'
21084         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21085                 [ "$ost1_FSTYPE" = "zfs" ] &&
21086                 echo "osd-zfs does not support dontneed or drop_caches" &&
21087                 return 0
21088
21089         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21090         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21091                 error_not_in_vm "Speedup with willread is less than " \
21092                         "$lowest_speedup%, got $average_ladvise%"
21093 }
21094
21095 test_255a() {
21096         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21097                 skip "lustre < 2.8.54 does not support ladvise "
21098         remote_ost_nodsh && skip "remote OST with nodsh"
21099
21100         stack_trap "rm -f $DIR/$tfile"
21101         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21102
21103         ladvise_no_type willread $DIR/$tfile &&
21104                 skip "willread ladvise is not supported"
21105
21106         ladvise_no_ioctl $DIR/$tfile &&
21107                 skip "ladvise ioctl is not supported"
21108
21109         local size_mb=100
21110         local size=$((size_mb * 1048576))
21111         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21112                 error "dd to $DIR/$tfile failed"
21113
21114         lfs ladvise -a willread $DIR/$tfile ||
21115                 error "Ladvise failed with no range argument"
21116
21117         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21118                 error "Ladvise failed with no -l or -e argument"
21119
21120         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21121                 error "Ladvise failed with only -e argument"
21122
21123         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21124                 error "Ladvise failed with only -l argument"
21125
21126         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21127                 error "End offset should not be smaller than start offset"
21128
21129         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21130                 error "End offset should not be equal to start offset"
21131
21132         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21133                 error "Ladvise failed with overflowing -s argument"
21134
21135         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21136                 error "Ladvise failed with overflowing -e argument"
21137
21138         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21139                 error "Ladvise failed with overflowing -l argument"
21140
21141         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21142                 error "Ladvise succeeded with conflicting -l and -e arguments"
21143
21144         echo "Synchronous ladvise should wait"
21145         local delay=4
21146 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21147         do_nodes $(comma_list $(osts_nodes)) \
21148                 $LCTL set_param fail_val=$delay fail_loc=0x237
21149
21150         local start_ts=$SECONDS
21151         lfs ladvise -a willread $DIR/$tfile ||
21152                 error "Ladvise failed with no range argument"
21153         local end_ts=$SECONDS
21154         local inteval_ts=$((end_ts - start_ts))
21155
21156         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21157                 error "Synchronous advice didn't wait reply"
21158         fi
21159
21160         echo "Asynchronous ladvise shouldn't wait"
21161         local start_ts=$SECONDS
21162         lfs ladvise -a willread -b $DIR/$tfile ||
21163                 error "Ladvise failed with no range argument"
21164         local end_ts=$SECONDS
21165         local inteval_ts=$((end_ts - start_ts))
21166
21167         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21168                 error "Asynchronous advice blocked"
21169         fi
21170
21171         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21172         ladvise_willread_performance
21173 }
21174 run_test 255a "check 'lfs ladvise -a willread'"
21175
21176 facet_meminfo() {
21177         local facet=$1
21178         local info=$2
21179
21180         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21181 }
21182
21183 test_255b() {
21184         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21185                 skip "lustre < 2.8.54 does not support ladvise "
21186         remote_ost_nodsh && skip "remote OST with nodsh"
21187
21188         stack_trap "rm -f $DIR/$tfile"
21189         lfs setstripe -c 1 -i 0 $DIR/$tfile
21190
21191         ladvise_no_type dontneed $DIR/$tfile &&
21192                 skip "dontneed ladvise is not supported"
21193
21194         ladvise_no_ioctl $DIR/$tfile &&
21195                 skip "ladvise ioctl is not supported"
21196
21197         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21198                 [ "$ost1_FSTYPE" = "zfs" ] &&
21199                 skip "zfs-osd does not support 'ladvise dontneed'"
21200
21201         local size_mb=100
21202         local size=$((size_mb * 1048576))
21203         # In order to prevent disturbance of other processes, only check 3/4
21204         # of the memory usage
21205         local kibibytes=$((size_mb * 1024 * 3 / 4))
21206
21207         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21208                 error "dd to $DIR/$tfile failed"
21209
21210         #force write to complete before dropping OST cache & checking memory
21211         sync
21212
21213         local total=$(facet_meminfo ost1 MemTotal)
21214         echo "Total memory: $total KiB"
21215
21216         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21217         local before_read=$(facet_meminfo ost1 Cached)
21218         echo "Cache used before read: $before_read KiB"
21219
21220         lfs ladvise -a willread $DIR/$tfile ||
21221                 error "Ladvise willread failed"
21222         local after_read=$(facet_meminfo ost1 Cached)
21223         echo "Cache used after read: $after_read KiB"
21224
21225         lfs ladvise -a dontneed $DIR/$tfile ||
21226                 error "Ladvise dontneed again failed"
21227         local no_read=$(facet_meminfo ost1 Cached)
21228         echo "Cache used after dontneed ladvise: $no_read KiB"
21229
21230         if [ $total -lt $((before_read + kibibytes)) ]; then
21231                 echo "Memory is too small, abort checking"
21232                 return 0
21233         fi
21234
21235         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21236                 error "Ladvise willread should use more memory" \
21237                         "than $kibibytes KiB"
21238         fi
21239
21240         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21241                 error "Ladvise dontneed should release more memory" \
21242                         "than $kibibytes KiB"
21243         fi
21244 }
21245 run_test 255b "check 'lfs ladvise -a dontneed'"
21246
21247 test_255c() {
21248         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21249                 skip "lustre < 2.10.50 does not support lockahead"
21250
21251         local ost1_imp=$(get_osc_import_name client ost1)
21252         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21253                          cut -d'.' -f2)
21254         local count
21255         local new_count
21256         local difference
21257         local i
21258         local rc
21259
21260         test_mkdir -p $DIR/$tdir
21261         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21262
21263         #test 10 returns only success/failure
21264         i=10
21265         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21266         rc=$?
21267         if [ $rc -eq 255 ]; then
21268                 error "Ladvise test${i} failed, ${rc}"
21269         fi
21270
21271         #test 11 counts lock enqueue requests, all others count new locks
21272         i=11
21273         count=$(do_facet ost1 \
21274                 $LCTL get_param -n ost.OSS.ost.stats)
21275         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21276
21277         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21278         rc=$?
21279         if [ $rc -eq 255 ]; then
21280                 error "Ladvise test${i} failed, ${rc}"
21281         fi
21282
21283         new_count=$(do_facet ost1 \
21284                 $LCTL get_param -n ost.OSS.ost.stats)
21285         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21286                    awk '{ print $2 }')
21287
21288         difference="$((new_count - count))"
21289         if [ $difference -ne $rc ]; then
21290                 error "Ladvise test${i}, bad enqueue count, returned " \
21291                       "${rc}, actual ${difference}"
21292         fi
21293
21294         for i in $(seq 12 21); do
21295                 # If we do not do this, we run the risk of having too many
21296                 # locks and starting lock cancellation while we are checking
21297                 # lock counts.
21298                 cancel_lru_locks osc
21299
21300                 count=$($LCTL get_param -n \
21301                        ldlm.namespaces.$imp_name.lock_unused_count)
21302
21303                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21304                 rc=$?
21305                 if [ $rc -eq 255 ]; then
21306                         error "Ladvise test ${i} failed, ${rc}"
21307                 fi
21308
21309                 new_count=$($LCTL get_param -n \
21310                        ldlm.namespaces.$imp_name.lock_unused_count)
21311                 difference="$((new_count - count))"
21312
21313                 # Test 15 output is divided by 100 to map down to valid return
21314                 if [ $i -eq 15 ]; then
21315                         rc="$((rc * 100))"
21316                 fi
21317
21318                 if [ $difference -ne $rc ]; then
21319                         error "Ladvise test ${i}, bad lock count, returned " \
21320                               "${rc}, actual ${difference}"
21321                 fi
21322         done
21323
21324         #test 22 returns only success/failure
21325         i=22
21326         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21327         rc=$?
21328         if [ $rc -eq 255 ]; then
21329                 error "Ladvise test${i} failed, ${rc}"
21330         fi
21331 }
21332 run_test 255c "suite of ladvise lockahead tests"
21333
21334 test_256() {
21335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21336         remote_mds_nodsh && skip "remote MDS with nodsh"
21337         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21338         changelog_users $SINGLEMDS | grep "^cl" &&
21339                 skip "active changelog user"
21340
21341         local cl_user
21342         local cat_sl
21343         local mdt_dev
21344
21345         mdt_dev=$(mdsdevname 1)
21346         echo $mdt_dev
21347
21348         changelog_register || error "changelog_register failed"
21349
21350         rm -rf $DIR/$tdir
21351         mkdir_on_mdt0 $DIR/$tdir
21352
21353         changelog_clear 0 || error "changelog_clear failed"
21354
21355         # change something
21356         touch $DIR/$tdir/{1..10}
21357
21358         # stop the MDT
21359         stop $SINGLEMDS || error "Fail to stop MDT"
21360
21361         # remount the MDT
21362
21363         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21364
21365         #after mount new plainllog is used
21366         touch $DIR/$tdir/{11..19}
21367         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21368         stack_trap "rm -f $tmpfile"
21369         cat_sl=$(do_facet $SINGLEMDS "sync; \
21370                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21371                  llog_reader $tmpfile | grep -c type=1064553b")
21372         do_facet $SINGLEMDS llog_reader $tmpfile
21373
21374         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21375
21376         changelog_clear 0 || error "changelog_clear failed"
21377
21378         cat_sl=$(do_facet $SINGLEMDS "sync; \
21379                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21380                  llog_reader $tmpfile | grep -c type=1064553b")
21381
21382         if (( cat_sl == 2 )); then
21383                 error "Empty plain llog was not deleted from changelog catalog"
21384         elif (( cat_sl != 1 )); then
21385                 error "Active plain llog shouldn't be deleted from catalog"
21386         fi
21387 }
21388 run_test 256 "Check llog delete for empty and not full state"
21389
21390 test_257() {
21391         remote_mds_nodsh && skip "remote MDS with nodsh"
21392         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21393                 skip "Need MDS version at least 2.8.55"
21394
21395         test_mkdir $DIR/$tdir
21396
21397         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21398                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21399         stat $DIR/$tdir
21400
21401 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21402         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21403         local facet=mds$((mdtidx + 1))
21404         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21405         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21406
21407         stop $facet || error "stop MDS failed"
21408         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21409                 error "start MDS fail"
21410         wait_recovery_complete $facet
21411 }
21412 run_test 257 "xattr locks are not lost"
21413
21414 # Verify we take the i_mutex when security requires it
21415 test_258a() {
21416 #define OBD_FAIL_IMUTEX_SEC 0x141c
21417         $LCTL set_param fail_loc=0x141c
21418         touch $DIR/$tfile
21419         chmod u+s $DIR/$tfile
21420         chmod a+rwx $DIR/$tfile
21421         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21422         RC=$?
21423         if [ $RC -ne 0 ]; then
21424                 error "error, failed to take i_mutex, rc=$?"
21425         fi
21426         rm -f $DIR/$tfile
21427 }
21428 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21429
21430 # Verify we do NOT take the i_mutex in the normal case
21431 test_258b() {
21432 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21433         $LCTL set_param fail_loc=0x141d
21434         touch $DIR/$tfile
21435         chmod a+rwx $DIR
21436         chmod a+rw $DIR/$tfile
21437         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21438         RC=$?
21439         if [ $RC -ne 0 ]; then
21440                 error "error, took i_mutex unnecessarily, rc=$?"
21441         fi
21442         rm -f $DIR/$tfile
21443
21444 }
21445 run_test 258b "verify i_mutex security behavior"
21446
21447 test_259() {
21448         local file=$DIR/$tfile
21449         local before
21450         local after
21451
21452         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21453
21454         stack_trap "rm -f $file" EXIT
21455
21456         wait_delete_completed
21457         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21458         echo "before: $before"
21459
21460         $LFS setstripe -i 0 -c 1 $file
21461         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21462         sync_all_data
21463         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21464         echo "after write: $after"
21465
21466 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21467         do_facet ost1 $LCTL set_param fail_loc=0x2301
21468         $TRUNCATE $file 0
21469         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21470         echo "after truncate: $after"
21471
21472         stop ost1
21473         do_facet ost1 $LCTL set_param fail_loc=0
21474         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21475         sleep 2
21476         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21477         echo "after restart: $after"
21478         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21479                 error "missing truncate?"
21480
21481         return 0
21482 }
21483 run_test 259 "crash at delayed truncate"
21484
21485 test_260() {
21486 #define OBD_FAIL_MDC_CLOSE               0x806
21487         $LCTL set_param fail_loc=0x80000806
21488         touch $DIR/$tfile
21489
21490 }
21491 run_test 260 "Check mdc_close fail"
21492
21493 ### Data-on-MDT sanity tests ###
21494 test_270a() {
21495         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21496                 skip "Need MDS version at least 2.10.55 for DoM"
21497
21498         # create DoM file
21499         local dom=$DIR/$tdir/dom_file
21500         local tmp=$DIR/$tdir/tmp_file
21501
21502         mkdir_on_mdt0 $DIR/$tdir
21503
21504         # basic checks for DoM component creation
21505         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21506                 error "Can set MDT layout to non-first entry"
21507
21508         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21509                 error "Can define multiple entries as MDT layout"
21510
21511         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21512
21513         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21514         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21515         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21516
21517         local mdtidx=$($LFS getstripe -m $dom)
21518         local mdtname=MDT$(printf %04x $mdtidx)
21519         local facet=mds$((mdtidx + 1))
21520         local space_check=1
21521
21522         # Skip free space checks with ZFS
21523         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21524
21525         # write
21526         sync
21527         local size_tmp=$((65536 * 3))
21528         local mdtfree1=$(do_facet $facet \
21529                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21530
21531         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21532         # check also direct IO along write
21533         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21534         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21535         sync
21536         cmp $tmp $dom || error "file data is different"
21537         [ $(stat -c%s $dom) == $size_tmp ] ||
21538                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21539         if [ $space_check == 1 ]; then
21540                 local mdtfree2=$(do_facet $facet \
21541                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21542
21543                 # increase in usage from by $size_tmp
21544                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21545                         error "MDT free space wrong after write: " \
21546                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21547         fi
21548
21549         # truncate
21550         local size_dom=10000
21551
21552         $TRUNCATE $dom $size_dom
21553         [ $(stat -c%s $dom) == $size_dom ] ||
21554                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21555         if [ $space_check == 1 ]; then
21556                 mdtfree1=$(do_facet $facet \
21557                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21558                 # decrease in usage from $size_tmp to new $size_dom
21559                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21560                   $(((size_tmp - size_dom) / 1024)) ] ||
21561                         error "MDT free space is wrong after truncate: " \
21562                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21563         fi
21564
21565         # append
21566         cat $tmp >> $dom
21567         sync
21568         size_dom=$((size_dom + size_tmp))
21569         [ $(stat -c%s $dom) == $size_dom ] ||
21570                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21571         if [ $space_check == 1 ]; then
21572                 mdtfree2=$(do_facet $facet \
21573                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21574                 # increase in usage by $size_tmp from previous
21575                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21576                         error "MDT free space is wrong after append: " \
21577                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21578         fi
21579
21580         # delete
21581         rm $dom
21582         if [ $space_check == 1 ]; then
21583                 mdtfree1=$(do_facet $facet \
21584                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21585                 # decrease in usage by $size_dom from previous
21586                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21587                         error "MDT free space is wrong after removal: " \
21588                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21589         fi
21590
21591         # combined striping
21592         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21593                 error "Can't create DoM + OST striping"
21594
21595         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21596         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21597         # check also direct IO along write
21598         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21599         sync
21600         cmp $tmp $dom || error "file data is different"
21601         [ $(stat -c%s $dom) == $size_tmp ] ||
21602                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21603         rm $dom $tmp
21604
21605         return 0
21606 }
21607 run_test 270a "DoM: basic functionality tests"
21608
21609 test_270b() {
21610         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21611                 skip "Need MDS version at least 2.10.55"
21612
21613         local dom=$DIR/$tdir/dom_file
21614         local max_size=1048576
21615
21616         mkdir -p $DIR/$tdir
21617         $LFS setstripe -E $max_size -L mdt $dom
21618
21619         # truncate over the limit
21620         $TRUNCATE $dom $(($max_size + 1)) &&
21621                 error "successful truncate over the maximum size"
21622         # write over the limit
21623         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21624                 error "successful write over the maximum size"
21625         # append over the limit
21626         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21627         echo "12345" >> $dom && error "successful append over the maximum size"
21628         rm $dom
21629
21630         return 0
21631 }
21632 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21633
21634 test_270c() {
21635         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21636                 skip "Need MDS version at least 2.10.55"
21637
21638         mkdir -p $DIR/$tdir
21639         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21640
21641         # check files inherit DoM EA
21642         touch $DIR/$tdir/first
21643         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21644                 error "bad pattern"
21645         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21646                 error "bad stripe count"
21647         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21648                 error "bad stripe size"
21649
21650         # check directory inherits DoM EA and uses it as default
21651         mkdir $DIR/$tdir/subdir
21652         touch $DIR/$tdir/subdir/second
21653         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21654                 error "bad pattern in sub-directory"
21655         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21656                 error "bad stripe count in sub-directory"
21657         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21658                 error "bad stripe size in sub-directory"
21659         return 0
21660 }
21661 run_test 270c "DoM: DoM EA inheritance tests"
21662
21663 test_270d() {
21664         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21665                 skip "Need MDS version at least 2.10.55"
21666
21667         mkdir -p $DIR/$tdir
21668         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21669
21670         # inherit default DoM striping
21671         mkdir $DIR/$tdir/subdir
21672         touch $DIR/$tdir/subdir/f1
21673
21674         # change default directory striping
21675         $LFS setstripe -c 1 $DIR/$tdir/subdir
21676         touch $DIR/$tdir/subdir/f2
21677         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21678                 error "wrong default striping in file 2"
21679         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21680                 error "bad pattern in file 2"
21681         return 0
21682 }
21683 run_test 270d "DoM: change striping from DoM to RAID0"
21684
21685 test_270e() {
21686         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21687                 skip "Need MDS version at least 2.10.55"
21688
21689         mkdir -p $DIR/$tdir/dom
21690         mkdir -p $DIR/$tdir/norm
21691         DOMFILES=20
21692         NORMFILES=10
21693         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21694         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21695
21696         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21697         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21698
21699         # find DoM files by layout
21700         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21701         [ $NUM -eq  $DOMFILES ] ||
21702                 error "lfs find -L: found $NUM, expected $DOMFILES"
21703         echo "Test 1: lfs find 20 DOM files by layout: OK"
21704
21705         # there should be 1 dir with default DOM striping
21706         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21707         [ $NUM -eq  1 ] ||
21708                 error "lfs find -L: found $NUM, expected 1 dir"
21709         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21710
21711         # find DoM files by stripe size
21712         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21713         [ $NUM -eq  $DOMFILES ] ||
21714                 error "lfs find -S: found $NUM, expected $DOMFILES"
21715         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21716
21717         # find files by stripe offset except DoM files
21718         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21719         [ $NUM -eq  $NORMFILES ] ||
21720                 error "lfs find -i: found $NUM, expected $NORMFILES"
21721         echo "Test 5: lfs find no DOM files by stripe index: OK"
21722         return 0
21723 }
21724 run_test 270e "DoM: lfs find with DoM files test"
21725
21726 test_270f() {
21727         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21728                 skip "Need MDS version at least 2.10.55"
21729
21730         local mdtname=${FSNAME}-MDT0000-mdtlov
21731         local dom=$DIR/$tdir/dom_file
21732         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21733                                                 lod.$mdtname.dom_stripesize)
21734         local dom_limit=131072
21735
21736         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21737         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21738                                                 lod.$mdtname.dom_stripesize)
21739         [ ${dom_limit} -eq ${dom_current} ] ||
21740                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21741
21742         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21743         $LFS setstripe -d $DIR/$tdir
21744         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21745                 error "Can't set directory default striping"
21746
21747         # exceed maximum stripe size
21748         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21749                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21750         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21751                 error "Able to create DoM component size more than LOD limit"
21752
21753         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21754         dom_current=$(do_facet mds1 $LCTL get_param -n \
21755                                                 lod.$mdtname.dom_stripesize)
21756         [ 0 -eq ${dom_current} ] ||
21757                 error "Can't set zero DoM stripe limit"
21758         rm $dom
21759
21760         # attempt to create DoM file on server with disabled DoM should
21761         # remove DoM entry from layout and be succeed
21762         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21763                 error "Can't create DoM file (DoM is disabled)"
21764         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21765                 error "File has DoM component while DoM is disabled"
21766         rm $dom
21767
21768         # attempt to create DoM file with only DoM stripe should return error
21769         $LFS setstripe -E $dom_limit -L mdt $dom &&
21770                 error "Able to create DoM-only file while DoM is disabled"
21771
21772         # too low values to be aligned with smallest stripe size 64K
21773         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21774         dom_current=$(do_facet mds1 $LCTL get_param -n \
21775                                                 lod.$mdtname.dom_stripesize)
21776         [ 30000 -eq ${dom_current} ] &&
21777                 error "Can set too small DoM stripe limit"
21778
21779         # 64K is a minimal stripe size in Lustre, expect limit of that size
21780         [ 65536 -eq ${dom_current} ] ||
21781                 error "Limit is not set to 64K but ${dom_current}"
21782
21783         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21784         dom_current=$(do_facet mds1 $LCTL get_param -n \
21785                                                 lod.$mdtname.dom_stripesize)
21786         echo $dom_current
21787         [ 2147483648 -eq ${dom_current} ] &&
21788                 error "Can set too large DoM stripe limit"
21789
21790         do_facet mds1 $LCTL set_param -n \
21791                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21792         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21793                 error "Can't create DoM component size after limit change"
21794         do_facet mds1 $LCTL set_param -n \
21795                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21796         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21797                 error "Can't create DoM file after limit decrease"
21798         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21799                 error "Can create big DoM component after limit decrease"
21800         touch ${dom}_def ||
21801                 error "Can't create file with old default layout"
21802
21803         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21804         return 0
21805 }
21806 run_test 270f "DoM: maximum DoM stripe size checks"
21807
21808 test_270g() {
21809         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21810                 skip "Need MDS version at least 2.13.52"
21811         local dom=$DIR/$tdir/$tfile
21812
21813         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21814         local lodname=${FSNAME}-MDT0000-mdtlov
21815
21816         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21817         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21818         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21819         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21820
21821         local dom_limit=1024
21822         local dom_threshold="50%"
21823
21824         $LFS setstripe -d $DIR/$tdir
21825         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21826                 error "Can't set directory default striping"
21827
21828         do_facet mds1 $LCTL set_param -n \
21829                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21830         # set 0 threshold and create DOM file to change tunable stripesize
21831         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21832         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21833                 error "Failed to create $dom file"
21834         # now tunable dom_cur_stripesize should reach maximum
21835         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21836                                         lod.${lodname}.dom_stripesize_cur_kb)
21837         [[ $dom_current == $dom_limit ]] ||
21838                 error "Current DOM stripesize is not maximum"
21839         rm $dom
21840
21841         # set threshold for further tests
21842         do_facet mds1 $LCTL set_param -n \
21843                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21844         echo "DOM threshold is $dom_threshold free space"
21845         local dom_def
21846         local dom_set
21847         # Spoof bfree to exceed threshold
21848         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21849         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21850         for spfree in 40 20 0 15 30 55; do
21851                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21852                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21853                         error "Failed to create $dom file"
21854                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21855                                         lod.${lodname}.dom_stripesize_cur_kb)
21856                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21857                 [[ $dom_def != $dom_current ]] ||
21858                         error "Default stripe size was not changed"
21859                 if [[ $spfree > 0 ]] ; then
21860                         dom_set=$($LFS getstripe -S $dom)
21861                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21862                                 error "DOM component size is still old"
21863                 else
21864                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21865                                 error "DoM component is set with no free space"
21866                 fi
21867                 rm $dom
21868                 dom_current=$dom_def
21869         done
21870 }
21871 run_test 270g "DoM: default DoM stripe size depends on free space"
21872
21873 test_270h() {
21874         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21875                 skip "Need MDS version at least 2.13.53"
21876
21877         local mdtname=${FSNAME}-MDT0000-mdtlov
21878         local dom=$DIR/$tdir/$tfile
21879         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21880
21881         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21882         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21883
21884         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21885         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21886                 error "can't create OST file"
21887         # mirrored file with DOM entry in the second mirror
21888         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21889                 error "can't create mirror with DoM component"
21890
21891         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21892
21893         # DOM component in the middle and has other enries in the same mirror,
21894         # should succeed but lost DoM component
21895         $LFS setstripe --copy=${dom}_1 $dom ||
21896                 error "Can't create file from OST|DOM mirror layout"
21897         # check new file has no DoM layout after all
21898         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21899                 error "File has DoM component while DoM is disabled"
21900 }
21901 run_test 270h "DoM: DoM stripe removal when disabled on server"
21902
21903 test_271a() {
21904         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21905                 skip "Need MDS version at least 2.10.55"
21906
21907         local dom=$DIR/$tdir/dom
21908
21909         mkdir -p $DIR/$tdir
21910
21911         $LFS setstripe -E 1024K -L mdt $dom
21912
21913         lctl set_param -n mdc.*.stats=clear
21914         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21915         cat $dom > /dev/null
21916         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21917         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21918         ls $dom
21919         rm -f $dom
21920 }
21921 run_test 271a "DoM: data is cached for read after write"
21922
21923 test_271b() {
21924         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21925                 skip "Need MDS version at least 2.10.55"
21926
21927         local dom=$DIR/$tdir/dom
21928
21929         mkdir -p $DIR/$tdir
21930
21931         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21932
21933         lctl set_param -n mdc.*.stats=clear
21934         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21935         cancel_lru_locks mdc
21936         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21937         # second stat to check size is cached on client
21938         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21939         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21940         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21941         rm -f $dom
21942 }
21943 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21944
21945 test_271ba() {
21946         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21947                 skip "Need MDS version at least 2.10.55"
21948
21949         local dom=$DIR/$tdir/dom
21950
21951         mkdir -p $DIR/$tdir
21952
21953         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21954
21955         lctl set_param -n mdc.*.stats=clear
21956         lctl set_param -n osc.*.stats=clear
21957         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21958         cancel_lru_locks mdc
21959         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21960         # second stat to check size is cached on client
21961         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21962         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21963         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21964         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21965         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21966         rm -f $dom
21967 }
21968 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21969
21970
21971 get_mdc_stats() {
21972         local mdtidx=$1
21973         local param=$2
21974         local mdt=MDT$(printf %04x $mdtidx)
21975
21976         if [ -z $param ]; then
21977                 lctl get_param -n mdc.*$mdt*.stats
21978         else
21979                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21980         fi
21981 }
21982
21983 test_271c() {
21984         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21985                 skip "Need MDS version at least 2.10.55"
21986
21987         local dom=$DIR/$tdir/dom
21988
21989         mkdir -p $DIR/$tdir
21990
21991         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21992
21993         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21994         local facet=mds$((mdtidx + 1))
21995
21996         cancel_lru_locks mdc
21997         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21998         createmany -o $dom 1000
21999         lctl set_param -n mdc.*.stats=clear
22000         smalliomany -w $dom 1000 200
22001         get_mdc_stats $mdtidx
22002         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22003         # Each file has 1 open, 1 IO enqueues, total 2000
22004         # but now we have also +1 getxattr for security.capability, total 3000
22005         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22006         unlinkmany $dom 1000
22007
22008         cancel_lru_locks mdc
22009         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22010         createmany -o $dom 1000
22011         lctl set_param -n mdc.*.stats=clear
22012         smalliomany -w $dom 1000 200
22013         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22014         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22015         # for OPEN and IO lock.
22016         [ $((enq - enq_2)) -ge 1000 ] ||
22017                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22018         unlinkmany $dom 1000
22019         return 0
22020 }
22021 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22022
22023 cleanup_271def_tests() {
22024         trap 0
22025         rm -f $1
22026 }
22027
22028 test_271d() {
22029         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22030                 skip "Need MDS version at least 2.10.57"
22031
22032         local dom=$DIR/$tdir/dom
22033         local tmp=$TMP/$tfile
22034         trap "cleanup_271def_tests $tmp" EXIT
22035
22036         mkdir -p $DIR/$tdir
22037
22038         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22039
22040         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22041
22042         cancel_lru_locks mdc
22043         dd if=/dev/urandom of=$tmp bs=1000 count=1
22044         dd if=$tmp of=$dom bs=1000 count=1
22045         cancel_lru_locks mdc
22046
22047         cat /etc/hosts >> $tmp
22048         lctl set_param -n mdc.*.stats=clear
22049
22050         # append data to the same file it should update local page
22051         echo "Append to the same page"
22052         cat /etc/hosts >> $dom
22053         local num=$(get_mdc_stats $mdtidx ost_read)
22054         local ra=$(get_mdc_stats $mdtidx req_active)
22055         local rw=$(get_mdc_stats $mdtidx req_waittime)
22056
22057         [ -z $num ] || error "$num READ RPC occured"
22058         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22059         echo "... DONE"
22060
22061         # compare content
22062         cmp $tmp $dom || error "file miscompare"
22063
22064         cancel_lru_locks mdc
22065         lctl set_param -n mdc.*.stats=clear
22066
22067         echo "Open and read file"
22068         cat $dom > /dev/null
22069         local num=$(get_mdc_stats $mdtidx ost_read)
22070         local ra=$(get_mdc_stats $mdtidx req_active)
22071         local rw=$(get_mdc_stats $mdtidx req_waittime)
22072
22073         [ -z $num ] || error "$num READ RPC occured"
22074         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22075         echo "... DONE"
22076
22077         # compare content
22078         cmp $tmp $dom || error "file miscompare"
22079
22080         return 0
22081 }
22082 run_test 271d "DoM: read on open (1K file in reply buffer)"
22083
22084 test_271f() {
22085         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22086                 skip "Need MDS version at least 2.10.57"
22087
22088         local dom=$DIR/$tdir/dom
22089         local tmp=$TMP/$tfile
22090         trap "cleanup_271def_tests $tmp" EXIT
22091
22092         mkdir -p $DIR/$tdir
22093
22094         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22095
22096         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22097
22098         cancel_lru_locks mdc
22099         dd if=/dev/urandom of=$tmp bs=265000 count=1
22100         dd if=$tmp of=$dom bs=265000 count=1
22101         cancel_lru_locks mdc
22102         cat /etc/hosts >> $tmp
22103         lctl set_param -n mdc.*.stats=clear
22104
22105         echo "Append to the same page"
22106         cat /etc/hosts >> $dom
22107         local num=$(get_mdc_stats $mdtidx ost_read)
22108         local ra=$(get_mdc_stats $mdtidx req_active)
22109         local rw=$(get_mdc_stats $mdtidx req_waittime)
22110
22111         [ -z $num ] || error "$num READ RPC occured"
22112         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22113         echo "... DONE"
22114
22115         # compare content
22116         cmp $tmp $dom || error "file miscompare"
22117
22118         cancel_lru_locks mdc
22119         lctl set_param -n mdc.*.stats=clear
22120
22121         echo "Open and read file"
22122         cat $dom > /dev/null
22123         local num=$(get_mdc_stats $mdtidx ost_read)
22124         local ra=$(get_mdc_stats $mdtidx req_active)
22125         local rw=$(get_mdc_stats $mdtidx req_waittime)
22126
22127         [ -z $num ] && num=0
22128         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22129         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22130         echo "... DONE"
22131
22132         # compare content
22133         cmp $tmp $dom || error "file miscompare"
22134
22135         return 0
22136 }
22137 run_test 271f "DoM: read on open (200K file and read tail)"
22138
22139 test_271g() {
22140         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22141                 skip "Skipping due to old client or server version"
22142
22143         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22144         # to get layout
22145         $CHECKSTAT -t file $DIR1/$tfile
22146
22147         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22148         MULTIOP_PID=$!
22149         sleep 1
22150         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22151         $LCTL set_param fail_loc=0x80000314
22152         rm $DIR1/$tfile || error "Unlink fails"
22153         RC=$?
22154         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22155         [ $RC -eq 0 ] || error "Failed write to stale object"
22156 }
22157 run_test 271g "Discard DoM data vs client flush race"
22158
22159 test_272a() {
22160         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22161                 skip "Need MDS version at least 2.11.50"
22162
22163         local dom=$DIR/$tdir/dom
22164         mkdir -p $DIR/$tdir
22165
22166         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22167         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22168                 error "failed to write data into $dom"
22169         local old_md5=$(md5sum $dom)
22170
22171         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22172                 error "failed to migrate to the same DoM component"
22173
22174         local new_md5=$(md5sum $dom)
22175
22176         [ "$old_md5" == "$new_md5" ] ||
22177                 error "md5sum differ: $old_md5, $new_md5"
22178
22179         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22180                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22181 }
22182 run_test 272a "DoM migration: new layout with the same DOM component"
22183
22184 test_272b() {
22185         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22186                 skip "Need MDS version at least 2.11.50"
22187
22188         local dom=$DIR/$tdir/dom
22189         mkdir -p $DIR/$tdir
22190         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22191
22192         local mdtidx=$($LFS getstripe -m $dom)
22193         local mdtname=MDT$(printf %04x $mdtidx)
22194         local facet=mds$((mdtidx + 1))
22195
22196         local mdtfree1=$(do_facet $facet \
22197                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22198         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22199                 error "failed to write data into $dom"
22200         local old_md5=$(md5sum $dom)
22201         cancel_lru_locks mdc
22202         local mdtfree1=$(do_facet $facet \
22203                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22204
22205         $LFS migrate -c2 $dom ||
22206                 error "failed to migrate to the new composite layout"
22207         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22208                 error "MDT stripe was not removed"
22209
22210         cancel_lru_locks mdc
22211         local new_md5=$(md5sum $dom)
22212         [ "$old_md5" == "$new_md5" ] ||
22213                 error "$old_md5 != $new_md5"
22214
22215         # Skip free space checks with ZFS
22216         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22217                 local mdtfree2=$(do_facet $facet \
22218                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22219                 [ $mdtfree2 -gt $mdtfree1 ] ||
22220                         error "MDT space is not freed after migration"
22221         fi
22222         return 0
22223 }
22224 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22225
22226 test_272c() {
22227         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22228                 skip "Need MDS version at least 2.11.50"
22229
22230         local dom=$DIR/$tdir/$tfile
22231         mkdir -p $DIR/$tdir
22232         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22233
22234         local mdtidx=$($LFS getstripe -m $dom)
22235         local mdtname=MDT$(printf %04x $mdtidx)
22236         local facet=mds$((mdtidx + 1))
22237
22238         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22239                 error "failed to write data into $dom"
22240         local old_md5=$(md5sum $dom)
22241         cancel_lru_locks mdc
22242         local mdtfree1=$(do_facet $facet \
22243                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22244
22245         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22246                 error "failed to migrate to the new composite layout"
22247         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22248                 error "MDT stripe was not removed"
22249
22250         cancel_lru_locks mdc
22251         local new_md5=$(md5sum $dom)
22252         [ "$old_md5" == "$new_md5" ] ||
22253                 error "$old_md5 != $new_md5"
22254
22255         # Skip free space checks with ZFS
22256         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22257                 local mdtfree2=$(do_facet $facet \
22258                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22259                 [ $mdtfree2 -gt $mdtfree1 ] ||
22260                         error "MDS space is not freed after migration"
22261         fi
22262         return 0
22263 }
22264 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22265
22266 test_272d() {
22267         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22268                 skip "Need MDS version at least 2.12.55"
22269
22270         local dom=$DIR/$tdir/$tfile
22271         mkdir -p $DIR/$tdir
22272         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22273
22274         local mdtidx=$($LFS getstripe -m $dom)
22275         local mdtname=MDT$(printf %04x $mdtidx)
22276         local facet=mds$((mdtidx + 1))
22277
22278         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22279                 error "failed to write data into $dom"
22280         local old_md5=$(md5sum $dom)
22281         cancel_lru_locks mdc
22282         local mdtfree1=$(do_facet $facet \
22283                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22284
22285         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22286                 error "failed mirroring to the new composite layout"
22287         $LFS mirror resync $dom ||
22288                 error "failed mirror resync"
22289         $LFS mirror split --mirror-id 1 -d $dom ||
22290                 error "failed mirror split"
22291
22292         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22293                 error "MDT stripe was not removed"
22294
22295         cancel_lru_locks mdc
22296         local new_md5=$(md5sum $dom)
22297         [ "$old_md5" == "$new_md5" ] ||
22298                 error "$old_md5 != $new_md5"
22299
22300         # Skip free space checks with ZFS
22301         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22302                 local mdtfree2=$(do_facet $facet \
22303                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22304                 [ $mdtfree2 -gt $mdtfree1 ] ||
22305                         error "MDS space is not freed after DOM mirror deletion"
22306         fi
22307         return 0
22308 }
22309 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22310
22311 test_272e() {
22312         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22313                 skip "Need MDS version at least 2.12.55"
22314
22315         local dom=$DIR/$tdir/$tfile
22316         mkdir -p $DIR/$tdir
22317         $LFS setstripe -c 2 $dom
22318
22319         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22320                 error "failed to write data into $dom"
22321         local old_md5=$(md5sum $dom)
22322         cancel_lru_locks mdc
22323
22324         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22325                 error "failed mirroring to the DOM layout"
22326         $LFS mirror resync $dom ||
22327                 error "failed mirror resync"
22328         $LFS mirror split --mirror-id 1 -d $dom ||
22329                 error "failed mirror split"
22330
22331         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22332                 error "MDT stripe was not removed"
22333
22334         cancel_lru_locks mdc
22335         local new_md5=$(md5sum $dom)
22336         [ "$old_md5" == "$new_md5" ] ||
22337                 error "$old_md5 != $new_md5"
22338
22339         return 0
22340 }
22341 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22342
22343 test_272f() {
22344         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22345                 skip "Need MDS version at least 2.12.55"
22346
22347         local dom=$DIR/$tdir/$tfile
22348         mkdir -p $DIR/$tdir
22349         $LFS setstripe -c 2 $dom
22350
22351         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22352                 error "failed to write data into $dom"
22353         local old_md5=$(md5sum $dom)
22354         cancel_lru_locks mdc
22355
22356         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22357                 error "failed migrating to the DOM file"
22358
22359         cancel_lru_locks mdc
22360         local new_md5=$(md5sum $dom)
22361         [ "$old_md5" != "$new_md5" ] &&
22362                 error "$old_md5 != $new_md5"
22363
22364         return 0
22365 }
22366 run_test 272f "DoM migration: OST-striped file to DOM file"
22367
22368 test_273a() {
22369         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22370                 skip "Need MDS version at least 2.11.50"
22371
22372         # Layout swap cannot be done if either file has DOM component,
22373         # this will never be supported, migration should be used instead
22374
22375         local dom=$DIR/$tdir/$tfile
22376         mkdir -p $DIR/$tdir
22377
22378         $LFS setstripe -c2 ${dom}_plain
22379         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22380         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22381                 error "can swap layout with DoM component"
22382         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22383                 error "can swap layout with DoM component"
22384
22385         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22386         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22387                 error "can swap layout with DoM component"
22388         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22389                 error "can swap layout with DoM component"
22390         return 0
22391 }
22392 run_test 273a "DoM: layout swapping should fail with DOM"
22393
22394 test_273b() {
22395         mkdir -p $DIR/$tdir
22396         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22397
22398 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22399         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22400
22401         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22402 }
22403 run_test 273b "DoM: race writeback and object destroy"
22404
22405 test_275() {
22406         remote_ost_nodsh && skip "remote OST with nodsh"
22407         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22408                 skip "Need OST version >= 2.10.57"
22409
22410         local file=$DIR/$tfile
22411         local oss
22412
22413         oss=$(comma_list $(osts_nodes))
22414
22415         dd if=/dev/urandom of=$file bs=1M count=2 ||
22416                 error "failed to create a file"
22417         cancel_lru_locks osc
22418
22419         #lock 1
22420         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22421                 error "failed to read a file"
22422
22423 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22424         $LCTL set_param fail_loc=0x8000031f
22425
22426         cancel_lru_locks osc &
22427         sleep 1
22428
22429 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22430         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22431         #IO takes another lock, but matches the PENDING one
22432         #and places it to the IO RPC
22433         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22434                 error "failed to read a file with PENDING lock"
22435 }
22436 run_test 275 "Read on a canceled duplicate lock"
22437
22438 test_276() {
22439         remote_ost_nodsh && skip "remote OST with nodsh"
22440         local pid
22441
22442         do_facet ost1 "(while true; do \
22443                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22444                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22445         pid=$!
22446
22447         for LOOP in $(seq 20); do
22448                 stop ost1
22449                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22450         done
22451         kill -9 $pid
22452         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22453                 rm $TMP/sanity_276_pid"
22454 }
22455 run_test 276 "Race between mount and obd_statfs"
22456
22457 test_277() {
22458         $LCTL set_param ldlm.namespaces.*.lru_size=0
22459         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22460         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22461                         grep ^used_mb | awk '{print $2}')
22462         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22463         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22464                 oflag=direct conv=notrunc
22465         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22466                         grep ^used_mb | awk '{print $2}')
22467         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22468 }
22469 run_test 277 "Direct IO shall drop page cache"
22470
22471 test_278() {
22472         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22473         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22474         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22475                 skip "needs the same host for mdt1 mdt2" && return
22476
22477         local pid1
22478         local pid2
22479
22480 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22481         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22482         stop mds2 &
22483         pid2=$!
22484
22485         stop mds1
22486
22487         echo "Starting MDTs"
22488         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22489         wait $pid2
22490 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22491 #will return NULL
22492         do_facet mds2 $LCTL set_param fail_loc=0
22493
22494         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22495         wait_recovery_complete mds2
22496 }
22497 run_test 278 "Race starting MDS between MDTs stop/start"
22498
22499 test_280() {
22500         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22501                 skip "Need MGS version at least 2.13.52"
22502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22503         combined_mgs_mds || skip "needs combined MGS/MDT"
22504
22505         umount_client $MOUNT
22506 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22507         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22508
22509         mount_client $MOUNT &
22510         sleep 1
22511         stop mgs || error "stop mgs failed"
22512         #for a race mgs would crash
22513         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22514         # make sure we unmount client before remounting
22515         wait
22516         umount_client $MOUNT
22517         mount_client $MOUNT || error "mount client failed"
22518 }
22519 run_test 280 "Race between MGS umount and client llog processing"
22520
22521 cleanup_test_300() {
22522         trap 0
22523         umask $SAVE_UMASK
22524 }
22525 test_striped_dir() {
22526         local mdt_index=$1
22527         local stripe_count
22528         local stripe_index
22529
22530         mkdir -p $DIR/$tdir
22531
22532         SAVE_UMASK=$(umask)
22533         trap cleanup_test_300 RETURN EXIT
22534
22535         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22536                                                 $DIR/$tdir/striped_dir ||
22537                 error "set striped dir error"
22538
22539         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22540         [ "$mode" = "755" ] || error "expect 755 got $mode"
22541
22542         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22543                 error "getdirstripe failed"
22544         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22545         if [ "$stripe_count" != "2" ]; then
22546                 error "1:stripe_count is $stripe_count, expect 2"
22547         fi
22548         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22549         if [ "$stripe_count" != "2" ]; then
22550                 error "2:stripe_count is $stripe_count, expect 2"
22551         fi
22552
22553         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22554         if [ "$stripe_index" != "$mdt_index" ]; then
22555                 error "stripe_index is $stripe_index, expect $mdt_index"
22556         fi
22557
22558         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22559                 error "nlink error after create striped dir"
22560
22561         mkdir $DIR/$tdir/striped_dir/a
22562         mkdir $DIR/$tdir/striped_dir/b
22563
22564         stat $DIR/$tdir/striped_dir/a ||
22565                 error "create dir under striped dir failed"
22566         stat $DIR/$tdir/striped_dir/b ||
22567                 error "create dir under striped dir failed"
22568
22569         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22570                 error "nlink error after mkdir"
22571
22572         rmdir $DIR/$tdir/striped_dir/a
22573         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22574                 error "nlink error after rmdir"
22575
22576         rmdir $DIR/$tdir/striped_dir/b
22577         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22578                 error "nlink error after rmdir"
22579
22580         chattr +i $DIR/$tdir/striped_dir
22581         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22582                 error "immutable flags not working under striped dir!"
22583         chattr -i $DIR/$tdir/striped_dir
22584
22585         rmdir $DIR/$tdir/striped_dir ||
22586                 error "rmdir striped dir error"
22587
22588         cleanup_test_300
22589
22590         true
22591 }
22592
22593 test_300a() {
22594         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22595                 skip "skipped for lustre < 2.7.0"
22596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22597         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22598
22599         test_striped_dir 0 || error "failed on striped dir on MDT0"
22600         test_striped_dir 1 || error "failed on striped dir on MDT0"
22601 }
22602 run_test 300a "basic striped dir sanity test"
22603
22604 test_300b() {
22605         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22606                 skip "skipped for lustre < 2.7.0"
22607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22608         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22609
22610         local i
22611         local mtime1
22612         local mtime2
22613         local mtime3
22614
22615         test_mkdir $DIR/$tdir || error "mkdir fail"
22616         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22617                 error "set striped dir error"
22618         for i in {0..9}; do
22619                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22620                 sleep 1
22621                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22622                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22623                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22624                 sleep 1
22625                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22626                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22627                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22628         done
22629         true
22630 }
22631 run_test 300b "check ctime/mtime for striped dir"
22632
22633 test_300c() {
22634         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22635                 skip "skipped for lustre < 2.7.0"
22636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22638
22639         local file_count
22640
22641         mkdir_on_mdt0 $DIR/$tdir
22642         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22643                 error "set striped dir error"
22644
22645         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22646                 error "chown striped dir failed"
22647
22648         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22649                 error "create 5k files failed"
22650
22651         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22652
22653         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22654
22655         rm -rf $DIR/$tdir
22656 }
22657 run_test 300c "chown && check ls under striped directory"
22658
22659 test_300d() {
22660         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22661                 skip "skipped for lustre < 2.7.0"
22662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22663         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22664
22665         local stripe_count
22666         local file
22667
22668         mkdir -p $DIR/$tdir
22669         $LFS setstripe -c 2 $DIR/$tdir
22670
22671         #local striped directory
22672         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22673                 error "set striped dir error"
22674         #look at the directories for debug purposes
22675         ls -l $DIR/$tdir
22676         $LFS getdirstripe $DIR/$tdir
22677         ls -l $DIR/$tdir/striped_dir
22678         $LFS getdirstripe $DIR/$tdir/striped_dir
22679         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22680                 error "create 10 files failed"
22681
22682         #remote striped directory
22683         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22684                 error "set striped dir error"
22685         #look at the directories for debug purposes
22686         ls -l $DIR/$tdir
22687         $LFS getdirstripe $DIR/$tdir
22688         ls -l $DIR/$tdir/remote_striped_dir
22689         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22690         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22691                 error "create 10 files failed"
22692
22693         for file in $(find $DIR/$tdir); do
22694                 stripe_count=$($LFS getstripe -c $file)
22695                 [ $stripe_count -eq 2 ] ||
22696                         error "wrong stripe $stripe_count for $file"
22697         done
22698
22699         rm -rf $DIR/$tdir
22700 }
22701 run_test 300d "check default stripe under striped directory"
22702
22703 test_300e() {
22704         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22705                 skip "Need MDS version at least 2.7.55"
22706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22708
22709         local stripe_count
22710         local file
22711
22712         mkdir -p $DIR/$tdir
22713
22714         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22715                 error "set striped dir error"
22716
22717         touch $DIR/$tdir/striped_dir/a
22718         touch $DIR/$tdir/striped_dir/b
22719         touch $DIR/$tdir/striped_dir/c
22720
22721         mkdir $DIR/$tdir/striped_dir/dir_a
22722         mkdir $DIR/$tdir/striped_dir/dir_b
22723         mkdir $DIR/$tdir/striped_dir/dir_c
22724
22725         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22726                 error "set striped adir under striped dir error"
22727
22728         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22729                 error "set striped bdir under striped dir error"
22730
22731         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22732                 error "set striped cdir under striped dir error"
22733
22734         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22735                 error "rename dir under striped dir fails"
22736
22737         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22738                 error "rename dir under different stripes fails"
22739
22740         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22741                 error "rename file under striped dir should succeed"
22742
22743         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22744                 error "rename dir under striped dir should succeed"
22745
22746         rm -rf $DIR/$tdir
22747 }
22748 run_test 300e "check rename under striped directory"
22749
22750 test_300f() {
22751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22752         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22753         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22754                 skip "Need MDS version at least 2.7.55"
22755
22756         local stripe_count
22757         local file
22758
22759         rm -rf $DIR/$tdir
22760         mkdir -p $DIR/$tdir
22761
22762         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22763                 error "set striped dir error"
22764
22765         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22766                 error "set striped dir error"
22767
22768         touch $DIR/$tdir/striped_dir/a
22769         mkdir $DIR/$tdir/striped_dir/dir_a
22770         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22771                 error "create striped dir under striped dir fails"
22772
22773         touch $DIR/$tdir/striped_dir1/b
22774         mkdir $DIR/$tdir/striped_dir1/dir_b
22775         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22776                 error "create striped dir under striped dir fails"
22777
22778         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22779                 error "rename dir under different striped dir should fail"
22780
22781         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22782                 error "rename striped dir under diff striped dir should fail"
22783
22784         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22785                 error "rename file under diff striped dirs fails"
22786
22787         rm -rf $DIR/$tdir
22788 }
22789 run_test 300f "check rename cross striped directory"
22790
22791 test_300_check_default_striped_dir()
22792 {
22793         local dirname=$1
22794         local default_count=$2
22795         local default_index=$3
22796         local stripe_count
22797         local stripe_index
22798         local dir_stripe_index
22799         local dir
22800
22801         echo "checking $dirname $default_count $default_index"
22802         $LFS setdirstripe -D -c $default_count -i $default_index \
22803                                 -H all_char $DIR/$tdir/$dirname ||
22804                 error "set default stripe on striped dir error"
22805         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22806         [ $stripe_count -eq $default_count ] ||
22807                 error "expect $default_count get $stripe_count for $dirname"
22808
22809         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22810         [ $stripe_index -eq $default_index ] ||
22811                 error "expect $default_index get $stripe_index for $dirname"
22812
22813         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22814                                                 error "create dirs failed"
22815
22816         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22817         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22818         for dir in $(find $DIR/$tdir/$dirname/*); do
22819                 stripe_count=$($LFS getdirstripe -c $dir)
22820                 (( $stripe_count == $default_count )) ||
22821                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22822                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22823                 error "stripe count $default_count != $stripe_count for $dir"
22824
22825                 stripe_index=$($LFS getdirstripe -i $dir)
22826                 [ $default_index -eq -1 ] ||
22827                         [ $stripe_index -eq $default_index ] ||
22828                         error "$stripe_index != $default_index for $dir"
22829
22830                 #check default stripe
22831                 stripe_count=$($LFS getdirstripe -D -c $dir)
22832                 [ $stripe_count -eq $default_count ] ||
22833                 error "default count $default_count != $stripe_count for $dir"
22834
22835                 stripe_index=$($LFS getdirstripe -D -i $dir)
22836                 [ $stripe_index -eq $default_index ] ||
22837                 error "default index $default_index != $stripe_index for $dir"
22838         done
22839         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22840 }
22841
22842 test_300g() {
22843         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22844         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22845                 skip "Need MDS version at least 2.7.55"
22846
22847         local dir
22848         local stripe_count
22849         local stripe_index
22850
22851         mkdir_on_mdt0 $DIR/$tdir
22852         mkdir $DIR/$tdir/normal_dir
22853
22854         #Checking when client cache stripe index
22855         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22856         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22857                 error "create striped_dir failed"
22858
22859         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22860                 error "create dir0 fails"
22861         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22862         [ $stripe_index -eq 0 ] ||
22863                 error "dir0 expect index 0 got $stripe_index"
22864
22865         mkdir $DIR/$tdir/striped_dir/dir1 ||
22866                 error "create dir1 fails"
22867         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22868         [ $stripe_index -eq 1 ] ||
22869                 error "dir1 expect index 1 got $stripe_index"
22870
22871         #check default stripe count/stripe index
22872         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22873         test_300_check_default_striped_dir normal_dir 1 0
22874         test_300_check_default_striped_dir normal_dir -1 1
22875         test_300_check_default_striped_dir normal_dir 2 -1
22876
22877         #delete default stripe information
22878         echo "delete default stripeEA"
22879         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22880                 error "set default stripe on striped dir error"
22881
22882         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22883         for dir in $(find $DIR/$tdir/normal_dir/*); do
22884                 stripe_count=$($LFS getdirstripe -c $dir)
22885                 [ $stripe_count -eq 0 ] ||
22886                         error "expect 1 get $stripe_count for $dir"
22887         done
22888 }
22889 run_test 300g "check default striped directory for normal directory"
22890
22891 test_300h() {
22892         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22893         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22894                 skip "Need MDS version at least 2.7.55"
22895
22896         local dir
22897         local stripe_count
22898
22899         mkdir $DIR/$tdir
22900         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22901                 error "set striped dir error"
22902
22903         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22904         test_300_check_default_striped_dir striped_dir 1 0
22905         test_300_check_default_striped_dir striped_dir -1 1
22906         test_300_check_default_striped_dir striped_dir 2 -1
22907
22908         #delete default stripe information
22909         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22910                 error "set default stripe on striped dir error"
22911
22912         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22913         for dir in $(find $DIR/$tdir/striped_dir/*); do
22914                 stripe_count=$($LFS getdirstripe -c $dir)
22915                 [ $stripe_count -eq 0 ] ||
22916                         error "expect 1 get $stripe_count for $dir"
22917         done
22918 }
22919 run_test 300h "check default striped directory for striped directory"
22920
22921 test_300i() {
22922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22923         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22924         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22925                 skip "Need MDS version at least 2.7.55"
22926
22927         local stripe_count
22928         local file
22929
22930         mkdir $DIR/$tdir
22931
22932         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22933                 error "set striped dir error"
22934
22935         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22936                 error "create files under striped dir failed"
22937
22938         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22939                 error "set striped hashdir error"
22940
22941         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22942                 error "create dir0 under hash dir failed"
22943         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22944                 error "create dir1 under hash dir failed"
22945         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22946                 error "create dir2 under hash dir failed"
22947
22948         # unfortunately, we need to umount to clear dir layout cache for now
22949         # once we fully implement dir layout, we can drop this
22950         umount_client $MOUNT || error "umount failed"
22951         mount_client $MOUNT || error "mount failed"
22952
22953         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22954         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22955         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22956
22957         #set the stripe to be unknown hash type
22958         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22959         $LCTL set_param fail_loc=0x1901
22960         for ((i = 0; i < 10; i++)); do
22961                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22962                         error "stat f-$i failed"
22963                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22964         done
22965
22966         touch $DIR/$tdir/striped_dir/f0 &&
22967                 error "create under striped dir with unknown hash should fail"
22968
22969         $LCTL set_param fail_loc=0
22970
22971         umount_client $MOUNT || error "umount failed"
22972         mount_client $MOUNT || error "mount failed"
22973
22974         return 0
22975 }
22976 run_test 300i "client handle unknown hash type striped directory"
22977
22978 test_300j() {
22979         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22981         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22982                 skip "Need MDS version at least 2.7.55"
22983
22984         local stripe_count
22985         local file
22986
22987         mkdir $DIR/$tdir
22988
22989         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22990         $LCTL set_param fail_loc=0x1702
22991         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22992                 error "set striped dir error"
22993
22994         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22995                 error "create files under striped dir failed"
22996
22997         $LCTL set_param fail_loc=0
22998
22999         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23000
23001         return 0
23002 }
23003 run_test 300j "test large update record"
23004
23005 test_300k() {
23006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23007         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23008         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23009                 skip "Need MDS version at least 2.7.55"
23010
23011         # this test needs a huge transaction
23012         local kb
23013         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23014              osd*.$FSNAME-MDT0000.kbytestotal")
23015         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23016
23017         local stripe_count
23018         local file
23019
23020         mkdir $DIR/$tdir
23021
23022         #define OBD_FAIL_LARGE_STRIPE   0x1703
23023         $LCTL set_param fail_loc=0x1703
23024         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23025                 error "set striped dir error"
23026         $LCTL set_param fail_loc=0
23027
23028         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23029                 error "getstripeddir fails"
23030         rm -rf $DIR/$tdir/striped_dir ||
23031                 error "unlink striped dir fails"
23032
23033         return 0
23034 }
23035 run_test 300k "test large striped directory"
23036
23037 test_300l() {
23038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23039         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23040         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23041                 skip "Need MDS version at least 2.7.55"
23042
23043         local stripe_index
23044
23045         test_mkdir -p $DIR/$tdir/striped_dir
23046         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23047                         error "chown $RUNAS_ID failed"
23048         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23049                 error "set default striped dir failed"
23050
23051         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23052         $LCTL set_param fail_loc=0x80000158
23053         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23054
23055         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23056         [ $stripe_index -eq 1 ] ||
23057                 error "expect 1 get $stripe_index for $dir"
23058 }
23059 run_test 300l "non-root user to create dir under striped dir with stale layout"
23060
23061 test_300m() {
23062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23063         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23064         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23065                 skip "Need MDS version at least 2.7.55"
23066
23067         mkdir -p $DIR/$tdir/striped_dir
23068         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23069                 error "set default stripes dir error"
23070
23071         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23072
23073         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23074         [ $stripe_count -eq 0 ] ||
23075                         error "expect 0 get $stripe_count for a"
23076
23077         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23078                 error "set default stripes dir error"
23079
23080         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23081
23082         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23083         [ $stripe_count -eq 0 ] ||
23084                         error "expect 0 get $stripe_count for b"
23085
23086         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23087                 error "set default stripes dir error"
23088
23089         mkdir $DIR/$tdir/striped_dir/c &&
23090                 error "default stripe_index is invalid, mkdir c should fails"
23091
23092         rm -rf $DIR/$tdir || error "rmdir fails"
23093 }
23094 run_test 300m "setstriped directory on single MDT FS"
23095
23096 cleanup_300n() {
23097         local list=$(comma_list $(mdts_nodes))
23098
23099         trap 0
23100         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23101 }
23102
23103 test_300n() {
23104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23105         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23106         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23107                 skip "Need MDS version at least 2.7.55"
23108         remote_mds_nodsh && skip "remote MDS with nodsh"
23109
23110         local stripe_index
23111         local list=$(comma_list $(mdts_nodes))
23112
23113         trap cleanup_300n RETURN EXIT
23114         mkdir -p $DIR/$tdir
23115         chmod 777 $DIR/$tdir
23116         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23117                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23118                 error "create striped dir succeeds with gid=0"
23119
23120         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23121         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23122                 error "create striped dir fails with gid=-1"
23123
23124         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23125         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23126                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23127                 error "set default striped dir succeeds with gid=0"
23128
23129
23130         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23131         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23132                 error "set default striped dir fails with gid=-1"
23133
23134
23135         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23136         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23137                                         error "create test_dir fails"
23138         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23139                                         error "create test_dir1 fails"
23140         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23141                                         error "create test_dir2 fails"
23142         cleanup_300n
23143 }
23144 run_test 300n "non-root user to create dir under striped dir with default EA"
23145
23146 test_300o() {
23147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23148         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23149         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23150                 skip "Need MDS version at least 2.7.55"
23151
23152         local numfree1
23153         local numfree2
23154
23155         mkdir -p $DIR/$tdir
23156
23157         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23158         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23159         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23160                 skip "not enough free inodes $numfree1 $numfree2"
23161         fi
23162
23163         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23164         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23165         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23166                 skip "not enough free space $numfree1 $numfree2"
23167         fi
23168
23169         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23170                 error "setdirstripe fails"
23171
23172         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23173                 error "create dirs fails"
23174
23175         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23176         ls $DIR/$tdir/striped_dir > /dev/null ||
23177                 error "ls striped dir fails"
23178         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23179                 error "unlink big striped dir fails"
23180 }
23181 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23182
23183 test_300p() {
23184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23186         remote_mds_nodsh && skip "remote MDS with nodsh"
23187
23188         mkdir_on_mdt0 $DIR/$tdir
23189
23190         #define OBD_FAIL_OUT_ENOSPC     0x1704
23191         do_facet mds2 lctl set_param fail_loc=0x80001704
23192         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23193                  && error "create striped directory should fail"
23194
23195         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23196
23197         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23198         true
23199 }
23200 run_test 300p "create striped directory without space"
23201
23202 test_300q() {
23203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23204         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23205
23206         local fd=$(free_fd)
23207         local cmd="exec $fd<$tdir"
23208         cd $DIR
23209         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23210         eval $cmd
23211         cmd="exec $fd<&-"
23212         trap "eval $cmd" EXIT
23213         cd $tdir || error "cd $tdir fails"
23214         rmdir  ../$tdir || error "rmdir $tdir fails"
23215         mkdir local_dir && error "create dir succeeds"
23216         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23217         eval $cmd
23218         return 0
23219 }
23220 run_test 300q "create remote directory under orphan directory"
23221
23222 test_300r() {
23223         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23224                 skip "Need MDS version at least 2.7.55" && return
23225         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23226
23227         mkdir $DIR/$tdir
23228
23229         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23230                 error "set striped dir error"
23231
23232         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23233                 error "getstripeddir fails"
23234
23235         local stripe_count
23236         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23237                       awk '/lmv_stripe_count:/ { print $2 }')
23238
23239         [ $MDSCOUNT -ne $stripe_count ] &&
23240                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23241
23242         rm -rf $DIR/$tdir/striped_dir ||
23243                 error "unlink striped dir fails"
23244 }
23245 run_test 300r "test -1 striped directory"
23246
23247 test_300s_helper() {
23248         local count=$1
23249
23250         local stripe_dir=$DIR/$tdir/striped_dir.$count
23251
23252         $LFS mkdir -c $count $stripe_dir ||
23253                 error "lfs mkdir -c error"
23254
23255         $LFS getdirstripe $stripe_dir ||
23256                 error "lfs getdirstripe fails"
23257
23258         local stripe_count
23259         stripe_count=$($LFS getdirstripe $stripe_dir |
23260                       awk '/lmv_stripe_count:/ { print $2 }')
23261
23262         [ $count -ne $stripe_count ] &&
23263                 error_noexit "bad stripe count $stripe_count expected $count"
23264
23265         local dupe_stripes
23266         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23267                 awk '/0x/ {count[$1] += 1}; END {
23268                         for (idx in count) {
23269                                 if (count[idx]>1) {
23270                                         print "index " idx " count " count[idx]
23271                                 }
23272                         }
23273                 }')
23274
23275         if [[ -n "$dupe_stripes" ]] ; then
23276                 lfs getdirstripe $stripe_dir
23277                 error_noexit "Dupe MDT above: $dupe_stripes "
23278         fi
23279
23280         rm -rf $stripe_dir ||
23281                 error_noexit "unlink $stripe_dir fails"
23282 }
23283
23284 test_300s() {
23285         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23286                 skip "Need MDS version at least 2.7.55" && return
23287         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23288
23289         mkdir $DIR/$tdir
23290         for count in $(seq 2 $MDSCOUNT); do
23291                 test_300s_helper $count
23292         done
23293 }
23294 run_test 300s "test lfs mkdir -c without -i"
23295
23296
23297 prepare_remote_file() {
23298         mkdir $DIR/$tdir/src_dir ||
23299                 error "create remote source failed"
23300
23301         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23302                  error "cp to remote source failed"
23303         touch $DIR/$tdir/src_dir/a
23304
23305         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23306                 error "create remote target dir failed"
23307
23308         touch $DIR/$tdir/tgt_dir/b
23309
23310         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23311                 error "rename dir cross MDT failed!"
23312
23313         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23314                 error "src_child still exists after rename"
23315
23316         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23317                 error "missing file(a) after rename"
23318
23319         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23320                 error "diff after rename"
23321 }
23322
23323 test_310a() {
23324         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23326
23327         local remote_file=$DIR/$tdir/tgt_dir/b
23328
23329         mkdir -p $DIR/$tdir
23330
23331         prepare_remote_file || error "prepare remote file failed"
23332
23333         #open-unlink file
23334         $OPENUNLINK $remote_file $remote_file ||
23335                 error "openunlink $remote_file failed"
23336         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23337 }
23338 run_test 310a "open unlink remote file"
23339
23340 test_310b() {
23341         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23343
23344         local remote_file=$DIR/$tdir/tgt_dir/b
23345
23346         mkdir -p $DIR/$tdir
23347
23348         prepare_remote_file || error "prepare remote file failed"
23349
23350         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23351         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23352         $CHECKSTAT -t file $remote_file || error "check file failed"
23353 }
23354 run_test 310b "unlink remote file with multiple links while open"
23355
23356 test_310c() {
23357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23358         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23359
23360         local remote_file=$DIR/$tdir/tgt_dir/b
23361
23362         mkdir -p $DIR/$tdir
23363
23364         prepare_remote_file || error "prepare remote file failed"
23365
23366         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23367         multiop_bg_pause $remote_file O_uc ||
23368                         error "mulitop failed for remote file"
23369         MULTIPID=$!
23370         $MULTIOP $DIR/$tfile Ouc
23371         kill -USR1 $MULTIPID
23372         wait $MULTIPID
23373 }
23374 run_test 310c "open-unlink remote file with multiple links"
23375
23376 #LU-4825
23377 test_311() {
23378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23379         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23380         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23381                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23382         remote_mds_nodsh && skip "remote MDS with nodsh"
23383
23384         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23385         local mdts=$(comma_list $(mdts_nodes))
23386
23387         mkdir -p $DIR/$tdir
23388         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23389         createmany -o $DIR/$tdir/$tfile. 1000
23390
23391         # statfs data is not real time, let's just calculate it
23392         old_iused=$((old_iused + 1000))
23393
23394         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23395                         osp.*OST0000*MDT0000.create_count")
23396         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23397                                 osp.*OST0000*MDT0000.max_create_count")
23398         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23399
23400         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23401         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23402         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23403
23404         unlinkmany $DIR/$tdir/$tfile. 1000
23405
23406         do_nodes $mdts "$LCTL set_param -n \
23407                         osp.*OST0000*.max_create_count=$max_count"
23408         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23409                 do_nodes $mdts "$LCTL set_param -n \
23410                                 osp.*OST0000*.create_count=$count"
23411         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23412                         grep "=0" && error "create_count is zero"
23413
23414         local new_iused
23415         for i in $(seq 120); do
23416                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23417                 # system may be too busy to destroy all objs in time, use
23418                 # a somewhat small value to not fail autotest
23419                 [ $((old_iused - new_iused)) -gt 400 ] && break
23420                 sleep 1
23421         done
23422
23423         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23424         [ $((old_iused - new_iused)) -gt 400 ] ||
23425                 error "objs not destroyed after unlink"
23426 }
23427 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23428
23429 zfs_oid_to_objid()
23430 {
23431         local ost=$1
23432         local objid=$2
23433
23434         local vdevdir=$(dirname $(facet_vdevice $ost))
23435         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23436         local zfs_zapid=$(do_facet $ost $cmd |
23437                           grep -w "/O/0/d$((objid%32))" -C 5 |
23438                           awk '/Object/{getline; print $1}')
23439         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23440                           awk "/$objid = /"'{printf $3}')
23441
23442         echo $zfs_objid
23443 }
23444
23445 zfs_object_blksz() {
23446         local ost=$1
23447         local objid=$2
23448
23449         local vdevdir=$(dirname $(facet_vdevice $ost))
23450         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23451         local blksz=$(do_facet $ost $cmd $objid |
23452                       awk '/dblk/{getline; printf $4}')
23453
23454         case "${blksz: -1}" in
23455                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23456                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23457                 *) ;;
23458         esac
23459
23460         echo $blksz
23461 }
23462
23463 test_312() { # LU-4856
23464         remote_ost_nodsh && skip "remote OST with nodsh"
23465         [ "$ost1_FSTYPE" = "zfs" ] ||
23466                 skip_env "the test only applies to zfs"
23467
23468         local max_blksz=$(do_facet ost1 \
23469                           $ZFS get -p recordsize $(facet_device ost1) |
23470                           awk '!/VALUE/{print $3}')
23471
23472         # to make life a little bit easier
23473         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23474         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23475
23476         local tf=$DIR/$tdir/$tfile
23477         touch $tf
23478         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23479
23480         # Get ZFS object id
23481         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23482         # block size change by sequential overwrite
23483         local bs
23484
23485         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23486                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23487
23488                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23489                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23490         done
23491         rm -f $tf
23492
23493         # block size change by sequential append write
23494         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23495         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23496         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23497         local count
23498
23499         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23500                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23501                         oflag=sync conv=notrunc
23502
23503                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23504                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23505                         error "blksz error, actual $blksz, " \
23506                                 "expected: 2 * $count * $PAGE_SIZE"
23507         done
23508         rm -f $tf
23509
23510         # random write
23511         touch $tf
23512         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23513         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23514
23515         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23516         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23517         [ $blksz -eq $PAGE_SIZE ] ||
23518                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23519
23520         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23521         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23522         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23523
23524         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23525         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23526         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23527 }
23528 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23529
23530 test_313() {
23531         remote_ost_nodsh && skip "remote OST with nodsh"
23532
23533         local file=$DIR/$tfile
23534
23535         rm -f $file
23536         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23537
23538         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23539         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23540         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23541                 error "write should failed"
23542         do_facet ost1 "$LCTL set_param fail_loc=0"
23543         rm -f $file
23544 }
23545 run_test 313 "io should fail after last_rcvd update fail"
23546
23547 test_314() {
23548         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23549
23550         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23551         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23552         rm -f $DIR/$tfile
23553         wait_delete_completed
23554         do_facet ost1 "$LCTL set_param fail_loc=0"
23555 }
23556 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23557
23558 test_315() { # LU-618
23559         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23560
23561         local file=$DIR/$tfile
23562         rm -f $file
23563
23564         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23565                 error "multiop file write failed"
23566         $MULTIOP $file oO_RDONLY:r4063232_c &
23567         PID=$!
23568
23569         sleep 2
23570
23571         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23572         kill -USR1 $PID
23573
23574         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23575         rm -f $file
23576 }
23577 run_test 315 "read should be accounted"
23578
23579 test_316() {
23580         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23581         large_xattr_enabled || skip_env "ea_inode feature disabled"
23582
23583         rm -rf $DIR/$tdir/d
23584         mkdir -p $DIR/$tdir/d
23585         chown nobody $DIR/$tdir/d
23586         touch $DIR/$tdir/d/file
23587
23588         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23589 }
23590 run_test 316 "lfs mv"
23591
23592 test_317() {
23593         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23594                 skip "Need MDS version at least 2.11.53"
23595         if [ "$ost1_FSTYPE" == "zfs" ]; then
23596                 skip "LU-10370: no implementation for ZFS"
23597         fi
23598
23599         local trunc_sz
23600         local grant_blk_size
23601
23602         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23603                         awk '/grant_block_size:/ { print $2; exit; }')
23604         #
23605         # Create File of size 5M. Truncate it to below size's and verify
23606         # blocks count.
23607         #
23608         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23609                 error "Create file $DIR/$tfile failed"
23610         stack_trap "rm -f $DIR/$tfile" EXIT
23611
23612         for trunc_sz in 2097152 4097 4000 509 0; do
23613                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23614                         error "truncate $tfile to $trunc_sz failed"
23615                 local sz=$(stat --format=%s $DIR/$tfile)
23616                 local blk=$(stat --format=%b $DIR/$tfile)
23617                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23618                                      grant_blk_size) * 8))
23619
23620                 if [[ $blk -ne $trunc_blk ]]; then
23621                         $(which stat) $DIR/$tfile
23622                         error "Expected Block $trunc_blk got $blk for $tfile"
23623                 fi
23624
23625                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23626                         error "Expected Size $trunc_sz got $sz for $tfile"
23627         done
23628
23629         #
23630         # sparse file test
23631         # Create file with a hole and write actual two blocks. Block count
23632         # must be 16.
23633         #
23634         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23635                 conv=fsync || error "Create file : $DIR/$tfile"
23636
23637         # Calculate the final truncate size.
23638         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23639
23640         #
23641         # truncate to size $trunc_sz bytes. Strip the last block
23642         # The block count must drop to 8
23643         #
23644         $TRUNCATE $DIR/$tfile $trunc_sz ||
23645                 error "truncate $tfile to $trunc_sz failed"
23646
23647         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23648         sz=$(stat --format=%s $DIR/$tfile)
23649         blk=$(stat --format=%b $DIR/$tfile)
23650
23651         if [[ $blk -ne $trunc_bsz ]]; then
23652                 $(which stat) $DIR/$tfile
23653                 error "Expected Block $trunc_bsz got $blk for $tfile"
23654         fi
23655
23656         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23657                 error "Expected Size $trunc_sz got $sz for $tfile"
23658 }
23659 run_test 317 "Verify blocks get correctly update after truncate"
23660
23661 test_318() {
23662         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23663         local old_max_active=$($LCTL get_param -n \
23664                             ${llite_name}.max_read_ahead_async_active \
23665                             2>/dev/null)
23666
23667         $LCTL set_param llite.*.max_read_ahead_async_active=256
23668         local max_active=$($LCTL get_param -n \
23669                            ${llite_name}.max_read_ahead_async_active \
23670                            2>/dev/null)
23671         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23672
23673         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23674                 error "set max_read_ahead_async_active should succeed"
23675
23676         $LCTL set_param llite.*.max_read_ahead_async_active=512
23677         max_active=$($LCTL get_param -n \
23678                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23679         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23680
23681         # restore @max_active
23682         [ $old_max_active -ne 0 ] && $LCTL set_param \
23683                 llite.*.max_read_ahead_async_active=$old_max_active
23684
23685         local old_threshold=$($LCTL get_param -n \
23686                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23687         local max_per_file_mb=$($LCTL get_param -n \
23688                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23689
23690         local invalid=$(($max_per_file_mb + 1))
23691         $LCTL set_param \
23692                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23693                         && error "set $invalid should fail"
23694
23695         local valid=$(($invalid - 1))
23696         $LCTL set_param \
23697                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23698                         error "set $valid should succeed"
23699         local threshold=$($LCTL get_param -n \
23700                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23701         [ $threshold -eq $valid ] || error \
23702                 "expect threshold $valid got $threshold"
23703         $LCTL set_param \
23704                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23705 }
23706 run_test 318 "Verify async readahead tunables"
23707
23708 test_319() {
23709         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23710
23711         local before=$(date +%s)
23712         local evict
23713         local mdir=$DIR/$tdir
23714         local file=$mdir/xxx
23715
23716         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23717         touch $file
23718
23719 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23720         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23721         $LFS mv -m1 $file &
23722
23723         sleep 1
23724         dd if=$file of=/dev/null
23725         wait
23726         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23727           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23728
23729         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23730 }
23731 run_test 319 "lost lease lock on migrate error"
23732
23733 test_398a() { # LU-4198
23734         local ost1_imp=$(get_osc_import_name client ost1)
23735         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23736                          cut -d'.' -f2)
23737
23738         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23739         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23740
23741         # request a new lock on client
23742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23743
23744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23745         local lock_count=$($LCTL get_param -n \
23746                            ldlm.namespaces.$imp_name.lru_size)
23747         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23748
23749         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23750
23751         # no lock cached, should use lockless IO and not enqueue new lock
23752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23753         lock_count=$($LCTL get_param -n \
23754                      ldlm.namespaces.$imp_name.lru_size)
23755         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23756 }
23757 run_test 398a "direct IO should cancel lock otherwise lockless"
23758
23759 test_398b() { # LU-4198
23760         which fio || skip_env "no fio installed"
23761         $LFS setstripe -c -1 $DIR/$tfile
23762
23763         local size=12
23764         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23765
23766         local njobs=4
23767         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23768         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23769                 --numjobs=$njobs --fallocate=none \
23770                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23771                 --filename=$DIR/$tfile &
23772         bg_pid=$!
23773
23774         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23775         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23776                 --numjobs=$njobs --fallocate=none \
23777                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23778                 --filename=$DIR/$tfile || true
23779         wait $bg_pid
23780
23781         rm -f $DIR/$tfile
23782 }
23783 run_test 398b "DIO and buffer IO race"
23784
23785 test_398c() { # LU-4198
23786         local ost1_imp=$(get_osc_import_name client ost1)
23787         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23788                          cut -d'.' -f2)
23789
23790         which fio || skip_env "no fio installed"
23791
23792         saved_debug=$($LCTL get_param -n debug)
23793         $LCTL set_param debug=0
23794
23795         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23796         ((size /= 1024)) # by megabytes
23797         ((size /= 2)) # write half of the OST at most
23798         [ $size -gt 40 ] && size=40 #reduce test time anyway
23799
23800         $LFS setstripe -c 1 $DIR/$tfile
23801
23802         # it seems like ldiskfs reserves more space than necessary if the
23803         # writing blocks are not mapped, so it extends the file firstly
23804         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23805         cancel_lru_locks osc
23806
23807         # clear and verify rpc_stats later
23808         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23809
23810         local njobs=4
23811         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23812         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23813                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23814                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23815                 --filename=$DIR/$tfile
23816         [ $? -eq 0 ] || error "fio write error"
23817
23818         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23819                 error "Locks were requested while doing AIO"
23820
23821         # get the percentage of 1-page I/O
23822         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23823                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23824                 awk '{print $7}')
23825         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23826
23827         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23828         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23829                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23830                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23831                 --filename=$DIR/$tfile
23832         [ $? -eq 0 ] || error "fio mixed read write error"
23833
23834         echo "AIO with large block size ${size}M"
23835         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23836                 --numjobs=1 --fallocate=none --ioengine=libaio \
23837                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23838                 --filename=$DIR/$tfile
23839         [ $? -eq 0 ] || error "fio large block size failed"
23840
23841         rm -f $DIR/$tfile
23842         $LCTL set_param debug="$saved_debug"
23843 }
23844 run_test 398c "run fio to test AIO"
23845
23846 test_398d() { #  LU-13846
23847         which aiocp || skip_env "no aiocp installed"
23848         local aio_file=$DIR/$tfile.aio
23849
23850         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23851
23852         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23853         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23854         stack_trap "rm -f $DIR/$tfile $aio_file"
23855
23856         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23857
23858         # make sure we don't crash and fail properly
23859         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23860                 error "aio not aligned with PAGE SIZE should fail"
23861
23862         rm -f $DIR/$tfile $aio_file
23863 }
23864 run_test 398d "run aiocp to verify block size > stripe size"
23865
23866 test_398e() {
23867         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23868         touch $DIR/$tfile.new
23869         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23870 }
23871 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23872
23873 test_398f() { #  LU-14687
23874         which aiocp || skip_env "no aiocp installed"
23875         local aio_file=$DIR/$tfile.aio
23876
23877         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23878
23879         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23880         stack_trap "rm -f $DIR/$tfile $aio_file"
23881
23882         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23883         $LCTL set_param fail_loc=0x1418
23884         # make sure we don't crash and fail properly
23885         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23886                 error "aio with page allocation failure succeeded"
23887         $LCTL set_param fail_loc=0
23888         diff $DIR/$tfile $aio_file
23889         [[ $? != 0 ]] || error "no diff after failed aiocp"
23890 }
23891 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23892
23893 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23894 # stripe and i/o size must be > stripe size
23895 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23896 # single RPC in flight.  This test shows async DIO submission is working by
23897 # showing multiple RPCs in flight.
23898 test_398g() { #  LU-13798
23899         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23900
23901         # We need to do some i/o first to acquire enough grant to put our RPCs
23902         # in flight; otherwise a new connection may not have enough grant
23903         # available
23904         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23905                 error "parallel dio failed"
23906         stack_trap "rm -f $DIR/$tfile"
23907
23908         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23909         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23910         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23911         stack_trap "$LCTL set_param -n $pages_per_rpc"
23912
23913         # Recreate file so it's empty
23914         rm -f $DIR/$tfile
23915         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23916         #Pause rpc completion to guarantee we see multiple rpcs in flight
23917         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23918         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23919         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23920
23921         # Clear rpc stats
23922         $LCTL set_param osc.*.rpc_stats=c
23923
23924         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23925                 error "parallel dio failed"
23926         stack_trap "rm -f $DIR/$tfile"
23927
23928         $LCTL get_param osc.*-OST0000-*.rpc_stats
23929         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23930                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23931                 grep "8:" | awk '{print $8}')
23932         # We look at the "8 rpcs in flight" field, and verify A) it is present
23933         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23934         # as expected for an 8M DIO to a file with 1M stripes.
23935         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23936
23937         # Verify turning off parallel dio works as expected
23938         # Clear rpc stats
23939         $LCTL set_param osc.*.rpc_stats=c
23940         $LCTL set_param llite.*.parallel_dio=0
23941         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23942
23943         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23944                 error "dio with parallel dio disabled failed"
23945
23946         # Ideally, we would see only one RPC in flight here, but there is an
23947         # unavoidable race between i/o completion and RPC in flight counting,
23948         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23949         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23950         # So instead we just verify it's always < 8.
23951         $LCTL get_param osc.*-OST0000-*.rpc_stats
23952         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23953                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23954                 grep '^$' -B1 | grep . | awk '{print $1}')
23955         [ $ret != "8:" ] ||
23956                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23957 }
23958 run_test 398g "verify parallel dio async RPC submission"
23959
23960 test_398h() { #  LU-13798
23961         local dio_file=$DIR/$tfile.dio
23962
23963         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23964
23965         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23966         stack_trap "rm -f $DIR/$tfile $dio_file"
23967
23968         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23969                 error "parallel dio failed"
23970         diff $DIR/$tfile $dio_file
23971         [[ $? == 0 ]] || error "file diff after aiocp"
23972 }
23973 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23974
23975 test_398i() { #  LU-13798
23976         local dio_file=$DIR/$tfile.dio
23977
23978         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23979
23980         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23981         stack_trap "rm -f $DIR/$tfile $dio_file"
23982
23983         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23984         $LCTL set_param fail_loc=0x1418
23985         # make sure we don't crash and fail properly
23986         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23987                 error "parallel dio page allocation failure succeeded"
23988         diff $DIR/$tfile $dio_file
23989         [[ $? != 0 ]] || error "no diff after failed aiocp"
23990 }
23991 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23992
23993 test_398j() { #  LU-13798
23994         # Stripe size > RPC size but less than i/o size tests split across
23995         # stripes and RPCs for individual i/o op
23996         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23997
23998         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23999         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24000         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24001         stack_trap "$LCTL set_param -n $pages_per_rpc"
24002
24003         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24004                 error "parallel dio write failed"
24005         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24006
24007         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24008                 error "parallel dio read failed"
24009         diff $DIR/$tfile $DIR/$tfile.2
24010         [[ $? == 0 ]] || error "file diff after parallel dio read"
24011 }
24012 run_test 398j "test parallel dio where stripe size > rpc_size"
24013
24014 test_398k() { #  LU-13798
24015         wait_delete_completed
24016         wait_mds_ost_sync
24017
24018         # 4 stripe file; we will cause out of space on OST0
24019         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24020
24021         # Fill OST0 (if it's not too large)
24022         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24023                    head -n1)
24024         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24025                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24026         fi
24027         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24028         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24029                 error "dd should fill OST0"
24030         stack_trap "rm -f $DIR/$tfile.1"
24031
24032         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24033         err=$?
24034
24035         ls -la $DIR/$tfile
24036         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24037                 error "file is not 0 bytes in size"
24038
24039         # dd above should not succeed, but don't error until here so we can
24040         # get debug info above
24041         [[ $err != 0 ]] ||
24042                 error "parallel dio write with enospc succeeded"
24043         stack_trap "rm -f $DIR/$tfile"
24044 }
24045 run_test 398k "test enospc on first stripe"
24046
24047 test_398l() { #  LU-13798
24048         wait_delete_completed
24049         wait_mds_ost_sync
24050
24051         # 4 stripe file; we will cause out of space on OST0
24052         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24053         # happens on the second i/o chunk we issue
24054         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24055
24056         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24057         stack_trap "rm -f $DIR/$tfile"
24058
24059         # Fill OST0 (if it's not too large)
24060         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24061                    head -n1)
24062         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24063                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24064         fi
24065         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24066         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24067                 error "dd should fill OST0"
24068         stack_trap "rm -f $DIR/$tfile.1"
24069
24070         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24071         err=$?
24072         stack_trap "rm -f $DIR/$tfile.2"
24073
24074         # Check that short write completed as expected
24075         ls -la $DIR/$tfile.2
24076         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24077                 error "file is not 1M in size"
24078
24079         # dd above should not succeed, but don't error until here so we can
24080         # get debug info above
24081         [[ $err != 0 ]] ||
24082                 error "parallel dio write with enospc succeeded"
24083
24084         # Truncate source file to same length as output file and diff them
24085         $TRUNCATE $DIR/$tfile 1048576
24086         diff $DIR/$tfile $DIR/$tfile.2
24087         [[ $? == 0 ]] || error "data incorrect after short write"
24088 }
24089 run_test 398l "test enospc on intermediate stripe/RPC"
24090
24091 test_398m() { #  LU-13798
24092         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24093
24094         # Set up failure on OST0, the first stripe:
24095         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24096         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24097         # So this fail_val specifies OST0
24098         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24099         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24100
24101         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24102                 error "parallel dio write with failure on first stripe succeeded"
24103         stack_trap "rm -f $DIR/$tfile"
24104         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24105
24106         # Place data in file for read
24107         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24108                 error "parallel dio write failed"
24109
24110         # Fail read on OST0, first stripe
24111         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24112         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24113         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24114                 error "parallel dio read with error on first stripe succeeded"
24115         rm -f $DIR/$tfile.2
24116         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24117
24118         # Switch to testing on OST1, second stripe
24119         # Clear file contents, maintain striping
24120         echo > $DIR/$tfile
24121         # Set up failure on OST1, second stripe:
24122         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24123         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24124
24125         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24126                 error "parallel dio write with failure on first stripe succeeded"
24127         stack_trap "rm -f $DIR/$tfile"
24128         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24129
24130         # Place data in file for read
24131         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24132                 error "parallel dio write failed"
24133
24134         # Fail read on OST1, second stripe
24135         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24136         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24137         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24138                 error "parallel dio read with error on first stripe succeeded"
24139         rm -f $DIR/$tfile.2
24140         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24141 }
24142 run_test 398m "test RPC failures with parallel dio"
24143
24144 # Parallel submission of DIO should not cause problems for append, but it's
24145 # important to verify.
24146 test_398n() { #  LU-13798
24147         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24148
24149         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24150                 error "dd to create source file failed"
24151         stack_trap "rm -f $DIR/$tfile"
24152
24153         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24154                 error "parallel dio write with failure on second stripe succeeded"
24155         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24156         diff $DIR/$tfile $DIR/$tfile.1
24157         [[ $? == 0 ]] || error "data incorrect after append"
24158
24159 }
24160 run_test 398n "test append with parallel DIO"
24161
24162 test_fake_rw() {
24163         local read_write=$1
24164         if [ "$read_write" = "write" ]; then
24165                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24166         elif [ "$read_write" = "read" ]; then
24167                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24168         else
24169                 error "argument error"
24170         fi
24171
24172         # turn off debug for performance testing
24173         local saved_debug=$($LCTL get_param -n debug)
24174         $LCTL set_param debug=0
24175
24176         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24177
24178         # get ost1 size - $FSNAME-OST0000
24179         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24180         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24181         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24182
24183         if [ "$read_write" = "read" ]; then
24184                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24185         fi
24186
24187         local start_time=$(date +%s.%N)
24188         $dd_cmd bs=1M count=$blocks oflag=sync ||
24189                 error "real dd $read_write error"
24190         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24191
24192         if [ "$read_write" = "write" ]; then
24193                 rm -f $DIR/$tfile
24194         fi
24195
24196         # define OBD_FAIL_OST_FAKE_RW           0x238
24197         do_facet ost1 $LCTL set_param fail_loc=0x238
24198
24199         local start_time=$(date +%s.%N)
24200         $dd_cmd bs=1M count=$blocks oflag=sync ||
24201                 error "fake dd $read_write error"
24202         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24203
24204         if [ "$read_write" = "write" ]; then
24205                 # verify file size
24206                 cancel_lru_locks osc
24207                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24208                         error "$tfile size not $blocks MB"
24209         fi
24210         do_facet ost1 $LCTL set_param fail_loc=0
24211
24212         echo "fake $read_write $duration_fake vs. normal $read_write" \
24213                 "$duration in seconds"
24214         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24215                 error_not_in_vm "fake write is slower"
24216
24217         $LCTL set_param -n debug="$saved_debug"
24218         rm -f $DIR/$tfile
24219 }
24220 test_399a() { # LU-7655 for OST fake write
24221         remote_ost_nodsh && skip "remote OST with nodsh"
24222
24223         test_fake_rw write
24224 }
24225 run_test 399a "fake write should not be slower than normal write"
24226
24227 test_399b() { # LU-8726 for OST fake read
24228         remote_ost_nodsh && skip "remote OST with nodsh"
24229         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24230                 skip_env "ldiskfs only test"
24231         fi
24232
24233         test_fake_rw read
24234 }
24235 run_test 399b "fake read should not be slower than normal read"
24236
24237 test_400a() { # LU-1606, was conf-sanity test_74
24238         if ! which $CC > /dev/null 2>&1; then
24239                 skip_env "$CC is not installed"
24240         fi
24241
24242         local extra_flags=''
24243         local out=$TMP/$tfile
24244         local prefix=/usr/include/lustre
24245         local prog
24246
24247         # Oleg removes c files in his test rig so test if any c files exist
24248         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24249                 skip_env "Needed c test files are missing"
24250
24251         if ! [[ -d $prefix ]]; then
24252                 # Assume we're running in tree and fixup the include path.
24253                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24254                 extra_flags+=" -L$LUSTRE/utils/.lib"
24255         fi
24256
24257         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24258                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24259                         error "client api broken"
24260         done
24261         rm -f $out
24262 }
24263 run_test 400a "Lustre client api program can compile and link"
24264
24265 test_400b() { # LU-1606, LU-5011
24266         local header
24267         local out=$TMP/$tfile
24268         local prefix=/usr/include/linux/lustre
24269
24270         # We use a hard coded prefix so that this test will not fail
24271         # when run in tree. There are headers in lustre/include/lustre/
24272         # that are not packaged (like lustre_idl.h) and have more
24273         # complicated include dependencies (like config.h and lnet/types.h).
24274         # Since this test about correct packaging we just skip them when
24275         # they don't exist (see below) rather than try to fixup cppflags.
24276
24277         if ! which $CC > /dev/null 2>&1; then
24278                 skip_env "$CC is not installed"
24279         fi
24280
24281         for header in $prefix/*.h; do
24282                 if ! [[ -f "$header" ]]; then
24283                         continue
24284                 fi
24285
24286                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24287                         continue # lustre_ioctl.h is internal header
24288                 fi
24289
24290                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24291                         error "cannot compile '$header'"
24292         done
24293         rm -f $out
24294 }
24295 run_test 400b "packaged headers can be compiled"
24296
24297 test_401a() { #LU-7437
24298         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24299         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24300
24301         #count the number of parameters by "list_param -R"
24302         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24303         #count the number of parameters by listing proc files
24304         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24305         echo "proc_dirs='$proc_dirs'"
24306         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24307         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24308                       sort -u | wc -l)
24309
24310         [ $params -eq $procs ] ||
24311                 error "found $params parameters vs. $procs proc files"
24312
24313         # test the list_param -D option only returns directories
24314         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24315         #count the number of parameters by listing proc directories
24316         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24317                 sort -u | wc -l)
24318
24319         [ $params -eq $procs ] ||
24320                 error "found $params parameters vs. $procs proc files"
24321 }
24322 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24323
24324 test_401b() {
24325         # jobid_var may not allow arbitrary values, so use jobid_name
24326         # if available
24327         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24328                 local testname=jobid_name tmp='testing%p'
24329         else
24330                 local testname=jobid_var tmp=testing
24331         fi
24332
24333         local save=$($LCTL get_param -n $testname)
24334
24335         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24336                 error "no error returned when setting bad parameters"
24337
24338         local jobid_new=$($LCTL get_param -n foe $testname baz)
24339         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24340
24341         $LCTL set_param -n fog=bam $testname=$save bat=fog
24342         local jobid_old=$($LCTL get_param -n foe $testname bag)
24343         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24344 }
24345 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24346
24347 test_401c() {
24348         # jobid_var may not allow arbitrary values, so use jobid_name
24349         # if available
24350         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24351                 local testname=jobid_name
24352         else
24353                 local testname=jobid_var
24354         fi
24355
24356         local jobid_var_old=$($LCTL get_param -n $testname)
24357         local jobid_var_new
24358
24359         $LCTL set_param $testname= &&
24360                 error "no error returned for 'set_param a='"
24361
24362         jobid_var_new=$($LCTL get_param -n $testname)
24363         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24364                 error "$testname was changed by setting without value"
24365
24366         $LCTL set_param $testname &&
24367                 error "no error returned for 'set_param a'"
24368
24369         jobid_var_new=$($LCTL get_param -n $testname)
24370         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24371                 error "$testname was changed by setting without value"
24372 }
24373 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24374
24375 test_401d() {
24376         # jobid_var may not allow arbitrary values, so use jobid_name
24377         # if available
24378         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24379                 local testname=jobid_name new_value='foo=bar%p'
24380         else
24381                 local testname=jobid_var new_valuie=foo=bar
24382         fi
24383
24384         local jobid_var_old=$($LCTL get_param -n $testname)
24385         local jobid_var_new
24386
24387         $LCTL set_param $testname=$new_value ||
24388                 error "'set_param a=b' did not accept a value containing '='"
24389
24390         jobid_var_new=$($LCTL get_param -n $testname)
24391         [[ "$jobid_var_new" == "$new_value" ]] ||
24392                 error "'set_param a=b' failed on a value containing '='"
24393
24394         # Reset the $testname to test the other format
24395         $LCTL set_param $testname=$jobid_var_old
24396         jobid_var_new=$($LCTL get_param -n $testname)
24397         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24398                 error "failed to reset $testname"
24399
24400         $LCTL set_param $testname $new_value ||
24401                 error "'set_param a b' did not accept a value containing '='"
24402
24403         jobid_var_new=$($LCTL get_param -n $testname)
24404         [[ "$jobid_var_new" == "$new_value" ]] ||
24405                 error "'set_param a b' failed on a value containing '='"
24406
24407         $LCTL set_param $testname $jobid_var_old
24408         jobid_var_new=$($LCTL get_param -n $testname)
24409         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24410                 error "failed to reset $testname"
24411 }
24412 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24413
24414 test_401e() { # LU-14779
24415         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24416                 error "lctl list_param MGC* failed"
24417         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24418         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24419                 error "lctl get_param lru_size failed"
24420 }
24421 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24422
24423 test_402() {
24424         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24425         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24426                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24427         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24428                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24429                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24430         remote_mds_nodsh && skip "remote MDS with nodsh"
24431
24432         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24433 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24434         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24435         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24436                 echo "Touch failed - OK"
24437 }
24438 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24439
24440 test_403() {
24441         local file1=$DIR/$tfile.1
24442         local file2=$DIR/$tfile.2
24443         local tfile=$TMP/$tfile
24444
24445         rm -f $file1 $file2 $tfile
24446
24447         touch $file1
24448         ln $file1 $file2
24449
24450         # 30 sec OBD_TIMEOUT in ll_getattr()
24451         # right before populating st_nlink
24452         $LCTL set_param fail_loc=0x80001409
24453         stat -c %h $file1 > $tfile &
24454
24455         # create an alias, drop all locks and reclaim the dentry
24456         < $file2
24457         cancel_lru_locks mdc
24458         cancel_lru_locks osc
24459         sysctl -w vm.drop_caches=2
24460
24461         wait
24462
24463         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24464
24465         rm -f $tfile $file1 $file2
24466 }
24467 run_test 403 "i_nlink should not drop to zero due to aliasing"
24468
24469 test_404() { # LU-6601
24470         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24471                 skip "Need server version newer than 2.8.52"
24472         remote_mds_nodsh && skip "remote MDS with nodsh"
24473
24474         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24475                 awk '/osp .*-osc-MDT/ { print $4}')
24476
24477         local osp
24478         for osp in $mosps; do
24479                 echo "Deactivate: " $osp
24480                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24481                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24482                         awk -vp=$osp '$4 == p { print $2 }')
24483                 [ $stat = IN ] || {
24484                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24485                         error "deactivate error"
24486                 }
24487                 echo "Activate: " $osp
24488                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24489                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24490                         awk -vp=$osp '$4 == p { print $2 }')
24491                 [ $stat = UP ] || {
24492                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24493                         error "activate error"
24494                 }
24495         done
24496 }
24497 run_test 404 "validate manual {de}activated works properly for OSPs"
24498
24499 test_405() {
24500         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24501         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24502                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24503                         skip "Layout swap lock is not supported"
24504
24505         check_swap_layouts_support
24506         check_swap_layout_no_dom $DIR
24507
24508         test_mkdir $DIR/$tdir
24509         swap_lock_test -d $DIR/$tdir ||
24510                 error "One layout swap locked test failed"
24511 }
24512 run_test 405 "Various layout swap lock tests"
24513
24514 test_406() {
24515         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24516         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24517         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24519         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24520                 skip "Need MDS version at least 2.8.50"
24521
24522         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24523         local test_pool=$TESTNAME
24524
24525         pool_add $test_pool || error "pool_add failed"
24526         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24527                 error "pool_add_targets failed"
24528
24529         save_layout_restore_at_exit $MOUNT
24530
24531         # parent set default stripe count only, child will stripe from both
24532         # parent and fs default
24533         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24534                 error "setstripe $MOUNT failed"
24535         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24536         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24537         for i in $(seq 10); do
24538                 local f=$DIR/$tdir/$tfile.$i
24539                 touch $f || error "touch failed"
24540                 local count=$($LFS getstripe -c $f)
24541                 [ $count -eq $OSTCOUNT ] ||
24542                         error "$f stripe count $count != $OSTCOUNT"
24543                 local offset=$($LFS getstripe -i $f)
24544                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24545                 local size=$($LFS getstripe -S $f)
24546                 [ $size -eq $((def_stripe_size * 2)) ] ||
24547                         error "$f stripe size $size != $((def_stripe_size * 2))"
24548                 local pool=$($LFS getstripe -p $f)
24549                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24550         done
24551
24552         # change fs default striping, delete parent default striping, now child
24553         # will stripe from new fs default striping only
24554         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24555                 error "change $MOUNT default stripe failed"
24556         $LFS setstripe -c 0 $DIR/$tdir ||
24557                 error "delete $tdir default stripe failed"
24558         for i in $(seq 11 20); do
24559                 local f=$DIR/$tdir/$tfile.$i
24560                 touch $f || error "touch $f failed"
24561                 local count=$($LFS getstripe -c $f)
24562                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24563                 local offset=$($LFS getstripe -i $f)
24564                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24565                 local size=$($LFS getstripe -S $f)
24566                 [ $size -eq $def_stripe_size ] ||
24567                         error "$f stripe size $size != $def_stripe_size"
24568                 local pool=$($LFS getstripe -p $f)
24569                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24570         done
24571
24572         unlinkmany $DIR/$tdir/$tfile. 1 20
24573
24574         local f=$DIR/$tdir/$tfile
24575         pool_remove_all_targets $test_pool $f
24576         pool_remove $test_pool $f
24577 }
24578 run_test 406 "DNE support fs default striping"
24579
24580 test_407() {
24581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24582         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24583                 skip "Need MDS version at least 2.8.55"
24584         remote_mds_nodsh && skip "remote MDS with nodsh"
24585
24586         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24587                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24588         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24589                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24590         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24591
24592         #define OBD_FAIL_DT_TXN_STOP    0x2019
24593         for idx in $(seq $MDSCOUNT); do
24594                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24595         done
24596         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24597         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24598                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24599         true
24600 }
24601 run_test 407 "transaction fail should cause operation fail"
24602
24603 test_408() {
24604         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24605
24606         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24607         lctl set_param fail_loc=0x8000040a
24608         # let ll_prepare_partial_page() fail
24609         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24610
24611         rm -f $DIR/$tfile
24612
24613         # create at least 100 unused inodes so that
24614         # shrink_icache_memory(0) should not return 0
24615         touch $DIR/$tfile-{0..100}
24616         rm -f $DIR/$tfile-{0..100}
24617         sync
24618
24619         echo 2 > /proc/sys/vm/drop_caches
24620 }
24621 run_test 408 "drop_caches should not hang due to page leaks"
24622
24623 test_409()
24624 {
24625         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24626
24627         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24628         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24629         touch $DIR/$tdir/guard || error "(2) Fail to create"
24630
24631         local PREFIX=$(str_repeat 'A' 128)
24632         echo "Create 1K hard links start at $(date)"
24633         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24634                 error "(3) Fail to hard link"
24635
24636         echo "Links count should be right although linkEA overflow"
24637         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24638         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24639         [ $linkcount -eq 1001 ] ||
24640                 error "(5) Unexpected hard links count: $linkcount"
24641
24642         echo "List all links start at $(date)"
24643         ls -l $DIR/$tdir/foo > /dev/null ||
24644                 error "(6) Fail to list $DIR/$tdir/foo"
24645
24646         echo "Unlink hard links start at $(date)"
24647         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24648                 error "(7) Fail to unlink"
24649         echo "Unlink hard links finished at $(date)"
24650 }
24651 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24652
24653 test_410()
24654 {
24655         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24656                 skip "Need client version at least 2.9.59"
24657         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24658                 skip "Need MODULES build"
24659
24660         # Create a file, and stat it from the kernel
24661         local testfile=$DIR/$tfile
24662         touch $testfile
24663
24664         local run_id=$RANDOM
24665         local my_ino=$(stat --format "%i" $testfile)
24666
24667         # Try to insert the module. This will always fail as the
24668         # module is designed to not be inserted.
24669         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24670             &> /dev/null
24671
24672         # Anything but success is a test failure
24673         dmesg | grep -q \
24674             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24675             error "no inode match"
24676 }
24677 run_test 410 "Test inode number returned from kernel thread"
24678
24679 cleanup_test411_cgroup() {
24680         trap 0
24681         rmdir "$1"
24682 }
24683
24684 test_411() {
24685         local cg_basedir=/sys/fs/cgroup/memory
24686         # LU-9966
24687         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24688                 skip "no setup for cgroup"
24689
24690         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24691                 error "test file creation failed"
24692         cancel_lru_locks osc
24693
24694         # Create a very small memory cgroup to force a slab allocation error
24695         local cgdir=$cg_basedir/osc_slab_alloc
24696         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24697         trap "cleanup_test411_cgroup $cgdir" EXIT
24698         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24699         echo 1M > $cgdir/memory.limit_in_bytes
24700
24701         # Should not LBUG, just be killed by oom-killer
24702         # dd will return 0 even allocation failure in some environment.
24703         # So don't check return value
24704         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24705         cleanup_test411_cgroup $cgdir
24706
24707         return 0
24708 }
24709 run_test 411 "Slab allocation error with cgroup does not LBUG"
24710
24711 test_412() {
24712         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24713         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24714                 skip "Need server version at least 2.10.55"
24715         fi
24716
24717         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24718                 error "mkdir failed"
24719         $LFS getdirstripe $DIR/$tdir
24720         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24721         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24722                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24723         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24724         [ $stripe_count -eq 2 ] ||
24725                 error "expect 2 get $stripe_count"
24726 }
24727 run_test 412 "mkdir on specific MDTs"
24728
24729 generate_uneven_mdts() {
24730         local threshold=$1
24731         local ffree
24732         local bavail
24733         local max
24734         local min
24735         local max_index
24736         local min_index
24737         local tmp
24738         local i
24739
24740         echo
24741         echo "Check for uneven MDTs: "
24742
24743         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24744         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24745         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24746
24747         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24748         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24749         max_index=0
24750         min_index=0
24751         for ((i = 1; i < ${#ffree[@]}; i++)); do
24752                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24753                 if [ $tmp -gt $max ]; then
24754                         max=$tmp
24755                         max_index=$i
24756                 fi
24757                 if [ $tmp -lt $min ]; then
24758                         min=$tmp
24759                         min_index=$i
24760                 fi
24761         done
24762
24763         # Check if we need to generate uneven MDTs
24764         local diff=$(((max - min) * 100 / min))
24765         local testdir=$DIR/$tdir-fillmdt
24766
24767         mkdir -p $testdir
24768
24769         i=0
24770         while (( diff < threshold )); do
24771                 # generate uneven MDTs, create till $threshold% diff
24772                 echo -n "weight diff=$diff% must be > $threshold% ..."
24773                 echo "Fill MDT$min_index with 100 files: loop $i"
24774                 testdir=$DIR/$tdir-fillmdt/$i
24775                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24776                         error "mkdir $testdir failed"
24777                 $LFS setstripe -E 1M -L mdt $testdir ||
24778                         error "setstripe $testdir failed"
24779                 for F in f.{0..99}; do
24780                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24781                                 /dev/null 2>&1 || error "dd $F failed"
24782                 done
24783
24784                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24785                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24786                 max=$(((${ffree[max_index]} >> 8) * \
24787                         (${bavail[max_index]} * bsize >> 16)))
24788                 min=$(((${ffree[min_index]} >> 8) * \
24789                         (${bavail[min_index]} * bsize >> 16)))
24790                 diff=$(((max - min) * 100 / min))
24791                 i=$((i + 1))
24792         done
24793
24794         echo "MDT filesfree available: ${ffree[@]}"
24795         echo "MDT blocks available: ${bavail[@]}"
24796         echo "weight diff=$diff%"
24797 }
24798
24799 test_qos_mkdir() {
24800         local mkdir_cmd=$1
24801         local stripe_count=$2
24802         local mdts=$(comma_list $(mdts_nodes))
24803
24804         local testdir
24805         local lmv_qos_prio_free
24806         local lmv_qos_threshold_rr
24807         local lmv_qos_maxage
24808         local lod_qos_prio_free
24809         local lod_qos_threshold_rr
24810         local lod_qos_maxage
24811         local count
24812         local i
24813
24814         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24815         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24816         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24817                 head -n1)
24818         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24819         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24820         stack_trap "$LCTL set_param \
24821                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24822         stack_trap "$LCTL set_param \
24823                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24824         stack_trap "$LCTL set_param \
24825                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24826
24827         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24828                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24829         lod_qos_prio_free=${lod_qos_prio_free%%%}
24830         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24831                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24832         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24833         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24834                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24835         stack_trap "do_nodes $mdts $LCTL set_param \
24836                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24837         stack_trap "do_nodes $mdts $LCTL set_param \
24838                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24839         stack_trap "do_nodes $mdts $LCTL set_param \
24840                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24841
24842         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24843         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24844
24845         testdir=$DIR/$tdir-s$stripe_count/rr
24846
24847         local stripe_index=$($LFS getstripe -m $testdir)
24848         local test_mkdir_rr=true
24849
24850         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24851         getfattr -d -m dmv -e hex $testdir | grep dmv
24852         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24853                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24854                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24855                         test_mkdir_rr=false
24856         fi
24857
24858         echo
24859         $test_mkdir_rr &&
24860                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24861                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24862
24863         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24864         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24865                 eval $mkdir_cmd $testdir/subdir$i ||
24866                         error "$mkdir_cmd subdir$i failed"
24867         done
24868
24869         for (( i = 0; i < $MDSCOUNT; i++ )); do
24870                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24871                 echo "$count directories created on MDT$i"
24872                 if $test_mkdir_rr; then
24873                         (( $count == 100 )) ||
24874                                 error "subdirs are not evenly distributed"
24875                 elif (( $i == $stripe_index )); then
24876                         (( $count == 100 * MDSCOUNT )) ||
24877                                 error "$count subdirs created on MDT$i"
24878                 else
24879                         (( $count == 0 )) ||
24880                                 error "$count subdirs created on MDT$i"
24881                 fi
24882
24883                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24884                         count=$($LFS getdirstripe $testdir/* |
24885                                 grep -c -P "^\s+$i\t")
24886                         echo "$count stripes created on MDT$i"
24887                         # deviation should < 5% of average
24888                         (( $count >= 95 * stripe_count &&
24889                            $count <= 105 * stripe_count)) ||
24890                                 error "stripes are not evenly distributed"
24891                 fi
24892         done
24893
24894         echo
24895         echo "Check for uneven MDTs: "
24896
24897         local ffree
24898         local bavail
24899         local max
24900         local min
24901         local max_index
24902         local min_index
24903         local tmp
24904
24905         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24906         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24907         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24908
24909         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24910         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24911         max_index=0
24912         min_index=0
24913         for ((i = 1; i < ${#ffree[@]}; i++)); do
24914                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24915                 if [ $tmp -gt $max ]; then
24916                         max=$tmp
24917                         max_index=$i
24918                 fi
24919                 if [ $tmp -lt $min ]; then
24920                         min=$tmp
24921                         min_index=$i
24922                 fi
24923         done
24924
24925         (( ${ffree[min_index]} > 0 )) ||
24926                 skip "no free files in MDT$min_index"
24927         (( ${ffree[min_index]} < 100000000 )) ||
24928                 skip "too many free files in MDT$min_index"
24929
24930         echo "MDT filesfree available: ${ffree[@]}"
24931         echo "MDT blocks available: ${bavail[@]}"
24932         echo "weight diff=$(((max - min) * 100 / min))%"
24933         echo
24934         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24935
24936         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24937         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24938         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24939         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24940         # decrease statfs age, so that it can be updated in time
24941         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24942         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24943
24944         sleep 1
24945
24946         testdir=$DIR/$tdir-s$stripe_count/qos
24947         local num=200
24948
24949         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24950         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24951                 eval $mkdir_cmd $testdir/subdir$i ||
24952                         error "$mkdir_cmd subdir$i failed"
24953         done
24954
24955         for (( i = 0; i < $MDSCOUNT; i++ )); do
24956                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24957                 echo "$count directories created on MDT$i"
24958
24959                 if [ $stripe_count -gt 1 ]; then
24960                         count=$($LFS getdirstripe $testdir/* |
24961                                 grep -c -P "^\s+$i\t")
24962                         echo "$count stripes created on MDT$i"
24963                 fi
24964         done
24965
24966         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24967         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24968
24969         # D-value should > 10% of averge
24970         (( max - min >= num / 10 )) ||
24971                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24972
24973         # 5% for stripes
24974         if (( stripe_count > 1 )); then
24975                 max=$($LFS getdirstripe $testdir/* |
24976                       grep -c -P "^\s+$max_index\t")
24977                 min=$($LFS getdirstripe $testdir/* |
24978                         grep -c -P "^\s+$min_index\t")
24979                 (( max - min >= num * stripe_count / 20 )) ||
24980                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24981         fi
24982 }
24983
24984 most_full_mdt() {
24985         local ffree
24986         local bavail
24987         local bsize
24988         local min
24989         local min_index
24990         local tmp
24991
24992         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24993         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24994         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24995
24996         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24997         min_index=0
24998         for ((i = 1; i < ${#ffree[@]}; i++)); do
24999                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25000                 (( tmp < min )) && min=$tmp && min_index=$i
25001         done
25002
25003         echo -n $min_index
25004 }
25005
25006 test_413a() {
25007         [ $MDSCOUNT -lt 2 ] &&
25008                 skip "We need at least 2 MDTs for this test"
25009
25010         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25011                 skip "Need server version at least 2.12.52"
25012
25013         local stripe_count
25014
25015         generate_uneven_mdts 100
25016         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25017                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25018                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25019                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25020                         error "mkdir failed"
25021                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25022         done
25023 }
25024 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25025
25026 test_413b() {
25027         [ $MDSCOUNT -lt 2 ] &&
25028                 skip "We need at least 2 MDTs for this test"
25029
25030         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25031                 skip "Need server version at least 2.12.52"
25032
25033         local testdir
25034         local stripe_count
25035
25036         generate_uneven_mdts 100
25037         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25038                 testdir=$DIR/$tdir-s$stripe_count
25039                 mkdir $testdir || error "mkdir $testdir failed"
25040                 mkdir $testdir/rr || error "mkdir rr failed"
25041                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25042                         error "mkdir qos failed"
25043                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25044                         $testdir/rr || error "setdirstripe rr failed"
25045                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25046                         error "setdirstripe failed"
25047                 test_qos_mkdir "mkdir" $stripe_count
25048         done
25049 }
25050 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25051
25052 test_413c() {
25053         (( $MDSCOUNT >= 2 )) ||
25054                 skip "We need at least 2 MDTs for this test"
25055
25056         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25057                 skip "Need server version at least 2.14.51"
25058
25059         local testdir
25060         local inherit
25061         local inherit_rr
25062
25063         testdir=$DIR/${tdir}-s1
25064         mkdir $testdir || error "mkdir $testdir failed"
25065         mkdir $testdir/rr || error "mkdir rr failed"
25066         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25067         # default max_inherit is -1, default max_inherit_rr is 0
25068         $LFS setdirstripe -D -c 1 $testdir/rr ||
25069                 error "setdirstripe rr failed"
25070         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25071                 error "setdirstripe qos failed"
25072         test_qos_mkdir "mkdir" 1
25073
25074         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25075         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25076         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25077         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25078         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25079
25080         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25081         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25082         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25083         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25084         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25085         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25086         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25087                 error "level2 shouldn't have default LMV" || true
25088 }
25089 run_test 413c "mkdir with default LMV max inherit rr"
25090
25091 test_413d() {
25092         (( MDSCOUNT >= 2 )) ||
25093                 skip "We need at least 2 MDTs for this test"
25094
25095         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25096                 skip "Need server version at least 2.14.51"
25097
25098         local lmv_qos_threshold_rr
25099
25100         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25101                 head -n1)
25102         stack_trap "$LCTL set_param \
25103                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25104
25105         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25106         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25107         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25108                 error "$tdir shouldn't have default LMV"
25109         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25110                 error "mkdir sub failed"
25111
25112         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25113
25114         (( count == 100 )) || error "$count subdirs on MDT0"
25115 }
25116 run_test 413d "inherit ROOT default LMV"
25117
25118 test_413z() {
25119         local pids=""
25120         local subdir
25121         local pid
25122
25123         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25124                 unlinkmany $subdir/f. 100 &
25125                 pids="$pids $!"
25126         done
25127
25128         for pid in $pids; do
25129                 wait $pid
25130         done
25131 }
25132 run_test 413z "413 test cleanup"
25133
25134 test_414() {
25135 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25136         $LCTL set_param fail_loc=0x80000521
25137         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25138         rm -f $DIR/$tfile
25139 }
25140 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25141
25142 test_415() {
25143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25144         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25145                 skip "Need server version at least 2.11.52"
25146
25147         # LU-11102
25148         local total
25149         local setattr_pid
25150         local start_time
25151         local end_time
25152         local duration
25153
25154         total=500
25155         # this test may be slow on ZFS
25156         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25157
25158         # though this test is designed for striped directory, let's test normal
25159         # directory too since lock is always saved as CoS lock.
25160         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25161         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25162
25163         (
25164                 while true; do
25165                         touch $DIR/$tdir
25166                 done
25167         ) &
25168         setattr_pid=$!
25169
25170         start_time=$(date +%s)
25171         for i in $(seq $total); do
25172                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25173                         > /dev/null
25174         done
25175         end_time=$(date +%s)
25176         duration=$((end_time - start_time))
25177
25178         kill -9 $setattr_pid
25179
25180         echo "rename $total files took $duration sec"
25181         [ $duration -lt 100 ] || error "rename took $duration sec"
25182 }
25183 run_test 415 "lock revoke is not missing"
25184
25185 test_416() {
25186         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25187                 skip "Need server version at least 2.11.55"
25188
25189         # define OBD_FAIL_OSD_TXN_START    0x19a
25190         do_facet mds1 lctl set_param fail_loc=0x19a
25191
25192         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25193
25194         true
25195 }
25196 run_test 416 "transaction start failure won't cause system hung"
25197
25198 cleanup_417() {
25199         trap 0
25200         do_nodes $(comma_list $(mdts_nodes)) \
25201                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25202         do_nodes $(comma_list $(mdts_nodes)) \
25203                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25204         do_nodes $(comma_list $(mdts_nodes)) \
25205                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25206 }
25207
25208 test_417() {
25209         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25210         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25211                 skip "Need MDS version at least 2.11.56"
25212
25213         trap cleanup_417 RETURN EXIT
25214
25215         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25216         do_nodes $(comma_list $(mdts_nodes)) \
25217                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25218         $LFS migrate -m 0 $DIR/$tdir.1 &&
25219                 error "migrate dir $tdir.1 should fail"
25220
25221         do_nodes $(comma_list $(mdts_nodes)) \
25222                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25223         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25224                 error "create remote dir $tdir.2 should fail"
25225
25226         do_nodes $(comma_list $(mdts_nodes)) \
25227                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25228         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25229                 error "create striped dir $tdir.3 should fail"
25230         true
25231 }
25232 run_test 417 "disable remote dir, striped dir and dir migration"
25233
25234 # Checks that the outputs of df [-i] and lfs df [-i] match
25235 #
25236 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25237 check_lfs_df() {
25238         local dir=$2
25239         local inodes
25240         local df_out
25241         local lfs_df_out
25242         local count
25243         local passed=false
25244
25245         # blocks or inodes
25246         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25247
25248         for count in {1..100}; do
25249                 do_rpc_nodes "$CLIENTS" cancel_lru_locks
25250                 sync; sleep 0.2
25251
25252                 # read the lines of interest
25253                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25254                         error "df $inodes $dir | tail -n +2 failed"
25255                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25256                         error "lfs df $inodes $dir | grep summary: failed"
25257
25258                 # skip first substrings of each output as they are different
25259                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25260                 # compare the two outputs
25261                 passed=true
25262                 for i in {1..5}; do
25263                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25264                 done
25265                 $passed && break
25266         done
25267
25268         if ! $passed; then
25269                 df -P $inodes $dir
25270                 echo
25271                 lfs df $inodes $dir
25272                 error "df and lfs df $1 output mismatch: "      \
25273                       "df ${inodes}: ${df_out[*]}, "            \
25274                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25275         fi
25276 }
25277
25278 test_418() {
25279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25280
25281         local dir=$DIR/$tdir
25282         local numfiles=$((RANDOM % 4096 + 2))
25283         local numblocks=$((RANDOM % 256 + 1))
25284
25285         wait_delete_completed
25286         test_mkdir $dir
25287
25288         # check block output
25289         check_lfs_df blocks $dir
25290         # check inode output
25291         check_lfs_df inodes $dir
25292
25293         # create a single file and retest
25294         echo "Creating a single file and testing"
25295         createmany -o $dir/$tfile- 1 &>/dev/null ||
25296                 error "creating 1 file in $dir failed"
25297         check_lfs_df blocks $dir
25298         check_lfs_df inodes $dir
25299
25300         # create a random number of files
25301         echo "Creating $((numfiles - 1)) files and testing"
25302         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25303                 error "creating $((numfiles - 1)) files in $dir failed"
25304
25305         # write a random number of blocks to the first test file
25306         echo "Writing $numblocks 4K blocks and testing"
25307         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25308                 count=$numblocks &>/dev/null ||
25309                 error "dd to $dir/${tfile}-0 failed"
25310
25311         # retest
25312         check_lfs_df blocks $dir
25313         check_lfs_df inodes $dir
25314
25315         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25316                 error "unlinking $numfiles files in $dir failed"
25317 }
25318 run_test 418 "df and lfs df outputs match"
25319
25320 test_419()
25321 {
25322         local dir=$DIR/$tdir
25323
25324         mkdir -p $dir
25325         touch $dir/file
25326
25327         cancel_lru_locks mdc
25328
25329         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25330         $LCTL set_param fail_loc=0x1410
25331         cat $dir/file
25332         $LCTL set_param fail_loc=0
25333         rm -rf $dir
25334 }
25335 run_test 419 "Verify open file by name doesn't crash kernel"
25336
25337 test_420()
25338 {
25339         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25340                 skip "Need MDS version at least 2.12.53"
25341
25342         local SAVE_UMASK=$(umask)
25343         local dir=$DIR/$tdir
25344         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25345
25346         mkdir -p $dir
25347         umask 0000
25348         mkdir -m03777 $dir/testdir
25349         ls -dn $dir/testdir
25350         # Need to remove trailing '.' when SELinux is enabled
25351         local dirperms=$(ls -dn $dir/testdir |
25352                          awk '{ sub(/\.$/, "", $1); print $1}')
25353         [ $dirperms == "drwxrwsrwt" ] ||
25354                 error "incorrect perms on $dir/testdir"
25355
25356         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25357                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25358         ls -n $dir/testdir/testfile
25359         local fileperms=$(ls -n $dir/testdir/testfile |
25360                           awk '{ sub(/\.$/, "", $1); print $1}')
25361         [ $fileperms == "-rwxr-xr-x" ] ||
25362                 error "incorrect perms on $dir/testdir/testfile"
25363
25364         umask $SAVE_UMASK
25365 }
25366 run_test 420 "clear SGID bit on non-directories for non-members"
25367
25368 test_421a() {
25369         local cnt
25370         local fid1
25371         local fid2
25372
25373         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25374                 skip "Need MDS version at least 2.12.54"
25375
25376         test_mkdir $DIR/$tdir
25377         createmany -o $DIR/$tdir/f 3
25378         cnt=$(ls -1 $DIR/$tdir | wc -l)
25379         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25380
25381         fid1=$(lfs path2fid $DIR/$tdir/f1)
25382         fid2=$(lfs path2fid $DIR/$tdir/f2)
25383         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25384
25385         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25386         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25387
25388         cnt=$(ls -1 $DIR/$tdir | wc -l)
25389         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25390
25391         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25392         createmany -o $DIR/$tdir/f 3
25393         cnt=$(ls -1 $DIR/$tdir | wc -l)
25394         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25395
25396         fid1=$(lfs path2fid $DIR/$tdir/f1)
25397         fid2=$(lfs path2fid $DIR/$tdir/f2)
25398         echo "remove using fsname $FSNAME"
25399         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25400
25401         cnt=$(ls -1 $DIR/$tdir | wc -l)
25402         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25403 }
25404 run_test 421a "simple rm by fid"
25405
25406 test_421b() {
25407         local cnt
25408         local FID1
25409         local FID2
25410
25411         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25412                 skip "Need MDS version at least 2.12.54"
25413
25414         test_mkdir $DIR/$tdir
25415         createmany -o $DIR/$tdir/f 3
25416         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25417         MULTIPID=$!
25418
25419         FID1=$(lfs path2fid $DIR/$tdir/f1)
25420         FID2=$(lfs path2fid $DIR/$tdir/f2)
25421         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25422
25423         kill -USR1 $MULTIPID
25424         wait
25425
25426         cnt=$(ls $DIR/$tdir | wc -l)
25427         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25428 }
25429 run_test 421b "rm by fid on open file"
25430
25431 test_421c() {
25432         local cnt
25433         local FIDS
25434
25435         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25436                 skip "Need MDS version at least 2.12.54"
25437
25438         test_mkdir $DIR/$tdir
25439         createmany -o $DIR/$tdir/f 3
25440         touch $DIR/$tdir/$tfile
25441         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25442         cnt=$(ls -1 $DIR/$tdir | wc -l)
25443         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25444
25445         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25446         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25447
25448         cnt=$(ls $DIR/$tdir | wc -l)
25449         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25450 }
25451 run_test 421c "rm by fid against hardlinked files"
25452
25453 test_421d() {
25454         local cnt
25455         local FIDS
25456
25457         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25458                 skip "Need MDS version at least 2.12.54"
25459
25460         test_mkdir $DIR/$tdir
25461         createmany -o $DIR/$tdir/f 4097
25462         cnt=$(ls -1 $DIR/$tdir | wc -l)
25463         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25464
25465         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25466         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25467
25468         cnt=$(ls $DIR/$tdir | wc -l)
25469         rm -rf $DIR/$tdir
25470         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25471 }
25472 run_test 421d "rmfid en masse"
25473
25474 test_421e() {
25475         local cnt
25476         local FID
25477
25478         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25479         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25480                 skip "Need MDS version at least 2.12.54"
25481
25482         mkdir -p $DIR/$tdir
25483         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25484         createmany -o $DIR/$tdir/striped_dir/f 512
25485         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25486         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25487
25488         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25489                 sed "s/[/][^:]*://g")
25490         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25491
25492         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25493         rm -rf $DIR/$tdir
25494         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25495 }
25496 run_test 421e "rmfid in DNE"
25497
25498 test_421f() {
25499         local cnt
25500         local FID
25501
25502         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25503                 skip "Need MDS version at least 2.12.54"
25504
25505         test_mkdir $DIR/$tdir
25506         touch $DIR/$tdir/f
25507         cnt=$(ls -1 $DIR/$tdir | wc -l)
25508         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25509
25510         FID=$(lfs path2fid $DIR/$tdir/f)
25511         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25512         # rmfid should fail
25513         cnt=$(ls -1 $DIR/$tdir | wc -l)
25514         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25515
25516         chmod a+rw $DIR/$tdir
25517         ls -la $DIR/$tdir
25518         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25519         # rmfid should fail
25520         cnt=$(ls -1 $DIR/$tdir | wc -l)
25521         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25522
25523         rm -f $DIR/$tdir/f
25524         $RUNAS touch $DIR/$tdir/f
25525         FID=$(lfs path2fid $DIR/$tdir/f)
25526         echo "rmfid as root"
25527         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25528         cnt=$(ls -1 $DIR/$tdir | wc -l)
25529         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25530
25531         rm -f $DIR/$tdir/f
25532         $RUNAS touch $DIR/$tdir/f
25533         cnt=$(ls -1 $DIR/$tdir | wc -l)
25534         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25535         FID=$(lfs path2fid $DIR/$tdir/f)
25536         # rmfid w/o user_fid2path mount option should fail
25537         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25538         cnt=$(ls -1 $DIR/$tdir | wc -l)
25539         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25540
25541         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25542         stack_trap "rmdir $tmpdir"
25543         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25544                 error "failed to mount client'"
25545         stack_trap "umount_client $tmpdir"
25546
25547         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25548         # rmfid should succeed
25549         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25550         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25551
25552         # rmfid shouldn't allow to remove files due to dir's permission
25553         chmod a+rwx $tmpdir/$tdir
25554         touch $tmpdir/$tdir/f
25555         ls -la $tmpdir/$tdir
25556         FID=$(lfs path2fid $tmpdir/$tdir/f)
25557         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25558         return 0
25559 }
25560 run_test 421f "rmfid checks permissions"
25561
25562 test_421g() {
25563         local cnt
25564         local FIDS
25565
25566         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25567         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25568                 skip "Need MDS version at least 2.12.54"
25569
25570         mkdir -p $DIR/$tdir
25571         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25572         createmany -o $DIR/$tdir/striped_dir/f 512
25573         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25574         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25575
25576         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25577                 sed "s/[/][^:]*://g")
25578
25579         rm -f $DIR/$tdir/striped_dir/f1*
25580         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25581         removed=$((512 - cnt))
25582
25583         # few files have been just removed, so we expect
25584         # rmfid to fail on their fids
25585         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25586         [ $removed != $errors ] && error "$errors != $removed"
25587
25588         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25589         rm -rf $DIR/$tdir
25590         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25591 }
25592 run_test 421g "rmfid to return errors properly"
25593
25594 test_422() {
25595         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25596         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25597         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25598         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25599         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25600
25601         local amc=$(at_max_get client)
25602         local amo=$(at_max_get mds1)
25603         local timeout=`lctl get_param -n timeout`
25604
25605         at_max_set 0 client
25606         at_max_set 0 mds1
25607
25608 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25609         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25610                         fail_val=$(((2*timeout + 10)*1000))
25611         touch $DIR/$tdir/d3/file &
25612         sleep 2
25613 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25614         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25615                         fail_val=$((2*timeout + 5))
25616         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25617         local pid=$!
25618         sleep 1
25619         kill -9 $pid
25620         sleep $((2 * timeout))
25621         echo kill $pid
25622         kill -9 $pid
25623         lctl mark touch
25624         touch $DIR/$tdir/d2/file3
25625         touch $DIR/$tdir/d2/file4
25626         touch $DIR/$tdir/d2/file5
25627
25628         wait
25629         at_max_set $amc client
25630         at_max_set $amo mds1
25631
25632         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25633         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25634                 error "Watchdog is always throttled"
25635 }
25636 run_test 422 "kill a process with RPC in progress"
25637
25638 stat_test() {
25639     df -h $MOUNT &
25640     df -h $MOUNT &
25641     df -h $MOUNT &
25642     df -h $MOUNT &
25643     df -h $MOUNT &
25644     df -h $MOUNT &
25645 }
25646
25647 test_423() {
25648     local _stats
25649     # ensure statfs cache is expired
25650     sleep 2;
25651
25652     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25653     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25654
25655     return 0
25656 }
25657 run_test 423 "statfs should return a right data"
25658
25659 test_424() {
25660 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25661         $LCTL set_param fail_loc=0x80000522
25662         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25663         rm -f $DIR/$tfile
25664 }
25665 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25666
25667 test_425() {
25668         test_mkdir -c -1 $DIR/$tdir
25669         $LFS setstripe -c -1 $DIR/$tdir
25670
25671         lru_resize_disable "" 100
25672         stack_trap "lru_resize_enable" EXIT
25673
25674         sleep 5
25675
25676         for i in $(seq $((MDSCOUNT * 125))); do
25677                 local t=$DIR/$tdir/$tfile_$i
25678
25679                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25680                         error_noexit "Create file $t"
25681         done
25682         stack_trap "rm -rf $DIR/$tdir" EXIT
25683
25684         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25685                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25686                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25687
25688                 [ $lock_count -le $lru_size ] ||
25689                         error "osc lock count $lock_count > lru size $lru_size"
25690         done
25691
25692         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25693                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25694                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25695
25696                 [ $lock_count -le $lru_size ] ||
25697                         error "mdc lock count $lock_count > lru size $lru_size"
25698         done
25699 }
25700 run_test 425 "lock count should not exceed lru size"
25701
25702 test_426() {
25703         splice-test -r $DIR/$tfile
25704         splice-test -rd $DIR/$tfile
25705         splice-test $DIR/$tfile
25706         splice-test -d $DIR/$tfile
25707 }
25708 run_test 426 "splice test on Lustre"
25709
25710 test_427() {
25711         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25712         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25713                 skip "Need MDS version at least 2.12.4"
25714         local log
25715
25716         mkdir $DIR/$tdir
25717         mkdir $DIR/$tdir/1
25718         mkdir $DIR/$tdir/2
25719         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25720         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25721
25722         $LFS getdirstripe $DIR/$tdir/1/dir
25723
25724         #first setfattr for creating updatelog
25725         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25726
25727 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25728         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25729         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25730         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25731
25732         sleep 2
25733         fail mds2
25734         wait_recovery_complete mds2 $((2*TIMEOUT))
25735
25736         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25737         echo $log | grep "get update log failed" &&
25738                 error "update log corruption is detected" || true
25739 }
25740 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25741
25742 test_428() {
25743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25744         local cache_limit=$CACHE_MAX
25745
25746         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25747         $LCTL set_param -n llite.*.max_cached_mb=64
25748
25749         mkdir $DIR/$tdir
25750         $LFS setstripe -c 1 $DIR/$tdir
25751         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25752         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25753         #test write
25754         for f in $(seq 4); do
25755                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25756         done
25757         wait
25758
25759         cancel_lru_locks osc
25760         # Test read
25761         for f in $(seq 4); do
25762                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25763         done
25764         wait
25765 }
25766 run_test 428 "large block size IO should not hang"
25767
25768 test_429() { # LU-7915 / LU-10948
25769         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25770         local testfile=$DIR/$tfile
25771         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25772         local new_flag=1
25773         local first_rpc
25774         local second_rpc
25775         local third_rpc
25776
25777         $LCTL get_param $ll_opencache_threshold_count ||
25778                 skip "client does not have opencache parameter"
25779
25780         set_opencache $new_flag
25781         stack_trap "restore_opencache"
25782         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25783                 error "enable opencache failed"
25784         touch $testfile
25785         # drop MDC DLM locks
25786         cancel_lru_locks mdc
25787         # clear MDC RPC stats counters
25788         $LCTL set_param $mdc_rpcstats=clear
25789
25790         # According to the current implementation, we need to run 3 times
25791         # open & close file to verify if opencache is enabled correctly.
25792         # 1st, RPCs are sent for lookup/open and open handle is released on
25793         #      close finally.
25794         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25795         #      so open handle won't be released thereafter.
25796         # 3rd, No RPC is sent out.
25797         $MULTIOP $testfile oc || error "multiop failed"
25798         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25799         echo "1st: $first_rpc RPCs in flight"
25800
25801         $MULTIOP $testfile oc || error "multiop failed"
25802         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25803         echo "2nd: $second_rpc RPCs in flight"
25804
25805         $MULTIOP $testfile oc || error "multiop failed"
25806         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25807         echo "3rd: $third_rpc RPCs in flight"
25808
25809         #verify no MDC RPC is sent
25810         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25811 }
25812 run_test 429 "verify if opencache flag on client side does work"
25813
25814 lseek_test_430() {
25815         local offset
25816         local file=$1
25817
25818         # data at [200K, 400K)
25819         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25820                 error "256K->512K dd fails"
25821         # data at [2M, 3M)
25822         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25823                 error "2M->3M dd fails"
25824         # data at [4M, 5M)
25825         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25826                 error "4M->5M dd fails"
25827         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25828         # start at first component hole #1
25829         printf "Seeking hole from 1000 ... "
25830         offset=$(lseek_test -l 1000 $file)
25831         echo $offset
25832         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25833         printf "Seeking data from 1000 ... "
25834         offset=$(lseek_test -d 1000 $file)
25835         echo $offset
25836         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25837
25838         # start at first component data block
25839         printf "Seeking hole from 300000 ... "
25840         offset=$(lseek_test -l 300000 $file)
25841         echo $offset
25842         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25843         printf "Seeking data from 300000 ... "
25844         offset=$(lseek_test -d 300000 $file)
25845         echo $offset
25846         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25847
25848         # start at the first component but beyond end of object size
25849         printf "Seeking hole from 1000000 ... "
25850         offset=$(lseek_test -l 1000000 $file)
25851         echo $offset
25852         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25853         printf "Seeking data from 1000000 ... "
25854         offset=$(lseek_test -d 1000000 $file)
25855         echo $offset
25856         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25857
25858         # start at second component stripe 2 (empty file)
25859         printf "Seeking hole from 1500000 ... "
25860         offset=$(lseek_test -l 1500000 $file)
25861         echo $offset
25862         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25863         printf "Seeking data from 1500000 ... "
25864         offset=$(lseek_test -d 1500000 $file)
25865         echo $offset
25866         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25867
25868         # start at second component stripe 1 (all data)
25869         printf "Seeking hole from 3000000 ... "
25870         offset=$(lseek_test -l 3000000 $file)
25871         echo $offset
25872         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25873         printf "Seeking data from 3000000 ... "
25874         offset=$(lseek_test -d 3000000 $file)
25875         echo $offset
25876         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25877
25878         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25879                 error "2nd dd fails"
25880         echo "Add data block at 640K...1280K"
25881
25882         # start at before new data block, in hole
25883         printf "Seeking hole from 600000 ... "
25884         offset=$(lseek_test -l 600000 $file)
25885         echo $offset
25886         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25887         printf "Seeking data from 600000 ... "
25888         offset=$(lseek_test -d 600000 $file)
25889         echo $offset
25890         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25891
25892         # start at the first component new data block
25893         printf "Seeking hole from 1000000 ... "
25894         offset=$(lseek_test -l 1000000 $file)
25895         echo $offset
25896         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25897         printf "Seeking data from 1000000 ... "
25898         offset=$(lseek_test -d 1000000 $file)
25899         echo $offset
25900         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25901
25902         # start at second component stripe 2, new data
25903         printf "Seeking hole from 1200000 ... "
25904         offset=$(lseek_test -l 1200000 $file)
25905         echo $offset
25906         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25907         printf "Seeking data from 1200000 ... "
25908         offset=$(lseek_test -d 1200000 $file)
25909         echo $offset
25910         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25911
25912         # start beyond file end
25913         printf "Using offset > filesize ... "
25914         lseek_test -l 4000000 $file && error "lseek should fail"
25915         printf "Using offset > filesize ... "
25916         lseek_test -d 4000000 $file && error "lseek should fail"
25917
25918         printf "Done\n\n"
25919 }
25920
25921 test_430a() {
25922         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25923                 skip "MDT does not support SEEK_HOLE"
25924
25925         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25926                 skip "OST does not support SEEK_HOLE"
25927
25928         local file=$DIR/$tdir/$tfile
25929
25930         mkdir -p $DIR/$tdir
25931
25932         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25933         # OST stripe #1 will have continuous data at [1M, 3M)
25934         # OST stripe #2 is empty
25935         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25936         lseek_test_430 $file
25937         rm $file
25938         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25939         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25940         lseek_test_430 $file
25941         rm $file
25942         $LFS setstripe -c2 -S 512K $file
25943         echo "Two stripes, stripe size 512K"
25944         lseek_test_430 $file
25945         rm $file
25946         # FLR with stale mirror
25947         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25948                        -N -c2 -S 1M $file
25949         echo "Mirrored file:"
25950         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25951         echo "Plain 2 stripes 1M"
25952         lseek_test_430 $file
25953         rm $file
25954 }
25955 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25956
25957 test_430b() {
25958         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25959                 skip "OST does not support SEEK_HOLE"
25960
25961         local offset
25962         local file=$DIR/$tdir/$tfile
25963
25964         mkdir -p $DIR/$tdir
25965         # Empty layout lseek should fail
25966         $MCREATE $file
25967         # seek from 0
25968         printf "Seeking hole from 0 ... "
25969         lseek_test -l 0 $file && error "lseek should fail"
25970         printf "Seeking data from 0 ... "
25971         lseek_test -d 0 $file && error "lseek should fail"
25972         rm $file
25973
25974         # 1M-hole file
25975         $LFS setstripe -E 1M -c2 -E eof $file
25976         $TRUNCATE $file 1048576
25977         printf "Seeking hole from 1000000 ... "
25978         offset=$(lseek_test -l 1000000 $file)
25979         echo $offset
25980         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25981         printf "Seeking data from 1000000 ... "
25982         lseek_test -d 1000000 $file && error "lseek should fail"
25983         rm $file
25984
25985         # full component followed by non-inited one
25986         $LFS setstripe -E 1M -c2 -E eof $file
25987         dd if=/dev/urandom of=$file bs=1M count=1
25988         printf "Seeking hole from 1000000 ... "
25989         offset=$(lseek_test -l 1000000 $file)
25990         echo $offset
25991         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25992         printf "Seeking hole from 1048576 ... "
25993         lseek_test -l 1048576 $file && error "lseek should fail"
25994         # init second component and truncate back
25995         echo "123" >> $file
25996         $TRUNCATE $file 1048576
25997         printf "Seeking hole from 1000000 ... "
25998         offset=$(lseek_test -l 1000000 $file)
25999         echo $offset
26000         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26001         printf "Seeking hole from 1048576 ... "
26002         lseek_test -l 1048576 $file && error "lseek should fail"
26003         # boundary checks for big values
26004         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26005         offset=$(lseek_test -d 0 $file.10g)
26006         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26007         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26008         offset=$(lseek_test -d 0 $file.100g)
26009         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26010         return 0
26011 }
26012 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26013
26014 test_430c() {
26015         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26016                 skip "OST does not support SEEK_HOLE"
26017
26018         local file=$DIR/$tdir/$tfile
26019         local start
26020
26021         mkdir -p $DIR/$tdir
26022         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26023
26024         # cp version 8.33+ prefers lseek over fiemap
26025         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26026                 start=$SECONDS
26027                 time cp $file /dev/null
26028                 (( SECONDS - start < 5 )) ||
26029                         error "cp: too long runtime $((SECONDS - start))"
26030
26031         fi
26032         # tar version 1.29+ supports SEEK_HOLE/DATA
26033         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26034                 start=$SECONDS
26035                 time tar cS $file - | cat > /dev/null
26036                 (( SECONDS - start < 5 )) ||
26037                         error "tar: too long runtime $((SECONDS - start))"
26038         fi
26039 }
26040 run_test 430c "lseek: external tools check"
26041
26042 test_431() { # LU-14187
26043         local file=$DIR/$tdir/$tfile
26044
26045         mkdir -p $DIR/$tdir
26046         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26047         dd if=/dev/urandom of=$file bs=4k count=1
26048         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26049         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26050         #define OBD_FAIL_OST_RESTART_IO 0x251
26051         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26052         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26053         cp $file $file.0
26054         cancel_lru_locks
26055         sync_all_data
26056         echo 3 > /proc/sys/vm/drop_caches
26057         diff  $file $file.0 || error "data diff"
26058 }
26059 run_test 431 "Restart transaction for IO"
26060
26061 cleanup_test_432() {
26062         do_facet mgs $LCTL nodemap_activate 0
26063         wait_nm_sync active
26064 }
26065
26066 test_432() {
26067         local tmpdir=$TMP/dir432
26068
26069         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26070                 skip "Need MDS version at least 2.14.52"
26071
26072         stack_trap cleanup_test_432 EXIT
26073         mkdir $DIR/$tdir
26074         mkdir $tmpdir
26075
26076         do_facet mgs $LCTL nodemap_activate 1
26077         wait_nm_sync active
26078         do_facet mgs $LCTL nodemap_modify --name default \
26079                 --property admin --value 1
26080         do_facet mgs $LCTL nodemap_modify --name default \
26081                 --property trusted --value 1
26082         cancel_lru_locks mdc
26083         wait_nm_sync default admin_nodemap
26084         wait_nm_sync default trusted_nodemap
26085
26086         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26087                grep -ci "Operation not permitted") -ne 0 ]; then
26088                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26089         fi
26090 }
26091 run_test 432 "mv dir from outside Lustre"
26092
26093 prep_801() {
26094         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26095         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26096                 skip "Need server version at least 2.9.55"
26097
26098         start_full_debug_logging
26099 }
26100
26101 post_801() {
26102         stop_full_debug_logging
26103 }
26104
26105 barrier_stat() {
26106         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26107                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26108                            awk '/The barrier for/ { print $7 }')
26109                 echo $st
26110         else
26111                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26112                 echo \'$st\'
26113         fi
26114 }
26115
26116 barrier_expired() {
26117         local expired
26118
26119         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26120                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26121                           awk '/will be expired/ { print $7 }')
26122         else
26123                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26124         fi
26125
26126         echo $expired
26127 }
26128
26129 test_801a() {
26130         prep_801
26131
26132         echo "Start barrier_freeze at: $(date)"
26133         #define OBD_FAIL_BARRIER_DELAY          0x2202
26134         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26135         # Do not reduce barrier time - See LU-11873
26136         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26137
26138         sleep 2
26139         local b_status=$(barrier_stat)
26140         echo "Got barrier status at: $(date)"
26141         [ "$b_status" = "'freezing_p1'" ] ||
26142                 error "(1) unexpected barrier status $b_status"
26143
26144         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26145         wait
26146         b_status=$(barrier_stat)
26147         [ "$b_status" = "'frozen'" ] ||
26148                 error "(2) unexpected barrier status $b_status"
26149
26150         local expired=$(barrier_expired)
26151         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26152         sleep $((expired + 3))
26153
26154         b_status=$(barrier_stat)
26155         [ "$b_status" = "'expired'" ] ||
26156                 error "(3) unexpected barrier status $b_status"
26157
26158         # Do not reduce barrier time - See LU-11873
26159         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26160                 error "(4) fail to freeze barrier"
26161
26162         b_status=$(barrier_stat)
26163         [ "$b_status" = "'frozen'" ] ||
26164                 error "(5) unexpected barrier status $b_status"
26165
26166         echo "Start barrier_thaw at: $(date)"
26167         #define OBD_FAIL_BARRIER_DELAY          0x2202
26168         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26169         do_facet mgs $LCTL barrier_thaw $FSNAME &
26170
26171         sleep 2
26172         b_status=$(barrier_stat)
26173         echo "Got barrier status at: $(date)"
26174         [ "$b_status" = "'thawing'" ] ||
26175                 error "(6) unexpected barrier status $b_status"
26176
26177         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26178         wait
26179         b_status=$(barrier_stat)
26180         [ "$b_status" = "'thawed'" ] ||
26181                 error "(7) unexpected barrier status $b_status"
26182
26183         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26184         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26185         do_facet mgs $LCTL barrier_freeze $FSNAME
26186
26187         b_status=$(barrier_stat)
26188         [ "$b_status" = "'failed'" ] ||
26189                 error "(8) unexpected barrier status $b_status"
26190
26191         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26192         do_facet mgs $LCTL barrier_thaw $FSNAME
26193
26194         post_801
26195 }
26196 run_test 801a "write barrier user interfaces and stat machine"
26197
26198 test_801b() {
26199         prep_801
26200
26201         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26202         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26203         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26204         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26205         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26206
26207         cancel_lru_locks mdc
26208
26209         # 180 seconds should be long enough
26210         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26211
26212         local b_status=$(barrier_stat)
26213         [ "$b_status" = "'frozen'" ] ||
26214                 error "(6) unexpected barrier status $b_status"
26215
26216         mkdir $DIR/$tdir/d0/d10 &
26217         mkdir_pid=$!
26218
26219         touch $DIR/$tdir/d1/f13 &
26220         touch_pid=$!
26221
26222         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26223         ln_pid=$!
26224
26225         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26226         mv_pid=$!
26227
26228         rm -f $DIR/$tdir/d4/f12 &
26229         rm_pid=$!
26230
26231         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26232
26233         # To guarantee taht the 'stat' is not blocked
26234         b_status=$(barrier_stat)
26235         [ "$b_status" = "'frozen'" ] ||
26236                 error "(8) unexpected barrier status $b_status"
26237
26238         # let above commands to run at background
26239         sleep 5
26240
26241         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26242         ps -p $touch_pid || error "(10) touch should be blocked"
26243         ps -p $ln_pid || error "(11) link should be blocked"
26244         ps -p $mv_pid || error "(12) rename should be blocked"
26245         ps -p $rm_pid || error "(13) unlink should be blocked"
26246
26247         b_status=$(barrier_stat)
26248         [ "$b_status" = "'frozen'" ] ||
26249                 error "(14) unexpected barrier status $b_status"
26250
26251         do_facet mgs $LCTL barrier_thaw $FSNAME
26252         b_status=$(barrier_stat)
26253         [ "$b_status" = "'thawed'" ] ||
26254                 error "(15) unexpected barrier status $b_status"
26255
26256         wait $mkdir_pid || error "(16) mkdir should succeed"
26257         wait $touch_pid || error "(17) touch should succeed"
26258         wait $ln_pid || error "(18) link should succeed"
26259         wait $mv_pid || error "(19) rename should succeed"
26260         wait $rm_pid || error "(20) unlink should succeed"
26261
26262         post_801
26263 }
26264 run_test 801b "modification will be blocked by write barrier"
26265
26266 test_801c() {
26267         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26268
26269         prep_801
26270
26271         stop mds2 || error "(1) Fail to stop mds2"
26272
26273         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26274
26275         local b_status=$(barrier_stat)
26276         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26277                 do_facet mgs $LCTL barrier_thaw $FSNAME
26278                 error "(2) unexpected barrier status $b_status"
26279         }
26280
26281         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26282                 error "(3) Fail to rescan barrier bitmap"
26283
26284         # Do not reduce barrier time - See LU-11873
26285         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26286
26287         b_status=$(barrier_stat)
26288         [ "$b_status" = "'frozen'" ] ||
26289                 error "(4) unexpected barrier status $b_status"
26290
26291         do_facet mgs $LCTL barrier_thaw $FSNAME
26292         b_status=$(barrier_stat)
26293         [ "$b_status" = "'thawed'" ] ||
26294                 error "(5) unexpected barrier status $b_status"
26295
26296         local devname=$(mdsdevname 2)
26297
26298         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26299
26300         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26301                 error "(7) Fail to rescan barrier bitmap"
26302
26303         post_801
26304 }
26305 run_test 801c "rescan barrier bitmap"
26306
26307 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26308 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26309 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26310 saved_MOUNT_OPTS=$MOUNT_OPTS
26311
26312 cleanup_802a() {
26313         trap 0
26314
26315         stopall
26316         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26317         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26318         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26319         MOUNT_OPTS=$saved_MOUNT_OPTS
26320         setupall
26321 }
26322
26323 test_802a() {
26324         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26325         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26326         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26327                 skip "Need server version at least 2.9.55"
26328
26329         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26330
26331         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26332
26333         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26334                 error "(2) Fail to copy"
26335
26336         trap cleanup_802a EXIT
26337
26338         # sync by force before remount as readonly
26339         sync; sync_all_data; sleep 3; sync_all_data
26340
26341         stopall
26342
26343         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26344         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26345         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26346
26347         echo "Mount the server as read only"
26348         setupall server_only || error "(3) Fail to start servers"
26349
26350         echo "Mount client without ro should fail"
26351         mount_client $MOUNT &&
26352                 error "(4) Mount client without 'ro' should fail"
26353
26354         echo "Mount client with ro should succeed"
26355         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26356         mount_client $MOUNT ||
26357                 error "(5) Mount client with 'ro' should succeed"
26358
26359         echo "Modify should be refused"
26360         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26361
26362         echo "Read should be allowed"
26363         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26364                 error "(7) Read should succeed under ro mode"
26365
26366         cleanup_802a
26367 }
26368 run_test 802a "simulate readonly device"
26369
26370 test_802b() {
26371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26372         remote_mds_nodsh && skip "remote MDS with nodsh"
26373
26374         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26375                 skip "readonly option not available"
26376
26377         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26378
26379         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26380                 error "(2) Fail to copy"
26381
26382         # write back all cached data before setting MDT to readonly
26383         cancel_lru_locks
26384         sync_all_data
26385
26386         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26387         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26388
26389         echo "Modify should be refused"
26390         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26391
26392         echo "Read should be allowed"
26393         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26394                 error "(7) Read should succeed under ro mode"
26395
26396         # disable readonly
26397         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26398 }
26399 run_test 802b "be able to set MDTs to readonly"
26400
26401 test_803a() {
26402         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26403         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26404                 skip "MDS needs to be newer than 2.10.54"
26405
26406         mkdir_on_mdt0 $DIR/$tdir
26407         # Create some objects on all MDTs to trigger related logs objects
26408         for idx in $(seq $MDSCOUNT); do
26409                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26410                         $DIR/$tdir/dir${idx} ||
26411                         error "Fail to create $DIR/$tdir/dir${idx}"
26412         done
26413
26414         sync; sleep 3
26415         wait_delete_completed # ensure old test cleanups are finished
26416         echo "before create:"
26417         $LFS df -i $MOUNT
26418         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26419
26420         for i in {1..10}; do
26421                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26422                         error "Fail to create $DIR/$tdir/foo$i"
26423         done
26424
26425         sync; sleep 3
26426         echo "after create:"
26427         $LFS df -i $MOUNT
26428         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26429
26430         # allow for an llog to be cleaned up during the test
26431         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26432                 error "before ($before_used) + 10 > after ($after_used)"
26433
26434         for i in {1..10}; do
26435                 rm -rf $DIR/$tdir/foo$i ||
26436                         error "Fail to remove $DIR/$tdir/foo$i"
26437         done
26438
26439         sleep 3 # avoid MDT return cached statfs
26440         wait_delete_completed
26441         echo "after unlink:"
26442         $LFS df -i $MOUNT
26443         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26444
26445         # allow for an llog to be created during the test
26446         [ $after_used -le $((before_used + 1)) ] ||
26447                 error "after ($after_used) > before ($before_used) + 1"
26448 }
26449 run_test 803a "verify agent object for remote object"
26450
26451 test_803b() {
26452         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26453         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26454                 skip "MDS needs to be newer than 2.13.56"
26455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26456
26457         for i in $(seq 0 $((MDSCOUNT - 1))); do
26458                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26459         done
26460
26461         local before=0
26462         local after=0
26463
26464         local tmp
26465
26466         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26467         for i in $(seq 0 $((MDSCOUNT - 1))); do
26468                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26469                         awk '/getattr/ { print $2 }')
26470                 before=$((before + tmp))
26471         done
26472         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26473         for i in $(seq 0 $((MDSCOUNT - 1))); do
26474                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26475                         awk '/getattr/ { print $2 }')
26476                 after=$((after + tmp))
26477         done
26478
26479         [ $before -eq $after ] || error "getattr count $before != $after"
26480 }
26481 run_test 803b "remote object can getattr from cache"
26482
26483 test_804() {
26484         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26485         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26486                 skip "MDS needs to be newer than 2.10.54"
26487         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26488
26489         mkdir -p $DIR/$tdir
26490         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26491                 error "Fail to create $DIR/$tdir/dir0"
26492
26493         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26494         local dev=$(mdsdevname 2)
26495
26496         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26497                 grep ${fid} || error "NOT found agent entry for dir0"
26498
26499         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26500                 error "Fail to create $DIR/$tdir/dir1"
26501
26502         touch $DIR/$tdir/dir1/foo0 ||
26503                 error "Fail to create $DIR/$tdir/dir1/foo0"
26504         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26505         local rc=0
26506
26507         for idx in $(seq $MDSCOUNT); do
26508                 dev=$(mdsdevname $idx)
26509                 do_facet mds${idx} \
26510                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26511                         grep ${fid} && rc=$idx
26512         done
26513
26514         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26515                 error "Fail to rename foo0 to foo1"
26516         if [ $rc -eq 0 ]; then
26517                 for idx in $(seq $MDSCOUNT); do
26518                         dev=$(mdsdevname $idx)
26519                         do_facet mds${idx} \
26520                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26521                         grep ${fid} && rc=$idx
26522                 done
26523         fi
26524
26525         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26526                 error "Fail to rename foo1 to foo2"
26527         if [ $rc -eq 0 ]; then
26528                 for idx in $(seq $MDSCOUNT); do
26529                         dev=$(mdsdevname $idx)
26530                         do_facet mds${idx} \
26531                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26532                         grep ${fid} && rc=$idx
26533                 done
26534         fi
26535
26536         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26537
26538         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26539                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26540         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26541                 error "Fail to rename foo2 to foo0"
26542         unlink $DIR/$tdir/dir1/foo0 ||
26543                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26544         rm -rf $DIR/$tdir/dir0 ||
26545                 error "Fail to rm $DIR/$tdir/dir0"
26546
26547         for idx in $(seq $MDSCOUNT); do
26548                 dev=$(mdsdevname $idx)
26549                 rc=0
26550
26551                 stop mds${idx}
26552                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26553                         rc=$?
26554                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26555                         error "mount mds$idx failed"
26556                 df $MOUNT > /dev/null 2>&1
26557
26558                 # e2fsck should not return error
26559                 [ $rc -eq 0 ] ||
26560                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26561         done
26562 }
26563 run_test 804 "verify agent entry for remote entry"
26564
26565 cleanup_805() {
26566         do_facet $SINGLEMDS zfs set quota=$old $fsset
26567         unlinkmany $DIR/$tdir/f- 1000000
26568         trap 0
26569 }
26570
26571 test_805() {
26572         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26573         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26574         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26575                 skip "netfree not implemented before 0.7"
26576         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26577                 skip "Need MDS version at least 2.10.57"
26578
26579         local fsset
26580         local freekb
26581         local usedkb
26582         local old
26583         local quota
26584         local pref="osd-zfs.$FSNAME-MDT0000."
26585
26586         # limit available space on MDS dataset to meet nospace issue
26587         # quickly. then ZFS 0.7.2 can use reserved space if asked
26588         # properly (using netfree flag in osd_declare_destroy()
26589         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26590         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26591                 gawk '{print $3}')
26592         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26593         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26594         let "usedkb=usedkb-freekb"
26595         let "freekb=freekb/2"
26596         if let "freekb > 5000"; then
26597                 let "freekb=5000"
26598         fi
26599         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26600         trap cleanup_805 EXIT
26601         mkdir_on_mdt0 $DIR/$tdir
26602         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26603                 error "Can't set PFL layout"
26604         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26605         rm -rf $DIR/$tdir || error "not able to remove"
26606         do_facet $SINGLEMDS zfs set quota=$old $fsset
26607         trap 0
26608 }
26609 run_test 805 "ZFS can remove from full fs"
26610
26611 # Size-on-MDS test
26612 check_lsom_data()
26613 {
26614         local file=$1
26615         local expect=$(stat -c %s $file)
26616
26617         check_lsom_size $1 $expect
26618
26619         local blocks=$($LFS getsom -b $file)
26620         expect=$(stat -c %b $file)
26621         [[ $blocks == $expect ]] ||
26622                 error "$file expected blocks: $expect, got: $blocks"
26623 }
26624
26625 check_lsom_size()
26626 {
26627         local size
26628         local expect=$2
26629
26630         cancel_lru_locks mdc
26631
26632         size=$($LFS getsom -s $1)
26633         [[ $size == $expect ]] ||
26634                 error "$file expected size: $expect, got: $size"
26635 }
26636
26637 test_806() {
26638         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26639                 skip "Need MDS version at least 2.11.52"
26640
26641         local bs=1048576
26642
26643         touch $DIR/$tfile || error "touch $tfile failed"
26644
26645         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26646         save_lustre_params client "llite.*.xattr_cache" > $save
26647         lctl set_param llite.*.xattr_cache=0
26648         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26649
26650         # single-threaded write
26651         echo "Test SOM for single-threaded write"
26652         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26653                 error "write $tfile failed"
26654         check_lsom_size $DIR/$tfile $bs
26655
26656         local num=32
26657         local size=$(($num * $bs))
26658         local offset=0
26659         local i
26660
26661         echo "Test SOM for single client multi-threaded($num) write"
26662         $TRUNCATE $DIR/$tfile 0
26663         for ((i = 0; i < $num; i++)); do
26664                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26665                 local pids[$i]=$!
26666                 offset=$((offset + $bs))
26667         done
26668         for (( i=0; i < $num; i++ )); do
26669                 wait ${pids[$i]}
26670         done
26671         check_lsom_size $DIR/$tfile $size
26672
26673         $TRUNCATE $DIR/$tfile 0
26674         for ((i = 0; i < $num; i++)); do
26675                 offset=$((offset - $bs))
26676                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26677                 local pids[$i]=$!
26678         done
26679         for (( i=0; i < $num; i++ )); do
26680                 wait ${pids[$i]}
26681         done
26682         check_lsom_size $DIR/$tfile $size
26683
26684         # multi-client writes
26685         num=$(get_node_count ${CLIENTS//,/ })
26686         size=$(($num * $bs))
26687         offset=0
26688         i=0
26689
26690         echo "Test SOM for multi-client ($num) writes"
26691         $TRUNCATE $DIR/$tfile 0
26692         for client in ${CLIENTS//,/ }; do
26693                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26694                 local pids[$i]=$!
26695                 i=$((i + 1))
26696                 offset=$((offset + $bs))
26697         done
26698         for (( i=0; i < $num; i++ )); do
26699                 wait ${pids[$i]}
26700         done
26701         check_lsom_size $DIR/$tfile $offset
26702
26703         i=0
26704         $TRUNCATE $DIR/$tfile 0
26705         for client in ${CLIENTS//,/ }; do
26706                 offset=$((offset - $bs))
26707                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26708                 local pids[$i]=$!
26709                 i=$((i + 1))
26710         done
26711         for (( i=0; i < $num; i++ )); do
26712                 wait ${pids[$i]}
26713         done
26714         check_lsom_size $DIR/$tfile $size
26715
26716         # verify truncate
26717         echo "Test SOM for truncate"
26718         $TRUNCATE $DIR/$tfile 1048576
26719         check_lsom_size $DIR/$tfile 1048576
26720         $TRUNCATE $DIR/$tfile 1234
26721         check_lsom_size $DIR/$tfile 1234
26722
26723         # verify SOM blocks count
26724         echo "Verify SOM block count"
26725         $TRUNCATE $DIR/$tfile 0
26726         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26727                 error "failed to write file $tfile"
26728         check_lsom_data $DIR/$tfile
26729 }
26730 run_test 806 "Verify Lazy Size on MDS"
26731
26732 test_807() {
26733         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26734         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26735                 skip "Need MDS version at least 2.11.52"
26736
26737         # Registration step
26738         changelog_register || error "changelog_register failed"
26739         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26740         changelog_users $SINGLEMDS | grep -q $cl_user ||
26741                 error "User $cl_user not found in changelog_users"
26742
26743         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26744         save_lustre_params client "llite.*.xattr_cache" > $save
26745         lctl set_param llite.*.xattr_cache=0
26746         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26747
26748         rm -rf $DIR/$tdir || error "rm $tdir failed"
26749         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26750         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26751         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26752         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26753                 error "truncate $tdir/trunc failed"
26754
26755         local bs=1048576
26756         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26757                 error "write $tfile failed"
26758
26759         # multi-client wirtes
26760         local num=$(get_node_count ${CLIENTS//,/ })
26761         local offset=0
26762         local i=0
26763
26764         echo "Test SOM for multi-client ($num) writes"
26765         touch $DIR/$tfile || error "touch $tfile failed"
26766         $TRUNCATE $DIR/$tfile 0
26767         for client in ${CLIENTS//,/ }; do
26768                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26769                 local pids[$i]=$!
26770                 i=$((i + 1))
26771                 offset=$((offset + $bs))
26772         done
26773         for (( i=0; i < $num; i++ )); do
26774                 wait ${pids[$i]}
26775         done
26776
26777         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26778         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26779         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26780         check_lsom_data $DIR/$tdir/trunc
26781         check_lsom_data $DIR/$tdir/single_dd
26782         check_lsom_data $DIR/$tfile
26783
26784         rm -rf $DIR/$tdir
26785         # Deregistration step
26786         changelog_deregister || error "changelog_deregister failed"
26787 }
26788 run_test 807 "verify LSOM syncing tool"
26789
26790 check_som_nologged()
26791 {
26792         local lines=$($LFS changelog $FSNAME-MDT0000 |
26793                 grep 'x=trusted.som' | wc -l)
26794         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26795 }
26796
26797 test_808() {
26798         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26799                 skip "Need MDS version at least 2.11.55"
26800
26801         # Registration step
26802         changelog_register || error "changelog_register failed"
26803
26804         touch $DIR/$tfile || error "touch $tfile failed"
26805         check_som_nologged
26806
26807         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26808                 error "write $tfile failed"
26809         check_som_nologged
26810
26811         $TRUNCATE $DIR/$tfile 1234
26812         check_som_nologged
26813
26814         $TRUNCATE $DIR/$tfile 1048576
26815         check_som_nologged
26816
26817         # Deregistration step
26818         changelog_deregister || error "changelog_deregister failed"
26819 }
26820 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26821
26822 check_som_nodata()
26823 {
26824         $LFS getsom $1
26825         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26826 }
26827
26828 test_809() {
26829         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26830                 skip "Need MDS version at least 2.11.56"
26831
26832         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26833                 error "failed to create DoM-only file $DIR/$tfile"
26834         touch $DIR/$tfile || error "touch $tfile failed"
26835         check_som_nodata $DIR/$tfile
26836
26837         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26838                 error "write $tfile failed"
26839         check_som_nodata $DIR/$tfile
26840
26841         $TRUNCATE $DIR/$tfile 1234
26842         check_som_nodata $DIR/$tfile
26843
26844         $TRUNCATE $DIR/$tfile 4097
26845         check_som_nodata $DIR/$file
26846 }
26847 run_test 809 "Verify no SOM xattr store for DoM-only files"
26848
26849 test_810() {
26850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26851         $GSS && skip_env "could not run with gss"
26852         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26853                 skip "OST < 2.12.58 doesn't align checksum"
26854
26855         set_checksums 1
26856         stack_trap "set_checksums $ORIG_CSUM" EXIT
26857         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26858
26859         local csum
26860         local before
26861         local after
26862         for csum in $CKSUM_TYPES; do
26863                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26864                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26865                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26866                         eval set -- $i
26867                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26868                         before=$(md5sum $DIR/$tfile)
26869                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26870                         after=$(md5sum $DIR/$tfile)
26871                         [ "$before" == "$after" ] ||
26872                                 error "$csum: $before != $after bs=$1 seek=$2"
26873                 done
26874         done
26875 }
26876 run_test 810 "partial page writes on ZFS (LU-11663)"
26877
26878 test_812a() {
26879         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26880                 skip "OST < 2.12.51 doesn't support this fail_loc"
26881
26882         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26883         # ensure ost1 is connected
26884         stat $DIR/$tfile >/dev/null || error "can't stat"
26885         wait_osc_import_state client ost1 FULL
26886         # no locks, no reqs to let the connection idle
26887         cancel_lru_locks osc
26888
26889         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26890 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26891         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26892         wait_osc_import_state client ost1 CONNECTING
26893         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26894
26895         stat $DIR/$tfile >/dev/null || error "can't stat file"
26896 }
26897 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26898
26899 test_812b() { # LU-12378
26900         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26901                 skip "OST < 2.12.51 doesn't support this fail_loc"
26902
26903         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26904         # ensure ost1 is connected
26905         stat $DIR/$tfile >/dev/null || error "can't stat"
26906         wait_osc_import_state client ost1 FULL
26907         # no locks, no reqs to let the connection idle
26908         cancel_lru_locks osc
26909
26910         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26911 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26912         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26913         wait_osc_import_state client ost1 CONNECTING
26914         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26915
26916         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26917         wait_osc_import_state client ost1 IDLE
26918 }
26919 run_test 812b "do not drop no resend request for idle connect"
26920
26921 test_812c() {
26922         local old
26923
26924         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26925
26926         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26927         $LFS getstripe $DIR/$tfile
26928         $LCTL set_param osc.*.idle_timeout=10
26929         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26930         # ensure ost1 is connected
26931         stat $DIR/$tfile >/dev/null || error "can't stat"
26932         wait_osc_import_state client ost1 FULL
26933         # no locks, no reqs to let the connection idle
26934         cancel_lru_locks osc
26935
26936 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26937         $LCTL set_param fail_loc=0x80000533
26938         sleep 15
26939         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26940 }
26941 run_test 812c "idle import vs lock enqueue race"
26942
26943 test_813() {
26944         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26945         [ -z "$file_heat_sav" ] && skip "no file heat support"
26946
26947         local readsample
26948         local writesample
26949         local readbyte
26950         local writebyte
26951         local readsample1
26952         local writesample1
26953         local readbyte1
26954         local writebyte1
26955
26956         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26957         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26958
26959         $LCTL set_param -n llite.*.file_heat=1
26960         echo "Turn on file heat"
26961         echo "Period second: $period_second, Decay percentage: $decay_pct"
26962
26963         echo "QQQQ" > $DIR/$tfile
26964         echo "QQQQ" > $DIR/$tfile
26965         echo "QQQQ" > $DIR/$tfile
26966         cat $DIR/$tfile > /dev/null
26967         cat $DIR/$tfile > /dev/null
26968         cat $DIR/$tfile > /dev/null
26969         cat $DIR/$tfile > /dev/null
26970
26971         local out=$($LFS heat_get $DIR/$tfile)
26972
26973         $LFS heat_get $DIR/$tfile
26974         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26975         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26976         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26977         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26978
26979         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26980         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26981         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26982         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26983
26984         sleep $((period_second + 3))
26985         echo "Sleep $((period_second + 3)) seconds..."
26986         # The recursion formula to calculate the heat of the file f is as
26987         # follow:
26988         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26989         # Where Hi is the heat value in the period between time points i*I and
26990         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26991         # to the weight of Ci.
26992         out=$($LFS heat_get $DIR/$tfile)
26993         $LFS heat_get $DIR/$tfile
26994         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26995         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26996         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26997         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26998
26999         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27000                 error "read sample ($readsample) is wrong"
27001         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27002                 error "write sample ($writesample) is wrong"
27003         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27004                 error "read bytes ($readbyte) is wrong"
27005         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27006                 error "write bytes ($writebyte) is wrong"
27007
27008         echo "QQQQ" > $DIR/$tfile
27009         echo "QQQQ" > $DIR/$tfile
27010         echo "QQQQ" > $DIR/$tfile
27011         cat $DIR/$tfile > /dev/null
27012         cat $DIR/$tfile > /dev/null
27013         cat $DIR/$tfile > /dev/null
27014         cat $DIR/$tfile > /dev/null
27015
27016         sleep $((period_second + 3))
27017         echo "Sleep $((period_second + 3)) seconds..."
27018
27019         out=$($LFS heat_get $DIR/$tfile)
27020         $LFS heat_get $DIR/$tfile
27021         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27022         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27023         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27024         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27025
27026         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27027                 4 * $decay_pct) / 100") -eq 1 ] ||
27028                 error "read sample ($readsample1) is wrong"
27029         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27030                 3 * $decay_pct) / 100") -eq 1 ] ||
27031                 error "write sample ($writesample1) is wrong"
27032         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27033                 20 * $decay_pct) / 100") -eq 1 ] ||
27034                 error "read bytes ($readbyte1) is wrong"
27035         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27036                 15 * $decay_pct) / 100") -eq 1 ] ||
27037                 error "write bytes ($writebyte1) is wrong"
27038
27039         echo "Turn off file heat for the file $DIR/$tfile"
27040         $LFS heat_set -o $DIR/$tfile
27041
27042         echo "QQQQ" > $DIR/$tfile
27043         echo "QQQQ" > $DIR/$tfile
27044         echo "QQQQ" > $DIR/$tfile
27045         cat $DIR/$tfile > /dev/null
27046         cat $DIR/$tfile > /dev/null
27047         cat $DIR/$tfile > /dev/null
27048         cat $DIR/$tfile > /dev/null
27049
27050         out=$($LFS heat_get $DIR/$tfile)
27051         $LFS heat_get $DIR/$tfile
27052         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27053         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27054         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27055         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27056
27057         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27058         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27059         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27060         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27061
27062         echo "Trun on file heat for the file $DIR/$tfile"
27063         $LFS heat_set -O $DIR/$tfile
27064
27065         echo "QQQQ" > $DIR/$tfile
27066         echo "QQQQ" > $DIR/$tfile
27067         echo "QQQQ" > $DIR/$tfile
27068         cat $DIR/$tfile > /dev/null
27069         cat $DIR/$tfile > /dev/null
27070         cat $DIR/$tfile > /dev/null
27071         cat $DIR/$tfile > /dev/null
27072
27073         out=$($LFS heat_get $DIR/$tfile)
27074         $LFS heat_get $DIR/$tfile
27075         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27076         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27077         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27078         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27079
27080         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27081         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27082         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27083         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27084
27085         $LFS heat_set -c $DIR/$tfile
27086         $LCTL set_param -n llite.*.file_heat=0
27087         echo "Turn off file heat support for the Lustre filesystem"
27088
27089         echo "QQQQ" > $DIR/$tfile
27090         echo "QQQQ" > $DIR/$tfile
27091         echo "QQQQ" > $DIR/$tfile
27092         cat $DIR/$tfile > /dev/null
27093         cat $DIR/$tfile > /dev/null
27094         cat $DIR/$tfile > /dev/null
27095         cat $DIR/$tfile > /dev/null
27096
27097         out=$($LFS heat_get $DIR/$tfile)
27098         $LFS heat_get $DIR/$tfile
27099         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27100         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27101         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27102         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27103
27104         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27105         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27106         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27107         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27108
27109         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27110         rm -f $DIR/$tfile
27111 }
27112 run_test 813 "File heat verfication"
27113
27114 test_814()
27115 {
27116         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27117         echo -n y >> $DIR/$tfile
27118         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27119         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27120 }
27121 run_test 814 "sparse cp works as expected (LU-12361)"
27122
27123 test_815()
27124 {
27125         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27126         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27127 }
27128 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27129
27130 test_816() {
27131         local ost1_imp=$(get_osc_import_name client ost1)
27132         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27133                          cut -d'.' -f2)
27134
27135         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27136         # ensure ost1 is connected
27137
27138         stat $DIR/$tfile >/dev/null || error "can't stat"
27139         wait_osc_import_state client ost1 FULL
27140         # no locks, no reqs to let the connection idle
27141         cancel_lru_locks osc
27142         lru_resize_disable osc
27143         local before
27144         local now
27145         before=$($LCTL get_param -n \
27146                  ldlm.namespaces.$imp_name.lru_size)
27147
27148         wait_osc_import_state client ost1 IDLE
27149         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27150         now=$($LCTL get_param -n \
27151               ldlm.namespaces.$imp_name.lru_size)
27152         [ $before == $now ] || error "lru_size changed $before != $now"
27153 }
27154 run_test 816 "do not reset lru_resize on idle reconnect"
27155
27156 cleanup_817() {
27157         umount $tmpdir
27158         exportfs -u localhost:$DIR/nfsexp
27159         rm -rf $DIR/nfsexp
27160 }
27161
27162 test_817() {
27163         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27164
27165         mkdir -p $DIR/nfsexp
27166         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27167                 error "failed to export nfs"
27168
27169         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27170         stack_trap cleanup_817 EXIT
27171
27172         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27173                 error "failed to mount nfs to $tmpdir"
27174
27175         cp /bin/true $tmpdir
27176         $DIR/nfsexp/true || error "failed to execute 'true' command"
27177 }
27178 run_test 817 "nfsd won't cache write lock for exec file"
27179
27180 test_818() {
27181         mkdir $DIR/$tdir
27182         $LFS setstripe -c1 -i0 $DIR/$tfile
27183         $LFS setstripe -c1 -i1 $DIR/$tfile
27184         stop $SINGLEMDS
27185         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27186         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27187         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27188                 error "start $SINGLEMDS failed"
27189         rm -rf $DIR/$tdir
27190 }
27191 run_test 818 "unlink with failed llog"
27192
27193 test_819a() {
27194         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27195         cancel_lru_locks osc
27196         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27197         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27198         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27199         rm -f $TDIR/$tfile
27200 }
27201 run_test 819a "too big niobuf in read"
27202
27203 test_819b() {
27204         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27205         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27206         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27207         cancel_lru_locks osc
27208         sleep 1
27209         rm -f $TDIR/$tfile
27210 }
27211 run_test 819b "too big niobuf in write"
27212
27213
27214 function test_820_start_ost() {
27215         sleep 5
27216
27217         for num in $(seq $OSTCOUNT); do
27218                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27219         done
27220 }
27221
27222 test_820() {
27223         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27224
27225         mkdir $DIR/$tdir
27226         umount_client $MOUNT || error "umount failed"
27227         for num in $(seq $OSTCOUNT); do
27228                 stop ost$num
27229         done
27230
27231         # mount client with no active OSTs
27232         # so that the client can't initialize max LOV EA size
27233         # from OSC notifications
27234         mount_client $MOUNT || error "mount failed"
27235         # delay OST starting to keep this 0 max EA size for a while
27236         test_820_start_ost &
27237
27238         # create a directory on MDS2
27239         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27240                 error "Failed to create directory"
27241         # open intent should update default EA size
27242         # see mdc_update_max_ea_from_body()
27243         # notice this is the very first RPC to MDS2
27244         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27245         ret=$?
27246         echo $out
27247         # With SSK, this situation can lead to -EPERM being returned.
27248         # In that case, simply retry.
27249         if [ $ret -ne 0 ] && $SHARED_KEY; then
27250                 if echo "$out" | grep -q "not permitted"; then
27251                         cp /etc/services $DIR/$tdir/mds2
27252                         ret=$?
27253                 fi
27254         fi
27255         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27256 }
27257 run_test 820 "update max EA from open intent"
27258
27259 test_822() {
27260         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27261
27262         save_lustre_params mds1 \
27263                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27264         do_facet $SINGLEMDS "$LCTL set_param -n \
27265                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27266         do_facet $SINGLEMDS "$LCTL set_param -n \
27267                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27268
27269         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27270         local maxage=$(do_facet mds1 $LCTL get_param -n \
27271                        osp.$FSNAME-OST0000*MDT0000.maxage)
27272         sleep $((maxage + 1))
27273
27274         #define OBD_FAIL_NET_ERROR_RPC          0x532
27275         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27276
27277         stack_trap "restore_lustre_params < $p; rm $p"
27278
27279         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27280                       osp.$FSNAME-OST0000*MDT0000.create_count")
27281         for i in $(seq 1 $count); do
27282                 touch $DIR/$tfile.${i} || error "touch failed"
27283         done
27284 }
27285 run_test 822 "test precreate failure"
27286
27287 #
27288 # tests that do cleanup/setup should be run at the end
27289 #
27290
27291 test_900() {
27292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27293         local ls
27294
27295         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27296         $LCTL set_param fail_loc=0x903
27297
27298         cancel_lru_locks MGC
27299
27300         FAIL_ON_ERROR=true cleanup
27301         FAIL_ON_ERROR=true setup
27302 }
27303 run_test 900 "umount should not race with any mgc requeue thread"
27304
27305 # LUS-6253/LU-11185
27306 test_901() {
27307         local oldc
27308         local newc
27309         local olds
27310         local news
27311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27312
27313         # some get_param have a bug to handle dot in param name
27314         cancel_lru_locks MGC
27315         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27316         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27317         umount_client $MOUNT || error "umount failed"
27318         mount_client $MOUNT || error "mount failed"
27319         cancel_lru_locks MGC
27320         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27321         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27322
27323         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27324         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27325
27326         return 0
27327 }
27328 run_test 901 "don't leak a mgc lock on client umount"
27329
27330 # LU-13377
27331 test_902() {
27332         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27333                 skip "client does not have LU-13377 fix"
27334         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27335         $LCTL set_param fail_loc=0x1415
27336         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27337         cancel_lru_locks osc
27338         rm -f $DIR/$tfile
27339 }
27340 run_test 902 "test short write doesn't hang lustre"
27341
27342 # LU-14711
27343 test_903() {
27344         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27345         echo "blah" > $DIR/${tfile}-2
27346         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27347         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27348         $LCTL set_param fail_loc=0x417 fail_val=20
27349
27350         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27351         sleep 1 # To start the destroy
27352         wait_destroy_complete 150 || error "Destroy taking too long"
27353         cat $DIR/$tfile > /dev/null || error "Evicted"
27354 }
27355 run_test 903 "Test long page discard does not cause evictions"
27356
27357 complete $SECONDS
27358 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27359 check_and_cleanup_lustre
27360 if [ "$I_MOUNTED" != "yes" ]; then
27361         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27362 fi
27363 exit_status