Whamcloud - gitweb
f8122990593e2e0f84c354fc6f464901d6dfcc68
[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         $LFS setstripe -C 4 $DIR/$tdir
3020
3021         echo 1 > $DIR/$tdir/${tfile}.1
3022         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3023         local setcount=4
3024         [ $count -eq $setcount ] ||
3025                 error "(1) stripe count $count, should be $setcount"
3026
3027         # Capture existing append_stripe_count setting for restore
3028         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3029         local mdts=$(comma_list $(mdts_nodes))
3030         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3031
3032         local appendcount=$orig_count
3033         echo 1 >> $DIR/$tdir/${tfile}.2_append
3034         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3035         [ $count -eq $appendcount ] ||
3036                 error "(2)stripe count $count, should be $appendcount for append"
3037
3038         # Disable O_APPEND striping, verify it works
3039         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3040
3041         # Should now get the default striping, which is 4
3042         setcount=4
3043         echo 1 >> $DIR/$tdir/${tfile}.3_append
3044         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3045         [ $count -eq $setcount ] ||
3046                 error "(3) stripe count $count, should be $setcount"
3047
3048         # Try changing the stripe count for append files
3049         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3050
3051         # Append striping is now 2 (directory default is still 4)
3052         appendcount=2
3053         echo 1 >> $DIR/$tdir/${tfile}.4_append
3054         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3055         [ $count -eq $appendcount ] ||
3056                 error "(4) stripe count $count, should be $appendcount for append"
3057
3058         # Test append stripe count of -1
3059         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3060         appendcount=$OSTCOUNT
3061         echo 1 >> $DIR/$tdir/${tfile}.5
3062         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3063         [ $count -eq $appendcount ] ||
3064                 error "(5) stripe count $count, should be $appendcount for append"
3065
3066         # Set append striping back to default of 1
3067         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3068
3069         # Try a new default striping, PFL + DOM
3070         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3071
3072         # Create normal DOM file, DOM returns stripe count == 0
3073         setcount=0
3074         touch $DIR/$tdir/${tfile}.6
3075         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3076         [ $count -eq $setcount ] ||
3077                 error "(6) stripe count $count, should be $setcount"
3078
3079         # Show
3080         appendcount=1
3081         echo 1 >> $DIR/$tdir/${tfile}.7_append
3082         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3083         [ $count -eq $appendcount ] ||
3084                 error "(7) stripe count $count, should be $appendcount for append"
3085
3086         # Clean up DOM layout
3087         $LFS setstripe -d $DIR/$tdir
3088
3089         # Now test that append striping works when layout is from root
3090         $LFS setstripe -c 2 $MOUNT
3091         # Make a special directory for this
3092         mkdir $DIR/${tdir}/${tdir}.2
3093         stack_trap "$LFS setstripe -d $MOUNT" EXIT
3094
3095         # Verify for normal file
3096         setcount=2
3097         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3098         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3099         [ $count -eq $setcount ] ||
3100                 error "(8) stripe count $count, should be $setcount"
3101
3102         appendcount=1
3103         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3104         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3105         [ $count -eq $appendcount ] ||
3106                 error "(9) stripe count $count, should be $appendcount for append"
3107
3108         # Now test O_APPEND striping with pools
3109         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3110         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3111
3112         # Create the pool
3113         pool_add $TESTNAME || error "pool creation failed"
3114         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3115
3116         echo 1 >> $DIR/$tdir/${tfile}.10_append
3117
3118         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3119         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3120
3121         # Check that count is still correct
3122         appendcount=1
3123         echo 1 >> $DIR/$tdir/${tfile}.11_append
3124         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3125         [ $count -eq $appendcount ] ||
3126                 error "(11) stripe count $count, should be $appendcount for append"
3127
3128         # Disable O_APPEND stripe count, verify pool works separately
3129         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3130
3131         echo 1 >> $DIR/$tdir/${tfile}.12_append
3132
3133         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3134         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3135
3136         # Remove pool setting, verify it's not applied
3137         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3138
3139         echo 1 >> $DIR/$tdir/${tfile}.13_append
3140
3141         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3142         [ "$pool" = "" ] || error "(13) pool found: $pool"
3143 }
3144 run_test 27M "test O_APPEND striping"
3145
3146 test_27N() {
3147         combined_mgs_mds && skip "needs separate MGS/MDT"
3148
3149         pool_add $TESTNAME || error "pool_add failed"
3150         do_facet mgs "$LCTL pool_list $FSNAME" |
3151                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3152                 error "lctl pool_list on MGS failed"
3153 }
3154 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3155
3156 clean_foreign_symlink() {
3157         trap 0
3158         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3159         for i in $DIR/$tdir/* ; do
3160                 $LFS unlink_foreign $i || true
3161         done
3162 }
3163
3164 test_27O() {
3165         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3166                 skip "Need MDS version newer than 2.12.51"
3167
3168         test_mkdir $DIR/$tdir
3169         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3170         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3171
3172         trap clean_foreign_symlink EXIT
3173
3174         # enable foreign_symlink behaviour
3175         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3176
3177         # foreign symlink LOV format is a partial path by default
3178
3179         # create foreign file (lfs + API)
3180         $LFS setstripe --foreign=symlink --flags 0xda05 \
3181                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3182                 error "$DIR/$tdir/${tfile}: create failed"
3183
3184         $LFS getstripe -v $DIR/$tdir/${tfile} |
3185                 grep "lfm_magic:.*0x0BD70BD0" ||
3186                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3187         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3188                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3189         $LFS getstripe -v $DIR/$tdir/${tfile} |
3190                 grep "lfm_flags:.*0x0000DA05" ||
3191                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3192         $LFS getstripe $DIR/$tdir/${tfile} |
3193                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3194                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3195
3196         # modify striping should fail
3197         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3198                 error "$DIR/$tdir/$tfile: setstripe should fail"
3199
3200         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3201         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3202         cat /etc/passwd > $DIR/$tdir/$tfile &&
3203                 error "$DIR/$tdir/$tfile: write should fail"
3204
3205         # rename should succeed
3206         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3207                 error "$DIR/$tdir/$tfile: rename has failed"
3208
3209         #remove foreign_symlink file should fail
3210         rm $DIR/$tdir/${tfile}.new &&
3211                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3212
3213         #test fake symlink
3214         mkdir /tmp/${uuid1} ||
3215                 error "/tmp/${uuid1}: mkdir has failed"
3216         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3217                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3218         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3219         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3220                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3221         #read should succeed now
3222         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3223                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3224         #write should succeed now
3225         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3226                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3227         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3228                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3229         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3230                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3231
3232         #check that getstripe still works
3233         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3234                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3235
3236         # chmod should still succeed
3237         chmod 644 $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3239
3240         # chown should still succeed
3241         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3242                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3243
3244         # rename should still succeed
3245         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3246                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3247
3248         #remove foreign_symlink file should still fail
3249         rm $DIR/$tdir/${tfile} &&
3250                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3251
3252         #use special ioctl() to unlink foreign_symlink file
3253         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3254                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3255
3256 }
3257 run_test 27O "basic ops on foreign file of symlink type"
3258
3259 test_27P() {
3260         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3261                 skip "Need MDS version newer than 2.12.49"
3262
3263         test_mkdir $DIR/$tdir
3264         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3265         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3266
3267         trap clean_foreign_symlink EXIT
3268
3269         # enable foreign_symlink behaviour
3270         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3271
3272         # foreign symlink LMV format is a partial path by default
3273
3274         # create foreign dir (lfs + API)
3275         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3276                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3277                 error "$DIR/$tdir/${tdir}: create failed"
3278
3279         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3280                 grep "lfm_magic:.*0x0CD50CD0" ||
3281                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3282         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3283                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3284         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3285                 grep "lfm_flags:.*0x0000DA05" ||
3286                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3287         $LFS getdirstripe $DIR/$tdir/${tdir} |
3288                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3289                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3290
3291         # file create in dir should fail
3292         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3293         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3294
3295         # rename should succeed
3296         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3297                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3298
3299         #remove foreign_symlink dir should fail
3300         rmdir $DIR/$tdir/${tdir}.new &&
3301                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3302
3303         #test fake symlink
3304         mkdir -p /tmp/${uuid1}/${uuid2} ||
3305                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3306         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3307                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3308         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3309         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3310                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3311         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3312                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3313
3314         #check that getstripe fails now that foreign_symlink enabled
3315         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3316                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3317
3318         # file create in dir should work now
3319         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3320                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3321         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3322                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3323         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3324                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3325
3326         # chmod should still succeed
3327         chmod 755 $DIR/$tdir/${tdir}.new ||
3328                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3329
3330         # chown should still succeed
3331         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3332                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3333
3334         # rename should still succeed
3335         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3336                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3337
3338         #remove foreign_symlink dir should still fail
3339         rmdir $DIR/$tdir/${tdir} &&
3340                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3341
3342         #use special ioctl() to unlink foreign_symlink file
3343         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3344                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3345
3346         #created file should still exist
3347         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3348                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3349         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3350                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3351 }
3352 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3353
3354 test_27Q() {
3355         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3356         stack_trap "rm -f $TMP/$tfile*"
3357
3358         test_mkdir $DIR/$tdir-1
3359         test_mkdir $DIR/$tdir-2
3360
3361         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3362         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3363
3364         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3365         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3366
3367         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3368         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3369
3370         # Create some bad symlinks and ensure that we don't loop
3371         # forever or something. These should return ELOOP (40) and
3372         # ENOENT (2) but I don't want to test for that because there's
3373         # always some weirdo architecture that needs to ruin
3374         # everything by defining these error numbers differently.
3375
3376         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3377         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3378
3379         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3380         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3381
3382         return 0
3383 }
3384 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3385
3386 # createtest also checks that device nodes are created and
3387 # then visible correctly (#2091)
3388 test_28() { # bug 2091
3389         test_mkdir $DIR/d28
3390         $CREATETEST $DIR/d28/ct || error "createtest failed"
3391 }
3392 run_test 28 "create/mknod/mkdir with bad file types ============"
3393
3394 test_29() {
3395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3396
3397         sync; sleep 1; sync # flush out any dirty pages from previous tests
3398         cancel_lru_locks
3399         test_mkdir $DIR/d29
3400         touch $DIR/d29/foo
3401         log 'first d29'
3402         ls -l $DIR/d29
3403
3404         declare -i LOCKCOUNTORIG=0
3405         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3406                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3407         done
3408         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3409
3410         declare -i LOCKUNUSEDCOUNTORIG=0
3411         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3412                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3413         done
3414
3415         log 'second d29'
3416         ls -l $DIR/d29
3417         log 'done'
3418
3419         declare -i LOCKCOUNTCURRENT=0
3420         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3421                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3422         done
3423
3424         declare -i LOCKUNUSEDCOUNTCURRENT=0
3425         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3426                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3427         done
3428
3429         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3430                 $LCTL set_param -n ldlm.dump_namespaces ""
3431                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3432                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3433                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3434                 return 2
3435         fi
3436         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3437                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3438                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3439                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3440                 return 3
3441         fi
3442 }
3443 run_test 29 "IT_GETATTR regression  ============================"
3444
3445 test_30a() { # was test_30
3446         cp $(which ls) $DIR || cp /bin/ls $DIR
3447         $DIR/ls / || error "Can't execute binary from lustre"
3448         rm $DIR/ls
3449 }
3450 run_test 30a "execute binary from Lustre (execve) =============="
3451
3452 test_30b() {
3453         cp `which ls` $DIR || cp /bin/ls $DIR
3454         chmod go+rx $DIR/ls
3455         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3456         rm $DIR/ls
3457 }
3458 run_test 30b "execute binary from Lustre as non-root ==========="
3459
3460 test_30c() { # b=22376
3461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3462
3463         cp $(which ls) $DIR || cp /bin/ls $DIR
3464         chmod a-rw $DIR/ls
3465         cancel_lru_locks mdc
3466         cancel_lru_locks osc
3467         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3468         rm -f $DIR/ls
3469 }
3470 run_test 30c "execute binary from Lustre without read perms ===="
3471
3472 test_30d() {
3473         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3474
3475         for i in {1..10}; do
3476                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3477                 local PID=$!
3478                 sleep 1
3479                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3480                 wait $PID || error "executing dd from Lustre failed"
3481                 rm -f $DIR/$tfile
3482         done
3483
3484         rm -f $DIR/dd
3485 }
3486 run_test 30d "execute binary from Lustre while clear locks"
3487
3488 test_31a() {
3489         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3490         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3491 }
3492 run_test 31a "open-unlink file =================================="
3493
3494 test_31b() {
3495         touch $DIR/f31 || error "touch $DIR/f31 failed"
3496         ln $DIR/f31 $DIR/f31b || error "ln failed"
3497         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3498         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3499 }
3500 run_test 31b "unlink file with multiple links while open ======="
3501
3502 test_31c() {
3503         touch $DIR/f31 || error "touch $DIR/f31 failed"
3504         ln $DIR/f31 $DIR/f31c || error "ln failed"
3505         multiop_bg_pause $DIR/f31 O_uc ||
3506                 error "multiop_bg_pause for $DIR/f31 failed"
3507         MULTIPID=$!
3508         $MULTIOP $DIR/f31c Ouc
3509         kill -USR1 $MULTIPID
3510         wait $MULTIPID
3511 }
3512 run_test 31c "open-unlink file with multiple links ============="
3513
3514 test_31d() {
3515         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3516         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3517 }
3518 run_test 31d "remove of open directory ========================="
3519
3520 test_31e() { # bug 2904
3521         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3522 }
3523 run_test 31e "remove of open non-empty directory ==============="
3524
3525 test_31f() { # bug 4554
3526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3527
3528         set -vx
3529         test_mkdir $DIR/d31f
3530         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3531         cp /etc/hosts $DIR/d31f
3532         ls -l $DIR/d31f
3533         $LFS getstripe $DIR/d31f/hosts
3534         multiop_bg_pause $DIR/d31f D_c || return 1
3535         MULTIPID=$!
3536
3537         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3538         test_mkdir $DIR/d31f
3539         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3540         cp /etc/hosts $DIR/d31f
3541         ls -l $DIR/d31f
3542         $LFS getstripe $DIR/d31f/hosts
3543         multiop_bg_pause $DIR/d31f D_c || return 1
3544         MULTIPID2=$!
3545
3546         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3547         wait $MULTIPID || error "first opendir $MULTIPID failed"
3548
3549         sleep 6
3550
3551         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3552         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3553         set +vx
3554 }
3555 run_test 31f "remove of open directory with open-unlink file ==="
3556
3557 test_31g() {
3558         echo "-- cross directory link --"
3559         test_mkdir -c1 $DIR/${tdir}ga
3560         test_mkdir -c1 $DIR/${tdir}gb
3561         touch $DIR/${tdir}ga/f
3562         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3563         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3564         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3565         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3566         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3567 }
3568 run_test 31g "cross directory link==============="
3569
3570 test_31h() {
3571         echo "-- cross directory link --"
3572         test_mkdir -c1 $DIR/${tdir}
3573         test_mkdir -c1 $DIR/${tdir}/dir
3574         touch $DIR/${tdir}/f
3575         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3576         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3577         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3578         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3579         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3580 }
3581 run_test 31h "cross directory link under child==============="
3582
3583 test_31i() {
3584         echo "-- cross directory link --"
3585         test_mkdir -c1 $DIR/$tdir
3586         test_mkdir -c1 $DIR/$tdir/dir
3587         touch $DIR/$tdir/dir/f
3588         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3589         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3590         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3591         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3592         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3593 }
3594 run_test 31i "cross directory link under parent==============="
3595
3596 test_31j() {
3597         test_mkdir -c1 -p $DIR/$tdir
3598         test_mkdir -c1 -p $DIR/$tdir/dir1
3599         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3600         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3601         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3602         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3603         return 0
3604 }
3605 run_test 31j "link for directory==============="
3606
3607 test_31k() {
3608         test_mkdir -c1 -p $DIR/$tdir
3609         touch $DIR/$tdir/s
3610         touch $DIR/$tdir/exist
3611         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3612         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3613         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3614         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3615         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3616         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3617         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3618         return 0
3619 }
3620 run_test 31k "link to file: the same, non-existing, dir==============="
3621
3622 test_31m() {
3623         mkdir $DIR/d31m
3624         touch $DIR/d31m/s
3625         mkdir $DIR/d31m2
3626         touch $DIR/d31m2/exist
3627         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3628         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3629         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3630         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3631         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3632         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3633         return 0
3634 }
3635 run_test 31m "link to file: the same, non-existing, dir==============="
3636
3637 test_31n() {
3638         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3639         nlink=$(stat --format=%h $DIR/$tfile)
3640         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3641         local fd=$(free_fd)
3642         local cmd="exec $fd<$DIR/$tfile"
3643         eval $cmd
3644         cmd="exec $fd<&-"
3645         trap "eval $cmd" EXIT
3646         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3647         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3648         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3649         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3650         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3651         eval $cmd
3652 }
3653 run_test 31n "check link count of unlinked file"
3654
3655 link_one() {
3656         local tempfile=$(mktemp $1_XXXXXX)
3657         mlink $tempfile $1 2> /dev/null &&
3658                 echo "$BASHPID: link $tempfile to $1 succeeded"
3659         munlink $tempfile
3660 }
3661
3662 test_31o() { # LU-2901
3663         test_mkdir $DIR/$tdir
3664         for LOOP in $(seq 100); do
3665                 rm -f $DIR/$tdir/$tfile*
3666                 for THREAD in $(seq 8); do
3667                         link_one $DIR/$tdir/$tfile.$LOOP &
3668                 done
3669                 wait
3670                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3671                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3672                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3673                         break || true
3674         done
3675 }
3676 run_test 31o "duplicate hard links with same filename"
3677
3678 test_31p() {
3679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3680
3681         test_mkdir $DIR/$tdir
3682         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3683         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3684
3685         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3686                 error "open unlink test1 failed"
3687         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3688                 error "open unlink test2 failed"
3689
3690         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3691                 error "test1 still exists"
3692         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3693                 error "test2 still exists"
3694 }
3695 run_test 31p "remove of open striped directory"
3696
3697 test_31q() {
3698         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3699
3700         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3701         index=$($LFS getdirstripe -i $DIR/$tdir)
3702         [ $index -eq 3 ] || error "first stripe index $index != 3"
3703         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3704         [ $index -eq 1 ] || error "second stripe index $index != 1"
3705
3706         # when "-c <stripe_count>" is set, the number of MDTs specified after
3707         # "-i" should equal to the stripe count
3708         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3709 }
3710 run_test 31q "create striped directory on specific MDTs"
3711
3712 cleanup_test32_mount() {
3713         local rc=0
3714         trap 0
3715         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3716         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3717         losetup -d $loopdev || true
3718         rm -rf $DIR/$tdir
3719         return $rc
3720 }
3721
3722 test_32a() {
3723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3724
3725         echo "== more mountpoints and symlinks ================="
3726         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3727         trap cleanup_test32_mount EXIT
3728         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3729         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3730                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3731         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3732                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3733         cleanup_test32_mount
3734 }
3735 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3736
3737 test_32b() {
3738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3739
3740         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3741         trap cleanup_test32_mount EXIT
3742         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3743         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3744                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3745         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3746                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3747         cleanup_test32_mount
3748 }
3749 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3750
3751 test_32c() {
3752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3753
3754         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3755         trap cleanup_test32_mount EXIT
3756         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3757         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3758                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3759         test_mkdir -p $DIR/$tdir/d2/test_dir
3760         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3761                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3762         cleanup_test32_mount
3763 }
3764 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3765
3766 test_32d() {
3767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3768
3769         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3770         trap cleanup_test32_mount EXIT
3771         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3772         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3773                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3774         test_mkdir -p $DIR/$tdir/d2/test_dir
3775         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3776                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3777         cleanup_test32_mount
3778 }
3779 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3780
3781 test_32e() {
3782         rm -fr $DIR/$tdir
3783         test_mkdir -p $DIR/$tdir/tmp
3784         local tmp_dir=$DIR/$tdir/tmp
3785         ln -s $DIR/$tdir $tmp_dir/symlink11
3786         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3787         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3788         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3789 }
3790 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3791
3792 test_32f() {
3793         rm -fr $DIR/$tdir
3794         test_mkdir -p $DIR/$tdir/tmp
3795         local tmp_dir=$DIR/$tdir/tmp
3796         ln -s $DIR/$tdir $tmp_dir/symlink11
3797         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3798         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3799         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3800 }
3801 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3802
3803 test_32g() {
3804         local tmp_dir=$DIR/$tdir/tmp
3805         test_mkdir -p $tmp_dir
3806         test_mkdir $DIR/${tdir}2
3807         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3808         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3809         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3810         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3811         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3812         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3813 }
3814 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3815
3816 test_32h() {
3817         rm -fr $DIR/$tdir $DIR/${tdir}2
3818         tmp_dir=$DIR/$tdir/tmp
3819         test_mkdir -p $tmp_dir
3820         test_mkdir $DIR/${tdir}2
3821         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3822         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3823         ls $tmp_dir/symlink12 || error "listing symlink12"
3824         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3825 }
3826 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3827
3828 test_32i() {
3829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3830
3831         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3832         trap cleanup_test32_mount EXIT
3833         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3834         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3835                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3836         touch $DIR/$tdir/test_file
3837         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3838                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3839         cleanup_test32_mount
3840 }
3841 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3842
3843 test_32j() {
3844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3845
3846         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3847         trap cleanup_test32_mount EXIT
3848         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3849         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3850                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3851         touch $DIR/$tdir/test_file
3852         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3853                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3854         cleanup_test32_mount
3855 }
3856 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3857
3858 test_32k() {
3859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3860
3861         rm -fr $DIR/$tdir
3862         trap cleanup_test32_mount EXIT
3863         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3864         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3865                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3866         test_mkdir -p $DIR/$tdir/d2
3867         touch $DIR/$tdir/d2/test_file || error "touch failed"
3868         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3869                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3870         cleanup_test32_mount
3871 }
3872 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3873
3874 test_32l() {
3875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3876
3877         rm -fr $DIR/$tdir
3878         trap cleanup_test32_mount EXIT
3879         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3880         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3881                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3882         test_mkdir -p $DIR/$tdir/d2
3883         touch $DIR/$tdir/d2/test_file || error "touch failed"
3884         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3885                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3886         cleanup_test32_mount
3887 }
3888 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3889
3890 test_32m() {
3891         rm -fr $DIR/d32m
3892         test_mkdir -p $DIR/d32m/tmp
3893         TMP_DIR=$DIR/d32m/tmp
3894         ln -s $DIR $TMP_DIR/symlink11
3895         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3896         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3897                 error "symlink11 not a link"
3898         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3899                 error "symlink01 not a link"
3900 }
3901 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3902
3903 test_32n() {
3904         rm -fr $DIR/d32n
3905         test_mkdir -p $DIR/d32n/tmp
3906         TMP_DIR=$DIR/d32n/tmp
3907         ln -s $DIR $TMP_DIR/symlink11
3908         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3909         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3910         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3911 }
3912 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3913
3914 test_32o() {
3915         touch $DIR/$tfile
3916         test_mkdir -p $DIR/d32o/tmp
3917         TMP_DIR=$DIR/d32o/tmp
3918         ln -s $DIR/$tfile $TMP_DIR/symlink12
3919         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3920         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3921                 error "symlink12 not a link"
3922         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3923         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3924                 error "$DIR/d32o/tmp/symlink12 not file type"
3925         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3926                 error "$DIR/d32o/symlink02 not file type"
3927 }
3928 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3929
3930 test_32p() {
3931         log 32p_1
3932         rm -fr $DIR/d32p
3933         log 32p_2
3934         rm -f $DIR/$tfile
3935         log 32p_3
3936         touch $DIR/$tfile
3937         log 32p_4
3938         test_mkdir -p $DIR/d32p/tmp
3939         log 32p_5
3940         TMP_DIR=$DIR/d32p/tmp
3941         log 32p_6
3942         ln -s $DIR/$tfile $TMP_DIR/symlink12
3943         log 32p_7
3944         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3945         log 32p_8
3946         cat $DIR/d32p/tmp/symlink12 ||
3947                 error "Can't open $DIR/d32p/tmp/symlink12"
3948         log 32p_9
3949         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3950         log 32p_10
3951 }
3952 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3953
3954 test_32q() {
3955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3956
3957         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3958         trap cleanup_test32_mount EXIT
3959         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3960         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3961         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3962                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3963         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3964         cleanup_test32_mount
3965 }
3966 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3967
3968 test_32r() {
3969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3970
3971         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3972         trap cleanup_test32_mount EXIT
3973         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3974         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3975         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3976                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3977         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3978         cleanup_test32_mount
3979 }
3980 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3981
3982 test_33aa() {
3983         rm -f $DIR/$tfile
3984         touch $DIR/$tfile
3985         chmod 444 $DIR/$tfile
3986         chown $RUNAS_ID $DIR/$tfile
3987         log 33_1
3988         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3989         log 33_2
3990 }
3991 run_test 33aa "write file with mode 444 (should return error)"
3992
3993 test_33a() {
3994         rm -fr $DIR/$tdir
3995         test_mkdir $DIR/$tdir
3996         chown $RUNAS_ID $DIR/$tdir
3997         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3998                 error "$RUNAS create $tdir/$tfile failed"
3999         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4000                 error "open RDWR" || true
4001 }
4002 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4003
4004 test_33b() {
4005         rm -fr $DIR/$tdir
4006         test_mkdir $DIR/$tdir
4007         chown $RUNAS_ID $DIR/$tdir
4008         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4009 }
4010 run_test 33b "test open file with malformed flags (No panic)"
4011
4012 test_33c() {
4013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4014         remote_ost_nodsh && skip "remote OST with nodsh"
4015
4016         local ostnum
4017         local ostname
4018         local write_bytes
4019         local all_zeros
4020
4021         all_zeros=true
4022         test_mkdir $DIR/$tdir
4023         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4024
4025         sync
4026         for ostnum in $(seq $OSTCOUNT); do
4027                 # test-framework's OST numbering is one-based, while Lustre's
4028                 # is zero-based
4029                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4030                 # check if at least some write_bytes stats are counted
4031                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4032                               obdfilter.$ostname.stats |
4033                               awk '/^write_bytes/ {print $7}' )
4034                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4035                 if (( ${write_bytes:-0} > 0 )); then
4036                         all_zeros=false
4037                         break
4038                 fi
4039         done
4040
4041         $all_zeros || return 0
4042
4043         # Write four bytes
4044         echo foo > $DIR/$tdir/bar
4045         # Really write them
4046         sync
4047
4048         # Total up write_bytes after writing.  We'd better find non-zeros.
4049         for ostnum in $(seq $OSTCOUNT); do
4050                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4051                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4052                               obdfilter/$ostname/stats |
4053                               awk '/^write_bytes/ {print $7}' )
4054                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4055                 if (( ${write_bytes:-0} > 0 )); then
4056                         all_zeros=false
4057                         break
4058                 fi
4059         done
4060
4061         if $all_zeros; then
4062                 for ostnum in $(seq $OSTCOUNT); do
4063                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4064                         echo "Check write_bytes is in obdfilter.*.stats:"
4065                         do_facet ost$ostnum lctl get_param -n \
4066                                 obdfilter.$ostname.stats
4067                 done
4068                 error "OST not keeping write_bytes stats (b=22312)"
4069         fi
4070 }
4071 run_test 33c "test write_bytes stats"
4072
4073 test_33d() {
4074         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4076
4077         local MDTIDX=1
4078         local remote_dir=$DIR/$tdir/remote_dir
4079
4080         test_mkdir $DIR/$tdir
4081         $LFS mkdir -i $MDTIDX $remote_dir ||
4082                 error "create remote directory failed"
4083
4084         touch $remote_dir/$tfile
4085         chmod 444 $remote_dir/$tfile
4086         chown $RUNAS_ID $remote_dir/$tfile
4087
4088         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4089
4090         chown $RUNAS_ID $remote_dir
4091         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4092                                         error "create" || true
4093         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4094                                     error "open RDWR" || true
4095         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4096 }
4097 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4098
4099 test_33e() {
4100         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4101
4102         mkdir $DIR/$tdir
4103
4104         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4105         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4106         mkdir $DIR/$tdir/local_dir
4107
4108         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4109         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4110         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4111
4112         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4113                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4114
4115         rmdir $DIR/$tdir/* || error "rmdir failed"
4116
4117         umask 777
4118         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4119         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4120         mkdir $DIR/$tdir/local_dir
4121
4122         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4123         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4124         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4125
4126         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4127                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4128
4129         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4130
4131         umask 000
4132         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4133         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4134         mkdir $DIR/$tdir/local_dir
4135
4136         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4137         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4138         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4139
4140         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4141                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4142 }
4143 run_test 33e "mkdir and striped directory should have same mode"
4144
4145 cleanup_33f() {
4146         trap 0
4147         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4148 }
4149
4150 test_33f() {
4151         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4152         remote_mds_nodsh && skip "remote MDS with nodsh"
4153
4154         mkdir $DIR/$tdir
4155         chmod go+rwx $DIR/$tdir
4156         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4157         trap cleanup_33f EXIT
4158
4159         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4160                 error "cannot create striped directory"
4161
4162         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4163                 error "cannot create files in striped directory"
4164
4165         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4166                 error "cannot remove files in striped directory"
4167
4168         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4169                 error "cannot remove striped directory"
4170
4171         cleanup_33f
4172 }
4173 run_test 33f "nonroot user can create, access, and remove a striped directory"
4174
4175 test_33g() {
4176         mkdir -p $DIR/$tdir/dir2
4177
4178         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4179         echo $err
4180         [[ $err =~ "exists" ]] || error "Not exists error"
4181 }
4182 run_test 33g "nonroot user create already existing root created file"
4183
4184 test_33h() {
4185         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4186         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4187                 skip "Need MDS version at least 2.13.50"
4188
4189         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4190                 error "mkdir $tdir failed"
4191         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4192
4193         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4194         local index2
4195
4196         for fname in $DIR/$tdir/$tfile.bak \
4197                      $DIR/$tdir/$tfile.SAV \
4198                      $DIR/$tdir/$tfile.orig \
4199                      $DIR/$tdir/$tfile~; do
4200                 touch $fname  || error "touch $fname failed"
4201                 index2=$($LFS getstripe -m $fname)
4202                 [ $index -eq $index2 ] ||
4203                         error "$fname MDT index mismatch $index != $index2"
4204         done
4205
4206         local failed=0
4207         for i in {1..250}; do
4208                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4209                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4210                         touch $fname  || error "touch $fname failed"
4211                         index2=$($LFS getstripe -m $fname)
4212                         if [[ $index != $index2 ]]; then
4213                                 failed=$((failed + 1))
4214                                 echo "$fname MDT index mismatch $index != $index2"
4215                         fi
4216                 done
4217         done
4218         echo "$failed MDT index mismatches"
4219         (( failed < 20 )) || error "MDT index mismatch $failed times"
4220
4221 }
4222 run_test 33h "temp file is located on the same MDT as target"
4223
4224 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4225 test_34a() {
4226         rm -f $DIR/f34
4227         $MCREATE $DIR/f34 || error "mcreate failed"
4228         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4229                 error "getstripe failed"
4230         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4231         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4232                 error "getstripe failed"
4233         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4234                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4235 }
4236 run_test 34a "truncate file that has not been opened ==========="
4237
4238 test_34b() {
4239         [ ! -f $DIR/f34 ] && test_34a
4240         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4241                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4242         $OPENFILE -f O_RDONLY $DIR/f34
4243         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4244                 error "getstripe failed"
4245         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4246                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4247 }
4248 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4249
4250 test_34c() {
4251         [ ! -f $DIR/f34 ] && test_34a
4252         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4253                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4254         $OPENFILE -f O_RDWR $DIR/f34
4255         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4256                 error "$LFS getstripe failed"
4257         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4258                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4259 }
4260 run_test 34c "O_RDWR opening file-with-size works =============="
4261
4262 test_34d() {
4263         [ ! -f $DIR/f34 ] && test_34a
4264         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4265                 error "dd failed"
4266         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4267                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4268         rm $DIR/f34
4269 }
4270 run_test 34d "write to sparse file ============================="
4271
4272 test_34e() {
4273         rm -f $DIR/f34e
4274         $MCREATE $DIR/f34e || error "mcreate failed"
4275         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4276         $CHECKSTAT -s 1000 $DIR/f34e ||
4277                 error "Size of $DIR/f34e not equal to 1000 bytes"
4278         $OPENFILE -f O_RDWR $DIR/f34e
4279         $CHECKSTAT -s 1000 $DIR/f34e ||
4280                 error "Size of $DIR/f34e not equal to 1000 bytes"
4281 }
4282 run_test 34e "create objects, some with size and some without =="
4283
4284 test_34f() { # bug 6242, 6243
4285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4286
4287         SIZE34F=48000
4288         rm -f $DIR/f34f
4289         $MCREATE $DIR/f34f || error "mcreate failed"
4290         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4291         dd if=$DIR/f34f of=$TMP/f34f
4292         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4293         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4294         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4295         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4296         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4297 }
4298 run_test 34f "read from a file with no objects until EOF ======="
4299
4300 test_34g() {
4301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4302
4303         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4304                 error "dd failed"
4305         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4306         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4307                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4308         cancel_lru_locks osc
4309         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4310                 error "wrong size after lock cancel"
4311
4312         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4313         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4314                 error "expanding truncate failed"
4315         cancel_lru_locks osc
4316         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4317                 error "wrong expanded size after lock cancel"
4318 }
4319 run_test 34g "truncate long file ==============================="
4320
4321 test_34h() {
4322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4323
4324         local gid=10
4325         local sz=1000
4326
4327         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4328         sync # Flush the cache so that multiop below does not block on cache
4329              # flush when getting the group lock
4330         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4331         MULTIPID=$!
4332
4333         # Since just timed wait is not good enough, let's do a sync write
4334         # that way we are sure enough time for a roundtrip + processing
4335         # passed + 2 seconds of extra margin.
4336         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4337         rm $DIR/${tfile}-1
4338         sleep 2
4339
4340         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4341                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4342                 kill -9 $MULTIPID
4343         fi
4344         wait $MULTIPID
4345         local nsz=`stat -c %s $DIR/$tfile`
4346         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4347 }
4348 run_test 34h "ftruncate file under grouplock should not block"
4349
4350 test_35a() {
4351         cp /bin/sh $DIR/f35a
4352         chmod 444 $DIR/f35a
4353         chown $RUNAS_ID $DIR/f35a
4354         $RUNAS $DIR/f35a && error || true
4355         rm $DIR/f35a
4356 }
4357 run_test 35a "exec file with mode 444 (should return and not leak)"
4358
4359 test_36a() {
4360         rm -f $DIR/f36
4361         utime $DIR/f36 || error "utime failed for MDS"
4362 }
4363 run_test 36a "MDS utime check (mknod, utime)"
4364
4365 test_36b() {
4366         echo "" > $DIR/f36
4367         utime $DIR/f36 || error "utime failed for OST"
4368 }
4369 run_test 36b "OST utime check (open, utime)"
4370
4371 test_36c() {
4372         rm -f $DIR/d36/f36
4373         test_mkdir $DIR/d36
4374         chown $RUNAS_ID $DIR/d36
4375         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4376 }
4377 run_test 36c "non-root MDS utime check (mknod, utime)"
4378
4379 test_36d() {
4380         [ ! -d $DIR/d36 ] && test_36c
4381         echo "" > $DIR/d36/f36
4382         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4383 }
4384 run_test 36d "non-root OST utime check (open, utime)"
4385
4386 test_36e() {
4387         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4388
4389         test_mkdir $DIR/$tdir
4390         touch $DIR/$tdir/$tfile
4391         $RUNAS utime $DIR/$tdir/$tfile &&
4392                 error "utime worked, expected failure" || true
4393 }
4394 run_test 36e "utime on non-owned file (should return error)"
4395
4396 subr_36fh() {
4397         local fl="$1"
4398         local LANG_SAVE=$LANG
4399         local LC_LANG_SAVE=$LC_LANG
4400         export LANG=C LC_LANG=C # for date language
4401
4402         DATESTR="Dec 20  2000"
4403         test_mkdir $DIR/$tdir
4404         lctl set_param fail_loc=$fl
4405         date; date +%s
4406         cp /etc/hosts $DIR/$tdir/$tfile
4407         sync & # write RPC generated with "current" inode timestamp, but delayed
4408         sleep 1
4409         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4410         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4411         cancel_lru_locks $OSC
4412         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4413         date; date +%s
4414         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4415                 echo "BEFORE: $LS_BEFORE" && \
4416                 echo "AFTER : $LS_AFTER" && \
4417                 echo "WANT  : $DATESTR" && \
4418                 error "$DIR/$tdir/$tfile timestamps changed" || true
4419
4420         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4421 }
4422
4423 test_36f() {
4424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4425
4426         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4427         subr_36fh "0x80000214"
4428 }
4429 run_test 36f "utime on file racing with OST BRW write =========="
4430
4431 test_36g() {
4432         remote_ost_nodsh && skip "remote OST with nodsh"
4433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4434         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4435                 skip "Need MDS version at least 2.12.51"
4436
4437         local fmd_max_age
4438         local fmd
4439         local facet="ost1"
4440         local tgt="obdfilter"
4441
4442         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4443
4444         test_mkdir $DIR/$tdir
4445         fmd_max_age=$(do_facet $facet \
4446                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4447                 head -n 1")
4448
4449         echo "FMD max age: ${fmd_max_age}s"
4450         touch $DIR/$tdir/$tfile
4451         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4452                 gawk '{cnt=cnt+$1}  END{print cnt}')
4453         echo "FMD before: $fmd"
4454         [[ $fmd == 0 ]] &&
4455                 error "FMD wasn't create by touch"
4456         sleep $((fmd_max_age + 12))
4457         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4458                 gawk '{cnt=cnt+$1}  END{print cnt}')
4459         echo "FMD after: $fmd"
4460         [[ $fmd == 0 ]] ||
4461                 error "FMD wasn't expired by ping"
4462 }
4463 run_test 36g "FMD cache expiry ====================="
4464
4465 test_36h() {
4466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4467
4468         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4469         subr_36fh "0x80000227"
4470 }
4471 run_test 36h "utime on file racing with OST BRW write =========="
4472
4473 test_36i() {
4474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4475
4476         test_mkdir $DIR/$tdir
4477         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4478
4479         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4480         local new_mtime=$((mtime + 200))
4481
4482         #change Modify time of striped dir
4483         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4484                         error "change mtime failed"
4485
4486         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4487
4488         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4489 }
4490 run_test 36i "change mtime on striped directory"
4491
4492 # test_37 - duplicate with tests 32q 32r
4493
4494 test_38() {
4495         local file=$DIR/$tfile
4496         touch $file
4497         openfile -f O_DIRECTORY $file
4498         local RC=$?
4499         local ENOTDIR=20
4500         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4501         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4502 }
4503 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4504
4505 test_39a() { # was test_39
4506         touch $DIR/$tfile
4507         touch $DIR/${tfile}2
4508 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4509 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4510 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4511         sleep 2
4512         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4513         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4514                 echo "mtime"
4515                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4516                 echo "atime"
4517                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4518                 echo "ctime"
4519                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4520                 error "O_TRUNC didn't change timestamps"
4521         fi
4522 }
4523 run_test 39a "mtime changed on create"
4524
4525 test_39b() {
4526         test_mkdir -c1 $DIR/$tdir
4527         cp -p /etc/passwd $DIR/$tdir/fopen
4528         cp -p /etc/passwd $DIR/$tdir/flink
4529         cp -p /etc/passwd $DIR/$tdir/funlink
4530         cp -p /etc/passwd $DIR/$tdir/frename
4531         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4532
4533         sleep 1
4534         echo "aaaaaa" >> $DIR/$tdir/fopen
4535         echo "aaaaaa" >> $DIR/$tdir/flink
4536         echo "aaaaaa" >> $DIR/$tdir/funlink
4537         echo "aaaaaa" >> $DIR/$tdir/frename
4538
4539         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4540         local link_new=`stat -c %Y $DIR/$tdir/flink`
4541         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4542         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4543
4544         cat $DIR/$tdir/fopen > /dev/null
4545         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4546         rm -f $DIR/$tdir/funlink2
4547         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4548
4549         for (( i=0; i < 2; i++ )) ; do
4550                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4551                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4552                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4553                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4554
4555                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4556                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4557                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4558                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4559
4560                 cancel_lru_locks $OSC
4561                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4562         done
4563 }
4564 run_test 39b "mtime change on open, link, unlink, rename  ======"
4565
4566 # this should be set to past
4567 TEST_39_MTIME=`date -d "1 year ago" +%s`
4568
4569 # bug 11063
4570 test_39c() {
4571         touch $DIR1/$tfile
4572         sleep 2
4573         local mtime0=`stat -c %Y $DIR1/$tfile`
4574
4575         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4576         local mtime1=`stat -c %Y $DIR1/$tfile`
4577         [ "$mtime1" = $TEST_39_MTIME ] || \
4578                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4579
4580         local d1=`date +%s`
4581         echo hello >> $DIR1/$tfile
4582         local d2=`date +%s`
4583         local mtime2=`stat -c %Y $DIR1/$tfile`
4584         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4585                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4586
4587         mv $DIR1/$tfile $DIR1/$tfile-1
4588
4589         for (( i=0; i < 2; i++ )) ; do
4590                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4591                 [ "$mtime2" = "$mtime3" ] || \
4592                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4593
4594                 cancel_lru_locks $OSC
4595                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4596         done
4597 }
4598 run_test 39c "mtime change on rename ==========================="
4599
4600 # bug 21114
4601 test_39d() {
4602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4603
4604         touch $DIR1/$tfile
4605         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4606
4607         for (( i=0; i < 2; i++ )) ; do
4608                 local mtime=`stat -c %Y $DIR1/$tfile`
4609                 [ $mtime = $TEST_39_MTIME ] || \
4610                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4611
4612                 cancel_lru_locks $OSC
4613                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4614         done
4615 }
4616 run_test 39d "create, utime, stat =============================="
4617
4618 # bug 21114
4619 test_39e() {
4620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4621
4622         touch $DIR1/$tfile
4623         local mtime1=`stat -c %Y $DIR1/$tfile`
4624
4625         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4626
4627         for (( i=0; i < 2; i++ )) ; do
4628                 local mtime2=`stat -c %Y $DIR1/$tfile`
4629                 [ $mtime2 = $TEST_39_MTIME ] || \
4630                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4631
4632                 cancel_lru_locks $OSC
4633                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4634         done
4635 }
4636 run_test 39e "create, stat, utime, stat ========================"
4637
4638 # bug 21114
4639 test_39f() {
4640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4641
4642         touch $DIR1/$tfile
4643         mtime1=`stat -c %Y $DIR1/$tfile`
4644
4645         sleep 2
4646         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4647
4648         for (( i=0; i < 2; i++ )) ; do
4649                 local mtime2=`stat -c %Y $DIR1/$tfile`
4650                 [ $mtime2 = $TEST_39_MTIME ] || \
4651                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4652
4653                 cancel_lru_locks $OSC
4654                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4655         done
4656 }
4657 run_test 39f "create, stat, sleep, utime, stat ================="
4658
4659 # bug 11063
4660 test_39g() {
4661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4662
4663         echo hello >> $DIR1/$tfile
4664         local mtime1=`stat -c %Y $DIR1/$tfile`
4665
4666         sleep 2
4667         chmod o+r $DIR1/$tfile
4668
4669         for (( i=0; i < 2; i++ )) ; do
4670                 local mtime2=`stat -c %Y $DIR1/$tfile`
4671                 [ "$mtime1" = "$mtime2" ] || \
4672                         error "lost mtime: $mtime2, should be $mtime1"
4673
4674                 cancel_lru_locks $OSC
4675                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4676         done
4677 }
4678 run_test 39g "write, chmod, stat ==============================="
4679
4680 # bug 11063
4681 test_39h() {
4682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4683
4684         touch $DIR1/$tfile
4685         sleep 1
4686
4687         local d1=`date`
4688         echo hello >> $DIR1/$tfile
4689         local mtime1=`stat -c %Y $DIR1/$tfile`
4690
4691         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4692         local d2=`date`
4693         if [ "$d1" != "$d2" ]; then
4694                 echo "write and touch not within one second"
4695         else
4696                 for (( i=0; i < 2; i++ )) ; do
4697                         local mtime2=`stat -c %Y $DIR1/$tfile`
4698                         [ "$mtime2" = $TEST_39_MTIME ] || \
4699                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4700
4701                         cancel_lru_locks $OSC
4702                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4703                 done
4704         fi
4705 }
4706 run_test 39h "write, utime within one second, stat ============="
4707
4708 test_39i() {
4709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4710
4711         touch $DIR1/$tfile
4712         sleep 1
4713
4714         echo hello >> $DIR1/$tfile
4715         local mtime1=`stat -c %Y $DIR1/$tfile`
4716
4717         mv $DIR1/$tfile $DIR1/$tfile-1
4718
4719         for (( i=0; i < 2; i++ )) ; do
4720                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4721
4722                 [ "$mtime1" = "$mtime2" ] || \
4723                         error "lost mtime: $mtime2, should be $mtime1"
4724
4725                 cancel_lru_locks $OSC
4726                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4727         done
4728 }
4729 run_test 39i "write, rename, stat =============================="
4730
4731 test_39j() {
4732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4733
4734         start_full_debug_logging
4735         touch $DIR1/$tfile
4736         sleep 1
4737
4738         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4739         lctl set_param fail_loc=0x80000412
4740         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4741                 error "multiop failed"
4742         local multipid=$!
4743         local mtime1=`stat -c %Y $DIR1/$tfile`
4744
4745         mv $DIR1/$tfile $DIR1/$tfile-1
4746
4747         kill -USR1 $multipid
4748         wait $multipid || error "multiop close failed"
4749
4750         for (( i=0; i < 2; i++ )) ; do
4751                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4752                 [ "$mtime1" = "$mtime2" ] ||
4753                         error "mtime is lost on close: $mtime2, " \
4754                               "should be $mtime1"
4755
4756                 cancel_lru_locks
4757                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4758         done
4759         lctl set_param fail_loc=0
4760         stop_full_debug_logging
4761 }
4762 run_test 39j "write, rename, close, stat ======================="
4763
4764 test_39k() {
4765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4766
4767         touch $DIR1/$tfile
4768         sleep 1
4769
4770         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4771         local multipid=$!
4772         local mtime1=`stat -c %Y $DIR1/$tfile`
4773
4774         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4775
4776         kill -USR1 $multipid
4777         wait $multipid || error "multiop close failed"
4778
4779         for (( i=0; i < 2; i++ )) ; do
4780                 local mtime2=`stat -c %Y $DIR1/$tfile`
4781
4782                 [ "$mtime2" = $TEST_39_MTIME ] || \
4783                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4784
4785                 cancel_lru_locks
4786                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4787         done
4788 }
4789 run_test 39k "write, utime, close, stat ========================"
4790
4791 # this should be set to future
4792 TEST_39_ATIME=`date -d "1 year" +%s`
4793
4794 test_39l() {
4795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4796         remote_mds_nodsh && skip "remote MDS with nodsh"
4797
4798         local atime_diff=$(do_facet $SINGLEMDS \
4799                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4800         rm -rf $DIR/$tdir
4801         mkdir_on_mdt0 $DIR/$tdir
4802
4803         # test setting directory atime to future
4804         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4805         local atime=$(stat -c %X $DIR/$tdir)
4806         [ "$atime" = $TEST_39_ATIME ] ||
4807                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4808
4809         # test setting directory atime from future to now
4810         local now=$(date +%s)
4811         touch -a -d @$now $DIR/$tdir
4812
4813         atime=$(stat -c %X $DIR/$tdir)
4814         [ "$atime" -eq "$now"  ] ||
4815                 error "atime is not updated from future: $atime, $now"
4816
4817         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4818         sleep 3
4819
4820         # test setting directory atime when now > dir atime + atime_diff
4821         local d1=$(date +%s)
4822         ls $DIR/$tdir
4823         local d2=$(date +%s)
4824         cancel_lru_locks mdc
4825         atime=$(stat -c %X $DIR/$tdir)
4826         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4827                 error "atime is not updated  : $atime, should be $d2"
4828
4829         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4830         sleep 3
4831
4832         # test not setting directory atime when now < dir atime + atime_diff
4833         ls $DIR/$tdir
4834         cancel_lru_locks mdc
4835         atime=$(stat -c %X $DIR/$tdir)
4836         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4837                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4838
4839         do_facet $SINGLEMDS \
4840                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4841 }
4842 run_test 39l "directory atime update ==========================="
4843
4844 test_39m() {
4845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4846
4847         touch $DIR1/$tfile
4848         sleep 2
4849         local far_past_mtime=$(date -d "May 29 1953" +%s)
4850         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4851
4852         touch -m -d @$far_past_mtime $DIR1/$tfile
4853         touch -a -d @$far_past_atime $DIR1/$tfile
4854
4855         for (( i=0; i < 2; i++ )) ; do
4856                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4857                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4858                         error "atime or mtime set incorrectly"
4859
4860                 cancel_lru_locks $OSC
4861                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4862         done
4863 }
4864 run_test 39m "test atime and mtime before 1970"
4865
4866 test_39n() { # LU-3832
4867         remote_mds_nodsh && skip "remote MDS with nodsh"
4868
4869         local atime_diff=$(do_facet $SINGLEMDS \
4870                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4871         local atime0
4872         local atime1
4873         local atime2
4874
4875         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4876
4877         rm -rf $DIR/$tfile
4878         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4879         atime0=$(stat -c %X $DIR/$tfile)
4880
4881         sleep 5
4882         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4883         atime1=$(stat -c %X $DIR/$tfile)
4884
4885         sleep 5
4886         cancel_lru_locks mdc
4887         cancel_lru_locks osc
4888         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4889         atime2=$(stat -c %X $DIR/$tfile)
4890
4891         do_facet $SINGLEMDS \
4892                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4893
4894         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4895         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4896 }
4897 run_test 39n "check that O_NOATIME is honored"
4898
4899 test_39o() {
4900         TESTDIR=$DIR/$tdir/$tfile
4901         [ -e $TESTDIR ] && rm -rf $TESTDIR
4902         mkdir -p $TESTDIR
4903         cd $TESTDIR
4904         links1=2
4905         ls
4906         mkdir a b
4907         ls
4908         links2=$(stat -c %h .)
4909         [ $(($links1 + 2)) != $links2 ] &&
4910                 error "wrong links count $(($links1 + 2)) != $links2"
4911         rmdir b
4912         links3=$(stat -c %h .)
4913         [ $(($links1 + 1)) != $links3 ] &&
4914                 error "wrong links count $links1 != $links3"
4915         return 0
4916 }
4917 run_test 39o "directory cached attributes updated after create"
4918
4919 test_39p() {
4920         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4921
4922         local MDTIDX=1
4923         TESTDIR=$DIR/$tdir/$tdir
4924         [ -e $TESTDIR ] && rm -rf $TESTDIR
4925         test_mkdir -p $TESTDIR
4926         cd $TESTDIR
4927         links1=2
4928         ls
4929         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4930         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4931         ls
4932         links2=$(stat -c %h .)
4933         [ $(($links1 + 2)) != $links2 ] &&
4934                 error "wrong links count $(($links1 + 2)) != $links2"
4935         rmdir remote_dir2
4936         links3=$(stat -c %h .)
4937         [ $(($links1 + 1)) != $links3 ] &&
4938                 error "wrong links count $links1 != $links3"
4939         return 0
4940 }
4941 run_test 39p "remote directory cached attributes updated after create ========"
4942
4943 test_39r() {
4944         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4945                 skip "no atime update on old OST"
4946         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4947                 skip_env "ldiskfs only test"
4948         fi
4949
4950         local saved_adiff
4951         saved_adiff=$(do_facet ost1 \
4952                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4953         stack_trap "do_facet ost1 \
4954                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4955
4956         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4957
4958         $LFS setstripe -i 0 $DIR/$tfile
4959         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4960                 error "can't write initial file"
4961         cancel_lru_locks osc
4962
4963         # exceed atime_diff and access file
4964         sleep 6
4965         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4966                 error "can't udpate atime"
4967
4968         local atime_cli=$(stat -c %X $DIR/$tfile)
4969         echo "client atime: $atime_cli"
4970         # allow atime update to be written to device
4971         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4972         sleep 5
4973
4974         local ostdev=$(ostdevname 1)
4975         local fid=($(lfs getstripe -y $DIR/$tfile |
4976                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4977         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4978         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4979
4980         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4981         local atime_ost=$(do_facet ost1 "$cmd" |&
4982                           awk -F'[: ]' '/atime:/ { print $4 }')
4983         (( atime_cli == atime_ost )) ||
4984                 error "atime on client $atime_cli != ost $atime_ost"
4985 }
4986 run_test 39r "lazy atime update on OST"
4987
4988 test_39q() { # LU-8041
4989         local testdir=$DIR/$tdir
4990         mkdir -p $testdir
4991         multiop_bg_pause $testdir D_c || error "multiop failed"
4992         local multipid=$!
4993         cancel_lru_locks mdc
4994         kill -USR1 $multipid
4995         local atime=$(stat -c %X $testdir)
4996         [ "$atime" -ne 0 ] || error "atime is zero"
4997 }
4998 run_test 39q "close won't zero out atime"
4999
5000 test_40() {
5001         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5002         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5003                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5004         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5005                 error "$tfile is not 4096 bytes in size"
5006 }
5007 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5008
5009 test_41() {
5010         # bug 1553
5011         small_write $DIR/f41 18
5012 }
5013 run_test 41 "test small file write + fstat ====================="
5014
5015 count_ost_writes() {
5016         lctl get_param -n ${OSC}.*.stats |
5017                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5018                         END { printf("%0.0f", writes) }'
5019 }
5020
5021 # decent default
5022 WRITEBACK_SAVE=500
5023 DIRTY_RATIO_SAVE=40
5024 MAX_DIRTY_RATIO=50
5025 BG_DIRTY_RATIO_SAVE=10
5026 MAX_BG_DIRTY_RATIO=25
5027
5028 start_writeback() {
5029         trap 0
5030         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5031         # dirty_ratio, dirty_background_ratio
5032         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5033                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5034                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5035                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5036         else
5037                 # if file not here, we are a 2.4 kernel
5038                 kill -CONT `pidof kupdated`
5039         fi
5040 }
5041
5042 stop_writeback() {
5043         # setup the trap first, so someone cannot exit the test at the
5044         # exact wrong time and mess up a machine
5045         trap start_writeback EXIT
5046         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5047         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5048                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5049                 sysctl -w vm.dirty_writeback_centisecs=0
5050                 sysctl -w vm.dirty_writeback_centisecs=0
5051                 # save and increase /proc/sys/vm/dirty_ratio
5052                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5053                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5054                 # save and increase /proc/sys/vm/dirty_background_ratio
5055                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5056                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5057         else
5058                 # if file not here, we are a 2.4 kernel
5059                 kill -STOP `pidof kupdated`
5060         fi
5061 }
5062
5063 # ensure that all stripes have some grant before we test client-side cache
5064 setup_test42() {
5065         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5066                 dd if=/dev/zero of=$i bs=4k count=1
5067                 rm $i
5068         done
5069 }
5070
5071 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5072 # file truncation, and file removal.
5073 test_42a() {
5074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5075
5076         setup_test42
5077         cancel_lru_locks $OSC
5078         stop_writeback
5079         sync; sleep 1; sync # just to be safe
5080         BEFOREWRITES=`count_ost_writes`
5081         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5082         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5083         AFTERWRITES=`count_ost_writes`
5084         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5085                 error "$BEFOREWRITES < $AFTERWRITES"
5086         start_writeback
5087 }
5088 run_test 42a "ensure that we don't flush on close"
5089
5090 test_42b() {
5091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5092
5093         setup_test42
5094         cancel_lru_locks $OSC
5095         stop_writeback
5096         sync
5097         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5098         BEFOREWRITES=$(count_ost_writes)
5099         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5100         AFTERWRITES=$(count_ost_writes)
5101         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5102                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5103         fi
5104         BEFOREWRITES=$(count_ost_writes)
5105         sync || error "sync: $?"
5106         AFTERWRITES=$(count_ost_writes)
5107         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5108                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5109         fi
5110         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5111         start_writeback
5112         return 0
5113 }
5114 run_test 42b "test destroy of file with cached dirty data ======"
5115
5116 # if these tests just want to test the effect of truncation,
5117 # they have to be very careful.  consider:
5118 # - the first open gets a {0,EOF}PR lock
5119 # - the first write conflicts and gets a {0, count-1}PW
5120 # - the rest of the writes are under {count,EOF}PW
5121 # - the open for truncate tries to match a {0,EOF}PR
5122 #   for the filesize and cancels the PWs.
5123 # any number of fixes (don't get {0,EOF} on open, match
5124 # composite locks, do smarter file size management) fix
5125 # this, but for now we want these tests to verify that
5126 # the cancellation with truncate intent works, so we
5127 # start the file with a full-file pw lock to match against
5128 # until the truncate.
5129 trunc_test() {
5130         test=$1
5131         file=$DIR/$test
5132         offset=$2
5133         cancel_lru_locks $OSC
5134         stop_writeback
5135         # prime the file with 0,EOF PW to match
5136         touch $file
5137         $TRUNCATE $file 0
5138         sync; sync
5139         # now the real test..
5140         dd if=/dev/zero of=$file bs=1024 count=100
5141         BEFOREWRITES=`count_ost_writes`
5142         $TRUNCATE $file $offset
5143         cancel_lru_locks $OSC
5144         AFTERWRITES=`count_ost_writes`
5145         start_writeback
5146 }
5147
5148 test_42c() {
5149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5150
5151         trunc_test 42c 1024
5152         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5153                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5154         rm $file
5155 }
5156 run_test 42c "test partial truncate of file with cached dirty data"
5157
5158 test_42d() {
5159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5160
5161         trunc_test 42d 0
5162         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5163                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5164         rm $file
5165 }
5166 run_test 42d "test complete truncate of file with cached dirty data"
5167
5168 test_42e() { # bug22074
5169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5170
5171         local TDIR=$DIR/${tdir}e
5172         local pages=16 # hardcoded 16 pages, don't change it.
5173         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5174         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5175         local max_dirty_mb
5176         local warmup_files
5177
5178         test_mkdir $DIR/${tdir}e
5179         $LFS setstripe -c 1 $TDIR
5180         createmany -o $TDIR/f $files
5181
5182         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5183
5184         # we assume that with $OSTCOUNT files, at least one of them will
5185         # be allocated on OST0.
5186         warmup_files=$((OSTCOUNT * max_dirty_mb))
5187         createmany -o $TDIR/w $warmup_files
5188
5189         # write a large amount of data into one file and sync, to get good
5190         # avail_grant number from OST.
5191         for ((i=0; i<$warmup_files; i++)); do
5192                 idx=$($LFS getstripe -i $TDIR/w$i)
5193                 [ $idx -ne 0 ] && continue
5194                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5195                 break
5196         done
5197         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5198         sync
5199         $LCTL get_param $proc_osc0/cur_dirty_bytes
5200         $LCTL get_param $proc_osc0/cur_grant_bytes
5201
5202         # create as much dirty pages as we can while not to trigger the actual
5203         # RPCs directly. but depends on the env, VFS may trigger flush during this
5204         # period, hopefully we are good.
5205         for ((i=0; i<$warmup_files; i++)); do
5206                 idx=$($LFS getstripe -i $TDIR/w$i)
5207                 [ $idx -ne 0 ] && continue
5208                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5209         done
5210         $LCTL get_param $proc_osc0/cur_dirty_bytes
5211         $LCTL get_param $proc_osc0/cur_grant_bytes
5212
5213         # perform the real test
5214         $LCTL set_param $proc_osc0/rpc_stats 0
5215         for ((;i<$files; i++)); do
5216                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5217                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5218         done
5219         sync
5220         $LCTL get_param $proc_osc0/rpc_stats
5221
5222         local percent=0
5223         local have_ppr=false
5224         $LCTL get_param $proc_osc0/rpc_stats |
5225                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5226                         # skip lines until we are at the RPC histogram data
5227                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5228                         $have_ppr || continue
5229
5230                         # we only want the percent stat for < 16 pages
5231                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5232
5233                         percent=$((percent + WPCT))
5234                         if [[ $percent -gt 15 ]]; then
5235                                 error "less than 16-pages write RPCs" \
5236                                       "$percent% > 15%"
5237                                 break
5238                         fi
5239                 done
5240         rm -rf $TDIR
5241 }
5242 run_test 42e "verify sub-RPC writes are not done synchronously"
5243
5244 test_43A() { # was test_43
5245         test_mkdir $DIR/$tdir
5246         cp -p /bin/ls $DIR/$tdir/$tfile
5247         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5248         pid=$!
5249         # give multiop a chance to open
5250         sleep 1
5251
5252         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5253         kill -USR1 $pid
5254         # Wait for multiop to exit
5255         wait $pid
5256 }
5257 run_test 43A "execution of file opened for write should return -ETXTBSY"
5258
5259 test_43a() {
5260         test_mkdir $DIR/$tdir
5261         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5262         $DIR/$tdir/sleep 60 &
5263         SLEEP_PID=$!
5264         # Make sure exec of $tdir/sleep wins race with truncate
5265         sleep 1
5266         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5267         kill $SLEEP_PID
5268 }
5269 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5270
5271 test_43b() {
5272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5273
5274         test_mkdir $DIR/$tdir
5275         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5276         $DIR/$tdir/sleep 60 &
5277         SLEEP_PID=$!
5278         # Make sure exec of $tdir/sleep wins race with truncate
5279         sleep 1
5280         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5281         kill $SLEEP_PID
5282 }
5283 run_test 43b "truncate of file being executed should return -ETXTBSY"
5284
5285 test_43c() {
5286         local testdir="$DIR/$tdir"
5287         test_mkdir $testdir
5288         cp $SHELL $testdir/
5289         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5290                 ( cd $testdir && md5sum -c )
5291 }
5292 run_test 43c "md5sum of copy into lustre"
5293
5294 test_44A() { # was test_44
5295         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5296
5297         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5298         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5299 }
5300 run_test 44A "zero length read from a sparse stripe"
5301
5302 test_44a() {
5303         local nstripe=$($LFS getstripe -c -d $DIR)
5304         [ -z "$nstripe" ] && skip "can't get stripe info"
5305         [[ $nstripe -gt $OSTCOUNT ]] &&
5306                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5307
5308         local stride=$($LFS getstripe -S -d $DIR)
5309         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5310                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5311         fi
5312
5313         OFFSETS="0 $((stride/2)) $((stride-1))"
5314         for offset in $OFFSETS; do
5315                 for i in $(seq 0 $((nstripe-1))); do
5316                         local GLOBALOFFSETS=""
5317                         # size in Bytes
5318                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5319                         local myfn=$DIR/d44a-$size
5320                         echo "--------writing $myfn at $size"
5321                         ll_sparseness_write $myfn $size ||
5322                                 error "ll_sparseness_write"
5323                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5324                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5325                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5326
5327                         for j in $(seq 0 $((nstripe-1))); do
5328                                 # size in Bytes
5329                                 size=$((((j + $nstripe )*$stride + $offset)))
5330                                 ll_sparseness_write $myfn $size ||
5331                                         error "ll_sparseness_write"
5332                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5333                         done
5334                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5335                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5336                         rm -f $myfn
5337                 done
5338         done
5339 }
5340 run_test 44a "test sparse pwrite ==============================="
5341
5342 dirty_osc_total() {
5343         tot=0
5344         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5345                 tot=$(($tot + $d))
5346         done
5347         echo $tot
5348 }
5349 do_dirty_record() {
5350         before=`dirty_osc_total`
5351         echo executing "\"$*\""
5352         eval $*
5353         after=`dirty_osc_total`
5354         echo before $before, after $after
5355 }
5356 test_45() {
5357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5358
5359         f="$DIR/f45"
5360         # Obtain grants from OST if it supports it
5361         echo blah > ${f}_grant
5362         stop_writeback
5363         sync
5364         do_dirty_record "echo blah > $f"
5365         [[ $before -eq $after ]] && error "write wasn't cached"
5366         do_dirty_record "> $f"
5367         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5368         do_dirty_record "echo blah > $f"
5369         [[ $before -eq $after ]] && error "write wasn't cached"
5370         do_dirty_record "sync"
5371         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5372         do_dirty_record "echo blah > $f"
5373         [[ $before -eq $after ]] && error "write wasn't cached"
5374         do_dirty_record "cancel_lru_locks osc"
5375         [[ $before -gt $after ]] ||
5376                 error "lock cancellation didn't lower dirty count"
5377         start_writeback
5378 }
5379 run_test 45 "osc io page accounting ============================"
5380
5381 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5382 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5383 # objects offset and an assert hit when an rpc was built with 1023's mapped
5384 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5385 test_46() {
5386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5387
5388         f="$DIR/f46"
5389         stop_writeback
5390         sync
5391         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5392         sync
5393         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5394         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5395         sync
5396         start_writeback
5397 }
5398 run_test 46 "dirtying a previously written page ================"
5399
5400 # test_47 is removed "Device nodes check" is moved to test_28
5401
5402 test_48a() { # bug 2399
5403         [ "$mds1_FSTYPE" = "zfs" ] &&
5404         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5405                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5406
5407         test_mkdir $DIR/$tdir
5408         cd $DIR/$tdir
5409         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5410         test_mkdir $DIR/$tdir
5411         touch foo || error "'touch foo' failed after recreating cwd"
5412         test_mkdir bar
5413         touch .foo || error "'touch .foo' failed after recreating cwd"
5414         test_mkdir .bar
5415         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5416         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5417         cd . || error "'cd .' failed after recreating cwd"
5418         mkdir . && error "'mkdir .' worked after recreating cwd"
5419         rmdir . && error "'rmdir .' worked after recreating cwd"
5420         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5421         cd .. || error "'cd ..' failed after recreating cwd"
5422 }
5423 run_test 48a "Access renamed working dir (should return errors)="
5424
5425 test_48b() { # bug 2399
5426         rm -rf $DIR/$tdir
5427         test_mkdir $DIR/$tdir
5428         cd $DIR/$tdir
5429         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5430         touch foo && error "'touch foo' worked after removing cwd"
5431         mkdir foo && error "'mkdir foo' worked after removing cwd"
5432         touch .foo && error "'touch .foo' worked after removing cwd"
5433         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5434         ls . > /dev/null && error "'ls .' worked after removing cwd"
5435         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5436         mkdir . && error "'mkdir .' worked after removing cwd"
5437         rmdir . && error "'rmdir .' worked after removing cwd"
5438         ln -s . foo && error "'ln -s .' worked after removing cwd"
5439         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5440 }
5441 run_test 48b "Access removed working dir (should return errors)="
5442
5443 test_48c() { # bug 2350
5444         #lctl set_param debug=-1
5445         #set -vx
5446         rm -rf $DIR/$tdir
5447         test_mkdir -p $DIR/$tdir/dir
5448         cd $DIR/$tdir/dir
5449         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5450         $TRACE touch foo && error "touch foo worked after removing cwd"
5451         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5452         touch .foo && error "touch .foo worked after removing cwd"
5453         mkdir .foo && error "mkdir .foo worked after removing cwd"
5454         $TRACE ls . && error "'ls .' worked after removing cwd"
5455         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5456         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5457         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5458         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5459         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5460 }
5461 run_test 48c "Access removed working subdir (should return errors)"
5462
5463 test_48d() { # bug 2350
5464         #lctl set_param debug=-1
5465         #set -vx
5466         rm -rf $DIR/$tdir
5467         test_mkdir -p $DIR/$tdir/dir
5468         cd $DIR/$tdir/dir
5469         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5470         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5471         $TRACE touch foo && error "'touch foo' worked after removing parent"
5472         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5473         touch .foo && error "'touch .foo' worked after removing parent"
5474         mkdir .foo && error "mkdir .foo worked after removing parent"
5475         $TRACE ls . && error "'ls .' worked after removing parent"
5476         $TRACE ls .. && error "'ls ..' worked after removing parent"
5477         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5478         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5479         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5480         true
5481 }
5482 run_test 48d "Access removed parent subdir (should return errors)"
5483
5484 test_48e() { # bug 4134
5485         #lctl set_param debug=-1
5486         #set -vx
5487         rm -rf $DIR/$tdir
5488         test_mkdir -p $DIR/$tdir/dir
5489         cd $DIR/$tdir/dir
5490         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5491         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5492         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5493         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5494         # On a buggy kernel addition of "touch foo" after cd .. will
5495         # produce kernel oops in lookup_hash_it
5496         touch ../foo && error "'cd ..' worked after recreate parent"
5497         cd $DIR
5498         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5499 }
5500 run_test 48e "Access to recreated parent subdir (should return errors)"
5501
5502 test_48f() {
5503         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5504                 skip "need MDS >= 2.13.55"
5505         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5506         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5507                 skip "needs different host for mdt1 mdt2"
5508         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5509
5510         $LFS mkdir -i0 $DIR/$tdir
5511         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5512
5513         for d in sub1 sub2 sub3; do
5514                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5515                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5516                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5517         done
5518
5519         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5520 }
5521 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5522
5523 test_49() { # LU-1030
5524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5525         remote_ost_nodsh && skip "remote OST with nodsh"
5526
5527         # get ost1 size - $FSNAME-OST0000
5528         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5529                 awk '{ print $4 }')
5530         # write 800M at maximum
5531         [[ $ost1_size -lt 2 ]] && ost1_size=2
5532         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5533
5534         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5535         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5536         local dd_pid=$!
5537
5538         # change max_pages_per_rpc while writing the file
5539         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5540         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5541         # loop until dd process exits
5542         while ps ax -opid | grep -wq $dd_pid; do
5543                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5544                 sleep $((RANDOM % 5 + 1))
5545         done
5546         # restore original max_pages_per_rpc
5547         $LCTL set_param $osc1_mppc=$orig_mppc
5548         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5549 }
5550 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5551
5552 test_50() {
5553         # bug 1485
5554         test_mkdir $DIR/$tdir
5555         cd $DIR/$tdir
5556         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5557 }
5558 run_test 50 "special situations: /proc symlinks  ==============="
5559
5560 test_51a() {    # was test_51
5561         # bug 1516 - create an empty entry right after ".." then split dir
5562         test_mkdir -c1 $DIR/$tdir
5563         touch $DIR/$tdir/foo
5564         $MCREATE $DIR/$tdir/bar
5565         rm $DIR/$tdir/foo
5566         createmany -m $DIR/$tdir/longfile 201
5567         FNUM=202
5568         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5569                 $MCREATE $DIR/$tdir/longfile$FNUM
5570                 FNUM=$(($FNUM + 1))
5571                 echo -n "+"
5572         done
5573         echo
5574         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5575 }
5576 run_test 51a "special situations: split htree with empty entry =="
5577
5578 cleanup_print_lfs_df () {
5579         trap 0
5580         $LFS df
5581         $LFS df -i
5582 }
5583
5584 test_51b() {
5585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5586
5587         local dir=$DIR/$tdir
5588         local nrdirs=$((65536 + 100))
5589
5590         # cleanup the directory
5591         rm -fr $dir
5592
5593         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5594
5595         $LFS df
5596         $LFS df -i
5597         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5598         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5599         [[ $numfree -lt $nrdirs ]] &&
5600                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5601
5602         # need to check free space for the directories as well
5603         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5604         numfree=$(( blkfree / $(fs_inode_ksize) ))
5605         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5606
5607         trap cleanup_print_lfs_df EXIT
5608
5609         # create files
5610         createmany -d $dir/d $nrdirs || {
5611                 unlinkmany $dir/d $nrdirs
5612                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5613         }
5614
5615         # really created :
5616         nrdirs=$(ls -U $dir | wc -l)
5617
5618         # unlink all but 100 subdirectories, then check it still works
5619         local left=100
5620         local delete=$((nrdirs - left))
5621
5622         $LFS df
5623         $LFS df -i
5624
5625         # for ldiskfs the nlink count should be 1, but this is OSD specific
5626         # and so this is listed for informational purposes only
5627         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5628         unlinkmany -d $dir/d $delete ||
5629                 error "unlink of first $delete subdirs failed"
5630
5631         echo "nlink between: $(stat -c %h $dir)"
5632         local found=$(ls -U $dir | wc -l)
5633         [ $found -ne $left ] &&
5634                 error "can't find subdirs: found only $found, expected $left"
5635
5636         unlinkmany -d $dir/d $delete $left ||
5637                 error "unlink of second $left subdirs failed"
5638         # regardless of whether the backing filesystem tracks nlink accurately
5639         # or not, the nlink count shouldn't be more than "." and ".." here
5640         local after=$(stat -c %h $dir)
5641         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5642                 echo "nlink after: $after"
5643
5644         cleanup_print_lfs_df
5645 }
5646 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5647
5648 test_51d() {
5649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5650         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5651
5652         test_mkdir $DIR/$tdir
5653         createmany -o $DIR/$tdir/t- 1000
5654         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5655         for N in $(seq 0 $((OSTCOUNT - 1))); do
5656                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5657                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5658                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5659                         '($1 == '$N') { objs += 1 } \
5660                         END { printf("%0.0f", objs) }')
5661                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5662         done
5663         unlinkmany $DIR/$tdir/t- 1000
5664
5665         NLAST=0
5666         for N in $(seq 1 $((OSTCOUNT - 1))); do
5667                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5668                         error "OST $N has less objects vs OST $NLAST" \
5669                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5670                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5671                         error "OST $N has less objects vs OST $NLAST" \
5672                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5673
5674                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5675                         error "OST $N has less #0 objects vs OST $NLAST" \
5676                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5677                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5678                         error "OST $N has less #0 objects vs OST $NLAST" \
5679                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5680                 NLAST=$N
5681         done
5682         rm -f $TMP/$tfile
5683 }
5684 run_test 51d "check object distribution"
5685
5686 test_51e() {
5687         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5688                 skip_env "ldiskfs only test"
5689         fi
5690
5691         test_mkdir -c1 $DIR/$tdir
5692         test_mkdir -c1 $DIR/$tdir/d0
5693
5694         touch $DIR/$tdir/d0/foo
5695         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5696                 error "file exceed 65000 nlink limit!"
5697         unlinkmany $DIR/$tdir/d0/f- 65001
5698         return 0
5699 }
5700 run_test 51e "check file nlink limit"
5701
5702 test_51f() {
5703         test_mkdir $DIR/$tdir
5704
5705         local max=100000
5706         local ulimit_old=$(ulimit -n)
5707         local spare=20 # number of spare fd's for scripts/libraries, etc.
5708         local mdt=$($LFS getstripe -m $DIR/$tdir)
5709         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5710
5711         echo "MDT$mdt numfree=$numfree, max=$max"
5712         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5713         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5714                 while ! ulimit -n $((numfree + spare)); do
5715                         numfree=$((numfree * 3 / 4))
5716                 done
5717                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5718         else
5719                 echo "left ulimit at $ulimit_old"
5720         fi
5721
5722         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5723                 unlinkmany $DIR/$tdir/f $numfree
5724                 error "create+open $numfree files in $DIR/$tdir failed"
5725         }
5726         ulimit -n $ulimit_old
5727
5728         # if createmany exits at 120s there will be fewer than $numfree files
5729         unlinkmany $DIR/$tdir/f $numfree || true
5730 }
5731 run_test 51f "check many open files limit"
5732
5733 test_52a() {
5734         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5735         test_mkdir $DIR/$tdir
5736         touch $DIR/$tdir/foo
5737         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5738         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5739         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5740         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5741         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5742                                         error "link worked"
5743         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5744         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5745         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5746                                                      error "lsattr"
5747         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5748         cp -r $DIR/$tdir $TMP/
5749         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5750 }
5751 run_test 52a "append-only flag test (should return errors)"
5752
5753 test_52b() {
5754         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5755         test_mkdir $DIR/$tdir
5756         touch $DIR/$tdir/foo
5757         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5758         cat test > $DIR/$tdir/foo && error "cat test worked"
5759         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5760         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5761         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5762                                         error "link worked"
5763         echo foo >> $DIR/$tdir/foo && error "echo worked"
5764         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5765         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5766         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5767         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5768                                                         error "lsattr"
5769         chattr -i $DIR/$tdir/foo || error "chattr failed"
5770
5771         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5772 }
5773 run_test 52b "immutable flag test (should return errors) ======="
5774
5775 test_53() {
5776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5777         remote_mds_nodsh && skip "remote MDS with nodsh"
5778         remote_ost_nodsh && skip "remote OST with nodsh"
5779
5780         local param
5781         local param_seq
5782         local ostname
5783         local mds_last
5784         local mds_last_seq
5785         local ost_last
5786         local ost_last_seq
5787         local ost_last_id
5788         local ostnum
5789         local node
5790         local found=false
5791         local support_last_seq=true
5792
5793         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5794                 support_last_seq=false
5795
5796         # only test MDT0000
5797         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5798         local value
5799         for value in $(do_facet $SINGLEMDS \
5800                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5801                 param=$(echo ${value[0]} | cut -d "=" -f1)
5802                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5803
5804                 if $support_last_seq; then
5805                         param_seq=$(echo $param |
5806                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5807                         mds_last_seq=$(do_facet $SINGLEMDS \
5808                                        $LCTL get_param -n $param_seq)
5809                 fi
5810                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5811
5812                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5813                 node=$(facet_active_host ost$((ostnum+1)))
5814                 param="obdfilter.$ostname.last_id"
5815                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5816                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5817                         ost_last_id=$ost_last
5818
5819                         if $support_last_seq; then
5820                                 ost_last_id=$(echo $ost_last |
5821                                               awk -F':' '{print $2}' |
5822                                               sed -e "s/^0x//g")
5823                                 ost_last_seq=$(echo $ost_last |
5824                                                awk -F':' '{print $1}')
5825                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5826                         fi
5827
5828                         if [[ $ost_last_id != $mds_last ]]; then
5829                                 error "$ost_last_id != $mds_last"
5830                         else
5831                                 found=true
5832                                 break
5833                         fi
5834                 done
5835         done
5836         $found || error "can not match last_seq/last_id for $mdtosc"
5837         return 0
5838 }
5839 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5840
5841 test_54a() {
5842         perl -MSocket -e ';' || skip "no Socket perl module installed"
5843
5844         $SOCKETSERVER $DIR/socket ||
5845                 error "$SOCKETSERVER $DIR/socket failed: $?"
5846         $SOCKETCLIENT $DIR/socket ||
5847                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5848         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5849 }
5850 run_test 54a "unix domain socket test =========================="
5851
5852 test_54b() {
5853         f="$DIR/f54b"
5854         mknod $f c 1 3
5855         chmod 0666 $f
5856         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5857 }
5858 run_test 54b "char device works in lustre ======================"
5859
5860 find_loop_dev() {
5861         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5862         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5863         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5864
5865         for i in $(seq 3 7); do
5866                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5867                 LOOPDEV=$LOOPBASE$i
5868                 LOOPNUM=$i
5869                 break
5870         done
5871 }
5872
5873 cleanup_54c() {
5874         local rc=0
5875         loopdev="$DIR/loop54c"
5876
5877         trap 0
5878         $UMOUNT $DIR/$tdir || rc=$?
5879         losetup -d $loopdev || true
5880         losetup -d $LOOPDEV || true
5881         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5882         return $rc
5883 }
5884
5885 test_54c() {
5886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5887
5888         loopdev="$DIR/loop54c"
5889
5890         find_loop_dev
5891         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5892         trap cleanup_54c EXIT
5893         mknod $loopdev b 7 $LOOPNUM
5894         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5895         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5896         losetup $loopdev $DIR/$tfile ||
5897                 error "can't set up $loopdev for $DIR/$tfile"
5898         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5899         test_mkdir $DIR/$tdir
5900         mount -t ext2 $loopdev $DIR/$tdir ||
5901                 error "error mounting $loopdev on $DIR/$tdir"
5902         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5903                 error "dd write"
5904         df $DIR/$tdir
5905         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5906                 error "dd read"
5907         cleanup_54c
5908 }
5909 run_test 54c "block device works in lustre ====================="
5910
5911 test_54d() {
5912         f="$DIR/f54d"
5913         string="aaaaaa"
5914         mknod $f p
5915         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5916 }
5917 run_test 54d "fifo device works in lustre ======================"
5918
5919 test_54e() {
5920         f="$DIR/f54e"
5921         string="aaaaaa"
5922         cp -aL /dev/console $f
5923         echo $string > $f || error "echo $string to $f failed"
5924 }
5925 run_test 54e "console/tty device works in lustre ======================"
5926
5927 test_56a() {
5928         local numfiles=3
5929         local numdirs=2
5930         local dir=$DIR/$tdir
5931
5932         rm -rf $dir
5933         test_mkdir -p $dir/dir
5934         for i in $(seq $numfiles); do
5935                 touch $dir/file$i
5936                 touch $dir/dir/file$i
5937         done
5938
5939         local numcomp=$($LFS getstripe --component-count $dir)
5940
5941         [[ $numcomp == 0 ]] && numcomp=1
5942
5943         # test lfs getstripe with --recursive
5944         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5945
5946         [[ $filenum -eq $((numfiles * 2)) ]] ||
5947                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5948         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5949         [[ $filenum -eq $numfiles ]] ||
5950                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5951         echo "$LFS getstripe showed obdidx or l_ost_idx"
5952
5953         # test lfs getstripe with file instead of dir
5954         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5955         [[ $filenum -eq 1 ]] ||
5956                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5957         echo "$LFS getstripe file1 passed"
5958
5959         #test lfs getstripe with --verbose
5960         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5961         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5962                 error "$LFS getstripe --verbose $dir: "\
5963                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5964         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5965                 error "$LFS getstripe $dir: showed lmm_magic"
5966
5967         #test lfs getstripe with -v prints lmm_fid
5968         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5969         local countfids=$((numdirs + numfiles * numcomp))
5970         [[ $filenum -eq $countfids ]] ||
5971                 error "$LFS getstripe -v $dir: "\
5972                       "got $filenum want $countfids lmm_fid"
5973         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5974                 error "$LFS getstripe $dir: showed lmm_fid by default"
5975         echo "$LFS getstripe --verbose passed"
5976
5977         #check for FID information
5978         local fid1=$($LFS getstripe --fid $dir/file1)
5979         local fid2=$($LFS getstripe --verbose $dir/file1 |
5980                      awk '/lmm_fid: / { print $2; exit; }')
5981         local fid3=$($LFS path2fid $dir/file1)
5982
5983         [ "$fid1" != "$fid2" ] &&
5984                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5985         [ "$fid1" != "$fid3" ] &&
5986                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5987         echo "$LFS getstripe --fid passed"
5988
5989         #test lfs getstripe with --obd
5990         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5991                 error "$LFS getstripe --obd wrong_uuid: should return error"
5992
5993         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5994
5995         local ostidx=1
5996         local obduuid=$(ostuuid_from_index $ostidx)
5997         local found=$($LFS getstripe -r --obd $obduuid $dir |
5998                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5999
6000         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6001         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6002                 ((filenum--))
6003         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6004                 ((filenum--))
6005
6006         [[ $found -eq $filenum ]] ||
6007                 error "$LFS getstripe --obd: found $found expect $filenum"
6008         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6009                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6010                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6011                 error "$LFS getstripe --obd: should not show file on other obd"
6012         echo "$LFS getstripe --obd passed"
6013 }
6014 run_test 56a "check $LFS getstripe"
6015
6016 test_56b() {
6017         local dir=$DIR/$tdir
6018         local numdirs=3
6019
6020         test_mkdir $dir
6021         for i in $(seq $numdirs); do
6022                 test_mkdir $dir/dir$i
6023         done
6024
6025         # test lfs getdirstripe default mode is non-recursion, which is
6026         # different from lfs getstripe
6027         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6028
6029         [[ $dircnt -eq 1 ]] ||
6030                 error "$LFS getdirstripe: found $dircnt, not 1"
6031         dircnt=$($LFS getdirstripe --recursive $dir |
6032                 grep -c lmv_stripe_count)
6033         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6034                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6035 }
6036 run_test 56b "check $LFS getdirstripe"
6037
6038 test_56c() {
6039         remote_ost_nodsh && skip "remote OST with nodsh"
6040
6041         local ost_idx=0
6042         local ost_name=$(ostname_from_index $ost_idx)
6043         local old_status=$(ost_dev_status $ost_idx)
6044         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6045
6046         [[ -z "$old_status" ]] ||
6047                 skip_env "OST $ost_name is in $old_status status"
6048
6049         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6050         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6051                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6052         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6053                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6054                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6055         fi
6056
6057         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6058                 error "$LFS df -v showing inactive devices"
6059         sleep_maxage
6060
6061         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6062
6063         [[ "$new_status" =~ "D" ]] ||
6064                 error "$ost_name status is '$new_status', missing 'D'"
6065         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6066                 [[ "$new_status" =~ "N" ]] ||
6067                         error "$ost_name status is '$new_status', missing 'N'"
6068         fi
6069         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6070                 [[ "$new_status" =~ "f" ]] ||
6071                         error "$ost_name status is '$new_status', missing 'f'"
6072         fi
6073
6074         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6075         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6076                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6077         [[ -z "$p" ]] && restore_lustre_params < $p || true
6078         sleep_maxage
6079
6080         new_status=$(ost_dev_status $ost_idx)
6081         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6082                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6083         # can't check 'f' as devices may actually be on flash
6084 }
6085 run_test 56c "check 'lfs df' showing device status"
6086
6087 test_56d() {
6088         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6089         local osts=$($LFS df -v $MOUNT | grep -c OST)
6090
6091         $LFS df $MOUNT
6092
6093         (( mdts == MDSCOUNT )) ||
6094                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6095         (( osts == OSTCOUNT )) ||
6096                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6097 }
6098 run_test 56d "'lfs df -v' prints only configured devices"
6099
6100 NUMFILES=3
6101 NUMDIRS=3
6102 setup_56() {
6103         local local_tdir="$1"
6104         local local_numfiles="$2"
6105         local local_numdirs="$3"
6106         local dir_params="$4"
6107         local dir_stripe_params="$5"
6108
6109         if [ ! -d "$local_tdir" ] ; then
6110                 test_mkdir -p $dir_stripe_params $local_tdir
6111                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6112                 for i in $(seq $local_numfiles) ; do
6113                         touch $local_tdir/file$i
6114                 done
6115                 for i in $(seq $local_numdirs) ; do
6116                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6117                         for j in $(seq $local_numfiles) ; do
6118                                 touch $local_tdir/dir$i/file$j
6119                         done
6120                 done
6121         fi
6122 }
6123
6124 setup_56_special() {
6125         local local_tdir=$1
6126         local local_numfiles=$2
6127         local local_numdirs=$3
6128
6129         setup_56 $local_tdir $local_numfiles $local_numdirs
6130
6131         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6132                 for i in $(seq $local_numfiles) ; do
6133                         mknod $local_tdir/loop${i}b b 7 $i
6134                         mknod $local_tdir/null${i}c c 1 3
6135                         ln -s $local_tdir/file1 $local_tdir/link${i}
6136                 done
6137                 for i in $(seq $local_numdirs) ; do
6138                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6139                         mknod $local_tdir/dir$i/null${i}c c 1 3
6140                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6141                 done
6142         fi
6143 }
6144
6145 test_56g() {
6146         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6147         local expected=$(($NUMDIRS + 2))
6148
6149         setup_56 $dir $NUMFILES $NUMDIRS
6150
6151         # test lfs find with -name
6152         for i in $(seq $NUMFILES) ; do
6153                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6154
6155                 [ $nums -eq $expected ] ||
6156                         error "lfs find -name '*$i' $dir wrong: "\
6157                               "found $nums, expected $expected"
6158         done
6159 }
6160 run_test 56g "check lfs find -name"
6161
6162 test_56h() {
6163         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6164         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6165
6166         setup_56 $dir $NUMFILES $NUMDIRS
6167
6168         # test lfs find with ! -name
6169         for i in $(seq $NUMFILES) ; do
6170                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6171
6172                 [ $nums -eq $expected ] ||
6173                         error "lfs find ! -name '*$i' $dir wrong: "\
6174                               "found $nums, expected $expected"
6175         done
6176 }
6177 run_test 56h "check lfs find ! -name"
6178
6179 test_56i() {
6180         local dir=$DIR/$tdir
6181
6182         test_mkdir $dir
6183
6184         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6185         local out=$($cmd)
6186
6187         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6188 }
6189 run_test 56i "check 'lfs find -ost UUID' skips directories"
6190
6191 test_56j() {
6192         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6193
6194         setup_56_special $dir $NUMFILES $NUMDIRS
6195
6196         local expected=$((NUMDIRS + 1))
6197         local cmd="$LFS find -type d $dir"
6198         local nums=$($cmd | wc -l)
6199
6200         [ $nums -eq $expected ] ||
6201                 error "'$cmd' wrong: found $nums, expected $expected"
6202 }
6203 run_test 56j "check lfs find -type d"
6204
6205 test_56k() {
6206         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6207
6208         setup_56_special $dir $NUMFILES $NUMDIRS
6209
6210         local expected=$(((NUMDIRS + 1) * NUMFILES))
6211         local cmd="$LFS find -type f $dir"
6212         local nums=$($cmd | wc -l)
6213
6214         [ $nums -eq $expected ] ||
6215                 error "'$cmd' wrong: found $nums, expected $expected"
6216 }
6217 run_test 56k "check lfs find -type f"
6218
6219 test_56l() {
6220         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6221
6222         setup_56_special $dir $NUMFILES $NUMDIRS
6223
6224         local expected=$((NUMDIRS + NUMFILES))
6225         local cmd="$LFS find -type b $dir"
6226         local nums=$($cmd | wc -l)
6227
6228         [ $nums -eq $expected ] ||
6229                 error "'$cmd' wrong: found $nums, expected $expected"
6230 }
6231 run_test 56l "check lfs find -type b"
6232
6233 test_56m() {
6234         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6235
6236         setup_56_special $dir $NUMFILES $NUMDIRS
6237
6238         local expected=$((NUMDIRS + NUMFILES))
6239         local cmd="$LFS find -type c $dir"
6240         local nums=$($cmd | wc -l)
6241         [ $nums -eq $expected ] ||
6242                 error "'$cmd' wrong: found $nums, expected $expected"
6243 }
6244 run_test 56m "check lfs find -type c"
6245
6246 test_56n() {
6247         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6248         setup_56_special $dir $NUMFILES $NUMDIRS
6249
6250         local expected=$((NUMDIRS + NUMFILES))
6251         local cmd="$LFS find -type l $dir"
6252         local nums=$($cmd | wc -l)
6253
6254         [ $nums -eq $expected ] ||
6255                 error "'$cmd' wrong: found $nums, expected $expected"
6256 }
6257 run_test 56n "check lfs find -type l"
6258
6259 test_56o() {
6260         local dir=$DIR/$tdir
6261
6262         setup_56 $dir $NUMFILES $NUMDIRS
6263         utime $dir/file1 > /dev/null || error "utime (1)"
6264         utime $dir/file2 > /dev/null || error "utime (2)"
6265         utime $dir/dir1 > /dev/null || error "utime (3)"
6266         utime $dir/dir2 > /dev/null || error "utime (4)"
6267         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6268         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6269
6270         local expected=4
6271         local nums=$($LFS find -mtime +0 $dir | wc -l)
6272
6273         [ $nums -eq $expected ] ||
6274                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6275
6276         expected=12
6277         cmd="$LFS find -mtime 0 $dir"
6278         nums=$($cmd | wc -l)
6279         [ $nums -eq $expected ] ||
6280                 error "'$cmd' wrong: found $nums, expected $expected"
6281 }
6282 run_test 56o "check lfs find -mtime for old files"
6283
6284 test_56ob() {
6285         local dir=$DIR/$tdir
6286         local expected=1
6287         local count=0
6288
6289         # just to make sure there is something that won't be found
6290         test_mkdir $dir
6291         touch $dir/$tfile.now
6292
6293         for age in year week day hour min; do
6294                 count=$((count + 1))
6295
6296                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6297                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6298                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6299
6300                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6301                 local nums=$($cmd | wc -l)
6302                 [ $nums -eq $expected ] ||
6303                         error "'$cmd' wrong: found $nums, expected $expected"
6304
6305                 cmd="$LFS find $dir -atime $count${age:0:1}"
6306                 nums=$($cmd | wc -l)
6307                 [ $nums -eq $expected ] ||
6308                         error "'$cmd' wrong: found $nums, expected $expected"
6309         done
6310
6311         sleep 2
6312         cmd="$LFS find $dir -ctime +1s -type f"
6313         nums=$($cmd | wc -l)
6314         (( $nums == $count * 2 + 1)) ||
6315                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6316 }
6317 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6318
6319 test_newerXY_base() {
6320         local x=$1
6321         local y=$2
6322         local dir=$DIR/$tdir
6323         local ref
6324         local negref
6325
6326         if [ $y == "t" ]; then
6327                 if [ $x == "b" ]; then
6328                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6329                 else
6330                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6331                 fi
6332         else
6333                 ref=$DIR/$tfile.newer.$x$y
6334                 touch $ref || error "touch $ref failed"
6335         fi
6336
6337         echo "before = $ref"
6338         sleep 2
6339         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6340         sleep 2
6341         if [ $y == "t" ]; then
6342                 if [ $x == "b" ]; then
6343                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6344                 else
6345                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6346                 fi
6347         else
6348                 negref=$DIR/$tfile.negnewer.$x$y
6349                 touch $negref || error "touch $negref failed"
6350         fi
6351
6352         echo "after = $negref"
6353         local cmd="$LFS find $dir -newer$x$y $ref"
6354         local nums=$(eval $cmd | wc -l)
6355         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6356
6357         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6358                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6359
6360         cmd="$LFS find $dir ! -newer$x$y $negref"
6361         nums=$(eval $cmd | wc -l)
6362         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6363                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6364
6365         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6366         nums=$(eval $cmd | wc -l)
6367         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6368                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6369
6370         rm -rf $DIR/*
6371 }
6372
6373 test_56oc() {
6374         test_newerXY_base "a" "a"
6375         test_newerXY_base "a" "m"
6376         test_newerXY_base "a" "c"
6377         test_newerXY_base "m" "a"
6378         test_newerXY_base "m" "m"
6379         test_newerXY_base "m" "c"
6380         test_newerXY_base "c" "a"
6381         test_newerXY_base "c" "m"
6382         test_newerXY_base "c" "c"
6383
6384         [[ -n "$sles_version" ]] &&
6385                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6386
6387         test_newerXY_base "a" "t"
6388         test_newerXY_base "m" "t"
6389         test_newerXY_base "c" "t"
6390
6391         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6392            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6393                 ! btime_supported && echo "btime unsupported" && return 0
6394
6395         test_newerXY_base "b" "b"
6396         test_newerXY_base "b" "t"
6397 }
6398 run_test 56oc "check lfs find -newerXY work"
6399
6400 btime_supported() {
6401         local dir=$DIR/$tdir
6402         local rc
6403
6404         mkdir -p $dir
6405         touch $dir/$tfile
6406         $LFS find $dir -btime -1d -type f
6407         rc=$?
6408         rm -rf $dir
6409         return $rc
6410 }
6411
6412 test_56od() {
6413         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6414                 ! btime_supported && skip "btime unsupported on MDS"
6415
6416         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6417                 ! btime_supported && skip "btime unsupported on clients"
6418
6419         local dir=$DIR/$tdir
6420         local ref=$DIR/$tfile.ref
6421         local negref=$DIR/$tfile.negref
6422
6423         mkdir $dir || error "mkdir $dir failed"
6424         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6425         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6426         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6427         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6428         touch $ref || error "touch $ref failed"
6429         # sleep 3 seconds at least
6430         sleep 3
6431
6432         local before=$(do_facet mds1 date +%s)
6433         local skew=$(($(date +%s) - before + 1))
6434
6435         if (( skew < 0 && skew > -5 )); then
6436                 sleep $((0 - skew + 1))
6437                 skew=0
6438         fi
6439
6440         # Set the dir stripe params to limit files all on MDT0,
6441         # otherwise we need to calc the max clock skew between
6442         # the client and MDTs.
6443         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6444         sleep 2
6445         touch $negref || error "touch $negref failed"
6446
6447         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6448         local nums=$($cmd | wc -l)
6449         local expected=$(((NUMFILES + 1) * NUMDIRS))
6450
6451         [ $nums -eq $expected ] ||
6452                 error "'$cmd' wrong: found $nums, expected $expected"
6453
6454         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6455         nums=$($cmd | wc -l)
6456         expected=$((NUMFILES + 1))
6457         [ $nums -eq $expected ] ||
6458                 error "'$cmd' wrong: found $nums, expected $expected"
6459
6460         [ $skew -lt 0 ] && return
6461
6462         local after=$(do_facet mds1 date +%s)
6463         local age=$((after - before + 1 + skew))
6464
6465         cmd="$LFS find $dir -btime -${age}s -type f"
6466         nums=$($cmd | wc -l)
6467         expected=$(((NUMFILES + 1) * NUMDIRS))
6468
6469         echo "Clock skew between client and server: $skew, age:$age"
6470         [ $nums -eq $expected ] ||
6471                 error "'$cmd' wrong: found $nums, expected $expected"
6472
6473         expected=$(($NUMDIRS + 1))
6474         cmd="$LFS find $dir -btime -${age}s -type d"
6475         nums=$($cmd | wc -l)
6476         [ $nums -eq $expected ] ||
6477                 error "'$cmd' wrong: found $nums, expected $expected"
6478         rm -f $ref $negref || error "Failed to remove $ref $negref"
6479 }
6480 run_test 56od "check lfs find -btime with units"
6481
6482 test_56p() {
6483         [ $RUNAS_ID -eq $UID ] &&
6484                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6485
6486         local dir=$DIR/$tdir
6487
6488         setup_56 $dir $NUMFILES $NUMDIRS
6489         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6490
6491         local expected=$NUMFILES
6492         local cmd="$LFS find -uid $RUNAS_ID $dir"
6493         local nums=$($cmd | wc -l)
6494
6495         [ $nums -eq $expected ] ||
6496                 error "'$cmd' wrong: found $nums, expected $expected"
6497
6498         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6499         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6500         nums=$($cmd | wc -l)
6501         [ $nums -eq $expected ] ||
6502                 error "'$cmd' wrong: found $nums, expected $expected"
6503 }
6504 run_test 56p "check lfs find -uid and ! -uid"
6505
6506 test_56q() {
6507         [ $RUNAS_ID -eq $UID ] &&
6508                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6509
6510         local dir=$DIR/$tdir
6511
6512         setup_56 $dir $NUMFILES $NUMDIRS
6513         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6514
6515         local expected=$NUMFILES
6516         local cmd="$LFS find -gid $RUNAS_GID $dir"
6517         local nums=$($cmd | wc -l)
6518
6519         [ $nums -eq $expected ] ||
6520                 error "'$cmd' wrong: found $nums, expected $expected"
6521
6522         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6523         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6524         nums=$($cmd | wc -l)
6525         [ $nums -eq $expected ] ||
6526                 error "'$cmd' wrong: found $nums, expected $expected"
6527 }
6528 run_test 56q "check lfs find -gid and ! -gid"
6529
6530 test_56r() {
6531         local dir=$DIR/$tdir
6532
6533         setup_56 $dir $NUMFILES $NUMDIRS
6534
6535         local expected=12
6536         local cmd="$LFS find -size 0 -type f -lazy $dir"
6537         local nums=$($cmd | wc -l)
6538
6539         [ $nums -eq $expected ] ||
6540                 error "'$cmd' wrong: found $nums, expected $expected"
6541         cmd="$LFS find -size 0 -type f $dir"
6542         nums=$($cmd | wc -l)
6543         [ $nums -eq $expected ] ||
6544                 error "'$cmd' wrong: found $nums, expected $expected"
6545
6546         expected=0
6547         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6548         nums=$($cmd | wc -l)
6549         [ $nums -eq $expected ] ||
6550                 error "'$cmd' wrong: found $nums, expected $expected"
6551         cmd="$LFS find ! -size 0 -type f $dir"
6552         nums=$($cmd | wc -l)
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555
6556         echo "test" > $dir/$tfile
6557         echo "test2" > $dir/$tfile.2 && sync
6558         expected=1
6559         cmd="$LFS find -size 5 -type f -lazy $dir"
6560         nums=$($cmd | wc -l)
6561         [ $nums -eq $expected ] ||
6562                 error "'$cmd' wrong: found $nums, expected $expected"
6563         cmd="$LFS find -size 5 -type f $dir"
6564         nums=$($cmd | wc -l)
6565         [ $nums -eq $expected ] ||
6566                 error "'$cmd' wrong: found $nums, expected $expected"
6567
6568         expected=1
6569         cmd="$LFS find -size +5 -type f -lazy $dir"
6570         nums=$($cmd | wc -l)
6571         [ $nums -eq $expected ] ||
6572                 error "'$cmd' wrong: found $nums, expected $expected"
6573         cmd="$LFS find -size +5 -type f $dir"
6574         nums=$($cmd | wc -l)
6575         [ $nums -eq $expected ] ||
6576                 error "'$cmd' wrong: found $nums, expected $expected"
6577
6578         expected=2
6579         cmd="$LFS find -size +0 -type f -lazy $dir"
6580         nums=$($cmd | wc -l)
6581         [ $nums -eq $expected ] ||
6582                 error "'$cmd' wrong: found $nums, expected $expected"
6583         cmd="$LFS find -size +0 -type f $dir"
6584         nums=$($cmd | wc -l)
6585         [ $nums -eq $expected ] ||
6586                 error "'$cmd' wrong: found $nums, expected $expected"
6587
6588         expected=2
6589         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6590         nums=$($cmd | wc -l)
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593         cmd="$LFS find ! -size -5 -type f $dir"
6594         nums=$($cmd | wc -l)
6595         [ $nums -eq $expected ] ||
6596                 error "'$cmd' wrong: found $nums, expected $expected"
6597
6598         expected=12
6599         cmd="$LFS find -size -5 -type f -lazy $dir"
6600         nums=$($cmd | wc -l)
6601         [ $nums -eq $expected ] ||
6602                 error "'$cmd' wrong: found $nums, expected $expected"
6603         cmd="$LFS find -size -5 -type f $dir"
6604         nums=$($cmd | wc -l)
6605         [ $nums -eq $expected ] ||
6606                 error "'$cmd' wrong: found $nums, expected $expected"
6607 }
6608 run_test 56r "check lfs find -size works"
6609
6610 test_56ra_sub() {
6611         local expected=$1
6612         local glimpses=$2
6613         local cmd="$3"
6614
6615         cancel_lru_locks $OSC
6616
6617         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6618         local nums=$($cmd | wc -l)
6619
6620         [ $nums -eq $expected ] ||
6621                 error "'$cmd' wrong: found $nums, expected $expected"
6622
6623         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6624
6625         if (( rpcs_before + glimpses != rpcs_after )); then
6626                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6627                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6628
6629                 if [[ $glimpses == 0 ]]; then
6630                         error "'$cmd' should not send glimpse RPCs to OST"
6631                 else
6632                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6633                 fi
6634         fi
6635 }
6636
6637 test_56ra() {
6638         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6639                 skip "MDS < 2.12.58 doesn't return LSOM data"
6640         local dir=$DIR/$tdir
6641         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6642
6643         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6644
6645         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6646         $LCTL set_param -n llite.*.statahead_agl=0
6647         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6648
6649         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6650         # open and close all files to ensure LSOM is updated
6651         cancel_lru_locks $OSC
6652         find $dir -type f | xargs cat > /dev/null
6653
6654         #   expect_found  glimpse_rpcs  command_to_run
6655         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6656         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6657         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6658         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6659
6660         echo "test" > $dir/$tfile
6661         echo "test2" > $dir/$tfile.2 && sync
6662         cancel_lru_locks $OSC
6663         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6664
6665         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6666         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6667         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6668         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6669
6670         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6671         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6672         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6673         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6674         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6675         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6676 }
6677 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6678
6679 test_56rb() {
6680         local dir=$DIR/$tdir
6681         local tmp=$TMP/$tfile.log
6682         local mdt_idx;
6683
6684         test_mkdir -p $dir || error "failed to mkdir $dir"
6685         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6686                 error "failed to setstripe $dir/$tfile"
6687         mdt_idx=$($LFS getdirstripe -i $dir)
6688         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6689
6690         stack_trap "rm -f $tmp" EXIT
6691         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6692         ! grep -q obd_uuid $tmp ||
6693                 error "failed to find --size +100K --ost 0 $dir"
6694         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6695         ! grep -q obd_uuid $tmp ||
6696                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6697 }
6698 run_test 56rb "check lfs find --size --ost/--mdt works"
6699
6700 test_56rc() {
6701         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6702         local dir=$DIR/$tdir
6703         local found
6704
6705         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6706         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6707         (( $MDSCOUNT > 2 )) &&
6708                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6709         mkdir $dir/$tdir-{1..10}
6710         touch $dir/$tfile-{1..10}
6711
6712         found=$($LFS find $dir --mdt-count 2 | wc -l)
6713         expect=11
6714         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6715
6716         found=$($LFS find $dir -T +1 | wc -l)
6717         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6718         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6719
6720         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6721         expect=11
6722         (( $found == $expect )) || error "found $found all_char, expect $expect"
6723
6724         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6725         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6726         (( $found == $expect )) || error "found $found all_char, expect $expect"
6727 }
6728 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6729
6730 test_56s() { # LU-611 #LU-9369
6731         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6732
6733         local dir=$DIR/$tdir
6734         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6735
6736         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6737         for i in $(seq $NUMDIRS); do
6738                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6739         done
6740
6741         local expected=$NUMDIRS
6742         local cmd="$LFS find -c $OSTCOUNT $dir"
6743         local nums=$($cmd | wc -l)
6744
6745         [ $nums -eq $expected ] || {
6746                 $LFS getstripe -R $dir
6747                 error "'$cmd' wrong: found $nums, expected $expected"
6748         }
6749
6750         expected=$((NUMDIRS + onestripe))
6751         cmd="$LFS find -stripe-count +0 -type f $dir"
6752         nums=$($cmd | wc -l)
6753         [ $nums -eq $expected ] || {
6754                 $LFS getstripe -R $dir
6755                 error "'$cmd' wrong: found $nums, expected $expected"
6756         }
6757
6758         expected=$onestripe
6759         cmd="$LFS find -stripe-count 1 -type f $dir"
6760         nums=$($cmd | wc -l)
6761         [ $nums -eq $expected ] || {
6762                 $LFS getstripe -R $dir
6763                 error "'$cmd' wrong: found $nums, expected $expected"
6764         }
6765
6766         cmd="$LFS find -stripe-count -2 -type f $dir"
6767         nums=$($cmd | wc -l)
6768         [ $nums -eq $expected ] || {
6769                 $LFS getstripe -R $dir
6770                 error "'$cmd' wrong: found $nums, expected $expected"
6771         }
6772
6773         expected=0
6774         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6775         nums=$($cmd | wc -l)
6776         [ $nums -eq $expected ] || {
6777                 $LFS getstripe -R $dir
6778                 error "'$cmd' wrong: found $nums, expected $expected"
6779         }
6780 }
6781 run_test 56s "check lfs find -stripe-count works"
6782
6783 test_56t() { # LU-611 #LU-9369
6784         local dir=$DIR/$tdir
6785
6786         setup_56 $dir 0 $NUMDIRS
6787         for i in $(seq $NUMDIRS); do
6788                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6789         done
6790
6791         local expected=$NUMDIRS
6792         local cmd="$LFS find -S 8M $dir"
6793         local nums=$($cmd | wc -l)
6794
6795         [ $nums -eq $expected ] || {
6796                 $LFS getstripe -R $dir
6797                 error "'$cmd' wrong: found $nums, expected $expected"
6798         }
6799         rm -rf $dir
6800
6801         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6802
6803         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6804
6805         expected=$(((NUMDIRS + 1) * NUMFILES))
6806         cmd="$LFS find -stripe-size 512k -type f $dir"
6807         nums=$($cmd | wc -l)
6808         [ $nums -eq $expected ] ||
6809                 error "'$cmd' wrong: found $nums, expected $expected"
6810
6811         cmd="$LFS find -stripe-size +320k -type f $dir"
6812         nums=$($cmd | wc -l)
6813         [ $nums -eq $expected ] ||
6814                 error "'$cmd' wrong: found $nums, expected $expected"
6815
6816         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6817         cmd="$LFS find -stripe-size +200k -type f $dir"
6818         nums=$($cmd | wc -l)
6819         [ $nums -eq $expected ] ||
6820                 error "'$cmd' wrong: found $nums, expected $expected"
6821
6822         cmd="$LFS find -stripe-size -640k -type f $dir"
6823         nums=$($cmd | wc -l)
6824         [ $nums -eq $expected ] ||
6825                 error "'$cmd' wrong: found $nums, expected $expected"
6826
6827         expected=4
6828         cmd="$LFS find -stripe-size 256k -type f $dir"
6829         nums=$($cmd | wc -l)
6830         [ $nums -eq $expected ] ||
6831                 error "'$cmd' wrong: found $nums, expected $expected"
6832
6833         cmd="$LFS find -stripe-size -320k -type f $dir"
6834         nums=$($cmd | wc -l)
6835         [ $nums -eq $expected ] ||
6836                 error "'$cmd' wrong: found $nums, expected $expected"
6837
6838         expected=0
6839         cmd="$LFS find -stripe-size 1024k -type f $dir"
6840         nums=$($cmd | wc -l)
6841         [ $nums -eq $expected ] ||
6842                 error "'$cmd' wrong: found $nums, expected $expected"
6843 }
6844 run_test 56t "check lfs find -stripe-size works"
6845
6846 test_56u() { # LU-611
6847         local dir=$DIR/$tdir
6848
6849         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6850
6851         if [[ $OSTCOUNT -gt 1 ]]; then
6852                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6853                 onestripe=4
6854         else
6855                 onestripe=0
6856         fi
6857
6858         local expected=$(((NUMDIRS + 1) * NUMFILES))
6859         local cmd="$LFS find -stripe-index 0 -type f $dir"
6860         local nums=$($cmd | wc -l)
6861
6862         [ $nums -eq $expected ] ||
6863                 error "'$cmd' wrong: found $nums, expected $expected"
6864
6865         expected=$onestripe
6866         cmd="$LFS find -stripe-index 1 -type f $dir"
6867         nums=$($cmd | wc -l)
6868         [ $nums -eq $expected ] ||
6869                 error "'$cmd' wrong: found $nums, expected $expected"
6870
6871         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6872         nums=$($cmd | wc -l)
6873         [ $nums -eq $expected ] ||
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875
6876         expected=0
6877         # This should produce an error and not return any files
6878         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6879         nums=$($cmd 2>/dev/null | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882
6883         if [[ $OSTCOUNT -gt 1 ]]; then
6884                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6885                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6886                 nums=$($cmd | wc -l)
6887                 [ $nums -eq $expected ] ||
6888                         error "'$cmd' wrong: found $nums, expected $expected"
6889         fi
6890 }
6891 run_test 56u "check lfs find -stripe-index works"
6892
6893 test_56v() {
6894         local mdt_idx=0
6895         local dir=$DIR/$tdir
6896
6897         setup_56 $dir $NUMFILES $NUMDIRS
6898
6899         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6900         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6901
6902         for file in $($LFS find -m $UUID $dir); do
6903                 file_midx=$($LFS getstripe -m $file)
6904                 [ $file_midx -eq $mdt_idx ] ||
6905                         error "lfs find -m $UUID != getstripe -m $file_midx"
6906         done
6907 }
6908 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6909
6910 test_56w() {
6911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6913
6914         local dir=$DIR/$tdir
6915
6916         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6917
6918         local stripe_size=$($LFS getstripe -S -d $dir) ||
6919                 error "$LFS getstripe -S -d $dir failed"
6920         stripe_size=${stripe_size%% *}
6921
6922         local file_size=$((stripe_size * OSTCOUNT))
6923         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6924         local required_space=$((file_num * file_size))
6925         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6926                            head -n1)
6927         [[ $free_space -le $((required_space / 1024)) ]] &&
6928                 skip_env "need $required_space, have $free_space kbytes"
6929
6930         local dd_bs=65536
6931         local dd_count=$((file_size / dd_bs))
6932
6933         # write data into the files
6934         local i
6935         local j
6936         local file
6937
6938         for i in $(seq $NUMFILES); do
6939                 file=$dir/file$i
6940                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6941                         error "write data into $file failed"
6942         done
6943         for i in $(seq $NUMDIRS); do
6944                 for j in $(seq $NUMFILES); do
6945                         file=$dir/dir$i/file$j
6946                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6947                                 error "write data into $file failed"
6948                 done
6949         done
6950
6951         # $LFS_MIGRATE will fail if hard link migration is unsupported
6952         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6953                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6954                         error "creating links to $dir/dir1/file1 failed"
6955         fi
6956
6957         local expected=-1
6958
6959         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6960
6961         # lfs_migrate file
6962         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6963
6964         echo "$cmd"
6965         eval $cmd || error "$cmd failed"
6966
6967         check_stripe_count $dir/file1 $expected
6968
6969         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6970         then
6971                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6972                 # OST 1 if it is on OST 0. This file is small enough to
6973                 # be on only one stripe.
6974                 file=$dir/migr_1_ost
6975                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6976                         error "write data into $file failed"
6977                 local obdidx=$($LFS getstripe -i $file)
6978                 local oldmd5=$(md5sum $file)
6979                 local newobdidx=0
6980
6981                 [[ $obdidx -eq 0 ]] && newobdidx=1
6982                 cmd="$LFS migrate -i $newobdidx $file"
6983                 echo $cmd
6984                 eval $cmd || error "$cmd failed"
6985
6986                 local realobdix=$($LFS getstripe -i $file)
6987                 local newmd5=$(md5sum $file)
6988
6989                 [[ $newobdidx -ne $realobdix ]] &&
6990                         error "new OST is different (was=$obdidx, "\
6991                               "wanted=$newobdidx, got=$realobdix)"
6992                 [[ "$oldmd5" != "$newmd5" ]] &&
6993                         error "md5sum differ: $oldmd5, $newmd5"
6994         fi
6995
6996         # lfs_migrate dir
6997         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6998         echo "$cmd"
6999         eval $cmd || error "$cmd failed"
7000
7001         for j in $(seq $NUMFILES); do
7002                 check_stripe_count $dir/dir1/file$j $expected
7003         done
7004
7005         # lfs_migrate works with lfs find
7006         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7007              $LFS_MIGRATE -y -c $expected"
7008         echo "$cmd"
7009         eval $cmd || error "$cmd failed"
7010
7011         for i in $(seq 2 $NUMFILES); do
7012                 check_stripe_count $dir/file$i $expected
7013         done
7014         for i in $(seq 2 $NUMDIRS); do
7015                 for j in $(seq $NUMFILES); do
7016                 check_stripe_count $dir/dir$i/file$j $expected
7017                 done
7018         done
7019 }
7020 run_test 56w "check lfs_migrate -c stripe_count works"
7021
7022 test_56wb() {
7023         local file1=$DIR/$tdir/file1
7024         local create_pool=false
7025         local initial_pool=$($LFS getstripe -p $DIR)
7026         local pool_list=()
7027         local pool=""
7028
7029         echo -n "Creating test dir..."
7030         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7031         echo "done."
7032
7033         echo -n "Creating test file..."
7034         touch $file1 || error "cannot create file"
7035         echo "done."
7036
7037         echo -n "Detecting existing pools..."
7038         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7039
7040         if [ ${#pool_list[@]} -gt 0 ]; then
7041                 echo "${pool_list[@]}"
7042                 for thispool in "${pool_list[@]}"; do
7043                         if [[ -z "$initial_pool" ||
7044                               "$initial_pool" != "$thispool" ]]; then
7045                                 pool="$thispool"
7046                                 echo "Using existing pool '$pool'"
7047                                 break
7048                         fi
7049                 done
7050         else
7051                 echo "none detected."
7052         fi
7053         if [ -z "$pool" ]; then
7054                 pool=${POOL:-testpool}
7055                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7056                 echo -n "Creating pool '$pool'..."
7057                 create_pool=true
7058                 pool_add $pool &> /dev/null ||
7059                         error "pool_add failed"
7060                 echo "done."
7061
7062                 echo -n "Adding target to pool..."
7063                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7064                         error "pool_add_targets failed"
7065                 echo "done."
7066         fi
7067
7068         echo -n "Setting pool using -p option..."
7069         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7070                 error "migrate failed rc = $?"
7071         echo "done."
7072
7073         echo -n "Verifying test file is in pool after migrating..."
7074         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7075                 error "file was not migrated to pool $pool"
7076         echo "done."
7077
7078         echo -n "Removing test file from pool '$pool'..."
7079         # "lfs migrate $file" won't remove the file from the pool
7080         # until some striping information is changed.
7081         $LFS migrate -c 1 $file1 &> /dev/null ||
7082                 error "cannot remove from pool"
7083         [ "$($LFS getstripe -p $file1)" ] &&
7084                 error "pool still set"
7085         echo "done."
7086
7087         echo -n "Setting pool using --pool option..."
7088         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7089                 error "migrate failed rc = $?"
7090         echo "done."
7091
7092         # Clean up
7093         rm -f $file1
7094         if $create_pool; then
7095                 destroy_test_pools 2> /dev/null ||
7096                         error "destroy test pools failed"
7097         fi
7098 }
7099 run_test 56wb "check lfs_migrate pool support"
7100
7101 test_56wc() {
7102         local file1="$DIR/$tdir/file1"
7103         local parent_ssize
7104         local parent_scount
7105         local cur_ssize
7106         local cur_scount
7107         local orig_ssize
7108
7109         echo -n "Creating test dir..."
7110         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7111         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7112                 error "cannot set stripe by '-S 1M -c 1'"
7113         echo "done"
7114
7115         echo -n "Setting initial stripe for test file..."
7116         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7117                 error "cannot set stripe"
7118         cur_ssize=$($LFS getstripe -S "$file1")
7119         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7120         echo "done."
7121
7122         # File currently set to -S 512K -c 1
7123
7124         # Ensure -c and -S options are rejected when -R is set
7125         echo -n "Verifying incompatible options are detected..."
7126         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7127                 error "incompatible -c and -R options not detected"
7128         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7129                 error "incompatible -S and -R options not detected"
7130         echo "done."
7131
7132         # Ensure unrecognized options are passed through to 'lfs migrate'
7133         echo -n "Verifying -S option is passed through to lfs migrate..."
7134         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7135                 error "migration failed"
7136         cur_ssize=$($LFS getstripe -S "$file1")
7137         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7138         echo "done."
7139
7140         # File currently set to -S 1M -c 1
7141
7142         # Ensure long options are supported
7143         echo -n "Verifying long options supported..."
7144         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7145                 error "long option without argument not supported"
7146         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7147                 error "long option with argument not supported"
7148         cur_ssize=$($LFS getstripe -S "$file1")
7149         [ $cur_ssize -eq 524288 ] ||
7150                 error "migrate --stripe-size $cur_ssize != 524288"
7151         echo "done."
7152
7153         # File currently set to -S 512K -c 1
7154
7155         if [ "$OSTCOUNT" -gt 1 ]; then
7156                 echo -n "Verifying explicit stripe count can be set..."
7157                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7158                         error "migrate failed"
7159                 cur_scount=$($LFS getstripe -c "$file1")
7160                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7161                 echo "done."
7162         fi
7163
7164         # File currently set to -S 512K -c 1 or -S 512K -c 2
7165
7166         # Ensure parent striping is used if -R is set, and no stripe
7167         # count or size is specified
7168         echo -n "Setting stripe for parent directory..."
7169         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7170                 error "cannot set stripe '-S 2M -c 1'"
7171         echo "done."
7172
7173         echo -n "Verifying restripe option uses parent stripe settings..."
7174         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7175         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7176         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7177                 error "migrate failed"
7178         cur_ssize=$($LFS getstripe -S "$file1")
7179         [ $cur_ssize -eq $parent_ssize ] ||
7180                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7181         cur_scount=$($LFS getstripe -c "$file1")
7182         [ $cur_scount -eq $parent_scount ] ||
7183                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7184         echo "done."
7185
7186         # File currently set to -S 1M -c 1
7187
7188         # Ensure striping is preserved if -R is not set, and no stripe
7189         # count or size is specified
7190         echo -n "Verifying striping size preserved when not specified..."
7191         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7192         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7193                 error "cannot set stripe on parent directory"
7194         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7195                 error "migrate failed"
7196         cur_ssize=$($LFS getstripe -S "$file1")
7197         [ $cur_ssize -eq $orig_ssize ] ||
7198                 error "migrate by default $cur_ssize != $orig_ssize"
7199         echo "done."
7200
7201         # Ensure file name properly detected when final option has no argument
7202         echo -n "Verifying file name properly detected..."
7203         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7204                 error "file name interpreted as option argument"
7205         echo "done."
7206
7207         # Clean up
7208         rm -f "$file1"
7209 }
7210 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7211
7212 test_56wd() {
7213         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7214
7215         local file1=$DIR/$tdir/file1
7216
7217         echo -n "Creating test dir..."
7218         test_mkdir $DIR/$tdir || error "cannot create dir"
7219         echo "done."
7220
7221         echo -n "Creating test file..."
7222         touch $file1
7223         echo "done."
7224
7225         # Ensure 'lfs migrate' will fail by using a non-existent option,
7226         # and make sure rsync is not called to recover
7227         echo -n "Make sure --no-rsync option works..."
7228         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7229                 grep -q 'refusing to fall back to rsync' ||
7230                 error "rsync was called with --no-rsync set"
7231         echo "done."
7232
7233         # Ensure rsync is called without trying 'lfs migrate' first
7234         echo -n "Make sure --rsync option works..."
7235         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7236                 grep -q 'falling back to rsync' &&
7237                 error "lfs migrate was called with --rsync set"
7238         echo "done."
7239
7240         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7241         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7242                 grep -q 'at the same time' ||
7243                 error "--rsync and --no-rsync accepted concurrently"
7244         echo "done."
7245
7246         # Clean up
7247         rm -f $file1
7248 }
7249 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7250
7251 test_56we() {
7252         local td=$DIR/$tdir
7253         local tf=$td/$tfile
7254
7255         test_mkdir $td || error "cannot create $td"
7256         touch $tf || error "cannot touch $tf"
7257
7258         echo -n "Make sure --non-direct|-D works..."
7259         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7260                 grep -q "lfs migrate --non-direct" ||
7261                 error "--non-direct option cannot work correctly"
7262         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7263                 grep -q "lfs migrate -D" ||
7264                 error "-D option cannot work correctly"
7265         echo "done."
7266 }
7267 run_test 56we "check lfs_migrate --non-direct|-D support"
7268
7269 test_56x() {
7270         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7271         check_swap_layouts_support
7272
7273         local dir=$DIR/$tdir
7274         local ref1=/etc/passwd
7275         local file1=$dir/file1
7276
7277         test_mkdir $dir || error "creating dir $dir"
7278         $LFS setstripe -c 2 $file1
7279         cp $ref1 $file1
7280         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7281         stripe=$($LFS getstripe -c $file1)
7282         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7283         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7284
7285         # clean up
7286         rm -f $file1
7287 }
7288 run_test 56x "lfs migration support"
7289
7290 test_56xa() {
7291         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7292         check_swap_layouts_support
7293
7294         local dir=$DIR/$tdir/$testnum
7295
7296         test_mkdir -p $dir
7297
7298         local ref1=/etc/passwd
7299         local file1=$dir/file1
7300
7301         $LFS setstripe -c 2 $file1
7302         cp $ref1 $file1
7303         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7304
7305         local stripe=$($LFS getstripe -c $file1)
7306
7307         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7308         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7309
7310         # clean up
7311         rm -f $file1
7312 }
7313 run_test 56xa "lfs migration --block support"
7314
7315 check_migrate_links() {
7316         local dir="$1"
7317         local file1="$dir/file1"
7318         local begin="$2"
7319         local count="$3"
7320         local runas="$4"
7321         local total_count=$(($begin + $count - 1))
7322         local symlink_count=10
7323         local uniq_count=10
7324
7325         if [ ! -f "$file1" ]; then
7326                 echo -n "creating initial file..."
7327                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7328                         error "cannot setstripe initial file"
7329                 echo "done"
7330
7331                 echo -n "creating symlinks..."
7332                 for s in $(seq 1 $symlink_count); do
7333                         ln -s "$file1" "$dir/slink$s" ||
7334                                 error "cannot create symlinks"
7335                 done
7336                 echo "done"
7337
7338                 echo -n "creating nonlinked files..."
7339                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7340                         error "cannot create nonlinked files"
7341                 echo "done"
7342         fi
7343
7344         # create hard links
7345         if [ ! -f "$dir/file$total_count" ]; then
7346                 echo -n "creating hard links $begin:$total_count..."
7347                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7348                         /dev/null || error "cannot create hard links"
7349                 echo "done"
7350         fi
7351
7352         echo -n "checking number of hard links listed in xattrs..."
7353         local fid=$($LFS getstripe -F "$file1")
7354         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7355
7356         echo "${#paths[*]}"
7357         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7358                         skip "hard link list has unexpected size, skipping test"
7359         fi
7360         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7361                         error "link names should exceed xattrs size"
7362         fi
7363
7364         echo -n "migrating files..."
7365         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7366         local rc=$?
7367         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7368         echo "done"
7369
7370         # make sure all links have been properly migrated
7371         echo -n "verifying files..."
7372         fid=$($LFS getstripe -F "$file1") ||
7373                 error "cannot get fid for file $file1"
7374         for i in $(seq 2 $total_count); do
7375                 local fid2=$($LFS getstripe -F $dir/file$i)
7376
7377                 [ "$fid2" == "$fid" ] ||
7378                         error "migrated hard link has mismatched FID"
7379         done
7380
7381         # make sure hard links were properly detected, and migration was
7382         # performed only once for the entire link set; nonlinked files should
7383         # also be migrated
7384         local actual=$(grep -c 'done' <<< "$migrate_out")
7385         local expected=$(($uniq_count + 1))
7386
7387         [ "$actual" -eq  "$expected" ] ||
7388                 error "hard links individually migrated ($actual != $expected)"
7389
7390         # make sure the correct number of hard links are present
7391         local hardlinks=$(stat -c '%h' "$file1")
7392
7393         [ $hardlinks -eq $total_count ] ||
7394                 error "num hard links $hardlinks != $total_count"
7395         echo "done"
7396
7397         return 0
7398 }
7399
7400 test_56xb() {
7401         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7402                 skip "Need MDS version at least 2.10.55"
7403
7404         local dir="$DIR/$tdir"
7405
7406         test_mkdir "$dir" || error "cannot create dir $dir"
7407
7408         echo "testing lfs migrate mode when all links fit within xattrs"
7409         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7410
7411         echo "testing rsync mode when all links fit within xattrs"
7412         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7413
7414         echo "testing lfs migrate mode when all links do not fit within xattrs"
7415         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7416
7417         echo "testing rsync mode when all links do not fit within xattrs"
7418         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7419
7420         chown -R $RUNAS_ID $dir
7421         echo "testing non-root lfs migrate mode when not all links are in xattr"
7422         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7423
7424         # clean up
7425         rm -rf $dir
7426 }
7427 run_test 56xb "lfs migration hard link support"
7428
7429 test_56xc() {
7430         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7431
7432         local dir="$DIR/$tdir"
7433
7434         test_mkdir "$dir" || error "cannot create dir $dir"
7435
7436         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7437         echo -n "Setting initial stripe for 20MB test file..."
7438         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7439                 error "cannot setstripe 20MB file"
7440         echo "done"
7441         echo -n "Sizing 20MB test file..."
7442         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7443         echo "done"
7444         echo -n "Verifying small file autostripe count is 1..."
7445         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7446                 error "cannot migrate 20MB file"
7447         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7448                 error "cannot get stripe for $dir/20mb"
7449         [ $stripe_count -eq 1 ] ||
7450                 error "unexpected stripe count $stripe_count for 20MB file"
7451         rm -f "$dir/20mb"
7452         echo "done"
7453
7454         # Test 2: File is small enough to fit within the available space on
7455         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7456         # have at least an additional 1KB for each desired stripe for test 3
7457         echo -n "Setting stripe for 1GB test file..."
7458         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7459         echo "done"
7460         echo -n "Sizing 1GB test file..."
7461         # File size is 1GB + 3KB
7462         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7463         echo "done"
7464
7465         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7466         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7467         if (( avail > 524288 * OSTCOUNT )); then
7468                 echo -n "Migrating 1GB file..."
7469                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7470                         error "cannot migrate 1GB file"
7471                 echo "done"
7472                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7473                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7474                         error "cannot getstripe for 1GB file"
7475                 [ $stripe_count -eq 2 ] ||
7476                         error "unexpected stripe count $stripe_count != 2"
7477                 echo "done"
7478         fi
7479
7480         # Test 3: File is too large to fit within the available space on
7481         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7482         if [ $OSTCOUNT -ge 3 ]; then
7483                 # The required available space is calculated as
7484                 # file size (1GB + 3KB) / OST count (3).
7485                 local kb_per_ost=349526
7486
7487                 echo -n "Migrating 1GB file with limit..."
7488                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7489                         error "cannot migrate 1GB file with limit"
7490                 echo "done"
7491
7492                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7493                 echo -n "Verifying 1GB autostripe count with limited space..."
7494                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7495                         error "unexpected stripe count $stripe_count (min 3)"
7496                 echo "done"
7497         fi
7498
7499         # clean up
7500         rm -rf $dir
7501 }
7502 run_test 56xc "lfs migration autostripe"
7503
7504 test_56xd() {
7505         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7506
7507         local dir=$DIR/$tdir
7508         local f_mgrt=$dir/$tfile.mgrt
7509         local f_yaml=$dir/$tfile.yaml
7510         local f_copy=$dir/$tfile.copy
7511         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7512         local layout_copy="-c 2 -S 2M -i 1"
7513         local yamlfile=$dir/yamlfile
7514         local layout_before;
7515         local layout_after;
7516
7517         test_mkdir "$dir" || error "cannot create dir $dir"
7518         $LFS setstripe $layout_yaml $f_yaml ||
7519                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7520         $LFS getstripe --yaml $f_yaml > $yamlfile
7521         $LFS setstripe $layout_copy $f_copy ||
7522                 error "cannot setstripe $f_copy with layout $layout_copy"
7523         touch $f_mgrt
7524         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7525
7526         # 1. test option --yaml
7527         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7528                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7529         layout_before=$(get_layout_param $f_yaml)
7530         layout_after=$(get_layout_param $f_mgrt)
7531         [ "$layout_after" == "$layout_before" ] ||
7532                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7533
7534         # 2. test option --copy
7535         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7536                 error "cannot migrate $f_mgrt with --copy $f_copy"
7537         layout_before=$(get_layout_param $f_copy)
7538         layout_after=$(get_layout_param $f_mgrt)
7539         [ "$layout_after" == "$layout_before" ] ||
7540                 error "lfs_migrate --copy: $layout_after != $layout_before"
7541 }
7542 run_test 56xd "check lfs_migrate --yaml and --copy support"
7543
7544 test_56xe() {
7545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7546
7547         local dir=$DIR/$tdir
7548         local f_comp=$dir/$tfile
7549         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7550         local layout_before=""
7551         local layout_after=""
7552
7553         test_mkdir "$dir" || error "cannot create dir $dir"
7554         $LFS setstripe $layout $f_comp ||
7555                 error "cannot setstripe $f_comp with layout $layout"
7556         layout_before=$(get_layout_param $f_comp)
7557         dd if=/dev/zero of=$f_comp bs=1M count=4
7558
7559         # 1. migrate a comp layout file by lfs_migrate
7560         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7561         layout_after=$(get_layout_param $f_comp)
7562         [ "$layout_before" == "$layout_after" ] ||
7563                 error "lfs_migrate: $layout_before != $layout_after"
7564
7565         # 2. migrate a comp layout file by lfs migrate
7566         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7567         layout_after=$(get_layout_param $f_comp)
7568         [ "$layout_before" == "$layout_after" ] ||
7569                 error "lfs migrate: $layout_before != $layout_after"
7570 }
7571 run_test 56xe "migrate a composite layout file"
7572
7573 test_56xf() {
7574         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7575
7576         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7577                 skip "Need server version at least 2.13.53"
7578
7579         local dir=$DIR/$tdir
7580         local f_comp=$dir/$tfile
7581         local layout="-E 1M -c1 -E -1 -c2"
7582         local fid_before=""
7583         local fid_after=""
7584
7585         test_mkdir "$dir" || error "cannot create dir $dir"
7586         $LFS setstripe $layout $f_comp ||
7587                 error "cannot setstripe $f_comp with layout $layout"
7588         fid_before=$($LFS getstripe --fid $f_comp)
7589         dd if=/dev/zero of=$f_comp bs=1M count=4
7590
7591         # 1. migrate a comp layout file to a comp layout
7592         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7593         fid_after=$($LFS getstripe --fid $f_comp)
7594         [ "$fid_before" == "$fid_after" ] ||
7595                 error "comp-to-comp migrate: $fid_before != $fid_after"
7596
7597         # 2. migrate a comp layout file to a plain layout
7598         $LFS migrate -c2 $f_comp ||
7599                 error "cannot migrate $f_comp by lfs migrate"
7600         fid_after=$($LFS getstripe --fid $f_comp)
7601         [ "$fid_before" == "$fid_after" ] ||
7602                 error "comp-to-plain migrate: $fid_before != $fid_after"
7603
7604         # 3. migrate a plain layout file to a comp layout
7605         $LFS migrate $layout $f_comp ||
7606                 error "cannot migrate $f_comp by lfs migrate"
7607         fid_after=$($LFS getstripe --fid $f_comp)
7608         [ "$fid_before" == "$fid_after" ] ||
7609                 error "plain-to-comp migrate: $fid_before != $fid_after"
7610 }
7611 run_test 56xf "FID is not lost during migration of a composite layout file"
7612
7613 test_56y() {
7614         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7615                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7616
7617         local res=""
7618         local dir=$DIR/$tdir
7619         local f1=$dir/file1
7620         local f2=$dir/file2
7621
7622         test_mkdir -p $dir || error "creating dir $dir"
7623         touch $f1 || error "creating std file $f1"
7624         $MULTIOP $f2 H2c || error "creating released file $f2"
7625
7626         # a directory can be raid0, so ask only for files
7627         res=$($LFS find $dir -L raid0 -type f | wc -l)
7628         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7629
7630         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7631         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7632
7633         # only files can be released, so no need to force file search
7634         res=$($LFS find $dir -L released)
7635         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7636
7637         res=$($LFS find $dir -type f \! -L released)
7638         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7639 }
7640 run_test 56y "lfs find -L raid0|released"
7641
7642 test_56z() { # LU-4824
7643         # This checks to make sure 'lfs find' continues after errors
7644         # There are two classes of errors that should be caught:
7645         # - If multiple paths are provided, all should be searched even if one
7646         #   errors out
7647         # - If errors are encountered during the search, it should not terminate
7648         #   early
7649         local dir=$DIR/$tdir
7650         local i
7651
7652         test_mkdir $dir
7653         for i in d{0..9}; do
7654                 test_mkdir $dir/$i
7655                 touch $dir/$i/$tfile
7656         done
7657         $LFS find $DIR/non_existent_dir $dir &&
7658                 error "$LFS find did not return an error"
7659         # Make a directory unsearchable. This should NOT be the last entry in
7660         # directory order.  Arbitrarily pick the 6th entry
7661         chmod 700 $($LFS find $dir -type d | sed '6!d')
7662
7663         $RUNAS $LFS find $DIR/non_existent $dir
7664         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7665
7666         # The user should be able to see 10 directories and 9 files
7667         (( count == 19 )) ||
7668                 error "$LFS find found $count != 19 entries after error"
7669 }
7670 run_test 56z "lfs find should continue after an error"
7671
7672 test_56aa() { # LU-5937
7673         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7674
7675         local dir=$DIR/$tdir
7676
7677         mkdir $dir
7678         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7679
7680         createmany -o $dir/striped_dir/${tfile}- 1024
7681         local dirs=$($LFS find --size +8k $dir/)
7682
7683         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7684 }
7685 run_test 56aa "lfs find --size under striped dir"
7686
7687 test_56ab() { # LU-10705
7688         test_mkdir $DIR/$tdir
7689         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7690         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7691         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7692         # Flush writes to ensure valid blocks.  Need to be more thorough for
7693         # ZFS, since blocks are not allocated/returned to client immediately.
7694         sync_all_data
7695         wait_zfs_commit ost1 2
7696         cancel_lru_locks osc
7697         ls -ls $DIR/$tdir
7698
7699         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7700
7701         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7702
7703         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7704         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7705
7706         rm -f $DIR/$tdir/$tfile.[123]
7707 }
7708 run_test 56ab "lfs find --blocks"
7709
7710 # LU-11188
7711 test_56aca() {
7712         local dir="$DIR/$tdir"
7713         local perms=(001 002 003 004 005 006 007
7714                      010 020 030 040 050 060 070
7715                      100 200 300 400 500 600 700
7716                      111 222 333 444 555 666 777)
7717         local perm_minus=(8 8 4 8 4 4 2
7718                           8 8 4 8 4 4 2
7719                           8 8 4 8 4 4 2
7720                           4 4 2 4 2 2 1)
7721         local perm_slash=(8  8 12  8 12 12 14
7722                           8  8 12  8 12 12 14
7723                           8  8 12  8 12 12 14
7724                          16 16 24 16 24 24 28)
7725
7726         test_mkdir "$dir"
7727         for perm in ${perms[*]}; do
7728                 touch "$dir/$tfile.$perm"
7729                 chmod $perm "$dir/$tfile.$perm"
7730         done
7731
7732         for ((i = 0; i < ${#perms[*]}; i++)); do
7733                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7734                 (( $num == 1 )) ||
7735                         error "lfs find -perm ${perms[i]}:"\
7736                               "$num != 1"
7737
7738                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7739                 (( $num == ${perm_minus[i]} )) ||
7740                         error "lfs find -perm -${perms[i]}:"\
7741                               "$num != ${perm_minus[i]}"
7742
7743                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7744                 (( $num == ${perm_slash[i]} )) ||
7745                         error "lfs find -perm /${perms[i]}:"\
7746                               "$num != ${perm_slash[i]}"
7747         done
7748 }
7749 run_test 56aca "check lfs find -perm with octal representation"
7750
7751 test_56acb() {
7752         local dir=$DIR/$tdir
7753         # p is the permission of write and execute for user, group and other
7754         # without the umask. It is used to test +wx.
7755         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7756         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7757         local symbolic=(+t  a+t u+t g+t o+t
7758                         g+s u+s o+s +s o+sr
7759                         o=r,ug+o,u+w
7760                         u+ g+ o+ a+ ugo+
7761                         u- g- o- a- ugo-
7762                         u= g= o= a= ugo=
7763                         o=r,ug+o,u+w u=r,a+u,u+w
7764                         g=r,ugo=g,u+w u+x,+X +X
7765                         u+x,u+X u+X u+x,g+X o+r,+X
7766                         u+x,go+X +wx +rwx)
7767
7768         test_mkdir $dir
7769         for perm in ${perms[*]}; do
7770                 touch "$dir/$tfile.$perm"
7771                 chmod $perm "$dir/$tfile.$perm"
7772         done
7773
7774         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7775                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7776
7777                 (( $num == 1 )) ||
7778                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7779         done
7780 }
7781 run_test 56acb "check lfs find -perm with symbolic representation"
7782
7783 test_56acc() {
7784         local dir=$DIR/$tdir
7785         local tests="17777 787 789 abcd
7786                 ug=uu ug=a ug=gu uo=ou urw
7787                 u+xg+x a=r,u+x,"
7788
7789         test_mkdir $dir
7790         for err in $tests; do
7791                 if $LFS find $dir -perm $err 2>/dev/null; then
7792                         error "lfs find -perm $err: parsing should have failed"
7793                 fi
7794         done
7795 }
7796 run_test 56acc "check parsing error for lfs find -perm"
7797
7798 test_56ba() {
7799         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7800                 skip "Need MDS version at least 2.10.50"
7801
7802         # Create composite files with one component
7803         local dir=$DIR/$tdir
7804
7805         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7806         # Create composite files with three components
7807         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7808         # Create non-composite files
7809         createmany -o $dir/${tfile}- 10
7810
7811         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7812
7813         [[ $nfiles == 10 ]] ||
7814                 error "lfs find -E 1M found $nfiles != 10 files"
7815
7816         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7817         [[ $nfiles == 25 ]] ||
7818                 error "lfs find ! -E 1M found $nfiles != 25 files"
7819
7820         # All files have a component that starts at 0
7821         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7822         [[ $nfiles == 35 ]] ||
7823                 error "lfs find --component-start 0 - $nfiles != 35 files"
7824
7825         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7826         [[ $nfiles == 15 ]] ||
7827                 error "lfs find --component-start 2M - $nfiles != 15 files"
7828
7829         # All files created here have a componenet that does not starts at 2M
7830         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7831         [[ $nfiles == 35 ]] ||
7832                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7833
7834         # Find files with a specified number of components
7835         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7836         [[ $nfiles == 15 ]] ||
7837                 error "lfs find --component-count 3 - $nfiles != 15 files"
7838
7839         # Remember non-composite files have a component count of zero
7840         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7841         [[ $nfiles == 10 ]] ||
7842                 error "lfs find --component-count 0 - $nfiles != 10 files"
7843
7844         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7845         [[ $nfiles == 20 ]] ||
7846                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7847
7848         # All files have a flag called "init"
7849         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7850         [[ $nfiles == 35 ]] ||
7851                 error "lfs find --component-flags init - $nfiles != 35 files"
7852
7853         # Multi-component files will have a component not initialized
7854         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7855         [[ $nfiles == 15 ]] ||
7856                 error "lfs find !--component-flags init - $nfiles != 15 files"
7857
7858         rm -rf $dir
7859
7860 }
7861 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7862
7863 test_56ca() {
7864         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7865                 skip "Need MDS version at least 2.10.57"
7866
7867         local td=$DIR/$tdir
7868         local tf=$td/$tfile
7869         local dir
7870         local nfiles
7871         local cmd
7872         local i
7873         local j
7874
7875         # create mirrored directories and mirrored files
7876         mkdir $td || error "mkdir $td failed"
7877         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7878         createmany -o $tf- 10 || error "create $tf- failed"
7879
7880         for i in $(seq 2); do
7881                 dir=$td/dir$i
7882                 mkdir $dir || error "mkdir $dir failed"
7883                 $LFS mirror create -N$((3 + i)) $dir ||
7884                         error "create mirrored dir $dir failed"
7885                 createmany -o $dir/$tfile- 10 ||
7886                         error "create $dir/$tfile- failed"
7887         done
7888
7889         # change the states of some mirrored files
7890         echo foo > $tf-6
7891         for i in $(seq 2); do
7892                 dir=$td/dir$i
7893                 for j in $(seq 4 9); do
7894                         echo foo > $dir/$tfile-$j
7895                 done
7896         done
7897
7898         # find mirrored files with specific mirror count
7899         cmd="$LFS find --mirror-count 3 --type f $td"
7900         nfiles=$($cmd | wc -l)
7901         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7902
7903         cmd="$LFS find ! --mirror-count 3 --type f $td"
7904         nfiles=$($cmd | wc -l)
7905         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7906
7907         cmd="$LFS find --mirror-count +2 --type f $td"
7908         nfiles=$($cmd | wc -l)
7909         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7910
7911         cmd="$LFS find --mirror-count -6 --type f $td"
7912         nfiles=$($cmd | wc -l)
7913         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7914
7915         # find mirrored files with specific file state
7916         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7917         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7918
7919         cmd="$LFS find --mirror-state=ro --type f $td"
7920         nfiles=$($cmd | wc -l)
7921         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7922
7923         cmd="$LFS find ! --mirror-state=ro --type f $td"
7924         nfiles=$($cmd | wc -l)
7925         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7926
7927         cmd="$LFS find --mirror-state=wp --type f $td"
7928         nfiles=$($cmd | wc -l)
7929         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7930
7931         cmd="$LFS find ! --mirror-state=sp --type f $td"
7932         nfiles=$($cmd | wc -l)
7933         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7934 }
7935 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7936
7937 test_56da() { # LU-14179
7938         local path=$DIR/$tdir
7939
7940         test_mkdir $path
7941         cd $path
7942
7943         local longdir=$(str_repeat 'a' 255)
7944
7945         for i in {1..15}; do
7946                 path=$path/$longdir
7947                 test_mkdir $longdir
7948                 cd $longdir
7949         done
7950
7951         local len=${#path}
7952         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7953
7954         test_mkdir $lastdir
7955         cd $lastdir
7956         # PATH_MAX-1
7957         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7958
7959         # NAME_MAX
7960         touch $(str_repeat 'f' 255)
7961
7962         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7963                 error "lfs find reported an error"
7964
7965         rm -rf $DIR/$tdir
7966 }
7967 run_test 56da "test lfs find with long paths"
7968
7969 test_57a() {
7970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7971         # note test will not do anything if MDS is not local
7972         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7973                 skip_env "ldiskfs only test"
7974         fi
7975         remote_mds_nodsh && skip "remote MDS with nodsh"
7976
7977         local MNTDEV="osd*.*MDT*.mntdev"
7978         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7979         [ -z "$DEV" ] && error "can't access $MNTDEV"
7980         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7981                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7982                         error "can't access $DEV"
7983                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7984                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7985                 rm $TMP/t57a.dump
7986         done
7987 }
7988 run_test 57a "verify MDS filesystem created with large inodes =="
7989
7990 test_57b() {
7991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7992         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7993                 skip_env "ldiskfs only test"
7994         fi
7995         remote_mds_nodsh && skip "remote MDS with nodsh"
7996
7997         local dir=$DIR/$tdir
7998         local filecount=100
7999         local file1=$dir/f1
8000         local fileN=$dir/f$filecount
8001
8002         rm -rf $dir || error "removing $dir"
8003         test_mkdir -c1 $dir
8004         local mdtidx=$($LFS getstripe -m $dir)
8005         local mdtname=MDT$(printf %04x $mdtidx)
8006         local facet=mds$((mdtidx + 1))
8007
8008         echo "mcreating $filecount files"
8009         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8010
8011         # verify that files do not have EAs yet
8012         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8013                 error "$file1 has an EA"
8014         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8015                 error "$fileN has an EA"
8016
8017         sync
8018         sleep 1
8019         df $dir  #make sure we get new statfs data
8020         local mdsfree=$(do_facet $facet \
8021                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8022         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8023         local file
8024
8025         echo "opening files to create objects/EAs"
8026         for file in $(seq -f $dir/f%g 1 $filecount); do
8027                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8028                         error "opening $file"
8029         done
8030
8031         # verify that files have EAs now
8032         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8033         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8034
8035         sleep 1  #make sure we get new statfs data
8036         df $dir
8037         local mdsfree2=$(do_facet $facet \
8038                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8039         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8040
8041         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8042                 if [ "$mdsfree" != "$mdsfree2" ]; then
8043                         error "MDC before $mdcfree != after $mdcfree2"
8044                 else
8045                         echo "MDC before $mdcfree != after $mdcfree2"
8046                         echo "unable to confirm if MDS has large inodes"
8047                 fi
8048         fi
8049         rm -rf $dir
8050 }
8051 run_test 57b "default LOV EAs are stored inside large inodes ==="
8052
8053 test_58() {
8054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8055         [ -z "$(which wiretest 2>/dev/null)" ] &&
8056                         skip_env "could not find wiretest"
8057
8058         wiretest
8059 }
8060 run_test 58 "verify cross-platform wire constants =============="
8061
8062 test_59() {
8063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8064
8065         echo "touch 130 files"
8066         createmany -o $DIR/f59- 130
8067         echo "rm 130 files"
8068         unlinkmany $DIR/f59- 130
8069         sync
8070         # wait for commitment of removal
8071         wait_delete_completed
8072 }
8073 run_test 59 "verify cancellation of llog records async ========="
8074
8075 TEST60_HEAD="test_60 run $RANDOM"
8076 test_60a() {
8077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8078         remote_mgs_nodsh && skip "remote MGS with nodsh"
8079         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8080                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8081                         skip_env "missing subtest run-llog.sh"
8082
8083         log "$TEST60_HEAD - from kernel mode"
8084         do_facet mgs "$LCTL dk > /dev/null"
8085         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8086         do_facet mgs $LCTL dk > $TMP/$tfile
8087
8088         # LU-6388: test llog_reader
8089         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8090         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8091         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8092                         skip_env "missing llog_reader"
8093         local fstype=$(facet_fstype mgs)
8094         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8095                 skip_env "Only for ldiskfs or zfs type mgs"
8096
8097         local mntpt=$(facet_mntpt mgs)
8098         local mgsdev=$(mgsdevname 1)
8099         local fid_list
8100         local fid
8101         local rec_list
8102         local rec
8103         local rec_type
8104         local obj_file
8105         local path
8106         local seq
8107         local oid
8108         local pass=true
8109
8110         #get fid and record list
8111         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8112                 tail -n 4))
8113         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8114                 tail -n 4))
8115         #remount mgs as ldiskfs or zfs type
8116         stop mgs || error "stop mgs failed"
8117         mount_fstype mgs || error "remount mgs failed"
8118         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8119                 fid=${fid_list[i]}
8120                 rec=${rec_list[i]}
8121                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8122                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8123                 oid=$((16#$oid))
8124
8125                 case $fstype in
8126                         ldiskfs )
8127                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8128                         zfs )
8129                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8130                 esac
8131                 echo "obj_file is $obj_file"
8132                 do_facet mgs $llog_reader $obj_file
8133
8134                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8135                         awk '{ print $3 }' | sed -e "s/^type=//g")
8136                 if [ $rec_type != $rec ]; then
8137                         echo "FAILED test_60a wrong record type $rec_type," \
8138                               "should be $rec"
8139                         pass=false
8140                         break
8141                 fi
8142
8143                 #check obj path if record type is LLOG_LOGID_MAGIC
8144                 if [ "$rec" == "1064553b" ]; then
8145                         path=$(do_facet mgs $llog_reader $obj_file |
8146                                 grep "path=" | awk '{ print $NF }' |
8147                                 sed -e "s/^path=//g")
8148                         if [ $obj_file != $mntpt/$path ]; then
8149                                 echo "FAILED test_60a wrong obj path" \
8150                                       "$montpt/$path, should be $obj_file"
8151                                 pass=false
8152                                 break
8153                         fi
8154                 fi
8155         done
8156         rm -f $TMP/$tfile
8157         #restart mgs before "error", otherwise it will block the next test
8158         stop mgs || error "stop mgs failed"
8159         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8160         $pass || error "test failed, see FAILED test_60a messages for specifics"
8161 }
8162 run_test 60a "llog_test run from kernel module and test llog_reader"
8163
8164 test_60b() { # bug 6411
8165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8166
8167         dmesg > $DIR/$tfile
8168         LLOG_COUNT=$(do_facet mgs dmesg |
8169                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8170                           /llog_[a-z]*.c:[0-9]/ {
8171                                 if (marker)
8172                                         from_marker++
8173                                 from_begin++
8174                           }
8175                           END {
8176                                 if (marker)
8177                                         print from_marker
8178                                 else
8179                                         print from_begin
8180                           }")
8181
8182         [[ $LLOG_COUNT -gt 120 ]] &&
8183                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8184 }
8185 run_test 60b "limit repeated messages from CERROR/CWARN"
8186
8187 test_60c() {
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         echo "create 5000 files"
8191         createmany -o $DIR/f60c- 5000
8192 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8193         lctl set_param fail_loc=0x80000137
8194         unlinkmany $DIR/f60c- 5000
8195         lctl set_param fail_loc=0
8196 }
8197 run_test 60c "unlink file when mds full"
8198
8199 test_60d() {
8200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8201
8202         SAVEPRINTK=$(lctl get_param -n printk)
8203         # verify "lctl mark" is even working"
8204         MESSAGE="test message ID $RANDOM $$"
8205         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8206         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8207
8208         lctl set_param printk=0 || error "set lnet.printk failed"
8209         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8210         MESSAGE="new test message ID $RANDOM $$"
8211         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8212         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8213         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8214
8215         lctl set_param -n printk="$SAVEPRINTK"
8216 }
8217 run_test 60d "test printk console message masking"
8218
8219 test_60e() {
8220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8221         remote_mds_nodsh && skip "remote MDS with nodsh"
8222
8223         touch $DIR/$tfile
8224 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8225         do_facet mds1 lctl set_param fail_loc=0x15b
8226         rm $DIR/$tfile
8227 }
8228 run_test 60e "no space while new llog is being created"
8229
8230 test_60f() {
8231         local old_path=$($LCTL get_param -n debug_path)
8232
8233         stack_trap "$LCTL set_param debug_path=$old_path"
8234         stack_trap "rm -f $TMP/$tfile*"
8235         rm -f $TMP/$tfile* 2> /dev/null
8236         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8237         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8238         test_mkdir $DIR/$tdir
8239         # retry in case the open is cached and not released
8240         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8241                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8242                 sleep 0.1
8243         done
8244         ls $TMP/$tfile*
8245         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8246 }
8247 run_test 60f "change debug_path works"
8248
8249 test_60g() {
8250         local pid
8251         local i
8252
8253         test_mkdir -c $MDSCOUNT $DIR/$tdir
8254
8255         (
8256                 local index=0
8257                 while true; do
8258                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8259                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8260                                 2>/dev/null
8261                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8262                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8263                         index=$((index + 1))
8264                 done
8265         ) &
8266
8267         pid=$!
8268
8269         for i in {0..100}; do
8270                 # define OBD_FAIL_OSD_TXN_START    0x19a
8271                 local index=$((i % MDSCOUNT + 1))
8272
8273                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8274                         > /dev/null
8275                 sleep 0.01
8276         done
8277
8278         kill -9 $pid
8279
8280         for i in $(seq $MDSCOUNT); do
8281                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8282         done
8283
8284         mkdir $DIR/$tdir/new || error "mkdir failed"
8285         rmdir $DIR/$tdir/new || error "rmdir failed"
8286
8287         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8288                 -t namespace
8289         for i in $(seq $MDSCOUNT); do
8290                 wait_update_facet mds$i "$LCTL get_param -n \
8291                         mdd.$(facet_svc mds$i).lfsck_namespace |
8292                         awk '/^status/ { print \\\$2 }'" "completed"
8293         done
8294
8295         ls -R $DIR/$tdir || error "ls failed"
8296         rm -rf $DIR/$tdir || error "rmdir failed"
8297 }
8298 run_test 60g "transaction abort won't cause MDT hung"
8299
8300 test_60h() {
8301         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8302                 skip "Need MDS version at least 2.12.52"
8303         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8304
8305         local f
8306
8307         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8308         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8309         for fail_loc in 0x80000188 0x80000189; do
8310                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8311                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8312                         error "mkdir $dir-$fail_loc failed"
8313                 for i in {0..10}; do
8314                         # create may fail on missing stripe
8315                         echo $i > $DIR/$tdir-$fail_loc/$i
8316                 done
8317                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8318                         error "getdirstripe $tdir-$fail_loc failed"
8319                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8320                         error "migrate $tdir-$fail_loc failed"
8321                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8322                         error "getdirstripe $tdir-$fail_loc failed"
8323                 pushd $DIR/$tdir-$fail_loc
8324                 for f in *; do
8325                         echo $f | cmp $f - || error "$f data mismatch"
8326                 done
8327                 popd
8328                 rm -rf $DIR/$tdir-$fail_loc
8329         done
8330 }
8331 run_test 60h "striped directory with missing stripes can be accessed"
8332
8333 function t60i_load() {
8334         mkdir $DIR/$tdir
8335         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8336         $LCTL set_param fail_loc=0x131c fail_val=1
8337         for ((i=0; i<5000; i++)); do
8338                 touch $DIR/$tdir/f$i
8339         done
8340 }
8341
8342 test_60i() {
8343         changelog_register || error "changelog_register failed"
8344         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8345         changelog_users $SINGLEMDS | grep -q $cl_user ||
8346                 error "User $cl_user not found in changelog_users"
8347         changelog_chmask "ALL"
8348         t60i_load &
8349         local PID=$!
8350         for((i=0; i<100; i++)); do
8351                 changelog_dump >/dev/null ||
8352                         error "can't read changelog"
8353         done
8354         kill $PID
8355         wait $PID
8356         changelog_deregister || error "changelog_deregister failed"
8357         $LCTL set_param fail_loc=0
8358 }
8359 run_test 60i "llog: new record vs reader race"
8360
8361 test_61a() {
8362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8363
8364         f="$DIR/f61"
8365         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8366         cancel_lru_locks osc
8367         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8368         sync
8369 }
8370 run_test 61a "mmap() writes don't make sync hang ================"
8371
8372 test_61b() {
8373         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8374 }
8375 run_test 61b "mmap() of unstriped file is successful"
8376
8377 # bug 2330 - insufficient obd_match error checking causes LBUG
8378 test_62() {
8379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8380
8381         f="$DIR/f62"
8382         echo foo > $f
8383         cancel_lru_locks osc
8384         lctl set_param fail_loc=0x405
8385         cat $f && error "cat succeeded, expect -EIO"
8386         lctl set_param fail_loc=0
8387 }
8388 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8389 # match every page all of the time.
8390 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8391
8392 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8393 # Though this test is irrelevant anymore, it helped to reveal some
8394 # other grant bugs (LU-4482), let's keep it.
8395 test_63a() {   # was test_63
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397
8398         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8399
8400         for i in `seq 10` ; do
8401                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8402                 sleep 5
8403                 kill $!
8404                 sleep 1
8405         done
8406
8407         rm -f $DIR/f63 || true
8408 }
8409 run_test 63a "Verify oig_wait interruption does not crash ======="
8410
8411 # bug 2248 - async write errors didn't return to application on sync
8412 # bug 3677 - async write errors left page locked
8413 test_63b() {
8414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8415
8416         debugsave
8417         lctl set_param debug=-1
8418
8419         # ensure we have a grant to do async writes
8420         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8421         rm $DIR/$tfile
8422
8423         sync    # sync lest earlier test intercept the fail_loc
8424
8425         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8426         lctl set_param fail_loc=0x80000406
8427         $MULTIOP $DIR/$tfile Owy && \
8428                 error "sync didn't return ENOMEM"
8429         sync; sleep 2; sync     # do a real sync this time to flush page
8430         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8431                 error "locked page left in cache after async error" || true
8432         debugrestore
8433 }
8434 run_test 63b "async write errors should be returned to fsync ==="
8435
8436 test_64a () {
8437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8438
8439         lfs df $DIR
8440         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8441 }
8442 run_test 64a "verify filter grant calculations (in kernel) ====="
8443
8444 test_64b () {
8445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8446
8447         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8448 }
8449 run_test 64b "check out-of-space detection on client"
8450
8451 test_64c() {
8452         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8453 }
8454 run_test 64c "verify grant shrink"
8455
8456 import_param() {
8457         local tgt=$1
8458         local param=$2
8459
8460         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8461 }
8462
8463 # this does exactly what osc_request.c:osc_announce_cached() does in
8464 # order to calculate max amount of grants to ask from server
8465 want_grant() {
8466         local tgt=$1
8467
8468         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8469         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8470
8471         ((rpc_in_flight++));
8472         nrpages=$((nrpages * rpc_in_flight))
8473
8474         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8475
8476         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8477
8478         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8479         local undirty=$((nrpages * PAGE_SIZE))
8480
8481         local max_extent_pages
8482         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8483         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8484         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8485         local grant_extent_tax
8486         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8487
8488         undirty=$((undirty + nrextents * grant_extent_tax))
8489
8490         echo $undirty
8491 }
8492
8493 # this is size of unit for grant allocation. It should be equal to
8494 # what tgt_grant.c:tgt_grant_chunk() calculates
8495 grant_chunk() {
8496         local tgt=$1
8497         local max_brw_size
8498         local grant_extent_tax
8499
8500         max_brw_size=$(import_param $tgt max_brw_size)
8501
8502         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8503
8504         echo $(((max_brw_size + grant_extent_tax) * 2))
8505 }
8506
8507 test_64d() {
8508         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8509                 skip "OST < 2.10.55 doesn't limit grants enough"
8510
8511         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8512
8513         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8514                 skip "no grant_param connect flag"
8515
8516         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8517
8518         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8519         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8520
8521
8522         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8523         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8524
8525         $LFS setstripe $DIR/$tfile -i 0 -c 1
8526         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8527         ddpid=$!
8528
8529         while kill -0 $ddpid; do
8530                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8531
8532                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8533                         kill $ddpid
8534                         error "cur_grant $cur_grant > $max_cur_granted"
8535                 fi
8536
8537                 sleep 1
8538         done
8539 }
8540 run_test 64d "check grant limit exceed"
8541
8542 check_grants() {
8543         local tgt=$1
8544         local expected=$2
8545         local msg=$3
8546         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8547
8548         ((cur_grants == expected)) ||
8549                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8550 }
8551
8552 round_up_p2() {
8553         echo $((($1 + $2 - 1) & ~($2 - 1)))
8554 }
8555
8556 test_64e() {
8557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8558         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8559                 skip "Need OSS version at least 2.11.56"
8560
8561         # Remount client to reset grant
8562         remount_client $MOUNT || error "failed to remount client"
8563         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8564
8565         local init_grants=$(import_param $osc_tgt initial_grant)
8566
8567         check_grants $osc_tgt $init_grants "init grants"
8568
8569         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8570         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8571         local gbs=$(import_param $osc_tgt grant_block_size)
8572
8573         # write random number of bytes from max_brw_size / 4 to max_brw_size
8574         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8575         # align for direct io
8576         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8577         # round to grant consumption unit
8578         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8579
8580         local grants=$((wb_round_up + extent_tax))
8581
8582         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8583
8584         # define OBD_FAIL_TGT_NO_GRANT 0x725
8585         # make the server not grant more back
8586         do_facet ost1 $LCTL set_param fail_loc=0x725
8587         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8588
8589         do_facet ost1 $LCTL set_param fail_loc=0
8590
8591         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8592
8593         rm -f $DIR/$tfile || error "rm failed"
8594
8595         # Remount client to reset grant
8596         remount_client $MOUNT || error "failed to remount client"
8597         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8598
8599         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8600
8601         # define OBD_FAIL_TGT_NO_GRANT 0x725
8602         # make the server not grant more back
8603         do_facet ost1 $LCTL set_param fail_loc=0x725
8604         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8605         do_facet ost1 $LCTL set_param fail_loc=0
8606
8607         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8608 }
8609 run_test 64e "check grant consumption (no grant allocation)"
8610
8611 test_64f() {
8612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8613
8614         # Remount client to reset grant
8615         remount_client $MOUNT || error "failed to remount client"
8616         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8617
8618         local init_grants=$(import_param $osc_tgt initial_grant)
8619         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8620         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8621         local gbs=$(import_param $osc_tgt grant_block_size)
8622         local chunk=$(grant_chunk $osc_tgt)
8623
8624         # write random number of bytes from max_brw_size / 4 to max_brw_size
8625         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8626         # align for direct io
8627         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8628         # round to grant consumption unit
8629         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8630
8631         local grants=$((wb_round_up + extent_tax))
8632
8633         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8634         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8635                 error "error writing to $DIR/$tfile"
8636
8637         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8638                 "direct io with grant allocation"
8639
8640         rm -f $DIR/$tfile || error "rm failed"
8641
8642         # Remount client to reset grant
8643         remount_client $MOUNT || error "failed to remount client"
8644         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8645
8646         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8647
8648         local cmd="oO_WRONLY:w${write_bytes}_yc"
8649
8650         $MULTIOP $DIR/$tfile $cmd &
8651         MULTIPID=$!
8652         sleep 1
8653
8654         check_grants $osc_tgt $((init_grants - grants)) \
8655                 "buffered io, not write rpc"
8656
8657         kill -USR1 $MULTIPID
8658         wait
8659
8660         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8661                 "buffered io, one RPC"
8662 }
8663 run_test 64f "check grant consumption (with grant allocation)"
8664
8665 # bug 1414 - set/get directories' stripe info
8666 test_65a() {
8667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8668
8669         test_mkdir $DIR/$tdir
8670         touch $DIR/$tdir/f1
8671         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8672 }
8673 run_test 65a "directory with no stripe info"
8674
8675 test_65b() {
8676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8677
8678         test_mkdir $DIR/$tdir
8679         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8680
8681         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8682                                                 error "setstripe"
8683         touch $DIR/$tdir/f2
8684         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8685 }
8686 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8687
8688 test_65c() {
8689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8690         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8691
8692         test_mkdir $DIR/$tdir
8693         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8694
8695         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8696                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8697         touch $DIR/$tdir/f3
8698         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8699 }
8700 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8701
8702 test_65d() {
8703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8704
8705         test_mkdir $DIR/$tdir
8706         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8707         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8708
8709         if [[ $STRIPECOUNT -le 0 ]]; then
8710                 sc=1
8711         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8712                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8713                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8714         else
8715                 sc=$(($STRIPECOUNT - 1))
8716         fi
8717         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8718         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8719         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8720                 error "lverify failed"
8721 }
8722 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8723
8724 test_65e() {
8725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8726
8727         test_mkdir $DIR/$tdir
8728
8729         $LFS setstripe $DIR/$tdir || error "setstripe"
8730         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8731                                         error "no stripe info failed"
8732         touch $DIR/$tdir/f6
8733         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8734 }
8735 run_test 65e "directory setstripe defaults"
8736
8737 test_65f() {
8738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8739
8740         test_mkdir $DIR/${tdir}f
8741         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8742                 error "setstripe succeeded" || true
8743 }
8744 run_test 65f "dir setstripe permission (should return error) ==="
8745
8746 test_65g() {
8747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8748
8749         test_mkdir $DIR/$tdir
8750         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8751
8752         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8753                 error "setstripe -S failed"
8754         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8755         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8756                 error "delete default stripe failed"
8757 }
8758 run_test 65g "directory setstripe -d"
8759
8760 test_65h() {
8761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8762
8763         test_mkdir $DIR/$tdir
8764         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8765
8766         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8767                 error "setstripe -S failed"
8768         test_mkdir $DIR/$tdir/dd1
8769         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8770                 error "stripe info inherit failed"
8771 }
8772 run_test 65h "directory stripe info inherit ===================="
8773
8774 test_65i() {
8775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8776
8777         save_layout_restore_at_exit $MOUNT
8778
8779         # bug6367: set non-default striping on root directory
8780         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8781
8782         # bug12836: getstripe on -1 default directory striping
8783         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8784
8785         # bug12836: getstripe -v on -1 default directory striping
8786         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8787
8788         # bug12836: new find on -1 default directory striping
8789         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8790 }
8791 run_test 65i "various tests to set root directory striping"
8792
8793 test_65j() { # bug6367
8794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8795
8796         sync; sleep 1
8797
8798         # if we aren't already remounting for each test, do so for this test
8799         if [ "$I_MOUNTED" = "yes" ]; then
8800                 cleanup || error "failed to unmount"
8801                 setup
8802         fi
8803
8804         save_layout_restore_at_exit $MOUNT
8805
8806         $LFS setstripe -d $MOUNT || error "setstripe failed"
8807 }
8808 run_test 65j "set default striping on root directory (bug 6367)="
8809
8810 cleanup_65k() {
8811         rm -rf $DIR/$tdir
8812         wait_delete_completed
8813         do_facet $SINGLEMDS "lctl set_param -n \
8814                 osp.$ost*MDT0000.max_create_count=$max_count"
8815         do_facet $SINGLEMDS "lctl set_param -n \
8816                 osp.$ost*MDT0000.create_count=$count"
8817         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8818         echo $INACTIVE_OSC "is Activate"
8819
8820         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8821 }
8822
8823 test_65k() { # bug11679
8824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8825         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8826         remote_mds_nodsh && skip "remote MDS with nodsh"
8827
8828         local disable_precreate=true
8829         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8830                 disable_precreate=false
8831
8832         echo "Check OST status: "
8833         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8834                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8835
8836         for OSC in $MDS_OSCS; do
8837                 echo $OSC "is active"
8838                 do_facet $SINGLEMDS lctl --device %$OSC activate
8839         done
8840
8841         for INACTIVE_OSC in $MDS_OSCS; do
8842                 local ost=$(osc_to_ost $INACTIVE_OSC)
8843                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8844                                lov.*md*.target_obd |
8845                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8846
8847                 mkdir -p $DIR/$tdir
8848                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8849                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8850
8851                 echo "Deactivate: " $INACTIVE_OSC
8852                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8853
8854                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8855                               osp.$ost*MDT0000.create_count")
8856                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8857                                   osp.$ost*MDT0000.max_create_count")
8858                 $disable_precreate &&
8859                         do_facet $SINGLEMDS "lctl set_param -n \
8860                                 osp.$ost*MDT0000.max_create_count=0"
8861
8862                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8863                         [ -f $DIR/$tdir/$idx ] && continue
8864                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8865                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8866                                 { cleanup_65k;
8867                                   error "setstripe $idx should succeed"; }
8868                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8869                 done
8870                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8871                 rmdir $DIR/$tdir
8872
8873                 do_facet $SINGLEMDS "lctl set_param -n \
8874                         osp.$ost*MDT0000.max_create_count=$max_count"
8875                 do_facet $SINGLEMDS "lctl set_param -n \
8876                         osp.$ost*MDT0000.create_count=$count"
8877                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8878                 echo $INACTIVE_OSC "is Activate"
8879
8880                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8881         done
8882 }
8883 run_test 65k "validate manual striping works properly with deactivated OSCs"
8884
8885 test_65l() { # bug 12836
8886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8887
8888         test_mkdir -p $DIR/$tdir/test_dir
8889         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8890         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8891 }
8892 run_test 65l "lfs find on -1 stripe dir ========================"
8893
8894 test_65m() {
8895         local layout=$(save_layout $MOUNT)
8896         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8897                 restore_layout $MOUNT $layout
8898                 error "setstripe should fail by non-root users"
8899         }
8900         true
8901 }
8902 run_test 65m "normal user can't set filesystem default stripe"
8903
8904 test_65n() {
8905         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8906         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8907                 skip "Need MDS version at least 2.12.50"
8908         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8909
8910         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8911         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8912         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8913
8914         save_layout_restore_at_exit $MOUNT
8915
8916         # new subdirectory under root directory should not inherit
8917         # the default layout from root
8918         local dir1=$MOUNT/$tdir-1
8919         mkdir $dir1 || error "mkdir $dir1 failed"
8920         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8921                 error "$dir1 shouldn't have LOV EA"
8922
8923         # delete the default layout on root directory
8924         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8925
8926         local dir2=$MOUNT/$tdir-2
8927         mkdir $dir2 || error "mkdir $dir2 failed"
8928         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8929                 error "$dir2 shouldn't have LOV EA"
8930
8931         # set a new striping pattern on root directory
8932         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8933         local new_def_stripe_size=$((def_stripe_size * 2))
8934         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8935                 error "set stripe size on $MOUNT failed"
8936
8937         # new file created in $dir2 should inherit the new stripe size from
8938         # the filesystem default
8939         local file2=$dir2/$tfile-2
8940         touch $file2 || error "touch $file2 failed"
8941
8942         local file2_stripe_size=$($LFS getstripe -S $file2)
8943         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8944         {
8945                 echo "file2_stripe_size: '$file2_stripe_size'"
8946                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8947                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8948         }
8949
8950         local dir3=$MOUNT/$tdir-3
8951         mkdir $dir3 || error "mkdir $dir3 failed"
8952         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8953         # the root layout, which is the actual default layout that will be used
8954         # when new files are created in $dir3.
8955         local dir3_layout=$(get_layout_param $dir3)
8956         local root_dir_layout=$(get_layout_param $MOUNT)
8957         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8958         {
8959                 echo "dir3_layout: '$dir3_layout'"
8960                 echo "root_dir_layout: '$root_dir_layout'"
8961                 error "$dir3 should show the default layout from $MOUNT"
8962         }
8963
8964         # set OST pool on root directory
8965         local pool=$TESTNAME
8966         pool_add $pool || error "add $pool failed"
8967         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8968                 error "add targets to $pool failed"
8969
8970         $LFS setstripe -p $pool $MOUNT ||
8971                 error "set OST pool on $MOUNT failed"
8972
8973         # new file created in $dir3 should inherit the pool from
8974         # the filesystem default
8975         local file3=$dir3/$tfile-3
8976         touch $file3 || error "touch $file3 failed"
8977
8978         local file3_pool=$($LFS getstripe -p $file3)
8979         [[ "$file3_pool" = "$pool" ]] ||
8980                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8981
8982         local dir4=$MOUNT/$tdir-4
8983         mkdir $dir4 || error "mkdir $dir4 failed"
8984         local dir4_layout=$(get_layout_param $dir4)
8985         root_dir_layout=$(get_layout_param $MOUNT)
8986         echo "$LFS getstripe -d $dir4"
8987         $LFS getstripe -d $dir4
8988         echo "$LFS getstripe -d $MOUNT"
8989         $LFS getstripe -d $MOUNT
8990         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8991         {
8992                 echo "dir4_layout: '$dir4_layout'"
8993                 echo "root_dir_layout: '$root_dir_layout'"
8994                 error "$dir4 should show the default layout from $MOUNT"
8995         }
8996
8997         # new file created in $dir4 should inherit the pool from
8998         # the filesystem default
8999         local file4=$dir4/$tfile-4
9000         touch $file4 || error "touch $file4 failed"
9001
9002         local file4_pool=$($LFS getstripe -p $file4)
9003         [[ "$file4_pool" = "$pool" ]] ||
9004                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9005
9006         # new subdirectory under non-root directory should inherit
9007         # the default layout from its parent directory
9008         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9009                 error "set directory layout on $dir4 failed"
9010
9011         local dir5=$dir4/$tdir-5
9012         mkdir $dir5 || error "mkdir $dir5 failed"
9013
9014         dir4_layout=$(get_layout_param $dir4)
9015         local dir5_layout=$(get_layout_param $dir5)
9016         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9017         {
9018                 echo "dir4_layout: '$dir4_layout'"
9019                 echo "dir5_layout: '$dir5_layout'"
9020                 error "$dir5 should inherit the default layout from $dir4"
9021         }
9022
9023         # though subdir under ROOT doesn't inherit default layout, but
9024         # its sub dir/file should be created with default layout.
9025         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9026         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9027                 skip "Need MDS version at least 2.12.59"
9028
9029         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9030         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9031         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9032
9033         if [ $default_lmv_hash == "none" ]; then
9034                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9035         else
9036                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9037                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9038         fi
9039
9040         $LFS setdirstripe -D -c 2 $MOUNT ||
9041                 error "setdirstripe -D -c 2 failed"
9042         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9043         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9044         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9045 }
9046 run_test 65n "don't inherit default layout from root for new subdirectories"
9047
9048 # bug 2543 - update blocks count on client
9049 test_66() {
9050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9051
9052         COUNT=${COUNT:-8}
9053         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9054         sync; sync_all_data; sync; sync_all_data
9055         cancel_lru_locks osc
9056         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9057         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9058 }
9059 run_test 66 "update inode blocks count on client ==============="
9060
9061 meminfo() {
9062         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9063 }
9064
9065 swap_used() {
9066         swapon -s | awk '($1 == "'$1'") { print $4 }'
9067 }
9068
9069 # bug5265, obdfilter oa2dentry return -ENOENT
9070 # #define OBD_FAIL_SRV_ENOENT 0x217
9071 test_69() {
9072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9073         remote_ost_nodsh && skip "remote OST with nodsh"
9074
9075         f="$DIR/$tfile"
9076         $LFS setstripe -c 1 -i 0 $f
9077
9078         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9079
9080         do_facet ost1 lctl set_param fail_loc=0x217
9081         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9082         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9083
9084         do_facet ost1 lctl set_param fail_loc=0
9085         $DIRECTIO write $f 0 2 || error "write error"
9086
9087         cancel_lru_locks osc
9088         $DIRECTIO read $f 0 1 || error "read error"
9089
9090         do_facet ost1 lctl set_param fail_loc=0x217
9091         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9092
9093         do_facet ost1 lctl set_param fail_loc=0
9094         rm -f $f
9095 }
9096 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9097
9098 test_71() {
9099         test_mkdir $DIR/$tdir
9100         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9101         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9102 }
9103 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9104
9105 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9107         [ "$RUNAS_ID" = "$UID" ] &&
9108                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9109         # Check that testing environment is properly set up. Skip if not
9110         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9111                 skip_env "User $RUNAS_ID does not exist - skipping"
9112
9113         touch $DIR/$tfile
9114         chmod 777 $DIR/$tfile
9115         chmod ug+s $DIR/$tfile
9116         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9117                 error "$RUNAS dd $DIR/$tfile failed"
9118         # See if we are still setuid/sgid
9119         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9120                 error "S/gid is not dropped on write"
9121         # Now test that MDS is updated too
9122         cancel_lru_locks mdc
9123         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9124                 error "S/gid is not dropped on MDS"
9125         rm -f $DIR/$tfile
9126 }
9127 run_test 72a "Test that remove suid works properly (bug5695) ===="
9128
9129 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9130         local perm
9131
9132         [ "$RUNAS_ID" = "$UID" ] &&
9133                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9134         [ "$RUNAS_ID" -eq 0 ] &&
9135                 skip_env "RUNAS_ID = 0 -- skipping"
9136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9137         # Check that testing environment is properly set up. Skip if not
9138         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9139                 skip_env "User $RUNAS_ID does not exist - skipping"
9140
9141         touch $DIR/${tfile}-f{g,u}
9142         test_mkdir $DIR/${tfile}-dg
9143         test_mkdir $DIR/${tfile}-du
9144         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9145         chmod g+s $DIR/${tfile}-{f,d}g
9146         chmod u+s $DIR/${tfile}-{f,d}u
9147         for perm in 777 2777 4777; do
9148                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9149                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9150                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9151                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9152         done
9153         true
9154 }
9155 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9156
9157 # bug 3462 - multiple simultaneous MDC requests
9158 test_73() {
9159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9160
9161         test_mkdir $DIR/d73-1
9162         test_mkdir $DIR/d73-2
9163         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9164         pid1=$!
9165
9166         lctl set_param fail_loc=0x80000129
9167         $MULTIOP $DIR/d73-1/f73-2 Oc &
9168         sleep 1
9169         lctl set_param fail_loc=0
9170
9171         $MULTIOP $DIR/d73-2/f73-3 Oc &
9172         pid3=$!
9173
9174         kill -USR1 $pid1
9175         wait $pid1 || return 1
9176
9177         sleep 25
9178
9179         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9180         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9181         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9182
9183         rm -rf $DIR/d73-*
9184 }
9185 run_test 73 "multiple MDC requests (should not deadlock)"
9186
9187 test_74a() { # bug 6149, 6184
9188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9189
9190         touch $DIR/f74a
9191         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9192         #
9193         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9194         # will spin in a tight reconnection loop
9195         $LCTL set_param fail_loc=0x8000030e
9196         # get any lock that won't be difficult - lookup works.
9197         ls $DIR/f74a
9198         $LCTL set_param fail_loc=0
9199         rm -f $DIR/f74a
9200         true
9201 }
9202 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9203
9204 test_74b() { # bug 13310
9205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9206
9207         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9208         #
9209         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9210         # will spin in a tight reconnection loop
9211         $LCTL set_param fail_loc=0x8000030e
9212         # get a "difficult" lock
9213         touch $DIR/f74b
9214         $LCTL set_param fail_loc=0
9215         rm -f $DIR/f74b
9216         true
9217 }
9218 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9219
9220 test_74c() {
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222
9223         #define OBD_FAIL_LDLM_NEW_LOCK
9224         $LCTL set_param fail_loc=0x319
9225         touch $DIR/$tfile && error "touch successful"
9226         $LCTL set_param fail_loc=0
9227         true
9228 }
9229 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9230
9231 slab_lic=/sys/kernel/slab/lustre_inode_cache
9232 num_objects() {
9233         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9234         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9235                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9236 }
9237
9238 test_76a() { # Now for b=20433, added originally in b=1443
9239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9240
9241         cancel_lru_locks osc
9242         # there may be some slab objects cached per core
9243         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9244         local before=$(num_objects)
9245         local count=$((512 * cpus))
9246         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9247         local margin=$((count / 10))
9248         if [[ -f $slab_lic/aliases ]]; then
9249                 local aliases=$(cat $slab_lic/aliases)
9250                 (( aliases > 0 )) && margin=$((margin * aliases))
9251         fi
9252
9253         echo "before slab objects: $before"
9254         for i in $(seq $count); do
9255                 touch $DIR/$tfile
9256                 rm -f $DIR/$tfile
9257         done
9258         cancel_lru_locks osc
9259         local after=$(num_objects)
9260         echo "created: $count, after slab objects: $after"
9261         # shared slab counts are not very accurate, allow significant margin
9262         # the main goal is that the cache growth is not permanently > $count
9263         while (( after > before + margin )); do
9264                 sleep 1
9265                 after=$(num_objects)
9266                 wait=$((wait + 1))
9267                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9268                 if (( wait > 60 )); then
9269                         error "inode slab grew from $before+$margin to $after"
9270                 fi
9271         done
9272 }
9273 run_test 76a "confirm clients recycle inodes properly ===="
9274
9275 test_76b() {
9276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9277         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9278
9279         local count=512
9280         local before=$(num_objects)
9281
9282         for i in $(seq $count); do
9283                 mkdir $DIR/$tdir
9284                 rmdir $DIR/$tdir
9285         done
9286
9287         local after=$(num_objects)
9288         local wait=0
9289
9290         while (( after > before )); do
9291                 sleep 1
9292                 after=$(num_objects)
9293                 wait=$((wait + 1))
9294                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9295                 if (( wait > 60 )); then
9296                         error "inode slab grew from $before to $after"
9297                 fi
9298         done
9299
9300         echo "slab objects before: $before, after: $after"
9301 }
9302 run_test 76b "confirm clients recycle directory inodes properly ===="
9303
9304 export ORIG_CSUM=""
9305 set_checksums()
9306 {
9307         # Note: in sptlrpc modes which enable its own bulk checksum, the
9308         # original crc32_le bulk checksum will be automatically disabled,
9309         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9310         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9311         # In this case set_checksums() will not be no-op, because sptlrpc
9312         # bulk checksum will be enabled all through the test.
9313
9314         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9315         lctl set_param -n osc.*.checksums $1
9316         return 0
9317 }
9318
9319 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9320                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9321 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9322                              tr -d [] | head -n1)}
9323 set_checksum_type()
9324 {
9325         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9326         rc=$?
9327         log "set checksum type to $1, rc = $rc"
9328         return $rc
9329 }
9330
9331 get_osc_checksum_type()
9332 {
9333         # arugment 1: OST name, like OST0000
9334         ost=$1
9335         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9336                         sed 's/.*\[\(.*\)\].*/\1/g')
9337         rc=$?
9338         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9339         echo $checksum_type
9340 }
9341
9342 F77_TMP=$TMP/f77-temp
9343 F77SZ=8
9344 setup_f77() {
9345         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9346                 error "error writing to $F77_TMP"
9347 }
9348
9349 test_77a() { # bug 10889
9350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9351         $GSS && skip_env "could not run with gss"
9352
9353         [ ! -f $F77_TMP ] && setup_f77
9354         set_checksums 1
9355         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9356         set_checksums 0
9357         rm -f $DIR/$tfile
9358 }
9359 run_test 77a "normal checksum read/write operation"
9360
9361 test_77b() { # bug 10889
9362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9363         $GSS && skip_env "could not run with gss"
9364
9365         [ ! -f $F77_TMP ] && setup_f77
9366         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9367         $LCTL set_param fail_loc=0x80000409
9368         set_checksums 1
9369
9370         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9371                 error "dd error: $?"
9372         $LCTL set_param fail_loc=0
9373
9374         for algo in $CKSUM_TYPES; do
9375                 cancel_lru_locks osc
9376                 set_checksum_type $algo
9377                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9378                 $LCTL set_param fail_loc=0x80000408
9379                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9380                 $LCTL set_param fail_loc=0
9381         done
9382         set_checksums 0
9383         set_checksum_type $ORIG_CSUM_TYPE
9384         rm -f $DIR/$tfile
9385 }
9386 run_test 77b "checksum error on client write, read"
9387
9388 cleanup_77c() {
9389         trap 0
9390         set_checksums 0
9391         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9392         $check_ost &&
9393                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9394         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9395         $check_ost && [ -n "$ost_file_prefix" ] &&
9396                 do_facet ost1 rm -f ${ost_file_prefix}\*
9397 }
9398
9399 test_77c() {
9400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9401         $GSS && skip_env "could not run with gss"
9402         remote_ost_nodsh && skip "remote OST with nodsh"
9403
9404         local bad1
9405         local osc_file_prefix
9406         local osc_file
9407         local check_ost=false
9408         local ost_file_prefix
9409         local ost_file
9410         local orig_cksum
9411         local dump_cksum
9412         local fid
9413
9414         # ensure corruption will occur on first OSS/OST
9415         $LFS setstripe -i 0 $DIR/$tfile
9416
9417         [ ! -f $F77_TMP ] && setup_f77
9418         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9419                 error "dd write error: $?"
9420         fid=$($LFS path2fid $DIR/$tfile)
9421
9422         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9423         then
9424                 check_ost=true
9425                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9426                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9427         else
9428                 echo "OSS do not support bulk pages dump upon error"
9429         fi
9430
9431         osc_file_prefix=$($LCTL get_param -n debug_path)
9432         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9433
9434         trap cleanup_77c EXIT
9435
9436         set_checksums 1
9437         # enable bulk pages dump upon error on Client
9438         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9439         # enable bulk pages dump upon error on OSS
9440         $check_ost &&
9441                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9442
9443         # flush Client cache to allow next read to reach OSS
9444         cancel_lru_locks osc
9445
9446         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9447         $LCTL set_param fail_loc=0x80000408
9448         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9449         $LCTL set_param fail_loc=0
9450
9451         rm -f $DIR/$tfile
9452
9453         # check cksum dump on Client
9454         osc_file=$(ls ${osc_file_prefix}*)
9455         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9456         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9457         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9458         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9459         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9460                      cksum)
9461         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9462         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9463                 error "dump content does not match on Client"
9464
9465         $check_ost || skip "No need to check cksum dump on OSS"
9466
9467         # check cksum dump on OSS
9468         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9469         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9470         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9471         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9472         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9473                 error "dump content does not match on OSS"
9474
9475         cleanup_77c
9476 }
9477 run_test 77c "checksum error on client read with debug"
9478
9479 test_77d() { # bug 10889
9480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9481         $GSS && skip_env "could not run with gss"
9482
9483         stack_trap "rm -f $DIR/$tfile"
9484         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9485         $LCTL set_param fail_loc=0x80000409
9486         set_checksums 1
9487         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9488                 error "direct write: rc=$?"
9489         $LCTL set_param fail_loc=0
9490         set_checksums 0
9491
9492         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9493         $LCTL set_param fail_loc=0x80000408
9494         set_checksums 1
9495         cancel_lru_locks osc
9496         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9497                 error "direct read: rc=$?"
9498         $LCTL set_param fail_loc=0
9499         set_checksums 0
9500 }
9501 run_test 77d "checksum error on OST direct write, read"
9502
9503 test_77f() { # bug 10889
9504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9505         $GSS && skip_env "could not run with gss"
9506
9507         set_checksums 1
9508         stack_trap "rm -f $DIR/$tfile"
9509         for algo in $CKSUM_TYPES; do
9510                 cancel_lru_locks osc
9511                 set_checksum_type $algo
9512                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9513                 $LCTL set_param fail_loc=0x409
9514                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9515                         error "direct write succeeded"
9516                 $LCTL set_param fail_loc=0
9517         done
9518         set_checksum_type $ORIG_CSUM_TYPE
9519         set_checksums 0
9520 }
9521 run_test 77f "repeat checksum error on write (expect error)"
9522
9523 test_77g() { # bug 10889
9524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9525         $GSS && skip_env "could not run with gss"
9526         remote_ost_nodsh && skip "remote OST with nodsh"
9527
9528         [ ! -f $F77_TMP ] && setup_f77
9529
9530         local file=$DIR/$tfile
9531         stack_trap "rm -f $file" EXIT
9532
9533         $LFS setstripe -c 1 -i 0 $file
9534         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9535         do_facet ost1 lctl set_param fail_loc=0x8000021a
9536         set_checksums 1
9537         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9538                 error "write error: rc=$?"
9539         do_facet ost1 lctl set_param fail_loc=0
9540         set_checksums 0
9541
9542         cancel_lru_locks osc
9543         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9544         do_facet ost1 lctl set_param fail_loc=0x8000021b
9545         set_checksums 1
9546         cmp $F77_TMP $file || error "file compare failed"
9547         do_facet ost1 lctl set_param fail_loc=0
9548         set_checksums 0
9549 }
9550 run_test 77g "checksum error on OST write, read"
9551
9552 test_77k() { # LU-10906
9553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9554         $GSS && skip_env "could not run with gss"
9555
9556         local cksum_param="osc.$FSNAME*.checksums"
9557         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9558         local checksum
9559         local i
9560
9561         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9562         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9563         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9564
9565         for i in 0 1; do
9566                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9567                         error "failed to set checksum=$i on MGS"
9568                 wait_update $HOSTNAME "$get_checksum" $i
9569                 #remount
9570                 echo "remount client, checksum should be $i"
9571                 remount_client $MOUNT || error "failed to remount client"
9572                 checksum=$(eval $get_checksum)
9573                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9574         done
9575         # remove persistent param to avoid races with checksum mountopt below
9576         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9577                 error "failed to delete checksum on MGS"
9578
9579         for opt in "checksum" "nochecksum"; do
9580                 #remount with mount option
9581                 echo "remount client with option $opt, checksum should be $i"
9582                 umount_client $MOUNT || error "failed to umount client"
9583                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9584                         error "failed to mount client with option '$opt'"
9585                 checksum=$(eval $get_checksum)
9586                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9587                 i=$((i - 1))
9588         done
9589
9590         remount_client $MOUNT || error "failed to remount client"
9591 }
9592 run_test 77k "enable/disable checksum correctly"
9593
9594 test_77l() {
9595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9596         $GSS && skip_env "could not run with gss"
9597
9598         set_checksums 1
9599         stack_trap "set_checksums $ORIG_CSUM" EXIT
9600         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9601
9602         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9603
9604         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9605         for algo in $CKSUM_TYPES; do
9606                 set_checksum_type $algo || error "fail to set checksum type $algo"
9607                 osc_algo=$(get_osc_checksum_type OST0000)
9608                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9609
9610                 # no locks, no reqs to let the connection idle
9611                 cancel_lru_locks osc
9612                 lru_resize_disable osc
9613                 wait_osc_import_state client ost1 IDLE
9614
9615                 # ensure ost1 is connected
9616                 stat $DIR/$tfile >/dev/null || error "can't stat"
9617                 wait_osc_import_state client ost1 FULL
9618
9619                 osc_algo=$(get_osc_checksum_type OST0000)
9620                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9621         done
9622         return 0
9623 }
9624 run_test 77l "preferred checksum type is remembered after reconnected"
9625
9626 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9627 rm -f $F77_TMP
9628 unset F77_TMP
9629
9630 test_77m() {
9631         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9632                 skip "Need at least version 2.14.52"
9633         local param=checksum_speed
9634
9635         $LCTL get_param $param || error "reading $param failed"
9636
9637         csum_speeds=$($LCTL get_param -n $param)
9638
9639         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9640                 error "known checksum types are missing"
9641 }
9642 run_test 77m "Verify checksum_speed is correctly read"
9643
9644 cleanup_test_78() {
9645         trap 0
9646         rm -f $DIR/$tfile
9647 }
9648
9649 test_78() { # bug 10901
9650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9651         remote_ost || skip_env "local OST"
9652
9653         NSEQ=5
9654         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9655         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9656         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9657         echo "MemTotal: $MEMTOTAL"
9658
9659         # reserve 256MB of memory for the kernel and other running processes,
9660         # and then take 1/2 of the remaining memory for the read/write buffers.
9661         if [ $MEMTOTAL -gt 512 ] ;then
9662                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9663         else
9664                 # for those poor memory-starved high-end clusters...
9665                 MEMTOTAL=$((MEMTOTAL / 2))
9666         fi
9667         echo "Mem to use for directio: $MEMTOTAL"
9668
9669         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9670         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9671         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9672         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9673                 head -n1)
9674         echo "Smallest OST: $SMALLESTOST"
9675         [[ $SMALLESTOST -lt 10240 ]] &&
9676                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9677
9678         trap cleanup_test_78 EXIT
9679
9680         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9681                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9682
9683         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9684         echo "File size: $F78SIZE"
9685         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9686         for i in $(seq 1 $NSEQ); do
9687                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9688                 echo directIO rdwr round $i of $NSEQ
9689                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9690         done
9691
9692         cleanup_test_78
9693 }
9694 run_test 78 "handle large O_DIRECT writes correctly ============"
9695
9696 test_79() { # bug 12743
9697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9698
9699         wait_delete_completed
9700
9701         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9702         BKFREE=$(calc_osc_kbytes kbytesfree)
9703         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9704
9705         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9706         DFTOTAL=`echo $STRING | cut -d, -f1`
9707         DFUSED=`echo $STRING  | cut -d, -f2`
9708         DFAVAIL=`echo $STRING | cut -d, -f3`
9709         DFFREE=$(($DFTOTAL - $DFUSED))
9710
9711         ALLOWANCE=$((64 * $OSTCOUNT))
9712
9713         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9714            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9715                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9716         fi
9717         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9718            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9719                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9720         fi
9721         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9722            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9723                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9724         fi
9725 }
9726 run_test 79 "df report consistency check ======================="
9727
9728 test_80() { # bug 10718
9729         remote_ost_nodsh && skip "remote OST with nodsh"
9730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9731
9732         # relax strong synchronous semantics for slow backends like ZFS
9733         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9734                 local soc="obdfilter.*.sync_lock_cancel"
9735                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9736
9737                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9738                 if [ -z "$save" ]; then
9739                         soc="obdfilter.*.sync_on_lock_cancel"
9740                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9741                 fi
9742
9743                 if [ "$save" != "never" ]; then
9744                         local hosts=$(comma_list $(osts_nodes))
9745
9746                         do_nodes $hosts $LCTL set_param $soc=never
9747                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9748                 fi
9749         fi
9750
9751         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9752         sync; sleep 1; sync
9753         local before=$(date +%s)
9754         cancel_lru_locks osc
9755         local after=$(date +%s)
9756         local diff=$((after - before))
9757         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9758
9759         rm -f $DIR/$tfile
9760 }
9761 run_test 80 "Page eviction is equally fast at high offsets too"
9762
9763 test_81a() { # LU-456
9764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9765         remote_ost_nodsh && skip "remote OST with nodsh"
9766
9767         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9768         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9769         do_facet ost1 lctl set_param fail_loc=0x80000228
9770
9771         # write should trigger a retry and success
9772         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9773         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9774         RC=$?
9775         if [ $RC -ne 0 ] ; then
9776                 error "write should success, but failed for $RC"
9777         fi
9778 }
9779 run_test 81a "OST should retry write when get -ENOSPC ==============="
9780
9781 test_81b() { # LU-456
9782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9783         remote_ost_nodsh && skip "remote OST with nodsh"
9784
9785         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9786         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9787         do_facet ost1 lctl set_param fail_loc=0x228
9788
9789         # write should retry several times and return -ENOSPC finally
9790         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9791         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9792         RC=$?
9793         ENOSPC=28
9794         if [ $RC -ne $ENOSPC ] ; then
9795                 error "dd should fail for -ENOSPC, but succeed."
9796         fi
9797 }
9798 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9799
9800 test_99() {
9801         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9802
9803         test_mkdir $DIR/$tdir.cvsroot
9804         chown $RUNAS_ID $DIR/$tdir.cvsroot
9805
9806         cd $TMP
9807         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9808
9809         cd /etc/init.d
9810         # some versions of cvs import exit(1) when asked to import links or
9811         # files they can't read.  ignore those files.
9812         local toignore=$(find . -type l -printf '-I %f\n' -o \
9813                          ! -perm /4 -printf '-I %f\n')
9814         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9815                 $tdir.reposname vtag rtag
9816
9817         cd $DIR
9818         test_mkdir $DIR/$tdir.reposname
9819         chown $RUNAS_ID $DIR/$tdir.reposname
9820         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9821
9822         cd $DIR/$tdir.reposname
9823         $RUNAS touch foo99
9824         $RUNAS cvs add -m 'addmsg' foo99
9825         $RUNAS cvs update
9826         $RUNAS cvs commit -m 'nomsg' foo99
9827         rm -fr $DIR/$tdir.cvsroot
9828 }
9829 run_test 99 "cvs strange file/directory operations"
9830
9831 test_100() {
9832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9833         [[ "$NETTYPE" =~ tcp ]] ||
9834                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9835         remote_ost_nodsh && skip "remote OST with nodsh"
9836         remote_mds_nodsh && skip "remote MDS with nodsh"
9837         remote_servers ||
9838                 skip "useless for local single node setup"
9839
9840         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9841                 [ "$PROT" != "tcp" ] && continue
9842                 RPORT=$(echo $REMOTE | cut -d: -f2)
9843                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9844
9845                 rc=0
9846                 LPORT=`echo $LOCAL | cut -d: -f2`
9847                 if [ $LPORT -ge 1024 ]; then
9848                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9849                         netstat -tna
9850                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9851                 fi
9852         done
9853         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9854 }
9855 run_test 100 "check local port using privileged port ==========="
9856
9857 function get_named_value()
9858 {
9859     local tag=$1
9860
9861     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9862 }
9863
9864 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9865                    awk '/^max_cached_mb/ { print $2 }')
9866
9867 cleanup_101a() {
9868         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9869         trap 0
9870 }
9871
9872 test_101a() {
9873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9874
9875         local s
9876         local discard
9877         local nreads=10000
9878         local cache_limit=32
9879
9880         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9881         trap cleanup_101a EXIT
9882         $LCTL set_param -n llite.*.read_ahead_stats=0
9883         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9884
9885         #
9886         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9887         #
9888         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9889         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9890
9891         discard=0
9892         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9893                    get_named_value 'read.but.discarded'); do
9894                         discard=$(($discard + $s))
9895         done
9896         cleanup_101a
9897
9898         $LCTL get_param osc.*-osc*.rpc_stats
9899         $LCTL get_param llite.*.read_ahead_stats
9900
9901         # Discard is generally zero, but sometimes a few random reads line up
9902         # and trigger larger readahead, which is wasted & leads to discards.
9903         if [[ $(($discard)) -gt $nreads ]]; then
9904                 error "too many ($discard) discarded pages"
9905         fi
9906         rm -f $DIR/$tfile || true
9907 }
9908 run_test 101a "check read-ahead for random reads"
9909
9910 setup_test101bc() {
9911         test_mkdir $DIR/$tdir
9912         local ssize=$1
9913         local FILE_LENGTH=$2
9914         STRIPE_OFFSET=0
9915
9916         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9917
9918         local list=$(comma_list $(osts_nodes))
9919         set_osd_param $list '' read_cache_enable 0
9920         set_osd_param $list '' writethrough_cache_enable 0
9921
9922         trap cleanup_test101bc EXIT
9923         # prepare the read-ahead file
9924         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9925
9926         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9927                                 count=$FILE_SIZE_MB 2> /dev/null
9928
9929 }
9930
9931 cleanup_test101bc() {
9932         trap 0
9933         rm -rf $DIR/$tdir
9934         rm -f $DIR/$tfile
9935
9936         local list=$(comma_list $(osts_nodes))
9937         set_osd_param $list '' read_cache_enable 1
9938         set_osd_param $list '' writethrough_cache_enable 1
9939 }
9940
9941 calc_total() {
9942         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9943 }
9944
9945 ra_check_101() {
9946         local READ_SIZE=$1
9947         local STRIPE_SIZE=$2
9948         local FILE_LENGTH=$3
9949         local RA_INC=1048576
9950         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9951         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9952                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9953         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9954                   get_named_value 'read.but.discarded' | calc_total)
9955         if [[ $DISCARD -gt $discard_limit ]]; then
9956                 $LCTL get_param llite.*.read_ahead_stats
9957                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9958         else
9959                 echo "Read-ahead success for size ${READ_SIZE}"
9960         fi
9961 }
9962
9963 test_101b() {
9964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9965         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9966
9967         local STRIPE_SIZE=1048576
9968         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9969
9970         if [ $SLOW == "yes" ]; then
9971                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9972         else
9973                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9974         fi
9975
9976         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9977
9978         # prepare the read-ahead file
9979         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9980         cancel_lru_locks osc
9981         for BIDX in 2 4 8 16 32 64 128 256
9982         do
9983                 local BSIZE=$((BIDX*4096))
9984                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9985                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9986                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9987                 $LCTL set_param -n llite.*.read_ahead_stats=0
9988                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9989                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9990                 cancel_lru_locks osc
9991                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9992         done
9993         cleanup_test101bc
9994         true
9995 }
9996 run_test 101b "check stride-io mode read-ahead ================="
9997
9998 test_101c() {
9999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10000
10001         local STRIPE_SIZE=1048576
10002         local FILE_LENGTH=$((STRIPE_SIZE*100))
10003         local nreads=10000
10004         local rsize=65536
10005         local osc_rpc_stats
10006
10007         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10008
10009         cancel_lru_locks osc
10010         $LCTL set_param osc.*.rpc_stats=0
10011         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10012         $LCTL get_param osc.*.rpc_stats
10013         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10014                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10015                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10016                 local size
10017
10018                 if [ $lines -le 20 ]; then
10019                         echo "continue debug"
10020                         continue
10021                 fi
10022                 for size in 1 2 4 8; do
10023                         local rpc=$(echo "$stats" |
10024                                     awk '($1 == "'$size':") {print $2; exit; }')
10025                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10026                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10027                 done
10028                 echo "$osc_rpc_stats check passed!"
10029         done
10030         cleanup_test101bc
10031         true
10032 }
10033 run_test 101c "check stripe_size aligned read-ahead"
10034
10035 test_101d() {
10036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10037
10038         local file=$DIR/$tfile
10039         local sz_MB=${FILESIZE_101d:-80}
10040         local ra_MB=${READAHEAD_MB:-40}
10041
10042         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10043         [ $free_MB -lt $sz_MB ] &&
10044                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10045
10046         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10047         $LFS setstripe -c -1 $file || error "setstripe failed"
10048
10049         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10050         echo Cancel LRU locks on lustre client to flush the client cache
10051         cancel_lru_locks osc
10052
10053         echo Disable read-ahead
10054         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10055         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10056         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10057         $LCTL get_param -n llite.*.max_read_ahead_mb
10058
10059         echo "Reading the test file $file with read-ahead disabled"
10060         local sz_KB=$((sz_MB * 1024 / 4))
10061         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10062         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10063         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10064                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10065
10066         echo "Cancel LRU locks on lustre client to flush the client cache"
10067         cancel_lru_locks osc
10068         echo Enable read-ahead with ${ra_MB}MB
10069         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10070
10071         echo "Reading the test file $file with read-ahead enabled"
10072         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10073                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10074
10075         echo "read-ahead disabled time read $raOFF"
10076         echo "read-ahead enabled time read $raON"
10077
10078         rm -f $file
10079         wait_delete_completed
10080
10081         # use awk for this check instead of bash because it handles decimals
10082         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10083                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10084 }
10085 run_test 101d "file read with and without read-ahead enabled"
10086
10087 test_101e() {
10088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10089
10090         local file=$DIR/$tfile
10091         local size_KB=500  #KB
10092         local count=100
10093         local bsize=1024
10094
10095         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10096         local need_KB=$((count * size_KB))
10097         [[ $free_KB -le $need_KB ]] &&
10098                 skip_env "Need free space $need_KB, have $free_KB"
10099
10100         echo "Creating $count ${size_KB}K test files"
10101         for ((i = 0; i < $count; i++)); do
10102                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10103         done
10104
10105         echo "Cancel LRU locks on lustre client to flush the client cache"
10106         cancel_lru_locks $OSC
10107
10108         echo "Reset readahead stats"
10109         $LCTL set_param -n llite.*.read_ahead_stats=0
10110
10111         for ((i = 0; i < $count; i++)); do
10112                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10113         done
10114
10115         $LCTL get_param llite.*.max_cached_mb
10116         $LCTL get_param llite.*.read_ahead_stats
10117         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10118                      get_named_value 'misses' | calc_total)
10119
10120         for ((i = 0; i < $count; i++)); do
10121                 rm -rf $file.$i 2>/dev/null
10122         done
10123
10124         #10000 means 20% reads are missing in readahead
10125         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10126 }
10127 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10128
10129 test_101f() {
10130         which iozone || skip_env "no iozone installed"
10131
10132         local old_debug=$($LCTL get_param debug)
10133         old_debug=${old_debug#*=}
10134         $LCTL set_param debug="reada mmap"
10135
10136         # create a test file
10137         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10138
10139         echo Cancel LRU locks on lustre client to flush the client cache
10140         cancel_lru_locks osc
10141
10142         echo Reset readahead stats
10143         $LCTL set_param -n llite.*.read_ahead_stats=0
10144
10145         echo mmap read the file with small block size
10146         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10147                 > /dev/null 2>&1
10148
10149         echo checking missing pages
10150         $LCTL get_param llite.*.read_ahead_stats
10151         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10152                         get_named_value 'misses' | calc_total)
10153
10154         $LCTL set_param debug="$old_debug"
10155         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10156         rm -f $DIR/$tfile
10157 }
10158 run_test 101f "check mmap read performance"
10159
10160 test_101g_brw_size_test() {
10161         local mb=$1
10162         local pages=$((mb * 1048576 / PAGE_SIZE))
10163         local file=$DIR/$tfile
10164
10165         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10166                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10167         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10168                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10169                         return 2
10170         done
10171
10172         stack_trap "rm -f $file" EXIT
10173         $LCTL set_param -n osc.*.rpc_stats=0
10174
10175         # 10 RPCs should be enough for the test
10176         local count=10
10177         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10178                 { error "dd write ${mb} MB blocks failed"; return 3; }
10179         cancel_lru_locks osc
10180         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10181                 { error "dd write ${mb} MB blocks failed"; return 4; }
10182
10183         # calculate number of full-sized read and write RPCs
10184         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10185                 sed -n '/pages per rpc/,/^$/p' |
10186                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10187                 END { print reads,writes }'))
10188         # allow one extra full-sized read RPC for async readahead
10189         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10190                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10191         [[ ${rpcs[1]} == $count ]] ||
10192                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10193 }
10194
10195 test_101g() {
10196         remote_ost_nodsh && skip "remote OST with nodsh"
10197
10198         local rpcs
10199         local osts=$(get_facets OST)
10200         local list=$(comma_list $(osts_nodes))
10201         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10202         local brw_size="obdfilter.*.brw_size"
10203
10204         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10205
10206         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10207
10208         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10209                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10210                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10211            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10212                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10213                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10214
10215                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10216                         suffix="M"
10217
10218                 if [[ $orig_mb -lt 16 ]]; then
10219                         save_lustre_params $osts "$brw_size" > $p
10220                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10221                                 error "set 16MB RPC size failed"
10222
10223                         echo "remount client to enable new RPC size"
10224                         remount_client $MOUNT || error "remount_client failed"
10225                 fi
10226
10227                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10228                 # should be able to set brw_size=12, but no rpc_stats for that
10229                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10230         fi
10231
10232         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10233
10234         if [[ $orig_mb -lt 16 ]]; then
10235                 restore_lustre_params < $p
10236                 remount_client $MOUNT || error "remount_client restore failed"
10237         fi
10238
10239         rm -f $p $DIR/$tfile
10240 }
10241 run_test 101g "Big bulk(4/16 MiB) readahead"
10242
10243 test_101h() {
10244         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10245
10246         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10247                 error "dd 70M file failed"
10248         echo Cancel LRU locks on lustre client to flush the client cache
10249         cancel_lru_locks osc
10250
10251         echo "Reset readahead stats"
10252         $LCTL set_param -n llite.*.read_ahead_stats 0
10253
10254         echo "Read 10M of data but cross 64M bundary"
10255         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10256         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10257                      get_named_value 'misses' | calc_total)
10258         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10259         rm -f $p $DIR/$tfile
10260 }
10261 run_test 101h "Readahead should cover current read window"
10262
10263 test_101i() {
10264         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10265                 error "dd 10M file failed"
10266
10267         local max_per_file_mb=$($LCTL get_param -n \
10268                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10269         cancel_lru_locks osc
10270         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10271         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10272                 error "set max_read_ahead_per_file_mb to 1 failed"
10273
10274         echo "Reset readahead stats"
10275         $LCTL set_param llite.*.read_ahead_stats=0
10276
10277         dd if=$DIR/$tfile of=/dev/null bs=2M
10278
10279         $LCTL get_param llite.*.read_ahead_stats
10280         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10281                      awk '/misses/ { print $2 }')
10282         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10283         rm -f $DIR/$tfile
10284 }
10285 run_test 101i "allow current readahead to exceed reservation"
10286
10287 test_101j() {
10288         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10289                 error "setstripe $DIR/$tfile failed"
10290         local file_size=$((1048576 * 16))
10291         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10292         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10293
10294         echo Disable read-ahead
10295         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10296
10297         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10298         for blk in $PAGE_SIZE 1048576 $file_size; do
10299                 cancel_lru_locks osc
10300                 echo "Reset readahead stats"
10301                 $LCTL set_param -n llite.*.read_ahead_stats=0
10302                 local count=$(($file_size / $blk))
10303                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10304                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10305                              get_named_value 'failed.to.fast.read' | calc_total)
10306                 $LCTL get_param -n llite.*.read_ahead_stats
10307                 [ $miss -eq $count ] || error "expected $count got $miss"
10308         done
10309
10310         rm -f $p $DIR/$tfile
10311 }
10312 run_test 101j "A complete read block should be submitted when no RA"
10313
10314 setup_test102() {
10315         test_mkdir $DIR/$tdir
10316         chown $RUNAS_ID $DIR/$tdir
10317         STRIPE_SIZE=65536
10318         STRIPE_OFFSET=1
10319         STRIPE_COUNT=$OSTCOUNT
10320         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10321
10322         trap cleanup_test102 EXIT
10323         cd $DIR
10324         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10325         cd $DIR/$tdir
10326         for num in 1 2 3 4; do
10327                 for count in $(seq 1 $STRIPE_COUNT); do
10328                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10329                                 local size=`expr $STRIPE_SIZE \* $num`
10330                                 local file=file"$num-$idx-$count"
10331                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10332                         done
10333                 done
10334         done
10335
10336         cd $DIR
10337         $1 tar cf $TMP/f102.tar $tdir --xattrs
10338 }
10339
10340 cleanup_test102() {
10341         trap 0
10342         rm -f $TMP/f102.tar
10343         rm -rf $DIR/d0.sanity/d102
10344 }
10345
10346 test_102a() {
10347         [ "$UID" != 0 ] && skip "must run as root"
10348         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10349                 skip_env "must have user_xattr"
10350
10351         [ -z "$(which setfattr 2>/dev/null)" ] &&
10352                 skip_env "could not find setfattr"
10353
10354         local testfile=$DIR/$tfile
10355
10356         touch $testfile
10357         echo "set/get xattr..."
10358         setfattr -n trusted.name1 -v value1 $testfile ||
10359                 error "setfattr -n trusted.name1=value1 $testfile failed"
10360         getfattr -n trusted.name1 $testfile 2> /dev/null |
10361           grep "trusted.name1=.value1" ||
10362                 error "$testfile missing trusted.name1=value1"
10363
10364         setfattr -n user.author1 -v author1 $testfile ||
10365                 error "setfattr -n user.author1=author1 $testfile failed"
10366         getfattr -n user.author1 $testfile 2> /dev/null |
10367           grep "user.author1=.author1" ||
10368                 error "$testfile missing trusted.author1=author1"
10369
10370         echo "listxattr..."
10371         setfattr -n trusted.name2 -v value2 $testfile ||
10372                 error "$testfile unable to set trusted.name2"
10373         setfattr -n trusted.name3 -v value3 $testfile ||
10374                 error "$testfile unable to set trusted.name3"
10375         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10376             grep "trusted.name" | wc -l) -eq 3 ] ||
10377                 error "$testfile missing 3 trusted.name xattrs"
10378
10379         setfattr -n user.author2 -v author2 $testfile ||
10380                 error "$testfile unable to set user.author2"
10381         setfattr -n user.author3 -v author3 $testfile ||
10382                 error "$testfile unable to set user.author3"
10383         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10384             grep "user.author" | wc -l) -eq 3 ] ||
10385                 error "$testfile missing 3 user.author xattrs"
10386
10387         echo "remove xattr..."
10388         setfattr -x trusted.name1 $testfile ||
10389                 error "$testfile error deleting trusted.name1"
10390         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10391                 error "$testfile did not delete trusted.name1 xattr"
10392
10393         setfattr -x user.author1 $testfile ||
10394                 error "$testfile error deleting user.author1"
10395         echo "set lustre special xattr ..."
10396         $LFS setstripe -c1 $testfile
10397         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10398                 awk -F "=" '/trusted.lov/ { print $2 }' )
10399         setfattr -n "trusted.lov" -v $lovea $testfile ||
10400                 error "$testfile doesn't ignore setting trusted.lov again"
10401         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10402                 error "$testfile allow setting invalid trusted.lov"
10403         rm -f $testfile
10404 }
10405 run_test 102a "user xattr test =================================="
10406
10407 check_102b_layout() {
10408         local layout="$*"
10409         local testfile=$DIR/$tfile
10410
10411         echo "test layout '$layout'"
10412         $LFS setstripe $layout $testfile || error "setstripe failed"
10413         $LFS getstripe -y $testfile
10414
10415         echo "get/set/list trusted.lov xattr ..." # b=10930
10416         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10417         [[ "$value" =~ "trusted.lov" ]] ||
10418                 error "can't get trusted.lov from $testfile"
10419         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10420                 error "getstripe failed"
10421
10422         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10423
10424         value=$(cut -d= -f2 <<<$value)
10425         # LU-13168: truncated xattr should fail if short lov_user_md header
10426         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10427                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10428         for len in $lens; do
10429                 echo "setfattr $len $testfile.2"
10430                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10431                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10432         done
10433         local stripe_size=$($LFS getstripe -S $testfile.2)
10434         local stripe_count=$($LFS getstripe -c $testfile.2)
10435         [[ $stripe_size -eq 65536 ]] ||
10436                 error "stripe size $stripe_size != 65536"
10437         [[ $stripe_count -eq $stripe_count_orig ]] ||
10438                 error "stripe count $stripe_count != $stripe_count_orig"
10439         rm $testfile $testfile.2
10440 }
10441
10442 test_102b() {
10443         [ -z "$(which setfattr 2>/dev/null)" ] &&
10444                 skip_env "could not find setfattr"
10445         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10446
10447         # check plain layout
10448         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10449
10450         # and also check composite layout
10451         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10452
10453 }
10454 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10455
10456 test_102c() {
10457         [ -z "$(which setfattr 2>/dev/null)" ] &&
10458                 skip_env "could not find setfattr"
10459         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10460
10461         # b10930: get/set/list lustre.lov xattr
10462         echo "get/set/list lustre.lov xattr ..."
10463         test_mkdir $DIR/$tdir
10464         chown $RUNAS_ID $DIR/$tdir
10465         local testfile=$DIR/$tdir/$tfile
10466         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10467                 error "setstripe failed"
10468         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10469                 error "getstripe failed"
10470         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10471         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10472
10473         local testfile2=${testfile}2
10474         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10475                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10476
10477         $RUNAS $MCREATE $testfile2
10478         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10479         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10480         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10481         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10482         [ $stripe_count -eq $STRIPECOUNT ] ||
10483                 error "stripe count $stripe_count != $STRIPECOUNT"
10484 }
10485 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10486
10487 compare_stripe_info1() {
10488         local stripe_index_all_zero=true
10489
10490         for num in 1 2 3 4; do
10491                 for count in $(seq 1 $STRIPE_COUNT); do
10492                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10493                                 local size=$((STRIPE_SIZE * num))
10494                                 local file=file"$num-$offset-$count"
10495                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10496                                 [[ $stripe_size -ne $size ]] &&
10497                                     error "$file: size $stripe_size != $size"
10498                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10499                                 # allow fewer stripes to be created, ORI-601
10500                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10501                                     error "$file: count $stripe_count != $count"
10502                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10503                                 [[ $stripe_index -ne 0 ]] &&
10504                                         stripe_index_all_zero=false
10505                         done
10506                 done
10507         done
10508         $stripe_index_all_zero &&
10509                 error "all files are being extracted starting from OST index 0"
10510         return 0
10511 }
10512
10513 have_xattrs_include() {
10514         tar --help | grep -q xattrs-include &&
10515                 echo --xattrs-include="lustre.*"
10516 }
10517
10518 test_102d() {
10519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10520         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10521
10522         XINC=$(have_xattrs_include)
10523         setup_test102
10524         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10525         cd $DIR/$tdir/$tdir
10526         compare_stripe_info1
10527 }
10528 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10529
10530 test_102f() {
10531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10532         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10533
10534         XINC=$(have_xattrs_include)
10535         setup_test102
10536         test_mkdir $DIR/$tdir.restore
10537         cd $DIR
10538         tar cf - --xattrs $tdir | tar xf - \
10539                 -C $DIR/$tdir.restore --xattrs $XINC
10540         cd $DIR/$tdir.restore/$tdir
10541         compare_stripe_info1
10542 }
10543 run_test 102f "tar copy files, not keep osts"
10544
10545 grow_xattr() {
10546         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10547                 skip "must have user_xattr"
10548         [ -z "$(which setfattr 2>/dev/null)" ] &&
10549                 skip_env "could not find setfattr"
10550         [ -z "$(which getfattr 2>/dev/null)" ] &&
10551                 skip_env "could not find getfattr"
10552
10553         local xsize=${1:-1024}  # in bytes
10554         local file=$DIR/$tfile
10555         local value="$(generate_string $xsize)"
10556         local xbig=trusted.big
10557         local toobig=$2
10558
10559         touch $file
10560         log "save $xbig on $file"
10561         if [ -z "$toobig" ]
10562         then
10563                 setfattr -n $xbig -v $value $file ||
10564                         error "saving $xbig on $file failed"
10565         else
10566                 setfattr -n $xbig -v $value $file &&
10567                         error "saving $xbig on $file succeeded"
10568                 return 0
10569         fi
10570
10571         local orig=$(get_xattr_value $xbig $file)
10572         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10573
10574         local xsml=trusted.sml
10575         log "save $xsml on $file"
10576         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10577
10578         local new=$(get_xattr_value $xbig $file)
10579         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10580
10581         log "grow $xsml on $file"
10582         setfattr -n $xsml -v "$value" $file ||
10583                 error "growing $xsml on $file failed"
10584
10585         new=$(get_xattr_value $xbig $file)
10586         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10587         log "$xbig still valid after growing $xsml"
10588
10589         rm -f $file
10590 }
10591
10592 test_102h() { # bug 15777
10593         grow_xattr 1024
10594 }
10595 run_test 102h "grow xattr from inside inode to external block"
10596
10597 test_102ha() {
10598         large_xattr_enabled || skip_env "ea_inode feature disabled"
10599
10600         echo "setting xattr of max xattr size: $(max_xattr_size)"
10601         grow_xattr $(max_xattr_size)
10602
10603         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10604         echo "This should fail:"
10605         grow_xattr $(($(max_xattr_size) + 10)) 1
10606 }
10607 run_test 102ha "grow xattr from inside inode to external inode"
10608
10609 test_102i() { # bug 17038
10610         [ -z "$(which getfattr 2>/dev/null)" ] &&
10611                 skip "could not find getfattr"
10612
10613         touch $DIR/$tfile
10614         ln -s $DIR/$tfile $DIR/${tfile}link
10615         getfattr -n trusted.lov $DIR/$tfile ||
10616                 error "lgetxattr on $DIR/$tfile failed"
10617         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10618                 grep -i "no such attr" ||
10619                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10620         rm -f $DIR/$tfile $DIR/${tfile}link
10621 }
10622 run_test 102i "lgetxattr test on symbolic link ============"
10623
10624 test_102j() {
10625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10626         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10627
10628         XINC=$(have_xattrs_include)
10629         setup_test102 "$RUNAS"
10630         chown $RUNAS_ID $DIR/$tdir
10631         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10632         cd $DIR/$tdir/$tdir
10633         compare_stripe_info1 "$RUNAS"
10634 }
10635 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10636
10637 test_102k() {
10638         [ -z "$(which setfattr 2>/dev/null)" ] &&
10639                 skip "could not find setfattr"
10640
10641         touch $DIR/$tfile
10642         # b22187 just check that does not crash for regular file.
10643         setfattr -n trusted.lov $DIR/$tfile
10644         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10645         local test_kdir=$DIR/$tdir
10646         test_mkdir $test_kdir
10647         local default_size=$($LFS getstripe -S $test_kdir)
10648         local default_count=$($LFS getstripe -c $test_kdir)
10649         local default_offset=$($LFS getstripe -i $test_kdir)
10650         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10651                 error 'dir setstripe failed'
10652         setfattr -n trusted.lov $test_kdir
10653         local stripe_size=$($LFS getstripe -S $test_kdir)
10654         local stripe_count=$($LFS getstripe -c $test_kdir)
10655         local stripe_offset=$($LFS getstripe -i $test_kdir)
10656         [ $stripe_size -eq $default_size ] ||
10657                 error "stripe size $stripe_size != $default_size"
10658         [ $stripe_count -eq $default_count ] ||
10659                 error "stripe count $stripe_count != $default_count"
10660         [ $stripe_offset -eq $default_offset ] ||
10661                 error "stripe offset $stripe_offset != $default_offset"
10662         rm -rf $DIR/$tfile $test_kdir
10663 }
10664 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10665
10666 test_102l() {
10667         [ -z "$(which getfattr 2>/dev/null)" ] &&
10668                 skip "could not find getfattr"
10669
10670         # LU-532 trusted. xattr is invisible to non-root
10671         local testfile=$DIR/$tfile
10672
10673         touch $testfile
10674
10675         echo "listxattr as user..."
10676         chown $RUNAS_ID $testfile
10677         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10678             grep -q "trusted" &&
10679                 error "$testfile trusted xattrs are user visible"
10680
10681         return 0;
10682 }
10683 run_test 102l "listxattr size test =================================="
10684
10685 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10686         local path=$DIR/$tfile
10687         touch $path
10688
10689         listxattr_size_check $path || error "listattr_size_check $path failed"
10690 }
10691 run_test 102m "Ensure listxattr fails on small bufffer ========"
10692
10693 cleanup_test102
10694
10695 getxattr() { # getxattr path name
10696         # Return the base64 encoding of the value of xattr name on path.
10697         local path=$1
10698         local name=$2
10699
10700         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10701         # file: $path
10702         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10703         #
10704         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10705
10706         getfattr --absolute-names --encoding=base64 --name=$name $path |
10707                 awk -F= -v name=$name '$1 == name {
10708                         print substr($0, index($0, "=") + 1);
10709         }'
10710 }
10711
10712 test_102n() { # LU-4101 mdt: protect internal xattrs
10713         [ -z "$(which setfattr 2>/dev/null)" ] &&
10714                 skip "could not find setfattr"
10715         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10716         then
10717                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10718         fi
10719
10720         local file0=$DIR/$tfile.0
10721         local file1=$DIR/$tfile.1
10722         local xattr0=$TMP/$tfile.0
10723         local xattr1=$TMP/$tfile.1
10724         local namelist="lov lma lmv link fid version som hsm"
10725         local name
10726         local value
10727
10728         rm -rf $file0 $file1 $xattr0 $xattr1
10729         touch $file0 $file1
10730
10731         # Get 'before' xattrs of $file1.
10732         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10733
10734         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10735                 namelist+=" lfsck_namespace"
10736         for name in $namelist; do
10737                 # Try to copy xattr from $file0 to $file1.
10738                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10739
10740                 setfattr --name=trusted.$name --value="$value" $file1 ||
10741                         error "setxattr 'trusted.$name' failed"
10742
10743                 # Try to set a garbage xattr.
10744                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10745
10746                 if [[ x$name == "xlov" ]]; then
10747                         setfattr --name=trusted.lov --value="$value" $file1 &&
10748                         error "setxattr invalid 'trusted.lov' success"
10749                 else
10750                         setfattr --name=trusted.$name --value="$value" $file1 ||
10751                                 error "setxattr invalid 'trusted.$name' failed"
10752                 fi
10753
10754                 # Try to remove the xattr from $file1. We don't care if this
10755                 # appears to succeed or fail, we just don't want there to be
10756                 # any changes or crashes.
10757                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10758         done
10759
10760         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10761         then
10762                 name="lfsck_ns"
10763                 # Try to copy xattr from $file0 to $file1.
10764                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10765
10766                 setfattr --name=trusted.$name --value="$value" $file1 ||
10767                         error "setxattr 'trusted.$name' failed"
10768
10769                 # Try to set a garbage xattr.
10770                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10771
10772                 setfattr --name=trusted.$name --value="$value" $file1 ||
10773                         error "setxattr 'trusted.$name' failed"
10774
10775                 # Try to remove the xattr from $file1. We don't care if this
10776                 # appears to succeed or fail, we just don't want there to be
10777                 # any changes or crashes.
10778                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10779         fi
10780
10781         # Get 'after' xattrs of file1.
10782         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10783
10784         if ! diff $xattr0 $xattr1; then
10785                 error "before and after xattrs of '$file1' differ"
10786         fi
10787
10788         rm -rf $file0 $file1 $xattr0 $xattr1
10789
10790         return 0
10791 }
10792 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10793
10794 test_102p() { # LU-4703 setxattr did not check ownership
10795         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10796                 skip "MDS needs to be at least 2.5.56"
10797
10798         local testfile=$DIR/$tfile
10799
10800         touch $testfile
10801
10802         echo "setfacl as user..."
10803         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10804         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10805
10806         echo "setfattr as user..."
10807         setfacl -m "u:$RUNAS_ID:---" $testfile
10808         $RUNAS setfattr -x system.posix_acl_access $testfile
10809         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10810 }
10811 run_test 102p "check setxattr(2) correctly fails without permission"
10812
10813 test_102q() {
10814         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10815                 skip "MDS needs to be at least 2.6.92"
10816
10817         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10818 }
10819 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10820
10821 test_102r() {
10822         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10823                 skip "MDS needs to be at least 2.6.93"
10824
10825         touch $DIR/$tfile || error "touch"
10826         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10827         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10828         rm $DIR/$tfile || error "rm"
10829
10830         #normal directory
10831         mkdir -p $DIR/$tdir || error "mkdir"
10832         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10833         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10834         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10835                 error "$testfile error deleting user.author1"
10836         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10837                 grep "user.$(basename $tdir)" &&
10838                 error "$tdir did not delete user.$(basename $tdir)"
10839         rmdir $DIR/$tdir || error "rmdir"
10840
10841         #striped directory
10842         test_mkdir $DIR/$tdir
10843         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10844         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10845         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10846                 error "$testfile error deleting user.author1"
10847         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10848                 grep "user.$(basename $tdir)" &&
10849                 error "$tdir did not delete user.$(basename $tdir)"
10850         rmdir $DIR/$tdir || error "rm striped dir"
10851 }
10852 run_test 102r "set EAs with empty values"
10853
10854 test_102s() {
10855         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10856                 skip "MDS needs to be at least 2.11.52"
10857
10858         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10859
10860         save_lustre_params client "llite.*.xattr_cache" > $save
10861
10862         for cache in 0 1; do
10863                 lctl set_param llite.*.xattr_cache=$cache
10864
10865                 rm -f $DIR/$tfile
10866                 touch $DIR/$tfile || error "touch"
10867                 for prefix in lustre security system trusted user; do
10868                         # Note getxattr() may fail with 'Operation not
10869                         # supported' or 'No such attribute' depending
10870                         # on prefix and cache.
10871                         getfattr -n $prefix.n102s $DIR/$tfile &&
10872                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10873                 done
10874         done
10875
10876         restore_lustre_params < $save
10877 }
10878 run_test 102s "getting nonexistent xattrs should fail"
10879
10880 test_102t() {
10881         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10882                 skip "MDS needs to be at least 2.11.52"
10883
10884         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10885
10886         save_lustre_params client "llite.*.xattr_cache" > $save
10887
10888         for cache in 0 1; do
10889                 lctl set_param llite.*.xattr_cache=$cache
10890
10891                 for buf_size in 0 256; do
10892                         rm -f $DIR/$tfile
10893                         touch $DIR/$tfile || error "touch"
10894                         setfattr -n user.multiop $DIR/$tfile
10895                         $MULTIOP $DIR/$tfile oa$buf_size ||
10896                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10897                 done
10898         done
10899
10900         restore_lustre_params < $save
10901 }
10902 run_test 102t "zero length xattr values handled correctly"
10903
10904 run_acl_subtest()
10905 {
10906     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10907     return $?
10908 }
10909
10910 test_103a() {
10911         [ "$UID" != 0 ] && skip "must run as root"
10912         $GSS && skip_env "could not run under gss"
10913         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10914                 skip_env "must have acl enabled"
10915         [ -z "$(which setfacl 2>/dev/null)" ] &&
10916                 skip_env "could not find setfacl"
10917         remote_mds_nodsh && skip "remote MDS with nodsh"
10918
10919         gpasswd -a daemon bin                           # LU-5641
10920         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10921
10922         declare -a identity_old
10923
10924         for num in $(seq $MDSCOUNT); do
10925                 switch_identity $num true || identity_old[$num]=$?
10926         done
10927
10928         SAVE_UMASK=$(umask)
10929         umask 0022
10930         mkdir -p $DIR/$tdir
10931         cd $DIR/$tdir
10932
10933         echo "performing cp ..."
10934         run_acl_subtest cp || error "run_acl_subtest cp failed"
10935         echo "performing getfacl-noacl..."
10936         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10937         echo "performing misc..."
10938         run_acl_subtest misc || error  "misc test failed"
10939         echo "performing permissions..."
10940         run_acl_subtest permissions || error "permissions failed"
10941         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10942         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10943                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10944                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10945         then
10946                 echo "performing permissions xattr..."
10947                 run_acl_subtest permissions_xattr ||
10948                         error "permissions_xattr failed"
10949         fi
10950         echo "performing setfacl..."
10951         run_acl_subtest setfacl || error  "setfacl test failed"
10952
10953         # inheritance test got from HP
10954         echo "performing inheritance..."
10955         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10956         chmod +x make-tree || error "chmod +x failed"
10957         run_acl_subtest inheritance || error "inheritance test failed"
10958         rm -f make-tree
10959
10960         echo "LU-974 ignore umask when acl is enabled..."
10961         run_acl_subtest 974 || error "LU-974 umask test failed"
10962         if [ $MDSCOUNT -ge 2 ]; then
10963                 run_acl_subtest 974_remote ||
10964                         error "LU-974 umask test failed under remote dir"
10965         fi
10966
10967         echo "LU-2561 newly created file is same size as directory..."
10968         if [ "$mds1_FSTYPE" != "zfs" ]; then
10969                 run_acl_subtest 2561 || error "LU-2561 test failed"
10970         else
10971                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10972         fi
10973
10974         run_acl_subtest 4924 || error "LU-4924 test failed"
10975
10976         cd $SAVE_PWD
10977         umask $SAVE_UMASK
10978
10979         for num in $(seq $MDSCOUNT); do
10980                 if [ "${identity_old[$num]}" = 1 ]; then
10981                         switch_identity $num false || identity_old[$num]=$?
10982                 fi
10983         done
10984 }
10985 run_test 103a "acl test"
10986
10987 test_103b() {
10988         declare -a pids
10989         local U
10990
10991         for U in {0..511}; do
10992                 {
10993                 local O=$(printf "%04o" $U)
10994
10995                 umask $(printf "%04o" $((511 ^ $O)))
10996                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10997                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10998
10999                 (( $S == ($O & 0666) )) ||
11000                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11001
11002                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11003                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11004                 (( $S == ($O & 0666) )) ||
11005                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11006
11007                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11008                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11009                 (( $S == ($O & 0666) )) ||
11010                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11011                 rm -f $DIR/$tfile.[smp]$0
11012                 } &
11013                 local pid=$!
11014
11015                 # limit the concurrently running threads to 64. LU-11878
11016                 local idx=$((U % 64))
11017                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11018                 pids[idx]=$pid
11019         done
11020         wait
11021 }
11022 run_test 103b "umask lfs setstripe"
11023
11024 test_103c() {
11025         mkdir -p $DIR/$tdir
11026         cp -rp $DIR/$tdir $DIR/$tdir.bak
11027
11028         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11029                 error "$DIR/$tdir shouldn't contain default ACL"
11030         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11031                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11032         true
11033 }
11034 run_test 103c "'cp -rp' won't set empty acl"
11035
11036 test_103e() {
11037         local numacl
11038         local fileacl
11039         local saved_debug=$($LCTL get_param -n debug)
11040
11041         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11042                 skip "MDS needs to be at least 2.14.0"
11043
11044         large_xattr_enabled || skip_env "ea_inode feature disabled"
11045
11046         mkdir -p $DIR/$tdir
11047         # add big LOV EA to cause reply buffer overflow earlier
11048         $LFS setstripe -C 1000 $DIR/$tdir
11049         lctl set_param mdc.*-mdc*.stats=clear
11050
11051         $LCTL set_param debug=0
11052         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11053         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11054
11055         # add a large number of default ACLs (expect 8000+ for 2.13+)
11056         for U in {2..7000}; do
11057                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11058                         error "Able to add just $U default ACLs"
11059         done
11060         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11061         echo "$numacl default ACLs created"
11062
11063         stat $DIR/$tdir || error "Cannot stat directory"
11064         # check file creation
11065         touch $DIR/$tdir/$tfile ||
11066                 error "failed to create $tfile with $numacl default ACLs"
11067         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11068         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11069         echo "$fileacl ACLs were inherited"
11070         (( $fileacl == $numacl )) ||
11071                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11072         # check that new ACLs creation adds new ACLs to inherited ACLs
11073         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11074                 error "Cannot set new ACL"
11075         numacl=$((numacl + 1))
11076         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11077         (( $fileacl == $numacl )) ||
11078                 error "failed to add new ACL: $fileacl != $numacl as expected"
11079         # adds more ACLs to a file to reach their maximum at 8000+
11080         numacl=0
11081         for U in {20000..25000}; do
11082                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11083                 numacl=$((numacl + 1))
11084         done
11085         echo "Added $numacl more ACLs to the file"
11086         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11087         echo "Total $fileacl ACLs in file"
11088         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11089         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11090         rmdir $DIR/$tdir || error "Cannot remove directory"
11091 }
11092 run_test 103e "inheritance of big amount of default ACLs"
11093
11094 test_103f() {
11095         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11096                 skip "MDS needs to be at least 2.14.51"
11097
11098         large_xattr_enabled || skip_env "ea_inode feature disabled"
11099
11100         # enable changelog to consume more internal MDD buffers
11101         changelog_register
11102
11103         mkdir -p $DIR/$tdir
11104         # add big LOV EA
11105         $LFS setstripe -C 1000 $DIR/$tdir
11106         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11107         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11108         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11109         rmdir $DIR/$tdir || error "Cannot remove directory"
11110 }
11111 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11112
11113 test_104a() {
11114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11115
11116         touch $DIR/$tfile
11117         lfs df || error "lfs df failed"
11118         lfs df -ih || error "lfs df -ih failed"
11119         lfs df -h $DIR || error "lfs df -h $DIR failed"
11120         lfs df -i $DIR || error "lfs df -i $DIR failed"
11121         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11122         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11123
11124         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11125         lctl --device %$OSC deactivate
11126         lfs df || error "lfs df with deactivated OSC failed"
11127         lctl --device %$OSC activate
11128         # wait the osc back to normal
11129         wait_osc_import_ready client ost
11130
11131         lfs df || error "lfs df with reactivated OSC failed"
11132         rm -f $DIR/$tfile
11133 }
11134 run_test 104a "lfs df [-ih] [path] test ========================="
11135
11136 test_104b() {
11137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11138         [ $RUNAS_ID -eq $UID ] &&
11139                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11140
11141         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11142                         grep "Permission denied" | wc -l)))
11143         if [ $denied_cnt -ne 0 ]; then
11144                 error "lfs check servers test failed"
11145         fi
11146 }
11147 run_test 104b "$RUNAS lfs check servers test ===================="
11148
11149 #
11150 # Verify $1 is within range of $2.
11151 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11152 # $1 is <= 2% of $2. Else Fail.
11153 #
11154 value_in_range() {
11155         # Strip all units (M, G, T)
11156         actual=$(echo $1 | tr -d A-Z)
11157         expect=$(echo $2 | tr -d A-Z)
11158
11159         expect_lo=$(($expect * 98 / 100)) # 2% below
11160         expect_hi=$(($expect * 102 / 100)) # 2% above
11161
11162         # permit 2% drift above and below
11163         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11164 }
11165
11166 test_104c() {
11167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11168         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11169
11170         local ost_param="osd-zfs.$FSNAME-OST0000."
11171         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11172         local ofacets=$(get_facets OST)
11173         local mfacets=$(get_facets MDS)
11174         local saved_ost_blocks=
11175         local saved_mdt_blocks=
11176
11177         echo "Before recordsize change"
11178         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11179         df=($(df -h | grep "/mnt/lustre"$))
11180
11181         # For checking.
11182         echo "lfs output : ${lfs_df[*]}"
11183         echo "df  output : ${df[*]}"
11184
11185         for facet in ${ofacets//,/ }; do
11186                 if [ -z $saved_ost_blocks ]; then
11187                         saved_ost_blocks=$(do_facet $facet \
11188                                 lctl get_param -n $ost_param.blocksize)
11189                         echo "OST Blocksize: $saved_ost_blocks"
11190                 fi
11191                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11192                 do_facet $facet zfs set recordsize=32768 $ost
11193         done
11194
11195         # BS too small. Sufficient for functional testing.
11196         for facet in ${mfacets//,/ }; do
11197                 if [ -z $saved_mdt_blocks ]; then
11198                         saved_mdt_blocks=$(do_facet $facet \
11199                                 lctl get_param -n $mdt_param.blocksize)
11200                         echo "MDT Blocksize: $saved_mdt_blocks"
11201                 fi
11202                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11203                 do_facet $facet zfs set recordsize=32768 $mdt
11204         done
11205
11206         # Give new values chance to reflect change
11207         sleep 2
11208
11209         echo "After recordsize change"
11210         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11211         df_after=($(df -h | grep "/mnt/lustre"$))
11212
11213         # For checking.
11214         echo "lfs output : ${lfs_df_after[*]}"
11215         echo "df  output : ${df_after[*]}"
11216
11217         # Verify lfs df
11218         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11219                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11220         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11221                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11222         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11223                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11224
11225         # Verify df
11226         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11227                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11228         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11229                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11230         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11231                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11232
11233         # Restore MDT recordize back to original
11234         for facet in ${mfacets//,/ }; do
11235                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11236                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11237         done
11238
11239         # Restore OST recordize back to original
11240         for facet in ${ofacets//,/ }; do
11241                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11242                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11243         done
11244
11245         return 0
11246 }
11247 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11248
11249 test_105a() {
11250         # doesn't work on 2.4 kernels
11251         touch $DIR/$tfile
11252         if $(flock_is_enabled); then
11253                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11254         else
11255                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11256         fi
11257         rm -f $DIR/$tfile
11258 }
11259 run_test 105a "flock when mounted without -o flock test ========"
11260
11261 test_105b() {
11262         touch $DIR/$tfile
11263         if $(flock_is_enabled); then
11264                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11265         else
11266                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11267         fi
11268         rm -f $DIR/$tfile
11269 }
11270 run_test 105b "fcntl when mounted without -o flock test ========"
11271
11272 test_105c() {
11273         touch $DIR/$tfile
11274         if $(flock_is_enabled); then
11275                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11276         else
11277                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11278         fi
11279         rm -f $DIR/$tfile
11280 }
11281 run_test 105c "lockf when mounted without -o flock test"
11282
11283 test_105d() { # bug 15924
11284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11285
11286         test_mkdir $DIR/$tdir
11287         flock_is_enabled || skip_env "mount w/o flock enabled"
11288         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11289         $LCTL set_param fail_loc=0x80000315
11290         flocks_test 2 $DIR/$tdir
11291 }
11292 run_test 105d "flock race (should not freeze) ========"
11293
11294 test_105e() { # bug 22660 && 22040
11295         flock_is_enabled || skip_env "mount w/o flock enabled"
11296
11297         touch $DIR/$tfile
11298         flocks_test 3 $DIR/$tfile
11299 }
11300 run_test 105e "Two conflicting flocks from same process"
11301
11302 test_106() { #bug 10921
11303         test_mkdir $DIR/$tdir
11304         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11305         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11306 }
11307 run_test 106 "attempt exec of dir followed by chown of that dir"
11308
11309 test_107() {
11310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11311
11312         CDIR=`pwd`
11313         local file=core
11314
11315         cd $DIR
11316         rm -f $file
11317
11318         local save_pattern=$(sysctl -n kernel.core_pattern)
11319         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11320         sysctl -w kernel.core_pattern=$file
11321         sysctl -w kernel.core_uses_pid=0
11322
11323         ulimit -c unlimited
11324         sleep 60 &
11325         SLEEPPID=$!
11326
11327         sleep 1
11328
11329         kill -s 11 $SLEEPPID
11330         wait $SLEEPPID
11331         if [ -e $file ]; then
11332                 size=`stat -c%s $file`
11333                 [ $size -eq 0 ] && error "Fail to create core file $file"
11334         else
11335                 error "Fail to create core file $file"
11336         fi
11337         rm -f $file
11338         sysctl -w kernel.core_pattern=$save_pattern
11339         sysctl -w kernel.core_uses_pid=$save_uses_pid
11340         cd $CDIR
11341 }
11342 run_test 107 "Coredump on SIG"
11343
11344 test_110() {
11345         test_mkdir $DIR/$tdir
11346         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11347         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11348                 error "mkdir with 256 char should fail, but did not"
11349         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11350                 error "create with 255 char failed"
11351         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11352                 error "create with 256 char should fail, but did not"
11353
11354         ls -l $DIR/$tdir
11355         rm -rf $DIR/$tdir
11356 }
11357 run_test 110 "filename length checking"
11358
11359 #
11360 # Purpose: To verify dynamic thread (OSS) creation.
11361 #
11362 test_115() {
11363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11364         remote_ost_nodsh && skip "remote OST with nodsh"
11365
11366         # Lustre does not stop service threads once they are started.
11367         # Reset number of running threads to default.
11368         stopall
11369         setupall
11370
11371         local OSTIO_pre
11372         local save_params="$TMP/sanity-$TESTNAME.parameters"
11373
11374         # Get ll_ost_io count before I/O
11375         OSTIO_pre=$(do_facet ost1 \
11376                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11377         # Exit if lustre is not running (ll_ost_io not running).
11378         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11379
11380         echo "Starting with $OSTIO_pre threads"
11381         local thread_max=$((OSTIO_pre * 2))
11382         local rpc_in_flight=$((thread_max * 2))
11383         # Number of I/O Process proposed to be started.
11384         local nfiles
11385         local facets=$(get_facets OST)
11386
11387         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11388         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11389
11390         # Set in_flight to $rpc_in_flight
11391         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11392                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11393         nfiles=${rpc_in_flight}
11394         # Set ost thread_max to $thread_max
11395         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11396
11397         # 5 Minutes should be sufficient for max number of OSS
11398         # threads(thread_max) to be created.
11399         local timeout=300
11400
11401         # Start I/O.
11402         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11403         test_mkdir $DIR/$tdir
11404         for i in $(seq $nfiles); do
11405                 local file=$DIR/$tdir/${tfile}-$i
11406                 $LFS setstripe -c -1 -i 0 $file
11407                 ($WTL $file $timeout)&
11408         done
11409
11410         # I/O Started - Wait for thread_started to reach thread_max or report
11411         # error if thread_started is more than thread_max.
11412         echo "Waiting for thread_started to reach thread_max"
11413         local thread_started=0
11414         local end_time=$((SECONDS + timeout))
11415
11416         while [ $SECONDS -le $end_time ] ; do
11417                 echo -n "."
11418                 # Get ost i/o thread_started count.
11419                 thread_started=$(do_facet ost1 \
11420                         "$LCTL get_param \
11421                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11422                 # Break out if thread_started is equal/greater than thread_max
11423                 if [[ $thread_started -ge $thread_max ]]; then
11424                         echo ll_ost_io thread_started $thread_started, \
11425                                 equal/greater than thread_max $thread_max
11426                         break
11427                 fi
11428                 sleep 1
11429         done
11430
11431         # Cleanup - We have the numbers, Kill i/o jobs if running.
11432         jobcount=($(jobs -p))
11433         for i in $(seq 0 $((${#jobcount[@]}-1)))
11434         do
11435                 kill -9 ${jobcount[$i]}
11436                 if [ $? -ne 0 ] ; then
11437                         echo Warning: \
11438                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11439                 fi
11440         done
11441
11442         # Cleanup files left by WTL binary.
11443         for i in $(seq $nfiles); do
11444                 local file=$DIR/$tdir/${tfile}-$i
11445                 rm -rf $file
11446                 if [ $? -ne 0 ] ; then
11447                         echo "Warning: Failed to delete file $file"
11448                 fi
11449         done
11450
11451         restore_lustre_params <$save_params
11452         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11453
11454         # Error out if no new thread has started or Thread started is greater
11455         # than thread max.
11456         if [[ $thread_started -le $OSTIO_pre ||
11457                         $thread_started -gt $thread_max ]]; then
11458                 error "ll_ost_io: thread_started $thread_started" \
11459                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11460                       "No new thread started or thread started greater " \
11461                       "than thread_max."
11462         fi
11463 }
11464 run_test 115 "verify dynamic thread creation===================="
11465
11466 free_min_max () {
11467         wait_delete_completed
11468         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11469         echo "OST kbytes available: ${AVAIL[@]}"
11470         MAXV=${AVAIL[0]}
11471         MAXI=0
11472         MINV=${AVAIL[0]}
11473         MINI=0
11474         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11475                 #echo OST $i: ${AVAIL[i]}kb
11476                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11477                         MAXV=${AVAIL[i]}
11478                         MAXI=$i
11479                 fi
11480                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11481                         MINV=${AVAIL[i]}
11482                         MINI=$i
11483                 fi
11484         done
11485         echo "Min free space: OST $MINI: $MINV"
11486         echo "Max free space: OST $MAXI: $MAXV"
11487 }
11488
11489 test_116a() { # was previously test_116()
11490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11491         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11492         remote_mds_nodsh && skip "remote MDS with nodsh"
11493
11494         echo -n "Free space priority "
11495         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11496                 head -n1
11497         declare -a AVAIL
11498         free_min_max
11499
11500         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11501         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11502         trap simple_cleanup_common EXIT
11503
11504         # Check if we need to generate uneven OSTs
11505         test_mkdir -p $DIR/$tdir/OST${MINI}
11506         local FILL=$((MINV / 4))
11507         local DIFF=$((MAXV - MINV))
11508         local DIFF2=$((DIFF * 100 / MINV))
11509
11510         local threshold=$(do_facet $SINGLEMDS \
11511                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11512         threshold=${threshold%%%}
11513         echo -n "Check for uneven OSTs: "
11514         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11515
11516         if [[ $DIFF2 -gt $threshold ]]; then
11517                 echo "ok"
11518                 echo "Don't need to fill OST$MINI"
11519         else
11520                 # generate uneven OSTs. Write 2% over the QOS threshold value
11521                 echo "no"
11522                 DIFF=$((threshold - DIFF2 + 2))
11523                 DIFF2=$((MINV * DIFF / 100))
11524                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11525                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11526                         error "setstripe failed"
11527                 DIFF=$((DIFF2 / 2048))
11528                 i=0
11529                 while [ $i -lt $DIFF ]; do
11530                         i=$((i + 1))
11531                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11532                                 bs=2M count=1 2>/dev/null
11533                         echo -n .
11534                 done
11535                 echo .
11536                 sync
11537                 sleep_maxage
11538                 free_min_max
11539         fi
11540
11541         DIFF=$((MAXV - MINV))
11542         DIFF2=$((DIFF * 100 / MINV))
11543         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11544         if [ $DIFF2 -gt $threshold ]; then
11545                 echo "ok"
11546         else
11547                 echo "failed - QOS mode won't be used"
11548                 simple_cleanup_common
11549                 skip "QOS imbalance criteria not met"
11550         fi
11551
11552         MINI1=$MINI
11553         MINV1=$MINV
11554         MAXI1=$MAXI
11555         MAXV1=$MAXV
11556
11557         # now fill using QOS
11558         $LFS setstripe -c 1 $DIR/$tdir
11559         FILL=$((FILL / 200))
11560         if [ $FILL -gt 600 ]; then
11561                 FILL=600
11562         fi
11563         echo "writing $FILL files to QOS-assigned OSTs"
11564         i=0
11565         while [ $i -lt $FILL ]; do
11566                 i=$((i + 1))
11567                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11568                         count=1 2>/dev/null
11569                 echo -n .
11570         done
11571         echo "wrote $i 200k files"
11572         sync
11573         sleep_maxage
11574
11575         echo "Note: free space may not be updated, so measurements might be off"
11576         free_min_max
11577         DIFF2=$((MAXV - MINV))
11578         echo "free space delta: orig $DIFF final $DIFF2"
11579         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11580         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11581         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11582         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11583         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11584         if [[ $DIFF -gt 0 ]]; then
11585                 FILL=$((DIFF2 * 100 / DIFF - 100))
11586                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11587         fi
11588
11589         # Figure out which files were written where
11590         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11591                awk '/'$MINI1': / {print $2; exit}')
11592         echo $UUID
11593         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11594         echo "$MINC files created on smaller OST $MINI1"
11595         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11596                awk '/'$MAXI1': / {print $2; exit}')
11597         echo $UUID
11598         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11599         echo "$MAXC files created on larger OST $MAXI1"
11600         if [[ $MINC -gt 0 ]]; then
11601                 FILL=$((MAXC * 100 / MINC - 100))
11602                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11603         fi
11604         [[ $MAXC -gt $MINC ]] ||
11605                 error_ignore LU-9 "stripe QOS didn't balance free space"
11606         simple_cleanup_common
11607 }
11608 run_test 116a "stripe QOS: free space balance ==================="
11609
11610 test_116b() { # LU-2093
11611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11612         remote_mds_nodsh && skip "remote MDS with nodsh"
11613
11614 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11615         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11616                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11617         [ -z "$old_rr" ] && skip "no QOS"
11618         do_facet $SINGLEMDS lctl set_param \
11619                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11620         mkdir -p $DIR/$tdir
11621         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11622         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11623         do_facet $SINGLEMDS lctl set_param fail_loc=0
11624         rm -rf $DIR/$tdir
11625         do_facet $SINGLEMDS lctl set_param \
11626                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11627 }
11628 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11629
11630 test_117() # bug 10891
11631 {
11632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11633
11634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11635         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11636         lctl set_param fail_loc=0x21e
11637         > $DIR/$tfile || error "truncate failed"
11638         lctl set_param fail_loc=0
11639         echo "Truncate succeeded."
11640         rm -f $DIR/$tfile
11641 }
11642 run_test 117 "verify osd extend =========="
11643
11644 NO_SLOW_RESENDCOUNT=4
11645 export OLD_RESENDCOUNT=""
11646 set_resend_count () {
11647         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11648         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11649         lctl set_param -n $PROC_RESENDCOUNT $1
11650         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11651 }
11652
11653 # for reduce test_118* time (b=14842)
11654 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11655
11656 # Reset async IO behavior after error case
11657 reset_async() {
11658         FILE=$DIR/reset_async
11659
11660         # Ensure all OSCs are cleared
11661         $LFS setstripe -c -1 $FILE
11662         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11663         sync
11664         rm $FILE
11665 }
11666
11667 test_118a() #bug 11710
11668 {
11669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11670
11671         reset_async
11672
11673         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11674         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11675         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11676
11677         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11678                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11679                 return 1;
11680         fi
11681         rm -f $DIR/$tfile
11682 }
11683 run_test 118a "verify O_SYNC works =========="
11684
11685 test_118b()
11686 {
11687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11688         remote_ost_nodsh && skip "remote OST with nodsh"
11689
11690         reset_async
11691
11692         #define OBD_FAIL_SRV_ENOENT 0x217
11693         set_nodes_failloc "$(osts_nodes)" 0x217
11694         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11695         RC=$?
11696         set_nodes_failloc "$(osts_nodes)" 0
11697         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11698         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11699                     grep -c writeback)
11700
11701         if [[ $RC -eq 0 ]]; then
11702                 error "Must return error due to dropped pages, rc=$RC"
11703                 return 1;
11704         fi
11705
11706         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11707                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11708                 return 1;
11709         fi
11710
11711         echo "Dirty pages not leaked on ENOENT"
11712
11713         # Due to the above error the OSC will issue all RPCs syncronously
11714         # until a subsequent RPC completes successfully without error.
11715         $MULTIOP $DIR/$tfile Ow4096yc
11716         rm -f $DIR/$tfile
11717
11718         return 0
11719 }
11720 run_test 118b "Reclaim dirty pages on fatal error =========="
11721
11722 test_118c()
11723 {
11724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11725
11726         # for 118c, restore the original resend count, LU-1940
11727         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11728                                 set_resend_count $OLD_RESENDCOUNT
11729         remote_ost_nodsh && skip "remote OST with nodsh"
11730
11731         reset_async
11732
11733         #define OBD_FAIL_OST_EROFS               0x216
11734         set_nodes_failloc "$(osts_nodes)" 0x216
11735
11736         # multiop should block due to fsync until pages are written
11737         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11738         MULTIPID=$!
11739         sleep 1
11740
11741         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11742                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11743         fi
11744
11745         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11746                     grep -c writeback)
11747         if [[ $WRITEBACK -eq 0 ]]; then
11748                 error "No page in writeback, writeback=$WRITEBACK"
11749         fi
11750
11751         set_nodes_failloc "$(osts_nodes)" 0
11752         wait $MULTIPID
11753         RC=$?
11754         if [[ $RC -ne 0 ]]; then
11755                 error "Multiop fsync failed, rc=$RC"
11756         fi
11757
11758         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11759         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11760                     grep -c writeback)
11761         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11762                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11763         fi
11764
11765         rm -f $DIR/$tfile
11766         echo "Dirty pages flushed via fsync on EROFS"
11767         return 0
11768 }
11769 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11770
11771 # continue to use small resend count to reduce test_118* time (b=14842)
11772 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11773
11774 test_118d()
11775 {
11776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11777         remote_ost_nodsh && skip "remote OST with nodsh"
11778
11779         reset_async
11780
11781         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11782         set_nodes_failloc "$(osts_nodes)" 0x214
11783         # multiop should block due to fsync until pages are written
11784         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11785         MULTIPID=$!
11786         sleep 1
11787
11788         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11789                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11790         fi
11791
11792         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11793                     grep -c writeback)
11794         if [[ $WRITEBACK -eq 0 ]]; then
11795                 error "No page in writeback, writeback=$WRITEBACK"
11796         fi
11797
11798         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11799         set_nodes_failloc "$(osts_nodes)" 0
11800
11801         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11802         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11803                     grep -c writeback)
11804         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11805                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11806         fi
11807
11808         rm -f $DIR/$tfile
11809         echo "Dirty pages gaurenteed flushed via fsync"
11810         return 0
11811 }
11812 run_test 118d "Fsync validation inject a delay of the bulk =========="
11813
11814 test_118f() {
11815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11816
11817         reset_async
11818
11819         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11820         lctl set_param fail_loc=0x8000040a
11821
11822         # Should simulate EINVAL error which is fatal
11823         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11824         RC=$?
11825         if [[ $RC -eq 0 ]]; then
11826                 error "Must return error due to dropped pages, rc=$RC"
11827         fi
11828
11829         lctl set_param fail_loc=0x0
11830
11831         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11832         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11833         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11834                     grep -c writeback)
11835         if [[ $LOCKED -ne 0 ]]; then
11836                 error "Locked pages remain in cache, locked=$LOCKED"
11837         fi
11838
11839         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11840                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11841         fi
11842
11843         rm -f $DIR/$tfile
11844         echo "No pages locked after fsync"
11845
11846         reset_async
11847         return 0
11848 }
11849 run_test 118f "Simulate unrecoverable OSC side error =========="
11850
11851 test_118g() {
11852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11853
11854         reset_async
11855
11856         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11857         lctl set_param fail_loc=0x406
11858
11859         # simulate local -ENOMEM
11860         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11861         RC=$?
11862
11863         lctl set_param fail_loc=0
11864         if [[ $RC -eq 0 ]]; then
11865                 error "Must return error due to dropped pages, rc=$RC"
11866         fi
11867
11868         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11869         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11870         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11871                         grep -c writeback)
11872         if [[ $LOCKED -ne 0 ]]; then
11873                 error "Locked pages remain in cache, locked=$LOCKED"
11874         fi
11875
11876         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11877                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11878         fi
11879
11880         rm -f $DIR/$tfile
11881         echo "No pages locked after fsync"
11882
11883         reset_async
11884         return 0
11885 }
11886 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11887
11888 test_118h() {
11889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11890         remote_ost_nodsh && skip "remote OST with nodsh"
11891
11892         reset_async
11893
11894         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11895         set_nodes_failloc "$(osts_nodes)" 0x20e
11896         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11897         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11898         RC=$?
11899
11900         set_nodes_failloc "$(osts_nodes)" 0
11901         if [[ $RC -eq 0 ]]; then
11902                 error "Must return error due to dropped pages, rc=$RC"
11903         fi
11904
11905         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11906         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11907         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11908                     grep -c writeback)
11909         if [[ $LOCKED -ne 0 ]]; then
11910                 error "Locked pages remain in cache, locked=$LOCKED"
11911         fi
11912
11913         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11914                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11915         fi
11916
11917         rm -f $DIR/$tfile
11918         echo "No pages locked after fsync"
11919
11920         return 0
11921 }
11922 run_test 118h "Verify timeout in handling recoverables errors  =========="
11923
11924 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11925
11926 test_118i() {
11927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11928         remote_ost_nodsh && skip "remote OST with nodsh"
11929
11930         reset_async
11931
11932         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11933         set_nodes_failloc "$(osts_nodes)" 0x20e
11934
11935         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11936         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11937         PID=$!
11938         sleep 5
11939         set_nodes_failloc "$(osts_nodes)" 0
11940
11941         wait $PID
11942         RC=$?
11943         if [[ $RC -ne 0 ]]; then
11944                 error "got error, but should be not, rc=$RC"
11945         fi
11946
11947         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11948         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11949         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11950         if [[ $LOCKED -ne 0 ]]; then
11951                 error "Locked pages remain in cache, locked=$LOCKED"
11952         fi
11953
11954         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11955                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11956         fi
11957
11958         rm -f $DIR/$tfile
11959         echo "No pages locked after fsync"
11960
11961         return 0
11962 }
11963 run_test 118i "Fix error before timeout in recoverable error  =========="
11964
11965 [ "$SLOW" = "no" ] && set_resend_count 4
11966
11967 test_118j() {
11968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11969         remote_ost_nodsh && skip "remote OST with nodsh"
11970
11971         reset_async
11972
11973         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11974         set_nodes_failloc "$(osts_nodes)" 0x220
11975
11976         # return -EIO from OST
11977         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11978         RC=$?
11979         set_nodes_failloc "$(osts_nodes)" 0x0
11980         if [[ $RC -eq 0 ]]; then
11981                 error "Must return error due to dropped pages, rc=$RC"
11982         fi
11983
11984         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11985         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11986         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11987         if [[ $LOCKED -ne 0 ]]; then
11988                 error "Locked pages remain in cache, locked=$LOCKED"
11989         fi
11990
11991         # in recoverable error on OST we want resend and stay until it finished
11992         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11993                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11994         fi
11995
11996         rm -f $DIR/$tfile
11997         echo "No pages locked after fsync"
11998
11999         return 0
12000 }
12001 run_test 118j "Simulate unrecoverable OST side error =========="
12002
12003 test_118k()
12004 {
12005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12006         remote_ost_nodsh && skip "remote OSTs with nodsh"
12007
12008         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12009         set_nodes_failloc "$(osts_nodes)" 0x20e
12010         test_mkdir $DIR/$tdir
12011
12012         for ((i=0;i<10;i++)); do
12013                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12014                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12015                 SLEEPPID=$!
12016                 sleep 0.500s
12017                 kill $SLEEPPID
12018                 wait $SLEEPPID
12019         done
12020
12021         set_nodes_failloc "$(osts_nodes)" 0
12022         rm -rf $DIR/$tdir
12023 }
12024 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12025
12026 test_118l() # LU-646
12027 {
12028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12029
12030         test_mkdir $DIR/$tdir
12031         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12032         rm -rf $DIR/$tdir
12033 }
12034 run_test 118l "fsync dir"
12035
12036 test_118m() # LU-3066
12037 {
12038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12039
12040         test_mkdir $DIR/$tdir
12041         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12042         rm -rf $DIR/$tdir
12043 }
12044 run_test 118m "fdatasync dir ========="
12045
12046 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12047
12048 test_118n()
12049 {
12050         local begin
12051         local end
12052
12053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12054         remote_ost_nodsh && skip "remote OSTs with nodsh"
12055
12056         # Sleep to avoid a cached response.
12057         #define OBD_STATFS_CACHE_SECONDS 1
12058         sleep 2
12059
12060         # Inject a 10 second delay in the OST_STATFS handler.
12061         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12062         set_nodes_failloc "$(osts_nodes)" 0x242
12063
12064         begin=$SECONDS
12065         stat --file-system $MOUNT > /dev/null
12066         end=$SECONDS
12067
12068         set_nodes_failloc "$(osts_nodes)" 0
12069
12070         if ((end - begin > 20)); then
12071             error "statfs took $((end - begin)) seconds, expected 10"
12072         fi
12073 }
12074 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12075
12076 test_119a() # bug 11737
12077 {
12078         BSIZE=$((512 * 1024))
12079         directio write $DIR/$tfile 0 1 $BSIZE
12080         # We ask to read two blocks, which is more than a file size.
12081         # directio will indicate an error when requested and actual
12082         # sizes aren't equeal (a normal situation in this case) and
12083         # print actual read amount.
12084         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12085         if [ "$NOB" != "$BSIZE" ]; then
12086                 error "read $NOB bytes instead of $BSIZE"
12087         fi
12088         rm -f $DIR/$tfile
12089 }
12090 run_test 119a "Short directIO read must return actual read amount"
12091
12092 test_119b() # bug 11737
12093 {
12094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12095
12096         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12097         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12098         sync
12099         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12100                 error "direct read failed"
12101         rm -f $DIR/$tfile
12102 }
12103 run_test 119b "Sparse directIO read must return actual read amount"
12104
12105 test_119c() # bug 13099
12106 {
12107         BSIZE=1048576
12108         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12109         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12110         rm -f $DIR/$tfile
12111 }
12112 run_test 119c "Testing for direct read hitting hole"
12113
12114 test_119d() # bug 15950
12115 {
12116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12117
12118         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12119         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12120         BSIZE=1048576
12121         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12122         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12123         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12124         lctl set_param fail_loc=0x40d
12125         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12126         pid_dio=$!
12127         sleep 1
12128         cat $DIR/$tfile > /dev/null &
12129         lctl set_param fail_loc=0
12130         pid_reads=$!
12131         wait $pid_dio
12132         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12133         sleep 2
12134         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12135         error "the read rpcs have not completed in 2s"
12136         rm -f $DIR/$tfile
12137         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12138 }
12139 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12140
12141 test_120a() {
12142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12143         remote_mds_nodsh && skip "remote MDS with nodsh"
12144         test_mkdir -i0 -c1 $DIR/$tdir
12145         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12146                 skip_env "no early lock cancel on server"
12147
12148         lru_resize_disable mdc
12149         lru_resize_disable osc
12150         cancel_lru_locks mdc
12151         # asynchronous object destroy at MDT could cause bl ast to client
12152         cancel_lru_locks osc
12153
12154         stat $DIR/$tdir > /dev/null
12155         can1=$(do_facet mds1 \
12156                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12157                awk '/ldlm_cancel/ {print $2}')
12158         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12159                awk '/ldlm_bl_callback/ {print $2}')
12160         test_mkdir -i0 -c1 $DIR/$tdir/d1
12161         can2=$(do_facet mds1 \
12162                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12163                awk '/ldlm_cancel/ {print $2}')
12164         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12165                awk '/ldlm_bl_callback/ {print $2}')
12166         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12167         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12168         lru_resize_enable mdc
12169         lru_resize_enable osc
12170 }
12171 run_test 120a "Early Lock Cancel: mkdir test"
12172
12173 test_120b() {
12174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12175         remote_mds_nodsh && skip "remote MDS with nodsh"
12176         test_mkdir $DIR/$tdir
12177         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12178                 skip_env "no early lock cancel on server"
12179
12180         lru_resize_disable mdc
12181         lru_resize_disable osc
12182         cancel_lru_locks mdc
12183         stat $DIR/$tdir > /dev/null
12184         can1=$(do_facet $SINGLEMDS \
12185                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12186                awk '/ldlm_cancel/ {print $2}')
12187         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12188                awk '/ldlm_bl_callback/ {print $2}')
12189         touch $DIR/$tdir/f1
12190         can2=$(do_facet $SINGLEMDS \
12191                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12192                awk '/ldlm_cancel/ {print $2}')
12193         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12194                awk '/ldlm_bl_callback/ {print $2}')
12195         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12196         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12197         lru_resize_enable mdc
12198         lru_resize_enable osc
12199 }
12200 run_test 120b "Early Lock Cancel: create test"
12201
12202 test_120c() {
12203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12204         remote_mds_nodsh && skip "remote MDS with nodsh"
12205         test_mkdir -i0 -c1 $DIR/$tdir
12206         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12207                 skip "no early lock cancel on server"
12208
12209         lru_resize_disable mdc
12210         lru_resize_disable osc
12211         test_mkdir -i0 -c1 $DIR/$tdir/d1
12212         test_mkdir -i0 -c1 $DIR/$tdir/d2
12213         touch $DIR/$tdir/d1/f1
12214         cancel_lru_locks mdc
12215         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12216         can1=$(do_facet mds1 \
12217                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12218                awk '/ldlm_cancel/ {print $2}')
12219         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12220                awk '/ldlm_bl_callback/ {print $2}')
12221         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12222         can2=$(do_facet mds1 \
12223                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12224                awk '/ldlm_cancel/ {print $2}')
12225         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12226                awk '/ldlm_bl_callback/ {print $2}')
12227         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12228         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12229         lru_resize_enable mdc
12230         lru_resize_enable osc
12231 }
12232 run_test 120c "Early Lock Cancel: link test"
12233
12234 test_120d() {
12235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12236         remote_mds_nodsh && skip "remote MDS with nodsh"
12237         test_mkdir -i0 -c1 $DIR/$tdir
12238         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12239                 skip_env "no early lock cancel on server"
12240
12241         lru_resize_disable mdc
12242         lru_resize_disable osc
12243         touch $DIR/$tdir
12244         cancel_lru_locks mdc
12245         stat $DIR/$tdir > /dev/null
12246         can1=$(do_facet mds1 \
12247                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12248                awk '/ldlm_cancel/ {print $2}')
12249         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12250                awk '/ldlm_bl_callback/ {print $2}')
12251         chmod a+x $DIR/$tdir
12252         can2=$(do_facet mds1 \
12253                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12254                awk '/ldlm_cancel/ {print $2}')
12255         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12256                awk '/ldlm_bl_callback/ {print $2}')
12257         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12258         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12259         lru_resize_enable mdc
12260         lru_resize_enable osc
12261 }
12262 run_test 120d "Early Lock Cancel: setattr test"
12263
12264 test_120e() {
12265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12266         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12267                 skip_env "no early lock cancel on server"
12268         remote_mds_nodsh && skip "remote MDS with nodsh"
12269
12270         local dlmtrace_set=false
12271
12272         test_mkdir -i0 -c1 $DIR/$tdir
12273         lru_resize_disable mdc
12274         lru_resize_disable osc
12275         ! $LCTL get_param debug | grep -q dlmtrace &&
12276                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12277         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12278         cancel_lru_locks mdc
12279         cancel_lru_locks osc
12280         dd if=$DIR/$tdir/f1 of=/dev/null
12281         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12282         # XXX client can not do early lock cancel of OST lock
12283         # during unlink (LU-4206), so cancel osc lock now.
12284         sleep 2
12285         cancel_lru_locks osc
12286         can1=$(do_facet mds1 \
12287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12288                awk '/ldlm_cancel/ {print $2}')
12289         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12290                awk '/ldlm_bl_callback/ {print $2}')
12291         unlink $DIR/$tdir/f1
12292         sleep 5
12293         can2=$(do_facet mds1 \
12294                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12295                awk '/ldlm_cancel/ {print $2}')
12296         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12297                awk '/ldlm_bl_callback/ {print $2}')
12298         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12299                 $LCTL dk $TMP/cancel.debug.txt
12300         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12301                 $LCTL dk $TMP/blocking.debug.txt
12302         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12303         lru_resize_enable mdc
12304         lru_resize_enable osc
12305 }
12306 run_test 120e "Early Lock Cancel: unlink test"
12307
12308 test_120f() {
12309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12310         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12311                 skip_env "no early lock cancel on server"
12312         remote_mds_nodsh && skip "remote MDS with nodsh"
12313
12314         test_mkdir -i0 -c1 $DIR/$tdir
12315         lru_resize_disable mdc
12316         lru_resize_disable osc
12317         test_mkdir -i0 -c1 $DIR/$tdir/d1
12318         test_mkdir -i0 -c1 $DIR/$tdir/d2
12319         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12320         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12321         cancel_lru_locks mdc
12322         cancel_lru_locks osc
12323         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12324         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12325         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12326         # XXX client can not do early lock cancel of OST lock
12327         # during rename (LU-4206), so cancel osc lock now.
12328         sleep 2
12329         cancel_lru_locks osc
12330         can1=$(do_facet mds1 \
12331                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12332                awk '/ldlm_cancel/ {print $2}')
12333         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12334                awk '/ldlm_bl_callback/ {print $2}')
12335         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12336         sleep 5
12337         can2=$(do_facet mds1 \
12338                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12339                awk '/ldlm_cancel/ {print $2}')
12340         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12341                awk '/ldlm_bl_callback/ {print $2}')
12342         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12343         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12344         lru_resize_enable mdc
12345         lru_resize_enable osc
12346 }
12347 run_test 120f "Early Lock Cancel: rename test"
12348
12349 test_120g() {
12350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12351         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12352                 skip_env "no early lock cancel on server"
12353         remote_mds_nodsh && skip "remote MDS with nodsh"
12354
12355         lru_resize_disable mdc
12356         lru_resize_disable osc
12357         count=10000
12358         echo create $count files
12359         test_mkdir $DIR/$tdir
12360         cancel_lru_locks mdc
12361         cancel_lru_locks osc
12362         t0=$(date +%s)
12363
12364         can0=$(do_facet $SINGLEMDS \
12365                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12366                awk '/ldlm_cancel/ {print $2}')
12367         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12368                awk '/ldlm_bl_callback/ {print $2}')
12369         createmany -o $DIR/$tdir/f $count
12370         sync
12371         can1=$(do_facet $SINGLEMDS \
12372                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12373                awk '/ldlm_cancel/ {print $2}')
12374         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12375                awk '/ldlm_bl_callback/ {print $2}')
12376         t1=$(date +%s)
12377         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12378         echo rm $count files
12379         rm -r $DIR/$tdir
12380         sync
12381         can2=$(do_facet $SINGLEMDS \
12382                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12383                awk '/ldlm_cancel/ {print $2}')
12384         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12385                awk '/ldlm_bl_callback/ {print $2}')
12386         t2=$(date +%s)
12387         echo total: $count removes in $((t2-t1))
12388         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12389         sleep 2
12390         # wait for commitment of removal
12391         lru_resize_enable mdc
12392         lru_resize_enable osc
12393 }
12394 run_test 120g "Early Lock Cancel: performance test"
12395
12396 test_121() { #bug #10589
12397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12398
12399         rm -rf $DIR/$tfile
12400         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12401 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12402         lctl set_param fail_loc=0x310
12403         cancel_lru_locks osc > /dev/null
12404         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12405         lctl set_param fail_loc=0
12406         [[ $reads -eq $writes ]] ||
12407                 error "read $reads blocks, must be $writes blocks"
12408 }
12409 run_test 121 "read cancel race ========="
12410
12411 test_123a_base() { # was test 123, statahead(bug 11401)
12412         local lsx="$1"
12413
12414         SLOWOK=0
12415         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12416                 log "testing UP system. Performance may be lower than expected."
12417                 SLOWOK=1
12418         fi
12419
12420         rm -rf $DIR/$tdir
12421         test_mkdir $DIR/$tdir
12422         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12423         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12424         MULT=10
12425         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12426                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12427
12428                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12429                 lctl set_param -n llite.*.statahead_max 0
12430                 lctl get_param llite.*.statahead_max
12431                 cancel_lru_locks mdc
12432                 cancel_lru_locks osc
12433                 stime=$(date +%s)
12434                 time $lsx $DIR/$tdir | wc -l
12435                 etime=$(date +%s)
12436                 delta=$((etime - stime))
12437                 log "$lsx $i files without statahead: $delta sec"
12438                 lctl set_param llite.*.statahead_max=$max
12439
12440                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12441                         grep "statahead wrong:" | awk '{print $3}')
12442                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12443                 cancel_lru_locks mdc
12444                 cancel_lru_locks osc
12445                 stime=$(date +%s)
12446                 time $lsx $DIR/$tdir | wc -l
12447                 etime=$(date +%s)
12448                 delta_sa=$((etime - stime))
12449                 log "$lsx $i files with statahead: $delta_sa sec"
12450                 lctl get_param -n llite.*.statahead_stats
12451                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12452                         grep "statahead wrong:" | awk '{print $3}')
12453
12454                 [[ $swrong -lt $ewrong ]] &&
12455                         log "statahead was stopped, maybe too many locks held!"
12456                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12457
12458                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12459                         max=$(lctl get_param -n llite.*.statahead_max |
12460                                 head -n 1)
12461                         lctl set_param -n llite.*.statahead_max 0
12462                         lctl get_param llite.*.statahead_max
12463                         cancel_lru_locks mdc
12464                         cancel_lru_locks osc
12465                         stime=$(date +%s)
12466                         time $lsx $DIR/$tdir | wc -l
12467                         etime=$(date +%s)
12468                         delta=$((etime - stime))
12469                         log "$lsx $i files again without statahead: $delta sec"
12470                         lctl set_param llite.*.statahead_max=$max
12471                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12472                                 if [  $SLOWOK -eq 0 ]; then
12473                                         error "$lsx $i files is slower with statahead!"
12474                                 else
12475                                         log "$lsx $i files is slower with statahead!"
12476                                 fi
12477                                 break
12478                         fi
12479                 fi
12480
12481                 [ $delta -gt 20 ] && break
12482                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12483                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12484         done
12485         log "$lsx done"
12486
12487         stime=$(date +%s)
12488         rm -r $DIR/$tdir
12489         sync
12490         etime=$(date +%s)
12491         delta=$((etime - stime))
12492         log "rm -r $DIR/$tdir/: $delta seconds"
12493         log "rm done"
12494         lctl get_param -n llite.*.statahead_stats
12495 }
12496
12497 test_123aa() {
12498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12499
12500         test_123a_base "ls -l"
12501 }
12502 run_test 123aa "verify statahead work"
12503
12504 test_123ab() {
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506
12507         statx_supported || skip_env "Test must be statx() syscall supported"
12508
12509         test_123a_base "$STATX -l"
12510 }
12511 run_test 123ab "verify statahead work by using statx"
12512
12513 test_123ac() {
12514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12515
12516         statx_supported || skip_env "Test must be statx() syscall supported"
12517
12518         local rpcs_before
12519         local rpcs_after
12520         local agl_before
12521         local agl_after
12522
12523         cancel_lru_locks $OSC
12524         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12525         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12526                 awk '/agl.total:/ {print $3}')
12527         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12528         test_123a_base "$STATX --cached=always -D"
12529         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12530                 awk '/agl.total:/ {print $3}')
12531         [ $agl_before -eq $agl_after ] ||
12532                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12533         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12534         [ $rpcs_after -eq $rpcs_before ] ||
12535                 error "$STATX should not send glimpse RPCs to $OSC"
12536 }
12537 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12538
12539 test_123b () { # statahead(bug 15027)
12540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12541
12542         test_mkdir $DIR/$tdir
12543         createmany -o $DIR/$tdir/$tfile-%d 1000
12544
12545         cancel_lru_locks mdc
12546         cancel_lru_locks osc
12547
12548 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12549         lctl set_param fail_loc=0x80000803
12550         ls -lR $DIR/$tdir > /dev/null
12551         log "ls done"
12552         lctl set_param fail_loc=0x0
12553         lctl get_param -n llite.*.statahead_stats
12554         rm -r $DIR/$tdir
12555         sync
12556
12557 }
12558 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12559
12560 test_123c() {
12561         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12562
12563         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12564         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12565         touch $DIR/$tdir.1/{1..3}
12566         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12567
12568         remount_client $MOUNT
12569
12570         $MULTIOP $DIR/$tdir.0 Q
12571
12572         # let statahead to complete
12573         ls -l $DIR/$tdir.0 > /dev/null
12574
12575         testid=$(echo $TESTNAME | tr '_' ' ')
12576         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12577                 error "statahead warning" || true
12578 }
12579 run_test 123c "Can not initialize inode warning on DNE statahead"
12580
12581 test_124a() {
12582         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12583         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12584                 skip_env "no lru resize on server"
12585
12586         local NR=2000
12587
12588         test_mkdir $DIR/$tdir
12589
12590         log "create $NR files at $DIR/$tdir"
12591         createmany -o $DIR/$tdir/f $NR ||
12592                 error "failed to create $NR files in $DIR/$tdir"
12593
12594         cancel_lru_locks mdc
12595         ls -l $DIR/$tdir > /dev/null
12596
12597         local NSDIR=""
12598         local LRU_SIZE=0
12599         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12600                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12601                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12602                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12603                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12604                         log "NSDIR=$NSDIR"
12605                         log "NS=$(basename $NSDIR)"
12606                         break
12607                 fi
12608         done
12609
12610         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12611                 skip "Not enough cached locks created!"
12612         fi
12613         log "LRU=$LRU_SIZE"
12614
12615         local SLEEP=30
12616
12617         # We know that lru resize allows one client to hold $LIMIT locks
12618         # for 10h. After that locks begin to be killed by client.
12619         local MAX_HRS=10
12620         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12621         log "LIMIT=$LIMIT"
12622         if [ $LIMIT -lt $LRU_SIZE ]; then
12623                 skip "Limit is too small $LIMIT"
12624         fi
12625
12626         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12627         # killing locks. Some time was spent for creating locks. This means
12628         # that up to the moment of sleep finish we must have killed some of
12629         # them (10-100 locks). This depends on how fast ther were created.
12630         # Many of them were touched in almost the same moment and thus will
12631         # be killed in groups.
12632         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12633
12634         # Use $LRU_SIZE_B here to take into account real number of locks
12635         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12636         local LRU_SIZE_B=$LRU_SIZE
12637         log "LVF=$LVF"
12638         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12639         log "OLD_LVF=$OLD_LVF"
12640         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12641
12642         # Let's make sure that we really have some margin. Client checks
12643         # cached locks every 10 sec.
12644         SLEEP=$((SLEEP+20))
12645         log "Sleep ${SLEEP} sec"
12646         local SEC=0
12647         while ((SEC<$SLEEP)); do
12648                 echo -n "..."
12649                 sleep 5
12650                 SEC=$((SEC+5))
12651                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12652                 echo -n "$LRU_SIZE"
12653         done
12654         echo ""
12655         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12656         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12657
12658         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12659                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12660                 unlinkmany $DIR/$tdir/f $NR
12661                 return
12662         }
12663
12664         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12665         log "unlink $NR files at $DIR/$tdir"
12666         unlinkmany $DIR/$tdir/f $NR
12667 }
12668 run_test 124a "lru resize ======================================="
12669
12670 get_max_pool_limit()
12671 {
12672         local limit=$($LCTL get_param \
12673                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12674         local max=0
12675         for l in $limit; do
12676                 if [[ $l -gt $max ]]; then
12677                         max=$l
12678                 fi
12679         done
12680         echo $max
12681 }
12682
12683 test_124b() {
12684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12685         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12686                 skip_env "no lru resize on server"
12687
12688         LIMIT=$(get_max_pool_limit)
12689
12690         NR=$(($(default_lru_size)*20))
12691         if [[ $NR -gt $LIMIT ]]; then
12692                 log "Limit lock number by $LIMIT locks"
12693                 NR=$LIMIT
12694         fi
12695
12696         IFree=$(mdsrate_inodes_available)
12697         if [ $IFree -lt $NR ]; then
12698                 log "Limit lock number by $IFree inodes"
12699                 NR=$IFree
12700         fi
12701
12702         lru_resize_disable mdc
12703         test_mkdir -p $DIR/$tdir/disable_lru_resize
12704
12705         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12706         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12707         cancel_lru_locks mdc
12708         stime=`date +%s`
12709         PID=""
12710         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12711         PID="$PID $!"
12712         sleep 2
12713         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12714         PID="$PID $!"
12715         sleep 2
12716         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12717         PID="$PID $!"
12718         wait $PID
12719         etime=`date +%s`
12720         nolruresize_delta=$((etime-stime))
12721         log "ls -la time: $nolruresize_delta seconds"
12722         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12723         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12724
12725         lru_resize_enable mdc
12726         test_mkdir -p $DIR/$tdir/enable_lru_resize
12727
12728         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12729         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12730         cancel_lru_locks mdc
12731         stime=`date +%s`
12732         PID=""
12733         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12734         PID="$PID $!"
12735         sleep 2
12736         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12737         PID="$PID $!"
12738         sleep 2
12739         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12740         PID="$PID $!"
12741         wait $PID
12742         etime=`date +%s`
12743         lruresize_delta=$((etime-stime))
12744         log "ls -la time: $lruresize_delta seconds"
12745         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12746
12747         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12748                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12749         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12750                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12751         else
12752                 log "lru resize performs the same with no lru resize"
12753         fi
12754         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12755 }
12756 run_test 124b "lru resize (performance test) ======================="
12757
12758 test_124c() {
12759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12760         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12761                 skip_env "no lru resize on server"
12762
12763         # cache ununsed locks on client
12764         local nr=100
12765         cancel_lru_locks mdc
12766         test_mkdir $DIR/$tdir
12767         createmany -o $DIR/$tdir/f $nr ||
12768                 error "failed to create $nr files in $DIR/$tdir"
12769         ls -l $DIR/$tdir > /dev/null
12770
12771         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12772         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12773         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12774         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12775         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12776
12777         # set lru_max_age to 1 sec
12778         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12779         echo "sleep $((recalc_p * 2)) seconds..."
12780         sleep $((recalc_p * 2))
12781
12782         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12783         # restore lru_max_age
12784         $LCTL set_param -n $nsdir.lru_max_age $max_age
12785         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12786         unlinkmany $DIR/$tdir/f $nr
12787 }
12788 run_test 124c "LRUR cancel very aged locks"
12789
12790 test_124d() {
12791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12792         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12793                 skip_env "no lru resize on server"
12794
12795         # cache ununsed locks on client
12796         local nr=100
12797
12798         lru_resize_disable mdc
12799         stack_trap "lru_resize_enable mdc" EXIT
12800
12801         cancel_lru_locks mdc
12802
12803         # asynchronous object destroy at MDT could cause bl ast to client
12804         test_mkdir $DIR/$tdir
12805         createmany -o $DIR/$tdir/f $nr ||
12806                 error "failed to create $nr files in $DIR/$tdir"
12807         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12808
12809         ls -l $DIR/$tdir > /dev/null
12810
12811         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12812         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12813         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12814         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12815
12816         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12817
12818         # set lru_max_age to 1 sec
12819         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12820         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12821
12822         echo "sleep $((recalc_p * 2)) seconds..."
12823         sleep $((recalc_p * 2))
12824
12825         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12826
12827         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12828 }
12829 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12830
12831 test_125() { # 13358
12832         $LCTL get_param -n llite.*.client_type | grep -q local ||
12833                 skip "must run as local client"
12834         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12835                 skip_env "must have acl enabled"
12836         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12837
12838         test_mkdir $DIR/$tdir
12839         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12840         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12841         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12842 }
12843 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12844
12845 test_126() { # bug 12829/13455
12846         $GSS && skip_env "must run as gss disabled"
12847         $LCTL get_param -n llite.*.client_type | grep -q local ||
12848                 skip "must run as local client"
12849         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12850
12851         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12852         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12853         rm -f $DIR/$tfile
12854         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12855 }
12856 run_test 126 "check that the fsgid provided by the client is taken into account"
12857
12858 test_127a() { # bug 15521
12859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12860         local name count samp unit min max sum sumsq
12861
12862         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12863         echo "stats before reset"
12864         $LCTL get_param osc.*.stats
12865         $LCTL set_param osc.*.stats=0
12866         local fsize=$((2048 * 1024))
12867
12868         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12869         cancel_lru_locks osc
12870         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12871
12872         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12873         stack_trap "rm -f $TMP/$tfile.tmp"
12874         while read name count samp unit min max sum sumsq; do
12875                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12876                 [ ! $min ] && error "Missing min value for $name proc entry"
12877                 eval $name=$count || error "Wrong proc format"
12878
12879                 case $name in
12880                 read_bytes|write_bytes)
12881                         [[ "$unit" =~ "bytes" ]] ||
12882                                 error "unit is not 'bytes': $unit"
12883                         (( $min >= 4096 )) || error "min is too small: $min"
12884                         (( $min <= $fsize )) || error "min is too big: $min"
12885                         (( $max >= 4096 )) || error "max is too small: $max"
12886                         (( $max <= $fsize )) || error "max is too big: $max"
12887                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12888                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12889                                 error "sumsquare is too small: $sumsq"
12890                         (( $sumsq <= $fsize * $fsize )) ||
12891                                 error "sumsquare is too big: $sumsq"
12892                         ;;
12893                 ost_read|ost_write)
12894                         [[ "$unit" =~ "usec" ]] ||
12895                                 error "unit is not 'usec': $unit"
12896                         ;;
12897                 *)      ;;
12898                 esac
12899         done < $DIR/$tfile.tmp
12900
12901         #check that we actually got some stats
12902         [ "$read_bytes" ] || error "Missing read_bytes stats"
12903         [ "$write_bytes" ] || error "Missing write_bytes stats"
12904         [ "$read_bytes" != 0 ] || error "no read done"
12905         [ "$write_bytes" != 0 ] || error "no write done"
12906 }
12907 run_test 127a "verify the client stats are sane"
12908
12909 test_127b() { # bug LU-333
12910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12911         local name count samp unit min max sum sumsq
12912
12913         echo "stats before reset"
12914         $LCTL get_param llite.*.stats
12915         $LCTL set_param llite.*.stats=0
12916
12917         # perform 2 reads and writes so MAX is different from SUM.
12918         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12919         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12920         cancel_lru_locks osc
12921         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12922         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12923
12924         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12925         stack_trap "rm -f $TMP/$tfile.tmp"
12926         while read name count samp unit min max sum sumsq; do
12927                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12928                 eval $name=$count || error "Wrong proc format"
12929
12930                 case $name in
12931                 read_bytes|write_bytes)
12932                         [[ "$unit" =~ "bytes" ]] ||
12933                                 error "unit is not 'bytes': $unit"
12934                         (( $count == 2 )) || error "count is not 2: $count"
12935                         (( $min == $PAGE_SIZE )) ||
12936                                 error "min is not $PAGE_SIZE: $min"
12937                         (( $max == $PAGE_SIZE )) ||
12938                                 error "max is not $PAGE_SIZE: $max"
12939                         (( $sum == $PAGE_SIZE * 2 )) ||
12940                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12941                         ;;
12942                 read|write)
12943                         [[ "$unit" =~ "usec" ]] ||
12944                                 error "unit is not 'usec': $unit"
12945                         ;;
12946                 *)      ;;
12947                 esac
12948         done < $TMP/$tfile.tmp
12949
12950         #check that we actually got some stats
12951         [ "$read_bytes" ] || error "Missing read_bytes stats"
12952         [ "$write_bytes" ] || error "Missing write_bytes stats"
12953         [ "$read_bytes" != 0 ] || error "no read done"
12954         [ "$write_bytes" != 0 ] || error "no write done"
12955 }
12956 run_test 127b "verify the llite client stats are sane"
12957
12958 test_127c() { # LU-12394
12959         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12960         local size
12961         local bsize
12962         local reads
12963         local writes
12964         local count
12965
12966         $LCTL set_param llite.*.extents_stats=1
12967         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12968
12969         # Use two stripes so there is enough space in default config
12970         $LFS setstripe -c 2 $DIR/$tfile
12971
12972         # Extent stats start at 0-4K and go in power of two buckets
12973         # LL_HIST_START = 12 --> 2^12 = 4K
12974         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12975         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12976         # small configs
12977         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12978                 do
12979                 # Write and read, 2x each, second time at a non-zero offset
12980                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12981                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12982                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12983                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12984                 rm -f $DIR/$tfile
12985         done
12986
12987         $LCTL get_param llite.*.extents_stats
12988
12989         count=2
12990         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12991                 do
12992                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12993                                 grep -m 1 $bsize)
12994                 reads=$(echo $bucket | awk '{print $5}')
12995                 writes=$(echo $bucket | awk '{print $9}')
12996                 [ "$reads" -eq $count ] ||
12997                         error "$reads reads in < $bsize bucket, expect $count"
12998                 [ "$writes" -eq $count ] ||
12999                         error "$writes writes in < $bsize bucket, expect $count"
13000         done
13001
13002         # Test mmap write and read
13003         $LCTL set_param llite.*.extents_stats=c
13004         size=512
13005         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13006         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13007         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13008
13009         $LCTL get_param llite.*.extents_stats
13010
13011         count=$(((size*1024) / PAGE_SIZE))
13012
13013         bsize=$((2 * PAGE_SIZE / 1024))K
13014
13015         bucket=$($LCTL get_param -n llite.*.extents_stats |
13016                         grep -m 1 $bsize)
13017         reads=$(echo $bucket | awk '{print $5}')
13018         writes=$(echo $bucket | awk '{print $9}')
13019         # mmap writes fault in the page first, creating an additonal read
13020         [ "$reads" -eq $((2 * count)) ] ||
13021                 error "$reads reads in < $bsize bucket, expect $count"
13022         [ "$writes" -eq $count ] ||
13023                 error "$writes writes in < $bsize bucket, expect $count"
13024 }
13025 run_test 127c "test llite extent stats with regular & mmap i/o"
13026
13027 test_128() { # bug 15212
13028         touch $DIR/$tfile
13029         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13030                 find $DIR/$tfile
13031                 find $DIR/$tfile
13032         EOF
13033
13034         result=$(grep error $TMP/$tfile.log)
13035         rm -f $DIR/$tfile $TMP/$tfile.log
13036         [ -z "$result" ] ||
13037                 error "consecutive find's under interactive lfs failed"
13038 }
13039 run_test 128 "interactive lfs for 2 consecutive find's"
13040
13041 set_dir_limits () {
13042         local mntdev
13043         local canondev
13044         local node
13045
13046         local ldproc=/proc/fs/ldiskfs
13047         local facets=$(get_facets MDS)
13048
13049         for facet in ${facets//,/ }; do
13050                 canondev=$(ldiskfs_canon \
13051                            *.$(convert_facet2label $facet).mntdev $facet)
13052                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13053                         ldproc=/sys/fs/ldiskfs
13054                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13055                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13056         done
13057 }
13058
13059 check_mds_dmesg() {
13060         local facets=$(get_facets MDS)
13061         for facet in ${facets//,/ }; do
13062                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13063         done
13064         return 1
13065 }
13066
13067 test_129() {
13068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13069         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13070                 skip "Need MDS version with at least 2.5.56"
13071         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13072                 skip_env "ldiskfs only test"
13073         fi
13074         remote_mds_nodsh && skip "remote MDS with nodsh"
13075
13076         local ENOSPC=28
13077         local has_warning=false
13078
13079         rm -rf $DIR/$tdir
13080         mkdir -p $DIR/$tdir
13081
13082         # block size of mds1
13083         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13084         set_dir_limits $maxsize $((maxsize * 6 / 8))
13085         stack_trap "set_dir_limits 0 0"
13086         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13087         local dirsize=$(stat -c%s "$DIR/$tdir")
13088         local nfiles=0
13089         while (( $dirsize <= $maxsize )); do
13090                 $MCREATE $DIR/$tdir/file_base_$nfiles
13091                 rc=$?
13092                 # check two errors:
13093                 # ENOSPC for ext4 max_dir_size, which has been used since
13094                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13095                 if (( rc == ENOSPC )); then
13096                         set_dir_limits 0 0
13097                         echo "rc=$rc returned as expected after $nfiles files"
13098
13099                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13100                                 error "create failed w/o dir size limit"
13101
13102                         # messages may be rate limited if test is run repeatedly
13103                         check_mds_dmesg '"is approaching max"' ||
13104                                 echo "warning message should be output"
13105                         check_mds_dmesg '"has reached max"' ||
13106                                 echo "reached message should be output"
13107
13108                         dirsize=$(stat -c%s "$DIR/$tdir")
13109
13110                         [[ $dirsize -ge $maxsize ]] && return 0
13111                         error "dirsize $dirsize < $maxsize after $nfiles files"
13112                 elif (( rc != 0 )); then
13113                         break
13114                 fi
13115                 nfiles=$((nfiles + 1))
13116                 dirsize=$(stat -c%s "$DIR/$tdir")
13117         done
13118
13119         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13120 }
13121 run_test 129 "test directory size limit ========================"
13122
13123 OLDIFS="$IFS"
13124 cleanup_130() {
13125         trap 0
13126         IFS="$OLDIFS"
13127 }
13128
13129 test_130a() {
13130         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13131         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13132
13133         trap cleanup_130 EXIT RETURN
13134
13135         local fm_file=$DIR/$tfile
13136         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13137         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13138                 error "dd failed for $fm_file"
13139
13140         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13141         filefrag -ves $fm_file
13142         RC=$?
13143         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13144                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13145         [ $RC != 0 ] && error "filefrag $fm_file failed"
13146
13147         filefrag_op=$(filefrag -ve -k $fm_file |
13148                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13149         lun=$($LFS getstripe -i $fm_file)
13150
13151         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13152         IFS=$'\n'
13153         tot_len=0
13154         for line in $filefrag_op
13155         do
13156                 frag_lun=`echo $line | cut -d: -f5`
13157                 ext_len=`echo $line | cut -d: -f4`
13158                 if (( $frag_lun != $lun )); then
13159                         cleanup_130
13160                         error "FIEMAP on 1-stripe file($fm_file) failed"
13161                         return
13162                 fi
13163                 (( tot_len += ext_len ))
13164         done
13165
13166         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13167                 cleanup_130
13168                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13169                 return
13170         fi
13171
13172         cleanup_130
13173
13174         echo "FIEMAP on single striped file succeeded"
13175 }
13176 run_test 130a "FIEMAP (1-stripe file)"
13177
13178 test_130b() {
13179         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13180
13181         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13182         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13183
13184         trap cleanup_130 EXIT RETURN
13185
13186         local fm_file=$DIR/$tfile
13187         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13188                         error "setstripe on $fm_file"
13189         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13190                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13191
13192         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13193                 error "dd failed on $fm_file"
13194
13195         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13196         filefrag_op=$(filefrag -ve -k $fm_file |
13197                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13198
13199         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13200                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13201
13202         IFS=$'\n'
13203         tot_len=0
13204         num_luns=1
13205         for line in $filefrag_op
13206         do
13207                 frag_lun=$(echo $line | cut -d: -f5 |
13208                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13209                 ext_len=$(echo $line | cut -d: -f4)
13210                 if (( $frag_lun != $last_lun )); then
13211                         if (( tot_len != 1024 )); then
13212                                 cleanup_130
13213                                 error "FIEMAP on $fm_file failed; returned " \
13214                                 "len $tot_len for OST $last_lun instead of 1024"
13215                                 return
13216                         else
13217                                 (( num_luns += 1 ))
13218                                 tot_len=0
13219                         fi
13220                 fi
13221                 (( tot_len += ext_len ))
13222                 last_lun=$frag_lun
13223         done
13224         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13225                 cleanup_130
13226                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13227                         "luns or wrong len for OST $last_lun"
13228                 return
13229         fi
13230
13231         cleanup_130
13232
13233         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13234 }
13235 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13236
13237 test_130c() {
13238         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13239
13240         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13241         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13242
13243         trap cleanup_130 EXIT RETURN
13244
13245         local fm_file=$DIR/$tfile
13246         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13247         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13248                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13249
13250         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13251                         error "dd failed on $fm_file"
13252
13253         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13254         filefrag_op=$(filefrag -ve -k $fm_file |
13255                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13256
13257         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13258                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13259
13260         IFS=$'\n'
13261         tot_len=0
13262         num_luns=1
13263         for line in $filefrag_op
13264         do
13265                 frag_lun=$(echo $line | cut -d: -f5 |
13266                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13267                 ext_len=$(echo $line | cut -d: -f4)
13268                 if (( $frag_lun != $last_lun )); then
13269                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13270                         if (( logical != 512 )); then
13271                                 cleanup_130
13272                                 error "FIEMAP on $fm_file failed; returned " \
13273                                 "logical start for lun $logical instead of 512"
13274                                 return
13275                         fi
13276                         if (( tot_len != 512 )); then
13277                                 cleanup_130
13278                                 error "FIEMAP on $fm_file failed; returned " \
13279                                 "len $tot_len for OST $last_lun instead of 1024"
13280                                 return
13281                         else
13282                                 (( num_luns += 1 ))
13283                                 tot_len=0
13284                         fi
13285                 fi
13286                 (( tot_len += ext_len ))
13287                 last_lun=$frag_lun
13288         done
13289         if (( num_luns != 2 || tot_len != 512 )); then
13290                 cleanup_130
13291                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13292                         "luns or wrong len for OST $last_lun"
13293                 return
13294         fi
13295
13296         cleanup_130
13297
13298         echo "FIEMAP on 2-stripe file with hole succeeded"
13299 }
13300 run_test 130c "FIEMAP (2-stripe file with hole)"
13301
13302 test_130d() {
13303         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13304
13305         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13306         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13307
13308         trap cleanup_130 EXIT RETURN
13309
13310         local fm_file=$DIR/$tfile
13311         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13312                         error "setstripe on $fm_file"
13313         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13314                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13315
13316         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13317         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13318                 error "dd failed on $fm_file"
13319
13320         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13321         filefrag_op=$(filefrag -ve -k $fm_file |
13322                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13323
13324         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13325                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13326
13327         IFS=$'\n'
13328         tot_len=0
13329         num_luns=1
13330         for line in $filefrag_op
13331         do
13332                 frag_lun=$(echo $line | cut -d: -f5 |
13333                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13334                 ext_len=$(echo $line | cut -d: -f4)
13335                 if (( $frag_lun != $last_lun )); then
13336                         if (( tot_len != 1024 )); then
13337                                 cleanup_130
13338                                 error "FIEMAP on $fm_file failed; returned " \
13339                                 "len $tot_len for OST $last_lun instead of 1024"
13340                                 return
13341                         else
13342                                 (( num_luns += 1 ))
13343                                 tot_len=0
13344                         fi
13345                 fi
13346                 (( tot_len += ext_len ))
13347                 last_lun=$frag_lun
13348         done
13349         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13350                 cleanup_130
13351                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13352                         "luns or wrong len for OST $last_lun"
13353                 return
13354         fi
13355
13356         cleanup_130
13357
13358         echo "FIEMAP on N-stripe file succeeded"
13359 }
13360 run_test 130d "FIEMAP (N-stripe file)"
13361
13362 test_130e() {
13363         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13364
13365         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13366         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13367
13368         trap cleanup_130 EXIT RETURN
13369
13370         local fm_file=$DIR/$tfile
13371         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13372
13373         NUM_BLKS=512
13374         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13375         for ((i = 0; i < $NUM_BLKS; i++)); do
13376                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13377                         conv=notrunc > /dev/null 2>&1
13378         done
13379
13380         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13381         filefrag_op=$(filefrag -ve -k $fm_file |
13382                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13383
13384         last_lun=$(echo $filefrag_op | cut -d: -f5)
13385
13386         IFS=$'\n'
13387         tot_len=0
13388         num_luns=1
13389         for line in $filefrag_op; do
13390                 frag_lun=$(echo $line | cut -d: -f5)
13391                 ext_len=$(echo $line | cut -d: -f4)
13392                 if [[ "$frag_lun" != "$last_lun" ]]; then
13393                         if (( tot_len != $EXPECTED_LEN )); then
13394                                 cleanup_130
13395                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13396                         else
13397                                 (( num_luns += 1 ))
13398                                 tot_len=0
13399                         fi
13400                 fi
13401                 (( tot_len += ext_len ))
13402                 last_lun=$frag_lun
13403         done
13404         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13405                 cleanup_130
13406                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13407         fi
13408
13409         echo "FIEMAP with continuation calls succeeded"
13410 }
13411 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13412
13413 test_130f() {
13414         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13415         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13416
13417         local fm_file=$DIR/$tfile
13418         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13419                 error "multiop create with lov_delay_create on $fm_file"
13420
13421         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13422         filefrag_extents=$(filefrag -vek $fm_file |
13423                            awk '/extents? found/ { print $2 }')
13424         if [[ "$filefrag_extents" != "0" ]]; then
13425                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13426         fi
13427
13428         rm -f $fm_file
13429 }
13430 run_test 130f "FIEMAP (unstriped file)"
13431
13432 test_130g() {
13433         local file=$DIR/$tfile
13434         local nr=$((OSTCOUNT * 100))
13435
13436         $LFS setstripe -C $nr $file ||
13437                 error "failed to setstripe -C $nr $file"
13438
13439         dd if=/dev/zero of=$file count=$nr bs=1M
13440         sync
13441         nr=$($LFS getstripe -c $file)
13442
13443         local extents=$(filefrag -v $file |
13444                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13445
13446         echo "filefrag list $extents extents in file with stripecount $nr"
13447         if (( extents < nr )); then
13448                 $LFS getstripe $file
13449                 filefrag -v $file
13450                 error "filefrag printed $extents < $nr extents"
13451         fi
13452
13453         rm -f $file
13454 }
13455 run_test 130g "FIEMAP (overstripe file)"
13456
13457 # Test for writev/readv
13458 test_131a() {
13459         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13460                 error "writev test failed"
13461         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13462                 error "readv failed"
13463         rm -f $DIR/$tfile
13464 }
13465 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13466
13467 test_131b() {
13468         local fsize=$((524288 + 1048576 + 1572864))
13469         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13470                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13471                         error "append writev test failed"
13472
13473         ((fsize += 1572864 + 1048576))
13474         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13475                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13476                         error "append writev test failed"
13477         rm -f $DIR/$tfile
13478 }
13479 run_test 131b "test append writev"
13480
13481 test_131c() {
13482         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13483         error "NOT PASS"
13484 }
13485 run_test 131c "test read/write on file w/o objects"
13486
13487 test_131d() {
13488         rwv -f $DIR/$tfile -w -n 1 1572864
13489         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13490         if [ "$NOB" != 1572864 ]; then
13491                 error "Short read filed: read $NOB bytes instead of 1572864"
13492         fi
13493         rm -f $DIR/$tfile
13494 }
13495 run_test 131d "test short read"
13496
13497 test_131e() {
13498         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13499         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13500         error "read hitting hole failed"
13501         rm -f $DIR/$tfile
13502 }
13503 run_test 131e "test read hitting hole"
13504
13505 check_stats() {
13506         local facet=$1
13507         local op=$2
13508         local want=${3:-0}
13509         local res
13510
13511         case $facet in
13512         mds*) res=$(do_facet $facet \
13513                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13514                  ;;
13515         ost*) res=$(do_facet $facet \
13516                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13517                  ;;
13518         *) error "Wrong facet '$facet'" ;;
13519         esac
13520         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13521         # if the argument $3 is zero, it means any stat increment is ok.
13522         if [[ $want -gt 0 ]]; then
13523                 local count=$(echo $res | awk '{ print $2 }')
13524                 [[ $count -ne $want ]] &&
13525                         error "The $op counter on $facet is $count, not $want"
13526         fi
13527 }
13528
13529 test_133a() {
13530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13531         remote_ost_nodsh && skip "remote OST with nodsh"
13532         remote_mds_nodsh && skip "remote MDS with nodsh"
13533         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13534                 skip_env "MDS doesn't support rename stats"
13535
13536         local testdir=$DIR/${tdir}/stats_testdir
13537
13538         mkdir -p $DIR/${tdir}
13539
13540         # clear stats.
13541         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13542         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13543
13544         # verify mdt stats first.
13545         mkdir ${testdir} || error "mkdir failed"
13546         check_stats $SINGLEMDS "mkdir" 1
13547         touch ${testdir}/${tfile} || error "touch failed"
13548         check_stats $SINGLEMDS "open" 1
13549         check_stats $SINGLEMDS "close" 1
13550         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13551                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13552                 check_stats $SINGLEMDS "mknod" 2
13553         }
13554         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13555         check_stats $SINGLEMDS "unlink" 1
13556         rm -f ${testdir}/${tfile} || error "file remove failed"
13557         check_stats $SINGLEMDS "unlink" 2
13558
13559         # remove working dir and check mdt stats again.
13560         rmdir ${testdir} || error "rmdir failed"
13561         check_stats $SINGLEMDS "rmdir" 1
13562
13563         local testdir1=$DIR/${tdir}/stats_testdir1
13564         mkdir -p ${testdir}
13565         mkdir -p ${testdir1}
13566         touch ${testdir1}/test1
13567         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13568         check_stats $SINGLEMDS "crossdir_rename" 1
13569
13570         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13571         check_stats $SINGLEMDS "samedir_rename" 1
13572
13573         rm -rf $DIR/${tdir}
13574 }
13575 run_test 133a "Verifying MDT stats ========================================"
13576
13577 test_133b() {
13578         local res
13579
13580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13581         remote_ost_nodsh && skip "remote OST with nodsh"
13582         remote_mds_nodsh && skip "remote MDS with nodsh"
13583
13584         local testdir=$DIR/${tdir}/stats_testdir
13585
13586         mkdir -p ${testdir} || error "mkdir failed"
13587         touch ${testdir}/${tfile} || error "touch failed"
13588         cancel_lru_locks mdc
13589
13590         # clear stats.
13591         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13592         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13593
13594         # extra mdt stats verification.
13595         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13596         check_stats $SINGLEMDS "setattr" 1
13597         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13598         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13599         then            # LU-1740
13600                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13601                 check_stats $SINGLEMDS "getattr" 1
13602         fi
13603         rm -rf $DIR/${tdir}
13604
13605         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13606         # so the check below is not reliable
13607         [ $MDSCOUNT -eq 1 ] || return 0
13608
13609         # Sleep to avoid a cached response.
13610         #define OBD_STATFS_CACHE_SECONDS 1
13611         sleep 2
13612         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13613         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13614         $LFS df || error "lfs failed"
13615         check_stats $SINGLEMDS "statfs" 1
13616
13617         # check aggregated statfs (LU-10018)
13618         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13619                 return 0
13620         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13621                 return 0
13622         sleep 2
13623         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13624         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13625         df $DIR
13626         check_stats $SINGLEMDS "statfs" 1
13627
13628         # We want to check that the client didn't send OST_STATFS to
13629         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13630         # extra care is needed here.
13631         if remote_mds; then
13632                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13633                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13634
13635                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13636                 [ "$res" ] && error "OST got STATFS"
13637         fi
13638
13639         return 0
13640 }
13641 run_test 133b "Verifying extra MDT stats =================================="
13642
13643 test_133c() {
13644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13645         remote_ost_nodsh && skip "remote OST with nodsh"
13646         remote_mds_nodsh && skip "remote MDS with nodsh"
13647
13648         local testdir=$DIR/$tdir/stats_testdir
13649
13650         test_mkdir -p $testdir
13651
13652         # verify obdfilter stats.
13653         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13654         sync
13655         cancel_lru_locks osc
13656         wait_delete_completed
13657
13658         # clear stats.
13659         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13660         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13661
13662         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13663                 error "dd failed"
13664         sync
13665         cancel_lru_locks osc
13666         check_stats ost1 "write" 1
13667
13668         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13669         check_stats ost1 "read" 1
13670
13671         > $testdir/$tfile || error "truncate failed"
13672         check_stats ost1 "punch" 1
13673
13674         rm -f $testdir/$tfile || error "file remove failed"
13675         wait_delete_completed
13676         check_stats ost1 "destroy" 1
13677
13678         rm -rf $DIR/$tdir
13679 }
13680 run_test 133c "Verifying OST stats ========================================"
13681
13682 order_2() {
13683         local value=$1
13684         local orig=$value
13685         local order=1
13686
13687         while [ $value -ge 2 ]; do
13688                 order=$((order*2))
13689                 value=$((value/2))
13690         done
13691
13692         if [ $orig -gt $order ]; then
13693                 order=$((order*2))
13694         fi
13695         echo $order
13696 }
13697
13698 size_in_KMGT() {
13699     local value=$1
13700     local size=('K' 'M' 'G' 'T');
13701     local i=0
13702     local size_string=$value
13703
13704     while [ $value -ge 1024 ]; do
13705         if [ $i -gt 3 ]; then
13706             #T is the biggest unit we get here, if that is bigger,
13707             #just return XXXT
13708             size_string=${value}T
13709             break
13710         fi
13711         value=$((value >> 10))
13712         if [ $value -lt 1024 ]; then
13713             size_string=${value}${size[$i]}
13714             break
13715         fi
13716         i=$((i + 1))
13717     done
13718
13719     echo $size_string
13720 }
13721
13722 get_rename_size() {
13723         local size=$1
13724         local context=${2:-.}
13725         local sample=$(do_facet $SINGLEMDS $LCTL \
13726                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13727                 grep -A1 $context |
13728                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13729         echo $sample
13730 }
13731
13732 test_133d() {
13733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13734         remote_ost_nodsh && skip "remote OST with nodsh"
13735         remote_mds_nodsh && skip "remote MDS with nodsh"
13736         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13737                 skip_env "MDS doesn't support rename stats"
13738
13739         local testdir1=$DIR/${tdir}/stats_testdir1
13740         local testdir2=$DIR/${tdir}/stats_testdir2
13741         mkdir -p $DIR/${tdir}
13742
13743         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13744
13745         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13746         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13747
13748         createmany -o $testdir1/test 512 || error "createmany failed"
13749
13750         # check samedir rename size
13751         mv ${testdir1}/test0 ${testdir1}/test_0
13752
13753         local testdir1_size=$(ls -l $DIR/${tdir} |
13754                 awk '/stats_testdir1/ {print $5}')
13755         local testdir2_size=$(ls -l $DIR/${tdir} |
13756                 awk '/stats_testdir2/ {print $5}')
13757
13758         testdir1_size=$(order_2 $testdir1_size)
13759         testdir2_size=$(order_2 $testdir2_size)
13760
13761         testdir1_size=$(size_in_KMGT $testdir1_size)
13762         testdir2_size=$(size_in_KMGT $testdir2_size)
13763
13764         echo "source rename dir size: ${testdir1_size}"
13765         echo "target rename dir size: ${testdir2_size}"
13766
13767         local cmd="do_facet $SINGLEMDS $LCTL "
13768         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13769
13770         eval $cmd || error "$cmd failed"
13771         local samedir=$($cmd | grep 'same_dir')
13772         local same_sample=$(get_rename_size $testdir1_size)
13773         [ -z "$samedir" ] && error "samedir_rename_size count error"
13774         [[ $same_sample -eq 1 ]] ||
13775                 error "samedir_rename_size error $same_sample"
13776         echo "Check same dir rename stats success"
13777
13778         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13779
13780         # check crossdir rename size
13781         mv ${testdir1}/test_0 ${testdir2}/test_0
13782
13783         testdir1_size=$(ls -l $DIR/${tdir} |
13784                 awk '/stats_testdir1/ {print $5}')
13785         testdir2_size=$(ls -l $DIR/${tdir} |
13786                 awk '/stats_testdir2/ {print $5}')
13787
13788         testdir1_size=$(order_2 $testdir1_size)
13789         testdir2_size=$(order_2 $testdir2_size)
13790
13791         testdir1_size=$(size_in_KMGT $testdir1_size)
13792         testdir2_size=$(size_in_KMGT $testdir2_size)
13793
13794         echo "source rename dir size: ${testdir1_size}"
13795         echo "target rename dir size: ${testdir2_size}"
13796
13797         eval $cmd || error "$cmd failed"
13798         local crossdir=$($cmd | grep 'crossdir')
13799         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13800         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13801         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13802         [[ $src_sample -eq 1 ]] ||
13803                 error "crossdir_rename_size error $src_sample"
13804         [[ $tgt_sample -eq 1 ]] ||
13805                 error "crossdir_rename_size error $tgt_sample"
13806         echo "Check cross dir rename stats success"
13807         rm -rf $DIR/${tdir}
13808 }
13809 run_test 133d "Verifying rename_stats ========================================"
13810
13811 test_133e() {
13812         remote_mds_nodsh && skip "remote MDS with nodsh"
13813         remote_ost_nodsh && skip "remote OST with nodsh"
13814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13815
13816         local testdir=$DIR/${tdir}/stats_testdir
13817         local ctr f0 f1 bs=32768 count=42 sum
13818
13819         mkdir -p ${testdir} || error "mkdir failed"
13820
13821         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13822
13823         for ctr in {write,read}_bytes; do
13824                 sync
13825                 cancel_lru_locks osc
13826
13827                 do_facet ost1 $LCTL set_param -n \
13828                         "obdfilter.*.exports.clear=clear"
13829
13830                 if [ $ctr = write_bytes ]; then
13831                         f0=/dev/zero
13832                         f1=${testdir}/${tfile}
13833                 else
13834                         f0=${testdir}/${tfile}
13835                         f1=/dev/null
13836                 fi
13837
13838                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13839                         error "dd failed"
13840                 sync
13841                 cancel_lru_locks osc
13842
13843                 sum=$(do_facet ost1 $LCTL get_param \
13844                         "obdfilter.*.exports.*.stats" |
13845                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13846                                 $1 == ctr { sum += $7 }
13847                                 END { printf("%0.0f", sum) }')
13848
13849                 if ((sum != bs * count)); then
13850                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13851                 fi
13852         done
13853
13854         rm -rf $DIR/${tdir}
13855 }
13856 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13857
13858 test_133f() {
13859         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13860                 skip "too old lustre for get_param -R ($facet_ver)"
13861
13862         # verifying readability.
13863         $LCTL get_param -R '*' &> /dev/null
13864
13865         # Verifing writability with badarea_io.
13866         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13867         local skipped_params='force_lbug|changelog_mask|daemon_file'
13868         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13869                 egrep -v "$skipped_params" |
13870                 xargs -n 1 find $proc_dirs -name |
13871                 xargs -n 1 badarea_io ||
13872                 error "client badarea_io failed"
13873
13874         # remount the FS in case writes/reads /proc break the FS
13875         cleanup || error "failed to unmount"
13876         setup || error "failed to setup"
13877 }
13878 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13879
13880 test_133g() {
13881         remote_mds_nodsh && skip "remote MDS with nodsh"
13882         remote_ost_nodsh && skip "remote OST with nodsh"
13883
13884         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13885         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
13886         local facet
13887         for facet in mds1 ost1; do
13888                 local facet_ver=$(lustre_version_code $facet)
13889                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13890                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13891                 else
13892                         log "$facet: too old lustre for get_param -R"
13893                 fi
13894                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13895                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13896                                 tr -d = | egrep -v $skipped_params |
13897                                 xargs -n 1 find $proc_dirs -name |
13898                                 xargs -n 1 badarea_io" ||
13899                                         error "$facet badarea_io failed"
13900                 else
13901                         skip_noexit "$facet: too old lustre for get_param -R"
13902                 fi
13903         done
13904
13905         # remount the FS in case writes/reads /proc break the FS
13906         cleanup || error "failed to unmount"
13907         setup || error "failed to setup"
13908 }
13909 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13910
13911 test_133h() {
13912         remote_mds_nodsh && skip "remote MDS with nodsh"
13913         remote_ost_nodsh && skip "remote OST with nodsh"
13914         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13915                 skip "Need MDS version at least 2.9.54"
13916
13917         local facet
13918         for facet in client mds1 ost1; do
13919                 # Get the list of files that are missing the terminating newline
13920                 local plist=$(do_facet $facet
13921                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13922                 local ent
13923                 for ent in $plist; do
13924                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13925                                 awk -v FS='\v' -v RS='\v\v' \
13926                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13927                                         print FILENAME}'" 2>/dev/null)
13928                         [ -z $missing ] || {
13929                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13930                                 error "file does not end with newline: $facet-$ent"
13931                         }
13932                 done
13933         done
13934 }
13935 run_test 133h "Proc files should end with newlines"
13936
13937 test_134a() {
13938         remote_mds_nodsh && skip "remote MDS with nodsh"
13939         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13940                 skip "Need MDS version at least 2.7.54"
13941
13942         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13943         cancel_lru_locks mdc
13944
13945         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13946         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13947         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13948
13949         local nr=1000
13950         createmany -o $DIR/$tdir/f $nr ||
13951                 error "failed to create $nr files in $DIR/$tdir"
13952         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13953
13954         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13955         do_facet mds1 $LCTL set_param fail_loc=0x327
13956         do_facet mds1 $LCTL set_param fail_val=500
13957         touch $DIR/$tdir/m
13958
13959         echo "sleep 10 seconds ..."
13960         sleep 10
13961         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13962
13963         do_facet mds1 $LCTL set_param fail_loc=0
13964         do_facet mds1 $LCTL set_param fail_val=0
13965         [ $lck_cnt -lt $unused ] ||
13966                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13967
13968         rm $DIR/$tdir/m
13969         unlinkmany $DIR/$tdir/f $nr
13970 }
13971 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13972
13973 test_134b() {
13974         remote_mds_nodsh && skip "remote MDS with nodsh"
13975         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13976                 skip "Need MDS version at least 2.7.54"
13977
13978         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
13979         cancel_lru_locks mdc
13980
13981         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13982                         ldlm.lock_reclaim_threshold_mb)
13983         # disable reclaim temporarily
13984         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13985
13986         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13987         do_facet mds1 $LCTL set_param fail_loc=0x328
13988         do_facet mds1 $LCTL set_param fail_val=500
13989
13990         $LCTL set_param debug=+trace
13991
13992         local nr=600
13993         createmany -o $DIR/$tdir/f $nr &
13994         local create_pid=$!
13995
13996         echo "Sleep $TIMEOUT seconds ..."
13997         sleep $TIMEOUT
13998         if ! ps -p $create_pid  > /dev/null 2>&1; then
13999                 do_facet mds1 $LCTL set_param fail_loc=0
14000                 do_facet mds1 $LCTL set_param fail_val=0
14001                 do_facet mds1 $LCTL set_param \
14002                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14003                 error "createmany finished incorrectly!"
14004         fi
14005         do_facet mds1 $LCTL set_param fail_loc=0
14006         do_facet mds1 $LCTL set_param fail_val=0
14007         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14008         wait $create_pid || return 1
14009
14010         unlinkmany $DIR/$tdir/f $nr
14011 }
14012 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14013
14014 test_135() {
14015         remote_mds_nodsh && skip "remote MDS with nodsh"
14016         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14017                 skip "Need MDS version at least 2.13.50"
14018         local fname
14019
14020         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14021
14022 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14023         #set only one record at plain llog
14024         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14025
14026         #fill already existed plain llog each 64767
14027         #wrapping whole catalog
14028         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14029
14030         createmany -o $DIR/$tdir/$tfile_ 64700
14031         for (( i = 0; i < 64700; i = i + 2 ))
14032         do
14033                 rm $DIR/$tdir/$tfile_$i &
14034                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14035                 local pid=$!
14036                 wait $pid
14037         done
14038
14039         #waiting osp synchronization
14040         wait_delete_completed
14041 }
14042 run_test 135 "Race catalog processing"
14043
14044 test_136() {
14045         remote_mds_nodsh && skip "remote MDS with nodsh"
14046         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14047                 skip "Need MDS version at least 2.13.50"
14048         local fname
14049
14050         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14051         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14052         #set only one record at plain llog
14053 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14054         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14055
14056         #fill already existed 2 plain llogs each 64767
14057         #wrapping whole catalog
14058         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14059         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14060         wait_delete_completed
14061
14062         createmany -o $DIR/$tdir/$tfile_ 10
14063         sleep 25
14064
14065         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14066         for (( i = 0; i < 10; i = i + 3 ))
14067         do
14068                 rm $DIR/$tdir/$tfile_$i &
14069                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14070                 local pid=$!
14071                 wait $pid
14072                 sleep 7
14073                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14074         done
14075
14076         #waiting osp synchronization
14077         wait_delete_completed
14078 }
14079 run_test 136 "Race catalog processing 2"
14080
14081 test_140() { #bug-17379
14082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14083
14084         test_mkdir $DIR/$tdir
14085         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14086         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14087
14088         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14089         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14090         local i=0
14091         while i=$((i + 1)); do
14092                 test_mkdir $i
14093                 cd $i || error "Changing to $i"
14094                 ln -s ../stat stat || error "Creating stat symlink"
14095                 # Read the symlink until ELOOP present,
14096                 # not LBUGing the system is considered success,
14097                 # we didn't overrun the stack.
14098                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14099                 if [ $ret -ne 0 ]; then
14100                         if [ $ret -eq 40 ]; then
14101                                 break  # -ELOOP
14102                         else
14103                                 error "Open stat symlink"
14104                                         return
14105                         fi
14106                 fi
14107         done
14108         i=$((i - 1))
14109         echo "The symlink depth = $i"
14110         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14111                 error "Invalid symlink depth"
14112
14113         # Test recursive symlink
14114         ln -s symlink_self symlink_self
14115         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14116         echo "open symlink_self returns $ret"
14117         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14118 }
14119 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14120
14121 test_150a() {
14122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14123
14124         local TF="$TMP/$tfile"
14125
14126         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14127         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14128         cp $TF $DIR/$tfile
14129         cancel_lru_locks $OSC
14130         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14131         remount_client $MOUNT
14132         df -P $MOUNT
14133         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14134
14135         $TRUNCATE $TF 6000
14136         $TRUNCATE $DIR/$tfile 6000
14137         cancel_lru_locks $OSC
14138         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14139
14140         echo "12345" >>$TF
14141         echo "12345" >>$DIR/$tfile
14142         cancel_lru_locks $OSC
14143         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14144
14145         echo "12345" >>$TF
14146         echo "12345" >>$DIR/$tfile
14147         cancel_lru_locks $OSC
14148         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14149 }
14150 run_test 150a "truncate/append tests"
14151
14152 test_150b() {
14153         check_set_fallocate_or_skip
14154
14155         touch $DIR/$tfile
14156         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14157         check_fallocate $DIR/$tfile || error "fallocate failed"
14158 }
14159 run_test 150b "Verify fallocate (prealloc) functionality"
14160
14161 test_150bb() {
14162         check_set_fallocate_or_skip
14163
14164         touch $DIR/$tfile
14165         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14166         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14167         > $DIR/$tfile
14168         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14169         # precomputed md5sum for 20MB of zeroes
14170         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14171         local sum=($(md5sum $DIR/$tfile))
14172
14173         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14174
14175         check_set_fallocate 1
14176
14177         > $DIR/$tfile
14178         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14179         sum=($(md5sum $DIR/$tfile))
14180
14181         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14182 }
14183 run_test 150bb "Verify fallocate modes both zero space"
14184
14185 test_150c() {
14186         check_set_fallocate_or_skip
14187         local striping="-c2"
14188
14189         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14190         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14191         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14192         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14193         local want=$((OSTCOUNT * 1048576))
14194
14195         # Must allocate all requested space, not more than 5% extra
14196         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14197                 error "bytes $bytes is not $want"
14198
14199         rm -f $DIR/$tfile
14200
14201         echo "verify fallocate on PFL file"
14202
14203         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14204
14205         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14206                 error "Create $DIR/$tfile failed"
14207         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14208                         error "fallocate failed"
14209         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14210         want=$((512 * 1048576))
14211
14212         # Must allocate all requested space, not more than 5% extra
14213         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14214                 error "bytes $bytes is not $want"
14215 }
14216 run_test 150c "Verify fallocate Size and Blocks"
14217
14218 test_150d() {
14219         check_set_fallocate_or_skip
14220         local striping="-c2"
14221
14222         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14223
14224         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14225         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14226                 error "setstripe failed"
14227         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14228         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14229         local want=$((OSTCOUNT * 1048576))
14230
14231         # Must allocate all requested space, not more than 5% extra
14232         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14233                 error "bytes $bytes is not $want"
14234 }
14235 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14236
14237 test_150e() {
14238         check_set_fallocate_or_skip
14239
14240         echo "df before:"
14241         $LFS df
14242         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14243         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14244                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14245
14246         # Find OST with Minimum Size
14247         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14248                        sort -un | head -1)
14249
14250         # Get 100MB per OST of the available space to reduce run time
14251         # else 60% of the available space if we are running SLOW tests
14252         if [ $SLOW == "no" ]; then
14253                 local space=$((1024 * 100 * OSTCOUNT))
14254         else
14255                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14256         fi
14257
14258         fallocate -l${space}k $DIR/$tfile ||
14259                 error "fallocate ${space}k $DIR/$tfile failed"
14260         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14261
14262         # get size immediately after fallocate. This should be correctly
14263         # updated
14264         local size=$(stat -c '%s' $DIR/$tfile)
14265         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14266
14267         # Sleep for a while for statfs to get updated. And not pull from cache.
14268         sleep 2
14269
14270         echo "df after fallocate:"
14271         $LFS df
14272
14273         (( size / 1024 == space )) || error "size $size != requested $space"
14274         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14275                 error "used $used < space $space"
14276
14277         rm $DIR/$tfile || error "rm failed"
14278         sync
14279         wait_delete_completed
14280
14281         echo "df after unlink:"
14282         $LFS df
14283 }
14284 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14285
14286 test_150f() {
14287         local size
14288         local blocks
14289         local want_size_before=20480 # in bytes
14290         local want_blocks_before=40 # 512 sized blocks
14291         local want_blocks_after=24  # 512 sized blocks
14292         local length=$(((want_blocks_before - want_blocks_after) * 512))
14293
14294         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14295                 skip "need at least 2.14.0 for fallocate punch"
14296
14297         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14298                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14299         fi
14300
14301         check_set_fallocate_or_skip
14302         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14303
14304         [[ "x$DOM" == "xyes" ]] &&
14305                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14306
14307         echo "Verify fallocate punch: Range within the file range"
14308         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14309                 error "dd failed for bs 4096 and count 5"
14310
14311         # Call fallocate with punch range which is within the file range
14312         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14313                 error "fallocate failed: offset 4096 and length $length"
14314         # client must see changes immediately after fallocate
14315         size=$(stat -c '%s' $DIR/$tfile)
14316         blocks=$(stat -c '%b' $DIR/$tfile)
14317
14318         # Verify punch worked.
14319         (( blocks == want_blocks_after )) ||
14320                 error "punch failed: blocks $blocks != $want_blocks_after"
14321
14322         (( size == want_size_before )) ||
14323                 error "punch failed: size $size != $want_size_before"
14324
14325         # Verify there is hole in file
14326         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14327         # precomputed md5sum
14328         local expect="4a9a834a2db02452929c0a348273b4aa"
14329
14330         cksum=($(md5sum $DIR/$tfile))
14331         [[ "${cksum[0]}" == "$expect" ]] ||
14332                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14333
14334         # Start second sub-case for fallocate punch.
14335         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14336         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14337                 error "dd failed for bs 4096 and count 5"
14338
14339         # Punch range less than block size will have no change in block count
14340         want_blocks_after=40  # 512 sized blocks
14341
14342         # Punch overlaps two blocks and less than blocksize
14343         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14344                 error "fallocate failed: offset 4000 length 3000"
14345         size=$(stat -c '%s' $DIR/$tfile)
14346         blocks=$(stat -c '%b' $DIR/$tfile)
14347
14348         # Verify punch worked.
14349         (( blocks == want_blocks_after )) ||
14350                 error "punch failed: blocks $blocks != $want_blocks_after"
14351
14352         (( size == want_size_before )) ||
14353                 error "punch failed: size $size != $want_size_before"
14354
14355         # Verify if range is really zero'ed out. We expect Zeros.
14356         # precomputed md5sum
14357         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14358         cksum=($(md5sum $DIR/$tfile))
14359         [[ "${cksum[0]}" == "$expect" ]] ||
14360                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14361 }
14362 run_test 150f "Verify fallocate punch functionality"
14363
14364 test_150g() {
14365         local space
14366         local size
14367         local blocks
14368         local blocks_after
14369         local size_after
14370         local BS=4096 # Block size in bytes
14371
14372         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14373                 skip "need at least 2.14.0 for fallocate punch"
14374
14375         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14376                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14377         fi
14378
14379         check_set_fallocate_or_skip
14380         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14381
14382         if [[ "x$DOM" == "xyes" ]]; then
14383                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14384                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14385         else
14386                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14387                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14388         fi
14389
14390         # Get 100MB per OST of the available space to reduce run time
14391         # else 60% of the available space if we are running SLOW tests
14392         if [ $SLOW == "no" ]; then
14393                 space=$((1024 * 100 * OSTCOUNT))
14394         else
14395                 # Find OST with Minimum Size
14396                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14397                         sort -un | head -1)
14398                 echo "min size OST: $space"
14399                 space=$(((space * 60)/100 * OSTCOUNT))
14400         fi
14401         # space in 1k units, round to 4k blocks
14402         local blkcount=$((space * 1024 / $BS))
14403
14404         echo "Verify fallocate punch: Very large Range"
14405         fallocate -l${space}k $DIR/$tfile ||
14406                 error "fallocate ${space}k $DIR/$tfile failed"
14407         # write 1M at the end, start and in the middle
14408         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14409                 error "dd failed: bs $BS count 256"
14410         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14411                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14412         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14413                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14414
14415         # Gather stats.
14416         size=$(stat -c '%s' $DIR/$tfile)
14417
14418         # gather punch length.
14419         local punch_size=$((size - (BS * 2)))
14420
14421         echo "punch_size = $punch_size"
14422         echo "size - punch_size: $((size - punch_size))"
14423         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14424
14425         # Call fallocate to punch all except 2 blocks. We leave the
14426         # first and the last block
14427         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14428         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14429                 error "fallocate failed: offset $BS length $punch_size"
14430
14431         size_after=$(stat -c '%s' $DIR/$tfile)
14432         blocks_after=$(stat -c '%b' $DIR/$tfile)
14433
14434         # Verify punch worked.
14435         # Size should be kept
14436         (( size == size_after )) ||
14437                 error "punch failed: size $size != $size_after"
14438
14439         # two 4k data blocks to remain plus possible 1 extra extent block
14440         (( blocks_after <= ((BS / 512) * 3) )) ||
14441                 error "too many blocks remains: $blocks_after"
14442
14443         # Verify that file has hole between the first and the last blocks
14444         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14445         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14446
14447         echo "Hole at [$hole_start, $hole_end)"
14448         (( hole_start == BS )) ||
14449                 error "no hole at offset $BS after punch"
14450
14451         (( hole_end == BS + punch_size )) ||
14452                 error "data at offset $hole_end < $((BS + punch_size))"
14453 }
14454 run_test 150g "Verify fallocate punch on large range"
14455
14456 #LU-2902 roc_hit was not able to read all values from lproc
14457 function roc_hit_init() {
14458         local list=$(comma_list $(osts_nodes))
14459         local dir=$DIR/$tdir-check
14460         local file=$dir/$tfile
14461         local BEFORE
14462         local AFTER
14463         local idx
14464
14465         test_mkdir $dir
14466         #use setstripe to do a write to every ost
14467         for i in $(seq 0 $((OSTCOUNT-1))); do
14468                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14469                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14470                 idx=$(printf %04x $i)
14471                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14472                         awk '$1 == "cache_access" {sum += $7}
14473                                 END { printf("%0.0f", sum) }')
14474
14475                 cancel_lru_locks osc
14476                 cat $file >/dev/null
14477
14478                 AFTER=$(get_osd_param $list *OST*$idx stats |
14479                         awk '$1 == "cache_access" {sum += $7}
14480                                 END { printf("%0.0f", sum) }')
14481
14482                 echo BEFORE:$BEFORE AFTER:$AFTER
14483                 if ! let "AFTER - BEFORE == 4"; then
14484                         rm -rf $dir
14485                         error "roc_hit is not safe to use"
14486                 fi
14487                 rm $file
14488         done
14489
14490         rm -rf $dir
14491 }
14492
14493 function roc_hit() {
14494         local list=$(comma_list $(osts_nodes))
14495         echo $(get_osd_param $list '' stats |
14496                 awk '$1 == "cache_hit" {sum += $7}
14497                         END { printf("%0.0f", sum) }')
14498 }
14499
14500 function set_cache() {
14501         local on=1
14502
14503         if [ "$2" == "off" ]; then
14504                 on=0;
14505         fi
14506         local list=$(comma_list $(osts_nodes))
14507         set_osd_param $list '' $1_cache_enable $on
14508
14509         cancel_lru_locks osc
14510 }
14511
14512 test_151() {
14513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14514         remote_ost_nodsh && skip "remote OST with nodsh"
14515
14516         local CPAGES=3
14517         local list=$(comma_list $(osts_nodes))
14518
14519         # check whether obdfilter is cache capable at all
14520         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14521                 skip "not cache-capable obdfilter"
14522         fi
14523
14524         # check cache is enabled on all obdfilters
14525         if get_osd_param $list '' read_cache_enable | grep 0; then
14526                 skip "oss cache is disabled"
14527         fi
14528
14529         set_osd_param $list '' writethrough_cache_enable 1
14530
14531         # check write cache is enabled on all obdfilters
14532         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14533                 skip "oss write cache is NOT enabled"
14534         fi
14535
14536         roc_hit_init
14537
14538         #define OBD_FAIL_OBD_NO_LRU  0x609
14539         do_nodes $list $LCTL set_param fail_loc=0x609
14540
14541         # pages should be in the case right after write
14542         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14543                 error "dd failed"
14544
14545         local BEFORE=$(roc_hit)
14546         cancel_lru_locks osc
14547         cat $DIR/$tfile >/dev/null
14548         local AFTER=$(roc_hit)
14549
14550         do_nodes $list $LCTL set_param fail_loc=0
14551
14552         if ! let "AFTER - BEFORE == CPAGES"; then
14553                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14554         fi
14555
14556         cancel_lru_locks osc
14557         # invalidates OST cache
14558         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14559         set_osd_param $list '' read_cache_enable 0
14560         cat $DIR/$tfile >/dev/null
14561
14562         # now data shouldn't be found in the cache
14563         BEFORE=$(roc_hit)
14564         cancel_lru_locks osc
14565         cat $DIR/$tfile >/dev/null
14566         AFTER=$(roc_hit)
14567         if let "AFTER - BEFORE != 0"; then
14568                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14569         fi
14570
14571         set_osd_param $list '' read_cache_enable 1
14572         rm -f $DIR/$tfile
14573 }
14574 run_test 151 "test cache on oss and controls ==============================="
14575
14576 test_152() {
14577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14578
14579         local TF="$TMP/$tfile"
14580
14581         # simulate ENOMEM during write
14582 #define OBD_FAIL_OST_NOMEM      0x226
14583         lctl set_param fail_loc=0x80000226
14584         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14585         cp $TF $DIR/$tfile
14586         sync || error "sync failed"
14587         lctl set_param fail_loc=0
14588
14589         # discard client's cache
14590         cancel_lru_locks osc
14591
14592         # simulate ENOMEM during read
14593         lctl set_param fail_loc=0x80000226
14594         cmp $TF $DIR/$tfile || error "cmp failed"
14595         lctl set_param fail_loc=0
14596
14597         rm -f $TF
14598 }
14599 run_test 152 "test read/write with enomem ============================"
14600
14601 test_153() {
14602         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14603 }
14604 run_test 153 "test if fdatasync does not crash ======================="
14605
14606 dot_lustre_fid_permission_check() {
14607         local fid=$1
14608         local ffid=$MOUNT/.lustre/fid/$fid
14609         local test_dir=$2
14610
14611         echo "stat fid $fid"
14612         stat $ffid > /dev/null || error "stat $ffid failed."
14613         echo "touch fid $fid"
14614         touch $ffid || error "touch $ffid failed."
14615         echo "write to fid $fid"
14616         cat /etc/hosts > $ffid || error "write $ffid failed."
14617         echo "read fid $fid"
14618         diff /etc/hosts $ffid || error "read $ffid failed."
14619         echo "append write to fid $fid"
14620         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14621         echo "rename fid $fid"
14622         mv $ffid $test_dir/$tfile.1 &&
14623                 error "rename $ffid to $tfile.1 should fail."
14624         touch $test_dir/$tfile.1
14625         mv $test_dir/$tfile.1 $ffid &&
14626                 error "rename $tfile.1 to $ffid should fail."
14627         rm -f $test_dir/$tfile.1
14628         echo "truncate fid $fid"
14629         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14630         echo "link fid $fid"
14631         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14632         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14633                 echo "setfacl fid $fid"
14634                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14635                 echo "getfacl fid $fid"
14636                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14637         fi
14638         echo "unlink fid $fid"
14639         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14640         echo "mknod fid $fid"
14641         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14642
14643         fid=[0xf00000400:0x1:0x0]
14644         ffid=$MOUNT/.lustre/fid/$fid
14645
14646         echo "stat non-exist fid $fid"
14647         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14648         echo "write to non-exist fid $fid"
14649         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14650         echo "link new fid $fid"
14651         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14652
14653         mkdir -p $test_dir/$tdir
14654         touch $test_dir/$tdir/$tfile
14655         fid=$($LFS path2fid $test_dir/$tdir)
14656         rc=$?
14657         [ $rc -ne 0 ] &&
14658                 error "error: could not get fid for $test_dir/$dir/$tfile."
14659
14660         ffid=$MOUNT/.lustre/fid/$fid
14661
14662         echo "ls $fid"
14663         ls $ffid > /dev/null || error "ls $ffid failed."
14664         echo "touch $fid/$tfile.1"
14665         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14666
14667         echo "touch $MOUNT/.lustre/fid/$tfile"
14668         touch $MOUNT/.lustre/fid/$tfile && \
14669                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14670
14671         echo "setxattr to $MOUNT/.lustre/fid"
14672         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14673
14674         echo "listxattr for $MOUNT/.lustre/fid"
14675         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14676
14677         echo "delxattr from $MOUNT/.lustre/fid"
14678         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14679
14680         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14681         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14682                 error "touch invalid fid should fail."
14683
14684         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14685         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14686                 error "touch non-normal fid should fail."
14687
14688         echo "rename $tdir to $MOUNT/.lustre/fid"
14689         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14690                 error "rename to $MOUNT/.lustre/fid should fail."
14691
14692         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14693         then            # LU-3547
14694                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14695                 local new_obf_mode=777
14696
14697                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14698                 chmod $new_obf_mode $DIR/.lustre/fid ||
14699                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14700
14701                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14702                 [ $obf_mode -eq $new_obf_mode ] ||
14703                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14704
14705                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14706                 chmod $old_obf_mode $DIR/.lustre/fid ||
14707                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14708         fi
14709
14710         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14711         fid=$($LFS path2fid $test_dir/$tfile-2)
14712
14713         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14714         then # LU-5424
14715                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14716                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14717                         error "create lov data thru .lustre failed"
14718         fi
14719         echo "cp /etc/passwd $test_dir/$tfile-2"
14720         cp /etc/passwd $test_dir/$tfile-2 ||
14721                 error "copy to $test_dir/$tfile-2 failed."
14722         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14723         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14724                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14725
14726         rm -rf $test_dir/tfile.lnk
14727         rm -rf $test_dir/$tfile-2
14728 }
14729
14730 test_154A() {
14731         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14732                 skip "Need MDS version at least 2.4.1"
14733
14734         local tf=$DIR/$tfile
14735         touch $tf
14736
14737         local fid=$($LFS path2fid $tf)
14738         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14739
14740         # check that we get the same pathname back
14741         local rootpath
14742         local found
14743         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14744                 echo "$rootpath $fid"
14745                 found=$($LFS fid2path $rootpath "$fid")
14746                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14747                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14748         done
14749
14750         # check wrong root path format
14751         rootpath=$MOUNT"_wrong"
14752         found=$($LFS fid2path $rootpath "$fid")
14753         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14754 }
14755 run_test 154A "lfs path2fid and fid2path basic checks"
14756
14757 test_154B() {
14758         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14759                 skip "Need MDS version at least 2.4.1"
14760
14761         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14762         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14763         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14764         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14765
14766         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14767         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14768
14769         # check that we get the same pathname
14770         echo "PFID: $PFID, name: $name"
14771         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14772         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14773         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14774                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14775
14776         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14777 }
14778 run_test 154B "verify the ll_decode_linkea tool"
14779
14780 test_154a() {
14781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14782         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14783         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14784                 skip "Need MDS version at least 2.2.51"
14785         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14786
14787         cp /etc/hosts $DIR/$tfile
14788
14789         fid=$($LFS path2fid $DIR/$tfile)
14790         rc=$?
14791         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14792
14793         dot_lustre_fid_permission_check "$fid" $DIR ||
14794                 error "dot lustre permission check $fid failed"
14795
14796         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14797
14798         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14799
14800         touch $MOUNT/.lustre/file &&
14801                 error "creation is not allowed under .lustre"
14802
14803         mkdir $MOUNT/.lustre/dir &&
14804                 error "mkdir is not allowed under .lustre"
14805
14806         rm -rf $DIR/$tfile
14807 }
14808 run_test 154a "Open-by-FID"
14809
14810 test_154b() {
14811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14812         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14813         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14814         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14815                 skip "Need MDS version at least 2.2.51"
14816
14817         local remote_dir=$DIR/$tdir/remote_dir
14818         local MDTIDX=1
14819         local rc=0
14820
14821         mkdir -p $DIR/$tdir
14822         $LFS mkdir -i $MDTIDX $remote_dir ||
14823                 error "create remote directory failed"
14824
14825         cp /etc/hosts $remote_dir/$tfile
14826
14827         fid=$($LFS path2fid $remote_dir/$tfile)
14828         rc=$?
14829         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14830
14831         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14832                 error "dot lustre permission check $fid failed"
14833         rm -rf $DIR/$tdir
14834 }
14835 run_test 154b "Open-by-FID for remote directory"
14836
14837 test_154c() {
14838         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14839                 skip "Need MDS version at least 2.4.1"
14840
14841         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14842         local FID1=$($LFS path2fid $DIR/$tfile.1)
14843         local FID2=$($LFS path2fid $DIR/$tfile.2)
14844         local FID3=$($LFS path2fid $DIR/$tfile.3)
14845
14846         local N=1
14847         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14848                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14849                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14850                 local want=FID$N
14851                 [ "$FID" = "${!want}" ] ||
14852                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14853                 N=$((N + 1))
14854         done
14855
14856         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14857         do
14858                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14859                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14860                 N=$((N + 1))
14861         done
14862 }
14863 run_test 154c "lfs path2fid and fid2path multiple arguments"
14864
14865 test_154d() {
14866         remote_mds_nodsh && skip "remote MDS with nodsh"
14867         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14868                 skip "Need MDS version at least 2.5.53"
14869
14870         if remote_mds; then
14871                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14872         else
14873                 nid="0@lo"
14874         fi
14875         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14876         local fd
14877         local cmd
14878
14879         rm -f $DIR/$tfile
14880         touch $DIR/$tfile
14881
14882         local fid=$($LFS path2fid $DIR/$tfile)
14883         # Open the file
14884         fd=$(free_fd)
14885         cmd="exec $fd<$DIR/$tfile"
14886         eval $cmd
14887         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14888         echo "$fid_list" | grep "$fid"
14889         rc=$?
14890
14891         cmd="exec $fd>/dev/null"
14892         eval $cmd
14893         if [ $rc -ne 0 ]; then
14894                 error "FID $fid not found in open files list $fid_list"
14895         fi
14896 }
14897 run_test 154d "Verify open file fid"
14898
14899 test_154e()
14900 {
14901         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14902                 skip "Need MDS version at least 2.6.50"
14903
14904         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14905                 error ".lustre returned by readdir"
14906         fi
14907 }
14908 run_test 154e ".lustre is not returned by readdir"
14909
14910 test_154f() {
14911         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14912
14913         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14914         mkdir_on_mdt0 $DIR/$tdir
14915         # test dirs inherit from its stripe
14916         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
14917         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
14918         cp /etc/hosts $DIR/$tdir/foo1/$tfile
14919         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
14920         touch $DIR/f
14921
14922         # get fid of parents
14923         local FID0=$($LFS path2fid $DIR/$tdir)
14924         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
14925         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
14926         local FID3=$($LFS path2fid $DIR)
14927
14928         # check that path2fid --parents returns expected <parent_fid>/name
14929         # 1) test for a directory (single parent)
14930         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
14931         [ "$parent" == "$FID0/foo1" ] ||
14932                 error "expected parent: $FID0/foo1, got: $parent"
14933
14934         # 2) test for a file with nlink > 1 (multiple parents)
14935         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
14936         echo "$parent" | grep -F "$FID1/$tfile" ||
14937                 error "$FID1/$tfile not returned in parent list"
14938         echo "$parent" | grep -F "$FID2/link" ||
14939                 error "$FID2/link not returned in parent list"
14940
14941         # 3) get parent by fid
14942         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
14943         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14944         echo "$parent" | grep -F "$FID1/$tfile" ||
14945                 error "$FID1/$tfile not returned in parent list (by fid)"
14946         echo "$parent" | grep -F "$FID2/link" ||
14947                 error "$FID2/link not returned in parent list (by fid)"
14948
14949         # 4) test for entry in root directory
14950         parent=$($LFS path2fid --parents $DIR/f)
14951         echo "$parent" | grep -F "$FID3/f" ||
14952                 error "$FID3/f not returned in parent list"
14953
14954         # 5) test it on root directory
14955         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14956                 error "$MOUNT should not have parents"
14957
14958         # enable xattr caching and check that linkea is correctly updated
14959         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14960         save_lustre_params client "llite.*.xattr_cache" > $save
14961         lctl set_param llite.*.xattr_cache 1
14962
14963         # 6.1) linkea update on rename
14964         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
14965
14966         # get parents by fid
14967         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14968         # foo1 should no longer be returned in parent list
14969         echo "$parent" | grep -F "$FID1" &&
14970                 error "$FID1 should no longer be in parent list"
14971         # the new path should appear
14972         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14973                 error "$FID2/$tfile.moved is not in parent list"
14974
14975         # 6.2) linkea update on unlink
14976         rm -f $DIR/$tdir/foo2/link
14977         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14978         # foo2/link should no longer be returned in parent list
14979         echo "$parent" | grep -F "$FID2/link" &&
14980                 error "$FID2/link should no longer be in parent list"
14981         true
14982
14983         rm -f $DIR/f
14984         restore_lustre_params < $save
14985         rm -f $save
14986 }
14987 run_test 154f "get parent fids by reading link ea"
14988
14989 test_154g()
14990 {
14991         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14992         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14993            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14994                 skip "Need MDS version at least 2.6.92"
14995
14996         mkdir_on_mdt0 $DIR/$tdir
14997         llapi_fid_test -d $DIR/$tdir
14998 }
14999 run_test 154g "various llapi FID tests"
15000
15001 test_155_small_load() {
15002     local temp=$TMP/$tfile
15003     local file=$DIR/$tfile
15004
15005     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15006         error "dd of=$temp bs=6096 count=1 failed"
15007     cp $temp $file
15008     cancel_lru_locks $OSC
15009     cmp $temp $file || error "$temp $file differ"
15010
15011     $TRUNCATE $temp 6000
15012     $TRUNCATE $file 6000
15013     cmp $temp $file || error "$temp $file differ (truncate1)"
15014
15015     echo "12345" >>$temp
15016     echo "12345" >>$file
15017     cmp $temp $file || error "$temp $file differ (append1)"
15018
15019     echo "12345" >>$temp
15020     echo "12345" >>$file
15021     cmp $temp $file || error "$temp $file differ (append2)"
15022
15023     rm -f $temp $file
15024     true
15025 }
15026
15027 test_155_big_load() {
15028         remote_ost_nodsh && skip "remote OST with nodsh"
15029
15030         local temp=$TMP/$tfile
15031         local file=$DIR/$tfile
15032
15033         free_min_max
15034         local cache_size=$(do_facet ost$((MAXI+1)) \
15035                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15036         local large_file_size=$((cache_size * 2))
15037
15038         echo "OSS cache size: $cache_size KB"
15039         echo "Large file size: $large_file_size KB"
15040
15041         [ $MAXV -le $large_file_size ] &&
15042                 skip_env "max available OST size needs > $large_file_size KB"
15043
15044         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15045
15046         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15047                 error "dd of=$temp bs=$large_file_size count=1k failed"
15048         cp $temp $file
15049         ls -lh $temp $file
15050         cancel_lru_locks osc
15051         cmp $temp $file || error "$temp $file differ"
15052
15053         rm -f $temp $file
15054         true
15055 }
15056
15057 save_writethrough() {
15058         local facets=$(get_facets OST)
15059
15060         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15061 }
15062
15063 test_155a() {
15064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15065
15066         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15067
15068         save_writethrough $p
15069
15070         set_cache read on
15071         set_cache writethrough on
15072         test_155_small_load
15073         restore_lustre_params < $p
15074         rm -f $p
15075 }
15076 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15077
15078 test_155b() {
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080
15081         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15082
15083         save_writethrough $p
15084
15085         set_cache read on
15086         set_cache writethrough off
15087         test_155_small_load
15088         restore_lustre_params < $p
15089         rm -f $p
15090 }
15091 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15092
15093 test_155c() {
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095
15096         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15097
15098         save_writethrough $p
15099
15100         set_cache read off
15101         set_cache writethrough on
15102         test_155_small_load
15103         restore_lustre_params < $p
15104         rm -f $p
15105 }
15106 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15107
15108 test_155d() {
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110
15111         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15112
15113         save_writethrough $p
15114
15115         set_cache read off
15116         set_cache writethrough off
15117         test_155_small_load
15118         restore_lustre_params < $p
15119         rm -f $p
15120 }
15121 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15122
15123 test_155e() {
15124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15125
15126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15127
15128         save_writethrough $p
15129
15130         set_cache read on
15131         set_cache writethrough on
15132         test_155_big_load
15133         restore_lustre_params < $p
15134         rm -f $p
15135 }
15136 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15137
15138 test_155f() {
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140
15141         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15142
15143         save_writethrough $p
15144
15145         set_cache read on
15146         set_cache writethrough off
15147         test_155_big_load
15148         restore_lustre_params < $p
15149         rm -f $p
15150 }
15151 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15152
15153 test_155g() {
15154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15155
15156         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15157
15158         save_writethrough $p
15159
15160         set_cache read off
15161         set_cache writethrough on
15162         test_155_big_load
15163         restore_lustre_params < $p
15164         rm -f $p
15165 }
15166 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15167
15168 test_155h() {
15169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15170
15171         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15172
15173         save_writethrough $p
15174
15175         set_cache read off
15176         set_cache writethrough off
15177         test_155_big_load
15178         restore_lustre_params < $p
15179         rm -f $p
15180 }
15181 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15182
15183 test_156() {
15184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15185         remote_ost_nodsh && skip "remote OST with nodsh"
15186         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15187                 skip "stats not implemented on old servers"
15188         [ "$ost1_FSTYPE" = "zfs" ] &&
15189                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15190
15191         local CPAGES=3
15192         local BEFORE
15193         local AFTER
15194         local file="$DIR/$tfile"
15195         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15196
15197         save_writethrough $p
15198         roc_hit_init
15199
15200         log "Turn on read and write cache"
15201         set_cache read on
15202         set_cache writethrough on
15203
15204         log "Write data and read it back."
15205         log "Read should be satisfied from the cache."
15206         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15207         BEFORE=$(roc_hit)
15208         cancel_lru_locks osc
15209         cat $file >/dev/null
15210         AFTER=$(roc_hit)
15211         if ! let "AFTER - BEFORE == CPAGES"; then
15212                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15213         else
15214                 log "cache hits: before: $BEFORE, after: $AFTER"
15215         fi
15216
15217         log "Read again; it should be satisfied from the cache."
15218         BEFORE=$AFTER
15219         cancel_lru_locks osc
15220         cat $file >/dev/null
15221         AFTER=$(roc_hit)
15222         if ! let "AFTER - BEFORE == CPAGES"; then
15223                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15224         else
15225                 log "cache hits:: before: $BEFORE, after: $AFTER"
15226         fi
15227
15228         log "Turn off the read cache and turn on the write cache"
15229         set_cache read off
15230         set_cache writethrough on
15231
15232         log "Read again; it should be satisfied from the cache."
15233         BEFORE=$(roc_hit)
15234         cancel_lru_locks osc
15235         cat $file >/dev/null
15236         AFTER=$(roc_hit)
15237         if ! let "AFTER - BEFORE == CPAGES"; then
15238                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15239         else
15240                 log "cache hits:: before: $BEFORE, after: $AFTER"
15241         fi
15242
15243         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15244                 # > 2.12.56 uses pagecache if cached
15245                 log "Read again; it should not be satisfied from the cache."
15246                 BEFORE=$AFTER
15247                 cancel_lru_locks osc
15248                 cat $file >/dev/null
15249                 AFTER=$(roc_hit)
15250                 if ! let "AFTER - BEFORE == 0"; then
15251                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15252                 else
15253                         log "cache hits:: before: $BEFORE, after: $AFTER"
15254                 fi
15255         fi
15256
15257         log "Write data and read it back."
15258         log "Read should be satisfied from the cache."
15259         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15260         BEFORE=$(roc_hit)
15261         cancel_lru_locks osc
15262         cat $file >/dev/null
15263         AFTER=$(roc_hit)
15264         if ! let "AFTER - BEFORE == CPAGES"; then
15265                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15266         else
15267                 log "cache hits:: before: $BEFORE, after: $AFTER"
15268         fi
15269
15270         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15271                 # > 2.12.56 uses pagecache if cached
15272                 log "Read again; it should not be satisfied from the cache."
15273                 BEFORE=$AFTER
15274                 cancel_lru_locks osc
15275                 cat $file >/dev/null
15276                 AFTER=$(roc_hit)
15277                 if ! let "AFTER - BEFORE == 0"; then
15278                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15279                 else
15280                         log "cache hits:: before: $BEFORE, after: $AFTER"
15281                 fi
15282         fi
15283
15284         log "Turn off read and write cache"
15285         set_cache read off
15286         set_cache writethrough off
15287
15288         log "Write data and read it back"
15289         log "It should not be satisfied from the cache."
15290         rm -f $file
15291         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15292         cancel_lru_locks osc
15293         BEFORE=$(roc_hit)
15294         cat $file >/dev/null
15295         AFTER=$(roc_hit)
15296         if ! let "AFTER - BEFORE == 0"; then
15297                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15298         else
15299                 log "cache hits:: before: $BEFORE, after: $AFTER"
15300         fi
15301
15302         log "Turn on the read cache and turn off the write cache"
15303         set_cache read on
15304         set_cache writethrough off
15305
15306         log "Write data and read it back"
15307         log "It should not be satisfied from the cache."
15308         rm -f $file
15309         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15310         BEFORE=$(roc_hit)
15311         cancel_lru_locks osc
15312         cat $file >/dev/null
15313         AFTER=$(roc_hit)
15314         if ! let "AFTER - BEFORE == 0"; then
15315                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15316         else
15317                 log "cache hits:: before: $BEFORE, after: $AFTER"
15318         fi
15319
15320         log "Read again; it should be satisfied from the cache."
15321         BEFORE=$(roc_hit)
15322         cancel_lru_locks osc
15323         cat $file >/dev/null
15324         AFTER=$(roc_hit)
15325         if ! let "AFTER - BEFORE == CPAGES"; then
15326                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15327         else
15328                 log "cache hits:: before: $BEFORE, after: $AFTER"
15329         fi
15330
15331         restore_lustre_params < $p
15332         rm -f $p $file
15333 }
15334 run_test 156 "Verification of tunables"
15335
15336 test_160a() {
15337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15338         remote_mds_nodsh && skip "remote MDS with nodsh"
15339         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15340                 skip "Need MDS version at least 2.2.0"
15341
15342         changelog_register || error "changelog_register failed"
15343         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15344         changelog_users $SINGLEMDS | grep -q $cl_user ||
15345                 error "User $cl_user not found in changelog_users"
15346
15347         mkdir_on_mdt0 $DIR/$tdir
15348
15349         # change something
15350         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15351         changelog_clear 0 || error "changelog_clear failed"
15352         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15353         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15354         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15355         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15356         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15357         rm $DIR/$tdir/pics/desktop.jpg
15358
15359         echo "verifying changelog mask"
15360         changelog_chmask "-MKDIR"
15361         changelog_chmask "-CLOSE"
15362
15363         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15364         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15365
15366         changelog_chmask "+MKDIR"
15367         changelog_chmask "+CLOSE"
15368
15369         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15370         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15371
15372         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15373         CLOSES=$(changelog_dump | grep -c "CLOSE")
15374         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15375         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15376
15377         # verify contents
15378         echo "verifying target fid"
15379         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15380         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15381         [ "$fidc" == "$fidf" ] ||
15382                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15383         echo "verifying parent fid"
15384         # The FID returned from the Changelog may be the directory shard on
15385         # a different MDT, and not the FID returned by path2fid on the parent.
15386         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15387         # since this is what will matter when recreating this file in the tree.
15388         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15389         local pathp=$($LFS fid2path $MOUNT "$fidp")
15390         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15391                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15392
15393         echo "getting records for $cl_user"
15394         changelog_users $SINGLEMDS
15395         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15396         local nclr=3
15397         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15398                 error "changelog_clear failed"
15399         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15400         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15401         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15402                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15403
15404         local min0_rec=$(changelog_users $SINGLEMDS |
15405                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15406         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15407                           awk '{ print $1; exit; }')
15408
15409         changelog_dump | tail -n 5
15410         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15411         [ $first_rec == $((min0_rec + 1)) ] ||
15412                 error "first index should be $min0_rec + 1 not $first_rec"
15413
15414         # LU-3446 changelog index reset on MDT restart
15415         local cur_rec1=$(changelog_users $SINGLEMDS |
15416                          awk '/^current.index:/ { print $NF }')
15417         changelog_clear 0 ||
15418                 error "clear all changelog records for $cl_user failed"
15419         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15420         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15421                 error "Fail to start $SINGLEMDS"
15422         local cur_rec2=$(changelog_users $SINGLEMDS |
15423                          awk '/^current.index:/ { print $NF }')
15424         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15425         [ $cur_rec1 == $cur_rec2 ] ||
15426                 error "current index should be $cur_rec1 not $cur_rec2"
15427
15428         echo "verifying users from this test are deregistered"
15429         changelog_deregister || error "changelog_deregister failed"
15430         changelog_users $SINGLEMDS | grep -q $cl_user &&
15431                 error "User '$cl_user' still in changelog_users"
15432
15433         # lctl get_param -n mdd.*.changelog_users
15434         # current_index: 144
15435         # ID    index (idle seconds)
15436         # cl3   144   (2) mask=<list>
15437         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15438                 # this is the normal case where all users were deregistered
15439                 # make sure no new records are added when no users are present
15440                 local last_rec1=$(changelog_users $SINGLEMDS |
15441                                   awk '/^current.index:/ { print $NF }')
15442                 touch $DIR/$tdir/chloe
15443                 local last_rec2=$(changelog_users $SINGLEMDS |
15444                                   awk '/^current.index:/ { print $NF }')
15445                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15446                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15447         else
15448                 # any changelog users must be leftovers from a previous test
15449                 changelog_users $SINGLEMDS
15450                 echo "other changelog users; can't verify off"
15451         fi
15452 }
15453 run_test 160a "changelog sanity"
15454
15455 test_160b() { # LU-3587
15456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15457         remote_mds_nodsh && skip "remote MDS with nodsh"
15458         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15459                 skip "Need MDS version at least 2.2.0"
15460
15461         changelog_register || error "changelog_register failed"
15462         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15463         changelog_users $SINGLEMDS | grep -q $cl_user ||
15464                 error "User '$cl_user' not found in changelog_users"
15465
15466         local longname1=$(str_repeat a 255)
15467         local longname2=$(str_repeat b 255)
15468
15469         cd $DIR
15470         echo "creating very long named file"
15471         touch $longname1 || error "create of '$longname1' failed"
15472         echo "renaming very long named file"
15473         mv $longname1 $longname2
15474
15475         changelog_dump | grep RENME | tail -n 5
15476         rm -f $longname2
15477 }
15478 run_test 160b "Verify that very long rename doesn't crash in changelog"
15479
15480 test_160c() {
15481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15482         remote_mds_nodsh && skip "remote MDS with nodsh"
15483
15484         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15485                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15486                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15487                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15488
15489         local rc=0
15490
15491         # Registration step
15492         changelog_register || error "changelog_register failed"
15493
15494         rm -rf $DIR/$tdir
15495         mkdir -p $DIR/$tdir
15496         $MCREATE $DIR/$tdir/foo_160c
15497         changelog_chmask "-TRUNC"
15498         $TRUNCATE $DIR/$tdir/foo_160c 200
15499         changelog_chmask "+TRUNC"
15500         $TRUNCATE $DIR/$tdir/foo_160c 199
15501         changelog_dump | tail -n 5
15502         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15503         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15504 }
15505 run_test 160c "verify that changelog log catch the truncate event"
15506
15507 test_160d() {
15508         remote_mds_nodsh && skip "remote MDS with nodsh"
15509         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15511         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15512                 skip "Need MDS version at least 2.7.60"
15513
15514         # Registration step
15515         changelog_register || error "changelog_register failed"
15516
15517         mkdir -p $DIR/$tdir/migrate_dir
15518         changelog_clear 0 || error "changelog_clear failed"
15519
15520         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15521         changelog_dump | tail -n 5
15522         local migrates=$(changelog_dump | grep -c "MIGRT")
15523         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15524 }
15525 run_test 160d "verify that changelog log catch the migrate event"
15526
15527 test_160e() {
15528         remote_mds_nodsh && skip "remote MDS with nodsh"
15529
15530         # Create a user
15531         changelog_register || error "changelog_register failed"
15532
15533         # Delete a future user (expect fail)
15534         local MDT0=$(facet_svc $SINGLEMDS)
15535         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15536         local rc=$?
15537
15538         if [ $rc -eq 0 ]; then
15539                 error "Deleted non-existant user cl77"
15540         elif [ $rc -ne 2 ]; then
15541                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15542         fi
15543
15544         # Clear to a bad index (1 billion should be safe)
15545         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15546         rc=$?
15547
15548         if [ $rc -eq 0 ]; then
15549                 error "Successfully cleared to invalid CL index"
15550         elif [ $rc -ne 22 ]; then
15551                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15552         fi
15553 }
15554 run_test 160e "changelog negative testing (should return errors)"
15555
15556 test_160f() {
15557         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15558         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15559                 skip "Need MDS version at least 2.10.56"
15560
15561         local mdts=$(comma_list $(mdts_nodes))
15562
15563         # Create a user
15564         changelog_register || error "first changelog_register failed"
15565         changelog_register || error "second changelog_register failed"
15566         local cl_users
15567         declare -A cl_user1
15568         declare -A cl_user2
15569         local user_rec1
15570         local user_rec2
15571         local i
15572
15573         # generate some changelog records to accumulate on each MDT
15574         # use all_char because created files should be evenly distributed
15575         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15576                 error "test_mkdir $tdir failed"
15577         log "$(date +%s): creating first files"
15578         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15579                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15580                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15581         done
15582
15583         # check changelogs have been generated
15584         local start=$SECONDS
15585         local idle_time=$((MDSCOUNT * 5 + 5))
15586         local nbcl=$(changelog_dump | wc -l)
15587         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15588
15589         for param in "changelog_max_idle_time=$idle_time" \
15590                      "changelog_gc=1" \
15591                      "changelog_min_gc_interval=2" \
15592                      "changelog_min_free_cat_entries=3"; do
15593                 local MDT0=$(facet_svc $SINGLEMDS)
15594                 local var="${param%=*}"
15595                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15596
15597                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15598                 do_nodes $mdts $LCTL set_param mdd.*.$param
15599         done
15600
15601         # force cl_user2 to be idle (1st part), but also cancel the
15602         # cl_user1 records so that it is not evicted later in the test.
15603         local sleep1=$((idle_time / 2))
15604         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15605         sleep $sleep1
15606
15607         # simulate changelog catalog almost full
15608         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15609         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15610
15611         for i in $(seq $MDSCOUNT); do
15612                 cl_users=(${CL_USERS[mds$i]})
15613                 cl_user1[mds$i]="${cl_users[0]}"
15614                 cl_user2[mds$i]="${cl_users[1]}"
15615
15616                 [ -n "${cl_user1[mds$i]}" ] ||
15617                         error "mds$i: no user registered"
15618                 [ -n "${cl_user2[mds$i]}" ] ||
15619                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15620
15621                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15622                 [ -n "$user_rec1" ] ||
15623                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15624                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15625                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15626                 [ -n "$user_rec2" ] ||
15627                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15628                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15629                      "$user_rec1 + 2 == $user_rec2"
15630                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15631                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15632                               "$user_rec1 + 2, but is $user_rec2"
15633                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15634                 [ -n "$user_rec2" ] ||
15635                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15636                 [ $user_rec1 == $user_rec2 ] ||
15637                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15638                               "$user_rec1, but is $user_rec2"
15639         done
15640
15641         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15642         local sleep2=$((idle_time - (SECONDS - start) + 1))
15643         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15644         sleep $sleep2
15645
15646         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15647         # cl_user1 should be OK because it recently processed records.
15648         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15649         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15650                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15651                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15652         done
15653
15654         # ensure gc thread is done
15655         for i in $(mdts_nodes); do
15656                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15657                         error "$i: GC-thread not done"
15658         done
15659
15660         local first_rec
15661         for (( i = 1; i <= MDSCOUNT; i++ )); do
15662                 # check cl_user1 still registered
15663                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15664                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15665                 # check cl_user2 unregistered
15666                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15667                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15668
15669                 # check changelogs are present and starting at $user_rec1 + 1
15670                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15671                 [ -n "$user_rec1" ] ||
15672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15673                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15674                             awk '{ print $1; exit; }')
15675
15676                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15677                 [ $((user_rec1 + 1)) == $first_rec ] ||
15678                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15679         done
15680 }
15681 run_test 160f "changelog garbage collect (timestamped users)"
15682
15683 test_160g() {
15684         remote_mds_nodsh && skip "remote MDS with nodsh"
15685         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15686                 skip "Need MDS version at least 2.10.56"
15687
15688         local mdts=$(comma_list $(mdts_nodes))
15689
15690         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15691         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15692
15693         # Create a user
15694         changelog_register || error "first changelog_register failed"
15695         changelog_register || error "second changelog_register failed"
15696         local cl_users
15697         declare -A cl_user1
15698         declare -A cl_user2
15699         local user_rec1
15700         local user_rec2
15701         local i
15702
15703         # generate some changelog records to accumulate on each MDT
15704         # use all_char because created files should be evenly distributed
15705         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15706                 error "test_mkdir $tdir failed"
15707         for ((i = 0; i < MDSCOUNT; i++)); do
15708                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15709                         error "create $DIR/$tdir/d$i.1 failed"
15710         done
15711
15712         # check changelogs have been generated
15713         local nbcl=$(changelog_dump | wc -l)
15714         (( $nbcl > 0 )) || error "no changelogs found"
15715
15716         # reduce the max_idle_indexes value to make sure we exceed it
15717         for param in "changelog_max_idle_indexes=1" \
15718                      "changelog_gc=1" \
15719                      "changelog_min_gc_interval=2" \
15720                      "changelog_min_free_cat_entries=3"; do
15721                 local MDT0=$(facet_svc $SINGLEMDS)
15722                 local var="${param%=*}"
15723                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15724
15725                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15726                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15727                         error "unable to set mdd.*.$param"
15728         done
15729
15730         # simulate changelog catalog almost full
15731         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15732         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15733
15734         local start=$SECONDS
15735         for i in $(seq $MDSCOUNT); do
15736                 cl_users=(${CL_USERS[mds$i]})
15737                 cl_user1[mds$i]="${cl_users[0]}"
15738                 cl_user2[mds$i]="${cl_users[1]}"
15739
15740                 [ -n "${cl_user1[mds$i]}" ] ||
15741                         error "mds$i: no user registered"
15742                 [ -n "${cl_user2[mds$i]}" ] ||
15743                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15744
15745                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15746                 [ -n "$user_rec1" ] ||
15747                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15748                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15749                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15750                 [ -n "$user_rec2" ] ||
15751                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15752                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15753                      "$user_rec1 + 2 == $user_rec2"
15754                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15755                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15756                               "$user_rec1 + 2, but is $user_rec2"
15757                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15758                 [ -n "$user_rec2" ] ||
15759                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15760                 [ $user_rec1 == $user_rec2 ] ||
15761                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15762                               "$user_rec1, but is $user_rec2"
15763         done
15764
15765         # ensure we are past the previous changelog_min_gc_interval set above
15766         local sleep2=$((start + 2 - SECONDS))
15767         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15768
15769         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15770         # cl_user1 should be OK because it recently processed records.
15771         for ((i = 0; i < MDSCOUNT; i++)); do
15772                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15773                         error "create $DIR/$tdir/d$i.3 failed"
15774         done
15775
15776         # ensure gc thread is done
15777         for i in $(mdts_nodes); do
15778                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15779                         error "$i: GC-thread not done"
15780         done
15781
15782         local first_rec
15783         for (( i = 1; i <= MDSCOUNT; i++ )); do
15784                 # check cl_user1 still registered
15785                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15786                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15787                 # check cl_user2 unregistered
15788                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15789                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15790
15791                 # check changelogs are present and starting at $user_rec1 + 1
15792                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15793                 [ -n "$user_rec1" ] ||
15794                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15795                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15796                             awk '{ print $1; exit; }')
15797
15798                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15799                 [ $((user_rec1 + 1)) == $first_rec ] ||
15800                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15801         done
15802 }
15803 run_test 160g "changelog garbage collect (old users)"
15804
15805 test_160h() {
15806         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15807         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15808                 skip "Need MDS version at least 2.10.56"
15809
15810         local mdts=$(comma_list $(mdts_nodes))
15811
15812         # Create a user
15813         changelog_register || error "first changelog_register failed"
15814         changelog_register || error "second changelog_register failed"
15815         local cl_users
15816         declare -A cl_user1
15817         declare -A cl_user2
15818         local user_rec1
15819         local user_rec2
15820         local i
15821
15822         # generate some changelog records to accumulate on each MDT
15823         # use all_char because created files should be evenly distributed
15824         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15825                 error "test_mkdir $tdir failed"
15826         for ((i = 0; i < MDSCOUNT; i++)); do
15827                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15828                         error "create $DIR/$tdir/d$i.1 failed"
15829         done
15830
15831         # check changelogs have been generated
15832         local nbcl=$(changelog_dump | wc -l)
15833         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15834
15835         for param in "changelog_max_idle_time=10" \
15836                      "changelog_gc=1" \
15837                      "changelog_min_gc_interval=2"; do
15838                 local MDT0=$(facet_svc $SINGLEMDS)
15839                 local var="${param%=*}"
15840                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15841
15842                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15843                 do_nodes $mdts $LCTL set_param mdd.*.$param
15844         done
15845
15846         # force cl_user2 to be idle (1st part)
15847         sleep 9
15848
15849         for i in $(seq $MDSCOUNT); do
15850                 cl_users=(${CL_USERS[mds$i]})
15851                 cl_user1[mds$i]="${cl_users[0]}"
15852                 cl_user2[mds$i]="${cl_users[1]}"
15853
15854                 [ -n "${cl_user1[mds$i]}" ] ||
15855                         error "mds$i: no user registered"
15856                 [ -n "${cl_user2[mds$i]}" ] ||
15857                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15858
15859                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15860                 [ -n "$user_rec1" ] ||
15861                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15862                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15863                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15864                 [ -n "$user_rec2" ] ||
15865                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15866                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15867                      "$user_rec1 + 2 == $user_rec2"
15868                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15869                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15870                               "$user_rec1 + 2, but is $user_rec2"
15871                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15872                 [ -n "$user_rec2" ] ||
15873                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15874                 [ $user_rec1 == $user_rec2 ] ||
15875                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15876                               "$user_rec1, but is $user_rec2"
15877         done
15878
15879         # force cl_user2 to be idle (2nd part) and to reach
15880         # changelog_max_idle_time
15881         sleep 2
15882
15883         # force each GC-thread start and block then
15884         # one per MDT/MDD, set fail_val accordingly
15885         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15886         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15887
15888         # generate more changelogs to trigger fail_loc
15889         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15890                 error "create $DIR/$tdir/${tfile}bis failed"
15891
15892         # stop MDT to stop GC-thread, should be done in back-ground as it will
15893         # block waiting for the thread to be released and exit
15894         declare -A stop_pids
15895         for i in $(seq $MDSCOUNT); do
15896                 stop mds$i &
15897                 stop_pids[mds$i]=$!
15898         done
15899
15900         for i in $(mdts_nodes); do
15901                 local facet
15902                 local nb=0
15903                 local facets=$(facets_up_on_host $i)
15904
15905                 for facet in ${facets//,/ }; do
15906                         if [[ $facet == mds* ]]; then
15907                                 nb=$((nb + 1))
15908                         fi
15909                 done
15910                 # ensure each MDS's gc threads are still present and all in "R"
15911                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15912                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15913                         error "$i: expected $nb GC-thread"
15914                 wait_update $i \
15915                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15916                         "R" 20 ||
15917                         error "$i: GC-thread not found in R-state"
15918                 # check umounts of each MDT on MDS have reached kthread_stop()
15919                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15920                         error "$i: expected $nb umount"
15921                 wait_update $i \
15922                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15923                         error "$i: umount not found in D-state"
15924         done
15925
15926         # release all GC-threads
15927         do_nodes $mdts $LCTL set_param fail_loc=0
15928
15929         # wait for MDT stop to complete
15930         for i in $(seq $MDSCOUNT); do
15931                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15932         done
15933
15934         # XXX
15935         # may try to check if any orphan changelog records are present
15936         # via ldiskfs/zfs and llog_reader...
15937
15938         # re-start/mount MDTs
15939         for i in $(seq $MDSCOUNT); do
15940                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15941                         error "Fail to start mds$i"
15942         done
15943
15944         local first_rec
15945         for i in $(seq $MDSCOUNT); do
15946                 # check cl_user1 still registered
15947                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15948                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15949                 # check cl_user2 unregistered
15950                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15951                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15952
15953                 # check changelogs are present and starting at $user_rec1 + 1
15954                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15955                 [ -n "$user_rec1" ] ||
15956                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15957                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15958                             awk '{ print $1; exit; }')
15959
15960                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15961                 [ $((user_rec1 + 1)) == $first_rec ] ||
15962                         error "mds$i: first index should be $user_rec1 + 1, " \
15963                               "but is $first_rec"
15964         done
15965 }
15966 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15967               "during mount"
15968
15969 test_160i() {
15970
15971         local mdts=$(comma_list $(mdts_nodes))
15972
15973         changelog_register || error "first changelog_register failed"
15974
15975         # generate some changelog records to accumulate on each MDT
15976         # use all_char because created files should be evenly distributed
15977         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15978                 error "test_mkdir $tdir failed"
15979         for ((i = 0; i < MDSCOUNT; i++)); do
15980                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15981                         error "create $DIR/$tdir/d$i.1 failed"
15982         done
15983
15984         # check changelogs have been generated
15985         local nbcl=$(changelog_dump | wc -l)
15986         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15987
15988         # simulate race between register and unregister
15989         # XXX as fail_loc is set per-MDS, with DNE configs the race
15990         # simulation will only occur for one MDT per MDS and for the
15991         # others the normal race scenario will take place
15992         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15993         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15994         do_nodes $mdts $LCTL set_param fail_val=1
15995
15996         # unregister 1st user
15997         changelog_deregister &
15998         local pid1=$!
15999         # wait some time for deregister work to reach race rdv
16000         sleep 2
16001         # register 2nd user
16002         changelog_register || error "2nd user register failed"
16003
16004         wait $pid1 || error "1st user deregister failed"
16005
16006         local i
16007         local last_rec
16008         declare -A LAST_REC
16009         for i in $(seq $MDSCOUNT); do
16010                 if changelog_users mds$i | grep "^cl"; then
16011                         # make sure new records are added with one user present
16012                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16013                                           awk '/^current.index:/ { print $NF }')
16014                 else
16015                         error "mds$i has no user registered"
16016                 fi
16017         done
16018
16019         # generate more changelog records to accumulate on each MDT
16020         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16021                 error "create $DIR/$tdir/${tfile}bis failed"
16022
16023         for i in $(seq $MDSCOUNT); do
16024                 last_rec=$(changelog_users $SINGLEMDS |
16025                            awk '/^current.index:/ { print $NF }')
16026                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16027                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16028                         error "changelogs are off on mds$i"
16029         done
16030 }
16031 run_test 160i "changelog user register/unregister race"
16032
16033 test_160j() {
16034         remote_mds_nodsh && skip "remote MDS with nodsh"
16035         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16036                 skip "Need MDS version at least 2.12.56"
16037
16038         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16039         stack_trap "umount $MOUNT2" EXIT
16040
16041         changelog_register || error "first changelog_register failed"
16042         stack_trap "changelog_deregister" EXIT
16043
16044         # generate some changelog
16045         # use all_char because created files should be evenly distributed
16046         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16047                 error "mkdir $tdir failed"
16048         for ((i = 0; i < MDSCOUNT; i++)); do
16049                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16050                         error "create $DIR/$tdir/d$i.1 failed"
16051         done
16052
16053         # open the changelog device
16054         exec 3>/dev/changelog-$FSNAME-MDT0000
16055         stack_trap "exec 3>&-" EXIT
16056         exec 4</dev/changelog-$FSNAME-MDT0000
16057         stack_trap "exec 4<&-" EXIT
16058
16059         # umount the first lustre mount
16060         umount $MOUNT
16061         stack_trap "mount_client $MOUNT" EXIT
16062
16063         # read changelog, which may or may not fail, but should not crash
16064         cat <&4 >/dev/null
16065
16066         # clear changelog
16067         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16068         changelog_users $SINGLEMDS | grep -q $cl_user ||
16069                 error "User $cl_user not found in changelog_users"
16070
16071         printf 'clear:'$cl_user':0' >&3
16072 }
16073 run_test 160j "client can be umounted while its chanangelog is being used"
16074
16075 test_160k() {
16076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16077         remote_mds_nodsh && skip "remote MDS with nodsh"
16078
16079         mkdir -p $DIR/$tdir/1/1
16080
16081         changelog_register || error "changelog_register failed"
16082         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16083
16084         changelog_users $SINGLEMDS | grep -q $cl_user ||
16085                 error "User '$cl_user' not found in changelog_users"
16086 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16087         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16088         rmdir $DIR/$tdir/1/1 & sleep 1
16089         mkdir $DIR/$tdir/2
16090         touch $DIR/$tdir/2/2
16091         rm -rf $DIR/$tdir/2
16092
16093         wait
16094         sleep 4
16095
16096         changelog_dump | grep rmdir || error "rmdir not recorded"
16097 }
16098 run_test 160k "Verify that changelog records are not lost"
16099
16100 # Verifies that a file passed as a parameter has recently had an operation
16101 # performed on it that has generated an MTIME changelog which contains the
16102 # correct parent FID. As files might reside on a different MDT from the
16103 # parent directory in DNE configurations, the FIDs are translated to paths
16104 # before being compared, which should be identical
16105 compare_mtime_changelog() {
16106         local file="${1}"
16107         local mdtidx
16108         local mtime
16109         local cl_fid
16110         local pdir
16111         local dir
16112
16113         mdtidx=$($LFS getstripe --mdt-index $file)
16114         mdtidx=$(printf "%04x" $mdtidx)
16115
16116         # Obtain the parent FID from the MTIME changelog
16117         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16118         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16119
16120         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16121         [ -z "$cl_fid" ] && error "parent FID not present"
16122
16123         # Verify that the path for the parent FID is the same as the path for
16124         # the test directory
16125         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16126
16127         dir=$(dirname $1)
16128
16129         [[ "${pdir%/}" == "$dir" ]] ||
16130                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16131 }
16132
16133 test_160l() {
16134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16135
16136         remote_mds_nodsh && skip "remote MDS with nodsh"
16137         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16138                 skip "Need MDS version at least 2.13.55"
16139
16140         local cl_user
16141
16142         changelog_register || error "changelog_register failed"
16143         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16144
16145         changelog_users $SINGLEMDS | grep -q $cl_user ||
16146                 error "User '$cl_user' not found in changelog_users"
16147
16148         # Clear some types so that MTIME changelogs are generated
16149         changelog_chmask "-CREAT"
16150         changelog_chmask "-CLOSE"
16151
16152         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16153
16154         # Test CL_MTIME during setattr
16155         touch $DIR/$tdir/$tfile
16156         compare_mtime_changelog $DIR/$tdir/$tfile
16157
16158         # Test CL_MTIME during close
16159         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16160         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16161 }
16162 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16163
16164 test_160m() {
16165         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16166         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16167                 skip "Need MDS version at least 2.14.51"
16168         local cl_users
16169         local cl_user1
16170         local cl_user2
16171         local pid1
16172
16173         # Create a user
16174         changelog_register || error "first changelog_register failed"
16175         changelog_register || error "second changelog_register failed"
16176
16177         cl_users=(${CL_USERS[mds1]})
16178         cl_user1="${cl_users[0]}"
16179         cl_user2="${cl_users[1]}"
16180         # generate some changelog records to accumulate on MDT0
16181         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16182         createmany -m $DIR/$tdir/$tfile 50 ||
16183                 error "create $DIR/$tdir/$tfile failed"
16184         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16185         rm -f $DIR/$tdir
16186
16187         # check changelogs have been generated
16188         local nbcl=$(changelog_dump | wc -l)
16189         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16190
16191 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16192         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16193
16194         __changelog_clear mds1 $cl_user1 +10
16195         __changelog_clear mds1 $cl_user2 0 &
16196         pid1=$!
16197         sleep 2
16198         __changelog_clear mds1 $cl_user1 0 ||
16199                 error "fail to cancel record for $cl_user1"
16200         wait $pid1
16201         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16202 }
16203 run_test 160m "Changelog clear race"
16204
16205 test_160n() {
16206         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16207         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16208                 skip "Need MDS version at least 2.14.51"
16209         local cl_users
16210         local cl_user1
16211         local cl_user2
16212         local pid1
16213         local first_rec
16214         local last_rec=0
16215
16216         # Create a user
16217         changelog_register || error "first changelog_register failed"
16218
16219         cl_users=(${CL_USERS[mds1]})
16220         cl_user1="${cl_users[0]}"
16221
16222         # generate some changelog records to accumulate on MDT0
16223         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16224         first_rec=$(changelog_users $SINGLEMDS |
16225                         awk '/^current.index:/ { print $NF }')
16226         while (( last_rec < (( first_rec + 65000)) )); do
16227                 createmany -m $DIR/$tdir/$tfile 10000 ||
16228                         error "create $DIR/$tdir/$tfile failed"
16229
16230                 for i in $(seq 0 10000); do
16231                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16232                                 > /dev/null
16233                 done
16234
16235                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16236                         error "unlinkmany failed unlink"
16237                 last_rec=$(changelog_users $SINGLEMDS |
16238                         awk '/^current.index:/ { print $NF }')
16239                 echo last record $last_rec
16240                 (( last_rec == 0 )) && error "no changelog found"
16241         done
16242
16243 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16244         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16245
16246         __changelog_clear mds1 $cl_user1 0 &
16247         pid1=$!
16248         sleep 2
16249         __changelog_clear mds1 $cl_user1 0 ||
16250                 error "fail to cancel record for $cl_user1"
16251         wait $pid1
16252         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16253 }
16254 run_test 160n "Changelog destroy race"
16255
16256 test_160o() {
16257         local mdt="$(facet_svc $SINGLEMDS)"
16258
16259         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16260         remote_mds_nodsh && skip "remote MDS with nodsh"
16261         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16262                 skip "Need MDS version at least 2.14.52"
16263
16264         changelog_register --user test_160o -m unlnk+close+open ||
16265                 error "changelog_register failed"
16266         # drop server mask so it doesn't interfere
16267         do_facet $SINGLEMDS $LCTL --device $mdt \
16268                                 changelog_register -u "Tt3_-#" &&
16269                 error "bad symbols in name should fail"
16270
16271         do_facet $SINGLEMDS $LCTL --device $mdt \
16272                                 changelog_register -u test_160o &&
16273                 error "the same name registration should fail"
16274
16275         do_facet $SINGLEMDS $LCTL --device $mdt \
16276                         changelog_register -u test_160toolongname &&
16277                 error "too long name registration should fail"
16278
16279         changelog_chmask "MARK+HSM"
16280         lctl get_param mdd.*.changelog*mask
16281         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16282         changelog_users $SINGLEMDS | grep -q $cl_user ||
16283                 error "User $cl_user not found in changelog_users"
16284         #verify username
16285         echo $cl_user | grep -q test_160o ||
16286                 error "User $cl_user has no specific name 'test160o'"
16287
16288         # change something
16289         changelog_clear 0 || error "changelog_clear failed"
16290         # generate some changelog records to accumulate on MDT0
16291         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16292         touch $DIR/$tdir/$tfile                 # open 1
16293
16294         OPENS=$(changelog_dump | grep -c "OPEN")
16295         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16296
16297         # must be no MKDIR it wasn't set as user mask
16298         MKDIR=$(changelog_dump | grep -c "MKDIR")
16299         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16300
16301         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16302                                 mdd.$mdt.changelog_current_mask -n)
16303         # register maskless user
16304         changelog_register || error "changelog_register failed"
16305         # effective mask should be not changed because it is not minimal
16306         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16307                                 mdd.$mdt.changelog_current_mask -n)
16308         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16309         # set server mask to minimal value
16310         changelog_chmask "MARK"
16311         # check effective mask again, should be treated as DEFMASK now
16312         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16313                                 mdd.$mdt.changelog_current_mask -n)
16314         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16315
16316         do_facet $SINGLEMDS $LCTL --device $mdt \
16317                                 changelog_deregister -u test_160o ||
16318                 error "cannot deregister by name"
16319 }
16320 run_test 160o "changelog user name and mask"
16321
16322 test_160p() {
16323         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16324         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16325                 skip "Need MDS version at least 2.14.51"
16326         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16327         local cl_users
16328         local cl_user1
16329         local entry_count
16330
16331         # Create a user
16332         changelog_register || error "first changelog_register failed"
16333
16334         cl_users=(${CL_USERS[mds1]})
16335         cl_user1="${cl_users[0]}"
16336
16337         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16338         createmany -m $DIR/$tdir/$tfile 50 ||
16339                 error "create $DIR/$tdir/$tfile failed"
16340         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16341         rm -rf $DIR/$tdir
16342
16343         # check changelogs have been generated
16344         entry_count=$(changelog_dump | wc -l)
16345         ((entry_count != 0)) || error "no changelog entries found"
16346
16347         # remove changelog_users and check that orphan entries are removed
16348         stop mds1
16349         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16350         start mds1 || error "cannot start mdt"
16351         entry_count=$(changelog_dump | wc -l)
16352         ((entry_count == 0)) ||
16353                 error "found $entry_count changelog entries, expected none"
16354 }
16355 run_test 160p "Changelog orphan cleanup with no users"
16356
16357 test_161a() {
16358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16359
16360         test_mkdir -c1 $DIR/$tdir
16361         cp /etc/hosts $DIR/$tdir/$tfile
16362         test_mkdir -c1 $DIR/$tdir/foo1
16363         test_mkdir -c1 $DIR/$tdir/foo2
16364         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16365         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16366         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16367         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16368         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16369         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16370                 $LFS fid2path $DIR $FID
16371                 error "bad link ea"
16372         fi
16373         # middle
16374         rm $DIR/$tdir/foo2/zachary
16375         # last
16376         rm $DIR/$tdir/foo2/thor
16377         # first
16378         rm $DIR/$tdir/$tfile
16379         # rename
16380         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16381         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16382                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16383         rm $DIR/$tdir/foo2/maggie
16384
16385         # overflow the EA
16386         local longname=$tfile.avg_len_is_thirty_two_
16387         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16388                 error_noexit 'failed to unlink many hardlinks'" EXIT
16389         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16390                 error "failed to hardlink many files"
16391         links=$($LFS fid2path $DIR $FID | wc -l)
16392         echo -n "${links}/1000 links in link EA"
16393         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16394 }
16395 run_test 161a "link ea sanity"
16396
16397 test_161b() {
16398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16399         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16400
16401         local MDTIDX=1
16402         local remote_dir=$DIR/$tdir/remote_dir
16403
16404         mkdir -p $DIR/$tdir
16405         $LFS mkdir -i $MDTIDX $remote_dir ||
16406                 error "create remote directory failed"
16407
16408         cp /etc/hosts $remote_dir/$tfile
16409         mkdir -p $remote_dir/foo1
16410         mkdir -p $remote_dir/foo2
16411         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16412         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16413         ln $remote_dir/$tfile $remote_dir/foo1/luna
16414         ln $remote_dir/$tfile $remote_dir/foo2/thor
16415
16416         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16417                      tr -d ']')
16418         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16419                 $LFS fid2path $DIR $FID
16420                 error "bad link ea"
16421         fi
16422         # middle
16423         rm $remote_dir/foo2/zachary
16424         # last
16425         rm $remote_dir/foo2/thor
16426         # first
16427         rm $remote_dir/$tfile
16428         # rename
16429         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16430         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16431         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16432                 $LFS fid2path $DIR $FID
16433                 error "bad link rename"
16434         fi
16435         rm $remote_dir/foo2/maggie
16436
16437         # overflow the EA
16438         local longname=filename_avg_len_is_thirty_two_
16439         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16440                 error "failed to hardlink many files"
16441         links=$($LFS fid2path $DIR $FID | wc -l)
16442         echo -n "${links}/1000 links in link EA"
16443         [[ ${links} -gt 60 ]] ||
16444                 error "expected at least 60 links in link EA"
16445         unlinkmany $remote_dir/foo2/$longname 1000 ||
16446         error "failed to unlink many hardlinks"
16447 }
16448 run_test 161b "link ea sanity under remote directory"
16449
16450 test_161c() {
16451         remote_mds_nodsh && skip "remote MDS with nodsh"
16452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16453         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16454                 skip "Need MDS version at least 2.1.5"
16455
16456         # define CLF_RENAME_LAST 0x0001
16457         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16458         changelog_register || error "changelog_register failed"
16459
16460         rm -rf $DIR/$tdir
16461         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16462         touch $DIR/$tdir/foo_161c
16463         touch $DIR/$tdir/bar_161c
16464         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16465         changelog_dump | grep RENME | tail -n 5
16466         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16467         changelog_clear 0 || error "changelog_clear failed"
16468         if [ x$flags != "x0x1" ]; then
16469                 error "flag $flags is not 0x1"
16470         fi
16471
16472         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16473         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16474         touch $DIR/$tdir/foo_161c
16475         touch $DIR/$tdir/bar_161c
16476         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16477         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16478         changelog_dump | grep RENME | tail -n 5
16479         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16480         changelog_clear 0 || error "changelog_clear failed"
16481         if [ x$flags != "x0x0" ]; then
16482                 error "flag $flags is not 0x0"
16483         fi
16484         echo "rename overwrite a target having nlink > 1," \
16485                 "changelog record has flags of $flags"
16486
16487         # rename doesn't overwrite a target (changelog flag 0x0)
16488         touch $DIR/$tdir/foo_161c
16489         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16490         changelog_dump | grep RENME | tail -n 5
16491         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16492         changelog_clear 0 || error "changelog_clear failed"
16493         if [ x$flags != "x0x0" ]; then
16494                 error "flag $flags is not 0x0"
16495         fi
16496         echo "rename doesn't overwrite a target," \
16497                 "changelog record has flags of $flags"
16498
16499         # define CLF_UNLINK_LAST 0x0001
16500         # unlink a file having nlink = 1 (changelog flag 0x1)
16501         rm -f $DIR/$tdir/foo2_161c
16502         changelog_dump | grep UNLNK | tail -n 5
16503         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16504         changelog_clear 0 || error "changelog_clear failed"
16505         if [ x$flags != "x0x1" ]; then
16506                 error "flag $flags is not 0x1"
16507         fi
16508         echo "unlink a file having nlink = 1," \
16509                 "changelog record has flags of $flags"
16510
16511         # unlink a file having nlink > 1 (changelog flag 0x0)
16512         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16513         rm -f $DIR/$tdir/foobar_161c
16514         changelog_dump | grep UNLNK | tail -n 5
16515         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16516         changelog_clear 0 || error "changelog_clear failed"
16517         if [ x$flags != "x0x0" ]; then
16518                 error "flag $flags is not 0x0"
16519         fi
16520         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16521 }
16522 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16523
16524 test_161d() {
16525         remote_mds_nodsh && skip "remote MDS with nodsh"
16526         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16527
16528         local pid
16529         local fid
16530
16531         changelog_register || error "changelog_register failed"
16532
16533         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16534         # interfer with $MOUNT/.lustre/fid/ access
16535         mkdir $DIR/$tdir
16536         [[ $? -eq 0 ]] || error "mkdir failed"
16537
16538         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16539         $LCTL set_param fail_loc=0x8000140c
16540         # 5s pause
16541         $LCTL set_param fail_val=5
16542
16543         # create file
16544         echo foofoo > $DIR/$tdir/$tfile &
16545         pid=$!
16546
16547         # wait for create to be delayed
16548         sleep 2
16549
16550         ps -p $pid
16551         [[ $? -eq 0 ]] || error "create should be blocked"
16552
16553         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16554         stack_trap "rm -f $tempfile"
16555         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16556         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16557         # some delay may occur during ChangeLog publishing and file read just
16558         # above, that could allow file write to happen finally
16559         [[ -s $tempfile ]] && echo "file should be empty"
16560
16561         $LCTL set_param fail_loc=0
16562
16563         wait $pid
16564         [[ $? -eq 0 ]] || error "create failed"
16565 }
16566 run_test 161d "create with concurrent .lustre/fid access"
16567
16568 check_path() {
16569         local expected="$1"
16570         shift
16571         local fid="$2"
16572
16573         local path
16574         path=$($LFS fid2path "$@")
16575         local rc=$?
16576
16577         if [ $rc -ne 0 ]; then
16578                 error "path looked up of '$expected' failed: rc=$rc"
16579         elif [ "$path" != "$expected" ]; then
16580                 error "path looked up '$path' instead of '$expected'"
16581         else
16582                 echo "FID '$fid' resolves to path '$path' as expected"
16583         fi
16584 }
16585
16586 test_162a() { # was test_162
16587         test_mkdir -p -c1 $DIR/$tdir/d2
16588         touch $DIR/$tdir/d2/$tfile
16589         touch $DIR/$tdir/d2/x1
16590         touch $DIR/$tdir/d2/x2
16591         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16592         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16593         # regular file
16594         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16595         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16596
16597         # softlink
16598         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16599         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16600         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16601
16602         # softlink to wrong file
16603         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16604         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16605         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16606
16607         # hardlink
16608         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16609         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16610         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16611         # fid2path dir/fsname should both work
16612         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16613         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16614
16615         # hardlink count: check that there are 2 links
16616         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16617         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16618
16619         # hardlink indexing: remove the first link
16620         rm $DIR/$tdir/d2/p/q/r/hlink
16621         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16622 }
16623 run_test 162a "path lookup sanity"
16624
16625 test_162b() {
16626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16627         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16628
16629         mkdir $DIR/$tdir
16630         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16631                                 error "create striped dir failed"
16632
16633         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16634                                         tail -n 1 | awk '{print $2}')
16635         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16636
16637         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16638         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16639
16640         # regular file
16641         for ((i=0;i<5;i++)); do
16642                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16643                         error "get fid for f$i failed"
16644                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16645
16646                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16647                         error "get fid for d$i failed"
16648                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16649         done
16650
16651         return 0
16652 }
16653 run_test 162b "striped directory path lookup sanity"
16654
16655 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16656 test_162c() {
16657         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16658                 skip "Need MDS version at least 2.7.51"
16659
16660         local lpath=$tdir.local
16661         local rpath=$tdir.remote
16662
16663         test_mkdir $DIR/$lpath
16664         test_mkdir $DIR/$rpath
16665
16666         for ((i = 0; i <= 101; i++)); do
16667                 lpath="$lpath/$i"
16668                 mkdir $DIR/$lpath
16669                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16670                         error "get fid for local directory $DIR/$lpath failed"
16671                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16672
16673                 rpath="$rpath/$i"
16674                 test_mkdir $DIR/$rpath
16675                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16676                         error "get fid for remote directory $DIR/$rpath failed"
16677                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16678         done
16679
16680         return 0
16681 }
16682 run_test 162c "fid2path works with paths 100 or more directories deep"
16683
16684 oalr_event_count() {
16685         local event="${1}"
16686         local trace="${2}"
16687
16688         awk -v name="${FSNAME}-OST0000" \
16689             -v event="${event}" \
16690             '$1 == "TRACE" && $2 == event && $3 == name' \
16691             "${trace}" |
16692         wc -l
16693 }
16694
16695 oalr_expect_event_count() {
16696         local event="${1}"
16697         local trace="${2}"
16698         local expect="${3}"
16699         local count
16700
16701         count=$(oalr_event_count "${event}" "${trace}")
16702         if ((count == expect)); then
16703                 return 0
16704         fi
16705
16706         error_noexit "${event} event count was '${count}', expected ${expect}"
16707         cat "${trace}" >&2
16708         exit 1
16709 }
16710
16711 cleanup_165() {
16712         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16713         stop ost1
16714         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16715 }
16716
16717 setup_165() {
16718         sync # Flush previous IOs so we can count log entries.
16719         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16720         stack_trap cleanup_165 EXIT
16721 }
16722
16723 test_165a() {
16724         local trace="/tmp/${tfile}.trace"
16725         local rc
16726         local count
16727
16728         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16729                 skip "OFD access log unsupported"
16730
16731         setup_165
16732         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16733         sleep 5
16734
16735         do_facet ost1 ofd_access_log_reader --list
16736         stop ost1
16737
16738         do_facet ost1 killall -TERM ofd_access_log_reader
16739         wait
16740         rc=$?
16741
16742         if ((rc != 0)); then
16743                 error "ofd_access_log_reader exited with rc = '${rc}'"
16744         fi
16745
16746         # Parse trace file for discovery events:
16747         oalr_expect_event_count alr_log_add "${trace}" 1
16748         oalr_expect_event_count alr_log_eof "${trace}" 1
16749         oalr_expect_event_count alr_log_free "${trace}" 1
16750 }
16751 run_test 165a "ofd access log discovery"
16752
16753 test_165b() {
16754         local trace="/tmp/${tfile}.trace"
16755         local file="${DIR}/${tfile}"
16756         local pfid1
16757         local pfid2
16758         local -a entry
16759         local rc
16760         local count
16761         local size
16762         local flags
16763
16764         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16765                 skip "OFD access log unsupported"
16766
16767         setup_165
16768         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16769         sleep 5
16770
16771         do_facet ost1 ofd_access_log_reader --list
16772
16773         lfs setstripe -c 1 -i 0 "${file}"
16774         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16775                 error "cannot create '${file}'"
16776
16777         sleep 5
16778         do_facet ost1 killall -TERM ofd_access_log_reader
16779         wait
16780         rc=$?
16781
16782         if ((rc != 0)); then
16783                 error "ofd_access_log_reader exited with rc = '${rc}'"
16784         fi
16785
16786         oalr_expect_event_count alr_log_entry "${trace}" 1
16787
16788         pfid1=$($LFS path2fid "${file}")
16789
16790         # 1     2             3   4    5     6   7    8    9     10
16791         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16792         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16793
16794         echo "entry = '${entry[*]}'" >&2
16795
16796         pfid2=${entry[4]}
16797         if [[ "${pfid1}" != "${pfid2}" ]]; then
16798                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16799         fi
16800
16801         size=${entry[8]}
16802         if ((size != 1048576)); then
16803                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16804         fi
16805
16806         flags=${entry[10]}
16807         if [[ "${flags}" != "w" ]]; then
16808                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16809         fi
16810
16811         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16812         sleep 5
16813
16814         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16815                 error "cannot read '${file}'"
16816         sleep 5
16817
16818         do_facet ost1 killall -TERM ofd_access_log_reader
16819         wait
16820         rc=$?
16821
16822         if ((rc != 0)); then
16823                 error "ofd_access_log_reader exited with rc = '${rc}'"
16824         fi
16825
16826         oalr_expect_event_count alr_log_entry "${trace}" 1
16827
16828         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16829         echo "entry = '${entry[*]}'" >&2
16830
16831         pfid2=${entry[4]}
16832         if [[ "${pfid1}" != "${pfid2}" ]]; then
16833                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16834         fi
16835
16836         size=${entry[8]}
16837         if ((size != 524288)); then
16838                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16839         fi
16840
16841         flags=${entry[10]}
16842         if [[ "${flags}" != "r" ]]; then
16843                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16844         fi
16845 }
16846 run_test 165b "ofd access log entries are produced and consumed"
16847
16848 test_165c() {
16849         local trace="/tmp/${tfile}.trace"
16850         local file="${DIR}/${tdir}/${tfile}"
16851
16852         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16853                 skip "OFD access log unsupported"
16854
16855         test_mkdir "${DIR}/${tdir}"
16856
16857         setup_165
16858         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16859         sleep 5
16860
16861         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16862
16863         # 4096 / 64 = 64. Create twice as many entries.
16864         for ((i = 0; i < 128; i++)); do
16865                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16866                         error "cannot create file"
16867         done
16868
16869         sync
16870
16871         do_facet ost1 killall -TERM ofd_access_log_reader
16872         wait
16873         rc=$?
16874         if ((rc != 0)); then
16875                 error "ofd_access_log_reader exited with rc = '${rc}'"
16876         fi
16877
16878         unlinkmany  "${file}-%d" 128
16879 }
16880 run_test 165c "full ofd access logs do not block IOs"
16881
16882 oal_get_read_count() {
16883         local stats="$1"
16884
16885         # STATS lustre-OST0001 alr_read_count 1
16886
16887         do_facet ost1 cat "${stats}" |
16888         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16889              END { print count; }'
16890 }
16891
16892 oal_expect_read_count() {
16893         local stats="$1"
16894         local count
16895         local expect="$2"
16896
16897         # Ask ofd_access_log_reader to write stats.
16898         do_facet ost1 killall -USR1 ofd_access_log_reader
16899
16900         # Allow some time for things to happen.
16901         sleep 1
16902
16903         count=$(oal_get_read_count "${stats}")
16904         if ((count == expect)); then
16905                 return 0
16906         fi
16907
16908         error_noexit "bad read count, got ${count}, expected ${expect}"
16909         do_facet ost1 cat "${stats}" >&2
16910         exit 1
16911 }
16912
16913 test_165d() {
16914         local stats="/tmp/${tfile}.stats"
16915         local file="${DIR}/${tdir}/${tfile}"
16916         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16917
16918         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16919                 skip "OFD access log unsupported"
16920
16921         test_mkdir "${DIR}/${tdir}"
16922
16923         setup_165
16924         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16925         sleep 5
16926
16927         lfs setstripe -c 1 -i 0 "${file}"
16928
16929         do_facet ost1 lctl set_param "${param}=rw"
16930         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16931                 error "cannot create '${file}'"
16932         oal_expect_read_count "${stats}" 1
16933
16934         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16935                 error "cannot read '${file}'"
16936         oal_expect_read_count "${stats}" 2
16937
16938         do_facet ost1 lctl set_param "${param}=r"
16939         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16940                 error "cannot create '${file}'"
16941         oal_expect_read_count "${stats}" 2
16942
16943         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16944                 error "cannot read '${file}'"
16945         oal_expect_read_count "${stats}" 3
16946
16947         do_facet ost1 lctl set_param "${param}=w"
16948         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16949                 error "cannot create '${file}'"
16950         oal_expect_read_count "${stats}" 4
16951
16952         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16953                 error "cannot read '${file}'"
16954         oal_expect_read_count "${stats}" 4
16955
16956         do_facet ost1 lctl set_param "${param}=0"
16957         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16958                 error "cannot create '${file}'"
16959         oal_expect_read_count "${stats}" 4
16960
16961         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16962                 error "cannot read '${file}'"
16963         oal_expect_read_count "${stats}" 4
16964
16965         do_facet ost1 killall -TERM ofd_access_log_reader
16966         wait
16967         rc=$?
16968         if ((rc != 0)); then
16969                 error "ofd_access_log_reader exited with rc = '${rc}'"
16970         fi
16971 }
16972 run_test 165d "ofd_access_log mask works"
16973
16974 test_165e() {
16975         local stats="/tmp/${tfile}.stats"
16976         local file0="${DIR}/${tdir}-0/${tfile}"
16977         local file1="${DIR}/${tdir}-1/${tfile}"
16978
16979         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16980                 skip "OFD access log unsupported"
16981
16982         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16983
16984         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16985         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16986
16987         lfs setstripe -c 1 -i 0 "${file0}"
16988         lfs setstripe -c 1 -i 0 "${file1}"
16989
16990         setup_165
16991         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16992         sleep 5
16993
16994         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16995                 error "cannot create '${file0}'"
16996         sync
16997         oal_expect_read_count "${stats}" 0
16998
16999         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17000                 error "cannot create '${file1}'"
17001         sync
17002         oal_expect_read_count "${stats}" 1
17003
17004         do_facet ost1 killall -TERM ofd_access_log_reader
17005         wait
17006         rc=$?
17007         if ((rc != 0)); then
17008                 error "ofd_access_log_reader exited with rc = '${rc}'"
17009         fi
17010 }
17011 run_test 165e "ofd_access_log MDT index filter works"
17012
17013 test_165f() {
17014         local trace="/tmp/${tfile}.trace"
17015         local rc
17016         local count
17017
17018         setup_165
17019         do_facet ost1 timeout 60 ofd_access_log_reader \
17020                 --exit-on-close --debug=- --trace=- > "${trace}" &
17021         sleep 5
17022         stop ost1
17023
17024         wait
17025         rc=$?
17026
17027         if ((rc != 0)); then
17028                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17029                 cat "${trace}"
17030                 exit 1
17031         fi
17032 }
17033 run_test 165f "ofd_access_log_reader --exit-on-close works"
17034
17035 test_169() {
17036         # do directio so as not to populate the page cache
17037         log "creating a 10 Mb file"
17038         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17039                 error "multiop failed while creating a file"
17040         log "starting reads"
17041         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17042         log "truncating the file"
17043         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17044                 error "multiop failed while truncating the file"
17045         log "killing dd"
17046         kill %+ || true # reads might have finished
17047         echo "wait until dd is finished"
17048         wait
17049         log "removing the temporary file"
17050         rm -rf $DIR/$tfile || error "tmp file removal failed"
17051 }
17052 run_test 169 "parallel read and truncate should not deadlock"
17053
17054 test_170() {
17055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17056
17057         $LCTL clear     # bug 18514
17058         $LCTL debug_daemon start $TMP/${tfile}_log_good
17059         touch $DIR/$tfile
17060         $LCTL debug_daemon stop
17061         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17062                 error "sed failed to read log_good"
17063
17064         $LCTL debug_daemon start $TMP/${tfile}_log_good
17065         rm -rf $DIR/$tfile
17066         $LCTL debug_daemon stop
17067
17068         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17069                error "lctl df log_bad failed"
17070
17071         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17072         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17073
17074         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17075         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17076
17077         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17078                 error "bad_line good_line1 good_line2 are empty"
17079
17080         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17081         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17082         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17083
17084         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17085         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17086         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17087
17088         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17089                 error "bad_line_new good_line_new are empty"
17090
17091         local expected_good=$((good_line1 + good_line2*2))
17092
17093         rm -f $TMP/${tfile}*
17094         # LU-231, short malformed line may not be counted into bad lines
17095         if [ $bad_line -ne $bad_line_new ] &&
17096                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17097                 error "expected $bad_line bad lines, but got $bad_line_new"
17098                 return 1
17099         fi
17100
17101         if [ $expected_good -ne $good_line_new ]; then
17102                 error "expected $expected_good good lines, but got $good_line_new"
17103                 return 2
17104         fi
17105         true
17106 }
17107 run_test 170 "test lctl df to handle corrupted log ====================="
17108
17109 test_171() { # bug20592
17110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17111
17112         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17113         $LCTL set_param fail_loc=0x50e
17114         $LCTL set_param fail_val=3000
17115         multiop_bg_pause $DIR/$tfile O_s || true
17116         local MULTIPID=$!
17117         kill -USR1 $MULTIPID
17118         # cause log dump
17119         sleep 3
17120         wait $MULTIPID
17121         if dmesg | grep "recursive fault"; then
17122                 error "caught a recursive fault"
17123         fi
17124         $LCTL set_param fail_loc=0
17125         true
17126 }
17127 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17128
17129 # it would be good to share it with obdfilter-survey/iokit-libecho code
17130 setup_obdecho_osc () {
17131         local rc=0
17132         local ost_nid=$1
17133         local obdfilter_name=$2
17134         echo "Creating new osc for $obdfilter_name on $ost_nid"
17135         # make sure we can find loopback nid
17136         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17137
17138         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17139                            ${obdfilter_name}_osc_UUID || rc=2; }
17140         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17141                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17142         return $rc
17143 }
17144
17145 cleanup_obdecho_osc () {
17146         local obdfilter_name=$1
17147         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17148         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17149         return 0
17150 }
17151
17152 obdecho_test() {
17153         local OBD=$1
17154         local node=$2
17155         local pages=${3:-64}
17156         local rc=0
17157         local id
17158
17159         local count=10
17160         local obd_size=$(get_obd_size $node $OBD)
17161         local page_size=$(get_page_size $node)
17162         if [[ -n "$obd_size" ]]; then
17163                 local new_count=$((obd_size / (pages * page_size / 1024)))
17164                 [[ $new_count -ge $count ]] || count=$new_count
17165         fi
17166
17167         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17168         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17169                            rc=2; }
17170         if [ $rc -eq 0 ]; then
17171             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17172             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17173         fi
17174         echo "New object id is $id"
17175         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17176                            rc=4; }
17177         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17178                            "test_brw $count w v $pages $id" || rc=4; }
17179         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17180                            rc=4; }
17181         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17182                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17183         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17184                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17185         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17186         return $rc
17187 }
17188
17189 test_180a() {
17190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17191
17192         if ! [ -d /sys/fs/lustre/echo_client ] &&
17193            ! module_loaded obdecho; then
17194                 load_module obdecho/obdecho &&
17195                         stack_trap "rmmod obdecho" EXIT ||
17196                         error "unable to load obdecho on client"
17197         fi
17198
17199         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17200         local host=$($LCTL get_param -n osc.$osc.import |
17201                      awk '/current_connection:/ { print $2 }' )
17202         local target=$($LCTL get_param -n osc.$osc.import |
17203                        awk '/target:/ { print $2 }' )
17204         target=${target%_UUID}
17205
17206         if [ -n "$target" ]; then
17207                 setup_obdecho_osc $host $target &&
17208                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17209                         { error "obdecho setup failed with $?"; return; }
17210
17211                 obdecho_test ${target}_osc client ||
17212                         error "obdecho_test failed on ${target}_osc"
17213         else
17214                 $LCTL get_param osc.$osc.import
17215                 error "there is no osc.$osc.import target"
17216         fi
17217 }
17218 run_test 180a "test obdecho on osc"
17219
17220 test_180b() {
17221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17222         remote_ost_nodsh && skip "remote OST with nodsh"
17223
17224         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17225                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17226                 error "failed to load module obdecho"
17227
17228         local target=$(do_facet ost1 $LCTL dl |
17229                        awk '/obdfilter/ { print $4; exit; }')
17230
17231         if [ -n "$target" ]; then
17232                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17233         else
17234                 do_facet ost1 $LCTL dl
17235                 error "there is no obdfilter target on ost1"
17236         fi
17237 }
17238 run_test 180b "test obdecho directly on obdfilter"
17239
17240 test_180c() { # LU-2598
17241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17242         remote_ost_nodsh && skip "remote OST with nodsh"
17243         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17244                 skip "Need MDS version at least 2.4.0"
17245
17246         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17247                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17248                 error "failed to load module obdecho"
17249
17250         local target=$(do_facet ost1 $LCTL dl |
17251                        awk '/obdfilter/ { print $4; exit; }')
17252
17253         if [ -n "$target" ]; then
17254                 local pages=16384 # 64MB bulk I/O RPC size
17255
17256                 obdecho_test "$target" ost1 "$pages" ||
17257                         error "obdecho_test with pages=$pages failed with $?"
17258         else
17259                 do_facet ost1 $LCTL dl
17260                 error "there is no obdfilter target on ost1"
17261         fi
17262 }
17263 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17264
17265 test_181() { # bug 22177
17266         test_mkdir $DIR/$tdir
17267         # create enough files to index the directory
17268         createmany -o $DIR/$tdir/foobar 4000
17269         # print attributes for debug purpose
17270         lsattr -d .
17271         # open dir
17272         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17273         MULTIPID=$!
17274         # remove the files & current working dir
17275         unlinkmany $DIR/$tdir/foobar 4000
17276         rmdir $DIR/$tdir
17277         kill -USR1 $MULTIPID
17278         wait $MULTIPID
17279         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17280         return 0
17281 }
17282 run_test 181 "Test open-unlinked dir ========================"
17283
17284 test_182() {
17285         local fcount=1000
17286         local tcount=10
17287
17288         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17289
17290         $LCTL set_param mdc.*.rpc_stats=clear
17291
17292         for (( i = 0; i < $tcount; i++ )) ; do
17293                 mkdir $DIR/$tdir/$i
17294         done
17295
17296         for (( i = 0; i < $tcount; i++ )) ; do
17297                 createmany -o $DIR/$tdir/$i/f- $fcount &
17298         done
17299         wait
17300
17301         for (( i = 0; i < $tcount; i++ )) ; do
17302                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17303         done
17304         wait
17305
17306         $LCTL get_param mdc.*.rpc_stats
17307
17308         rm -rf $DIR/$tdir
17309 }
17310 run_test 182 "Test parallel modify metadata operations ================"
17311
17312 test_183() { # LU-2275
17313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17314         remote_mds_nodsh && skip "remote MDS with nodsh"
17315         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17316                 skip "Need MDS version at least 2.3.56"
17317
17318         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17319         echo aaa > $DIR/$tdir/$tfile
17320
17321 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17322         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17323
17324         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17325         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17326
17327         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17328
17329         # Flush negative dentry cache
17330         touch $DIR/$tdir/$tfile
17331
17332         # We are not checking for any leaked references here, they'll
17333         # become evident next time we do cleanup with module unload.
17334         rm -rf $DIR/$tdir
17335 }
17336 run_test 183 "No crash or request leak in case of strange dispositions ========"
17337
17338 # test suite 184 is for LU-2016, LU-2017
17339 test_184a() {
17340         check_swap_layouts_support
17341
17342         dir0=$DIR/$tdir/$testnum
17343         test_mkdir -p -c1 $dir0
17344         ref1=/etc/passwd
17345         ref2=/etc/group
17346         file1=$dir0/f1
17347         file2=$dir0/f2
17348         $LFS setstripe -c1 $file1
17349         cp $ref1 $file1
17350         $LFS setstripe -c2 $file2
17351         cp $ref2 $file2
17352         gen1=$($LFS getstripe -g $file1)
17353         gen2=$($LFS getstripe -g $file2)
17354
17355         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17356         gen=$($LFS getstripe -g $file1)
17357         [[ $gen1 != $gen ]] ||
17358                 "Layout generation on $file1 does not change"
17359         gen=$($LFS getstripe -g $file2)
17360         [[ $gen2 != $gen ]] ||
17361                 "Layout generation on $file2 does not change"
17362
17363         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17364         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17365
17366         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17367 }
17368 run_test 184a "Basic layout swap"
17369
17370 test_184b() {
17371         check_swap_layouts_support
17372
17373         dir0=$DIR/$tdir/$testnum
17374         mkdir -p $dir0 || error "creating dir $dir0"
17375         file1=$dir0/f1
17376         file2=$dir0/f2
17377         file3=$dir0/f3
17378         dir1=$dir0/d1
17379         dir2=$dir0/d2
17380         mkdir $dir1 $dir2
17381         $LFS setstripe -c1 $file1
17382         $LFS setstripe -c2 $file2
17383         $LFS setstripe -c1 $file3
17384         chown $RUNAS_ID $file3
17385         gen1=$($LFS getstripe -g $file1)
17386         gen2=$($LFS getstripe -g $file2)
17387
17388         $LFS swap_layouts $dir1 $dir2 &&
17389                 error "swap of directories layouts should fail"
17390         $LFS swap_layouts $dir1 $file1 &&
17391                 error "swap of directory and file layouts should fail"
17392         $RUNAS $LFS swap_layouts $file1 $file2 &&
17393                 error "swap of file we cannot write should fail"
17394         $LFS swap_layouts $file1 $file3 &&
17395                 error "swap of file with different owner should fail"
17396         /bin/true # to clear error code
17397 }
17398 run_test 184b "Forbidden layout swap (will generate errors)"
17399
17400 test_184c() {
17401         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17402         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17403         check_swap_layouts_support
17404         check_swap_layout_no_dom $DIR
17405
17406         local dir0=$DIR/$tdir/$testnum
17407         mkdir -p $dir0 || error "creating dir $dir0"
17408
17409         local ref1=$dir0/ref1
17410         local ref2=$dir0/ref2
17411         local file1=$dir0/file1
17412         local file2=$dir0/file2
17413         # create a file large enough for the concurrent test
17414         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17415         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17416         echo "ref file size: ref1($(stat -c %s $ref1))," \
17417              "ref2($(stat -c %s $ref2))"
17418
17419         cp $ref2 $file2
17420         dd if=$ref1 of=$file1 bs=16k &
17421         local DD_PID=$!
17422
17423         # Make sure dd starts to copy file, but wait at most 5 seconds
17424         local loops=0
17425         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17426
17427         $LFS swap_layouts $file1 $file2
17428         local rc=$?
17429         wait $DD_PID
17430         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17431         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17432
17433         # how many bytes copied before swapping layout
17434         local copied=$(stat -c %s $file2)
17435         local remaining=$(stat -c %s $ref1)
17436         remaining=$((remaining - copied))
17437         echo "Copied $copied bytes before swapping layout..."
17438
17439         cmp -n $copied $file1 $ref2 | grep differ &&
17440                 error "Content mismatch [0, $copied) of ref2 and file1"
17441         cmp -n $copied $file2 $ref1 ||
17442                 error "Content mismatch [0, $copied) of ref1 and file2"
17443         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17444                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17445
17446         # clean up
17447         rm -f $ref1 $ref2 $file1 $file2
17448 }
17449 run_test 184c "Concurrent write and layout swap"
17450
17451 test_184d() {
17452         check_swap_layouts_support
17453         check_swap_layout_no_dom $DIR
17454         [ -z "$(which getfattr 2>/dev/null)" ] &&
17455                 skip_env "no getfattr command"
17456
17457         local file1=$DIR/$tdir/$tfile-1
17458         local file2=$DIR/$tdir/$tfile-2
17459         local file3=$DIR/$tdir/$tfile-3
17460         local lovea1
17461         local lovea2
17462
17463         mkdir -p $DIR/$tdir
17464         touch $file1 || error "create $file1 failed"
17465         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17466                 error "create $file2 failed"
17467         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17468                 error "create $file3 failed"
17469         lovea1=$(get_layout_param $file1)
17470
17471         $LFS swap_layouts $file2 $file3 ||
17472                 error "swap $file2 $file3 layouts failed"
17473         $LFS swap_layouts $file1 $file2 ||
17474                 error "swap $file1 $file2 layouts failed"
17475
17476         lovea2=$(get_layout_param $file2)
17477         echo "$lovea1"
17478         echo "$lovea2"
17479         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17480
17481         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17482         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17483 }
17484 run_test 184d "allow stripeless layouts swap"
17485
17486 test_184e() {
17487         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17488                 skip "Need MDS version at least 2.6.94"
17489         check_swap_layouts_support
17490         check_swap_layout_no_dom $DIR
17491         [ -z "$(which getfattr 2>/dev/null)" ] &&
17492                 skip_env "no getfattr command"
17493
17494         local file1=$DIR/$tdir/$tfile-1
17495         local file2=$DIR/$tdir/$tfile-2
17496         local file3=$DIR/$tdir/$tfile-3
17497         local lovea
17498
17499         mkdir -p $DIR/$tdir
17500         touch $file1 || error "create $file1 failed"
17501         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17502                 error "create $file2 failed"
17503         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17504                 error "create $file3 failed"
17505
17506         $LFS swap_layouts $file1 $file2 ||
17507                 error "swap $file1 $file2 layouts failed"
17508
17509         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17510         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17511
17512         echo 123 > $file1 || error "Should be able to write into $file1"
17513
17514         $LFS swap_layouts $file1 $file3 ||
17515                 error "swap $file1 $file3 layouts failed"
17516
17517         echo 123 > $file1 || error "Should be able to write into $file1"
17518
17519         rm -rf $file1 $file2 $file3
17520 }
17521 run_test 184e "Recreate layout after stripeless layout swaps"
17522
17523 test_184f() {
17524         # Create a file with name longer than sizeof(struct stat) ==
17525         # 144 to see if we can get chars from the file name to appear
17526         # in the returned striping. Note that 'f' == 0x66.
17527         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17528
17529         mkdir -p $DIR/$tdir
17530         mcreate $DIR/$tdir/$file
17531         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17532                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17533         fi
17534 }
17535 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17536
17537 test_185() { # LU-2441
17538         # LU-3553 - no volatile file support in old servers
17539         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17540                 skip "Need MDS version at least 2.3.60"
17541
17542         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17543         touch $DIR/$tdir/spoo
17544         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17545         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17546                 error "cannot create/write a volatile file"
17547         [ "$FILESET" == "" ] &&
17548         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17549                 error "FID is still valid after close"
17550
17551         multiop_bg_pause $DIR/$tdir vVw4096_c
17552         local multi_pid=$!
17553
17554         local OLD_IFS=$IFS
17555         IFS=":"
17556         local fidv=($fid)
17557         IFS=$OLD_IFS
17558         # assume that the next FID for this client is sequential, since stdout
17559         # is unfortunately eaten by multiop_bg_pause
17560         local n=$((${fidv[1]} + 1))
17561         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17562         if [ "$FILESET" == "" ]; then
17563                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17564                         error "FID is missing before close"
17565         fi
17566         kill -USR1 $multi_pid
17567         # 1 second delay, so if mtime change we will see it
17568         sleep 1
17569         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17570         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17571 }
17572 run_test 185 "Volatile file support"
17573
17574 function create_check_volatile() {
17575         local idx=$1
17576         local tgt
17577
17578         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17579         local PID=$!
17580         sleep 1
17581         local FID=$(cat /tmp/${tfile}.fid)
17582         [ "$FID" == "" ] && error "can't get FID for volatile"
17583         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17584         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17585         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17586         kill -USR1 $PID
17587         wait
17588         sleep 1
17589         cancel_lru_locks mdc # flush opencache
17590         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17591         return 0
17592 }
17593
17594 test_185a(){
17595         # LU-12516 - volatile creation via .lustre
17596         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17597                 skip "Need MDS version at least 2.3.55"
17598
17599         create_check_volatile 0
17600         [ $MDSCOUNT -lt 2 ] && return 0
17601
17602         # DNE case
17603         create_check_volatile 1
17604
17605         return 0
17606 }
17607 run_test 185a "Volatile file creation in .lustre/fid/"
17608
17609 test_187a() {
17610         remote_mds_nodsh && skip "remote MDS with nodsh"
17611         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17612                 skip "Need MDS version at least 2.3.0"
17613
17614         local dir0=$DIR/$tdir/$testnum
17615         mkdir -p $dir0 || error "creating dir $dir0"
17616
17617         local file=$dir0/file1
17618         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17619         local dv1=$($LFS data_version $file)
17620         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17621         local dv2=$($LFS data_version $file)
17622         [[ $dv1 != $dv2 ]] ||
17623                 error "data version did not change on write $dv1 == $dv2"
17624
17625         # clean up
17626         rm -f $file1
17627 }
17628 run_test 187a "Test data version change"
17629
17630 test_187b() {
17631         remote_mds_nodsh && skip "remote MDS with nodsh"
17632         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17633                 skip "Need MDS version at least 2.3.0"
17634
17635         local dir0=$DIR/$tdir/$testnum
17636         mkdir -p $dir0 || error "creating dir $dir0"
17637
17638         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17639         [[ ${DV[0]} != ${DV[1]} ]] ||
17640                 error "data version did not change on write"\
17641                       " ${DV[0]} == ${DV[1]}"
17642
17643         # clean up
17644         rm -f $file1
17645 }
17646 run_test 187b "Test data version change on volatile file"
17647
17648 test_200() {
17649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17650         remote_mgs_nodsh && skip "remote MGS with nodsh"
17651         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17652
17653         local POOL=${POOL:-cea1}
17654         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17655         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17656         # Pool OST targets
17657         local first_ost=0
17658         local last_ost=$(($OSTCOUNT - 1))
17659         local ost_step=2
17660         local ost_list=$(seq $first_ost $ost_step $last_ost)
17661         local ost_range="$first_ost $last_ost $ost_step"
17662         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17663         local file_dir=$POOL_ROOT/file_tst
17664         local subdir=$test_path/subdir
17665         local rc=0
17666
17667         while : ; do
17668                 # former test_200a test_200b
17669                 pool_add $POOL                          || { rc=$? ; break; }
17670                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17671                 # former test_200c test_200d
17672                 mkdir -p $test_path
17673                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17674                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17675                 mkdir -p $subdir
17676                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17677                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17678                                                         || { rc=$? ; break; }
17679                 # former test_200e test_200f
17680                 local files=$((OSTCOUNT*3))
17681                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17682                                                         || { rc=$? ; break; }
17683                 pool_create_files $POOL $file_dir $files "$ost_list" \
17684                                                         || { rc=$? ; break; }
17685                 # former test_200g test_200h
17686                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17687                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17688
17689                 # former test_201a test_201b test_201c
17690                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17691
17692                 local f=$test_path/$tfile
17693                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17694                 pool_remove $POOL $f                    || { rc=$? ; break; }
17695                 break
17696         done
17697
17698         destroy_test_pools
17699
17700         return $rc
17701 }
17702 run_test 200 "OST pools"
17703
17704 # usage: default_attr <count | size | offset>
17705 default_attr() {
17706         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17707 }
17708
17709 # usage: check_default_stripe_attr
17710 check_default_stripe_attr() {
17711         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17712         case $1 in
17713         --stripe-count|-c)
17714                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17715         --stripe-size|-S)
17716                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17717         --stripe-index|-i)
17718                 EXPECTED=-1;;
17719         *)
17720                 error "unknown getstripe attr '$1'"
17721         esac
17722
17723         [ $ACTUAL == $EXPECTED ] ||
17724                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17725 }
17726
17727 test_204a() {
17728         test_mkdir $DIR/$tdir
17729         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17730
17731         check_default_stripe_attr --stripe-count
17732         check_default_stripe_attr --stripe-size
17733         check_default_stripe_attr --stripe-index
17734 }
17735 run_test 204a "Print default stripe attributes"
17736
17737 test_204b() {
17738         test_mkdir $DIR/$tdir
17739         $LFS setstripe --stripe-count 1 $DIR/$tdir
17740
17741         check_default_stripe_attr --stripe-size
17742         check_default_stripe_attr --stripe-index
17743 }
17744 run_test 204b "Print default stripe size and offset"
17745
17746 test_204c() {
17747         test_mkdir $DIR/$tdir
17748         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17749
17750         check_default_stripe_attr --stripe-count
17751         check_default_stripe_attr --stripe-index
17752 }
17753 run_test 204c "Print default stripe count and offset"
17754
17755 test_204d() {
17756         test_mkdir $DIR/$tdir
17757         $LFS setstripe --stripe-index 0 $DIR/$tdir
17758
17759         check_default_stripe_attr --stripe-count
17760         check_default_stripe_attr --stripe-size
17761 }
17762 run_test 204d "Print default stripe count and size"
17763
17764 test_204e() {
17765         test_mkdir $DIR/$tdir
17766         $LFS setstripe -d $DIR/$tdir
17767
17768         check_default_stripe_attr --stripe-count --raw
17769         check_default_stripe_attr --stripe-size --raw
17770         check_default_stripe_attr --stripe-index --raw
17771 }
17772 run_test 204e "Print raw stripe attributes"
17773
17774 test_204f() {
17775         test_mkdir $DIR/$tdir
17776         $LFS setstripe --stripe-count 1 $DIR/$tdir
17777
17778         check_default_stripe_attr --stripe-size --raw
17779         check_default_stripe_attr --stripe-index --raw
17780 }
17781 run_test 204f "Print raw stripe size and offset"
17782
17783 test_204g() {
17784         test_mkdir $DIR/$tdir
17785         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17786
17787         check_default_stripe_attr --stripe-count --raw
17788         check_default_stripe_attr --stripe-index --raw
17789 }
17790 run_test 204g "Print raw stripe count and offset"
17791
17792 test_204h() {
17793         test_mkdir $DIR/$tdir
17794         $LFS setstripe --stripe-index 0 $DIR/$tdir
17795
17796         check_default_stripe_attr --stripe-count --raw
17797         check_default_stripe_attr --stripe-size --raw
17798 }
17799 run_test 204h "Print raw stripe count and size"
17800
17801 # Figure out which job scheduler is being used, if any,
17802 # or use a fake one
17803 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17804         JOBENV=SLURM_JOB_ID
17805 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17806         JOBENV=LSB_JOBID
17807 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17808         JOBENV=PBS_JOBID
17809 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17810         JOBENV=LOADL_STEP_ID
17811 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17812         JOBENV=JOB_ID
17813 else
17814         $LCTL list_param jobid_name > /dev/null 2>&1
17815         if [ $? -eq 0 ]; then
17816                 JOBENV=nodelocal
17817         else
17818                 JOBENV=FAKE_JOBID
17819         fi
17820 fi
17821 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17822
17823 verify_jobstats() {
17824         local cmd=($1)
17825         shift
17826         local facets="$@"
17827
17828 # we don't really need to clear the stats for this test to work, since each
17829 # command has a unique jobid, but it makes debugging easier if needed.
17830 #       for facet in $facets; do
17831 #               local dev=$(convert_facet2label $facet)
17832 #               # clear old jobstats
17833 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17834 #       done
17835
17836         # use a new JobID for each test, or we might see an old one
17837         [ "$JOBENV" = "FAKE_JOBID" ] &&
17838                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17839
17840         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17841
17842         [ "$JOBENV" = "nodelocal" ] && {
17843                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17844                 $LCTL set_param jobid_name=$FAKE_JOBID
17845                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17846         }
17847
17848         log "Test: ${cmd[*]}"
17849         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17850
17851         if [ $JOBENV = "FAKE_JOBID" ]; then
17852                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17853         else
17854                 ${cmd[*]}
17855         fi
17856
17857         # all files are created on OST0000
17858         for facet in $facets; do
17859                 local stats="*.$(convert_facet2label $facet).job_stats"
17860
17861                 # strip out libtool wrappers for in-tree executables
17862                 if [ $(do_facet $facet lctl get_param $stats |
17863                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17864                         do_facet $facet lctl get_param $stats
17865                         error "No jobstats for $JOBVAL found on $facet::$stats"
17866                 fi
17867         done
17868 }
17869
17870 jobstats_set() {
17871         local new_jobenv=$1
17872
17873         set_persistent_param_and_check client "jobid_var" \
17874                 "$FSNAME.sys.jobid_var" $new_jobenv
17875 }
17876
17877 test_205a() { # Job stats
17878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17879         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17880                 skip "Need MDS version with at least 2.7.1"
17881         remote_mgs_nodsh && skip "remote MGS with nodsh"
17882         remote_mds_nodsh && skip "remote MDS with nodsh"
17883         remote_ost_nodsh && skip "remote OST with nodsh"
17884         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17885                 skip "Server doesn't support jobstats"
17886         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17887
17888         local old_jobenv=$($LCTL get_param -n jobid_var)
17889         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17890
17891         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17892                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17893         else
17894                 stack_trap "do_facet mgs $PERM_CMD \
17895                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17896         fi
17897         changelog_register
17898
17899         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17900                                 mdt.*.job_cleanup_interval | head -n 1)
17901         local new_interval=5
17902         do_facet $SINGLEMDS \
17903                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17904         stack_trap "do_facet $SINGLEMDS \
17905                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17906         local start=$SECONDS
17907
17908         local cmd
17909         # mkdir
17910         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17911         verify_jobstats "$cmd" "$SINGLEMDS"
17912         # rmdir
17913         cmd="rmdir $DIR/$tdir"
17914         verify_jobstats "$cmd" "$SINGLEMDS"
17915         # mkdir on secondary MDT
17916         if [ $MDSCOUNT -gt 1 ]; then
17917                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17918                 verify_jobstats "$cmd" "mds2"
17919         fi
17920         # mknod
17921         cmd="mknod $DIR/$tfile c 1 3"
17922         verify_jobstats "$cmd" "$SINGLEMDS"
17923         # unlink
17924         cmd="rm -f $DIR/$tfile"
17925         verify_jobstats "$cmd" "$SINGLEMDS"
17926         # create all files on OST0000 so verify_jobstats can find OST stats
17927         # open & close
17928         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17929         verify_jobstats "$cmd" "$SINGLEMDS"
17930         # setattr
17931         cmd="touch $DIR/$tfile"
17932         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17933         # write
17934         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17935         verify_jobstats "$cmd" "ost1"
17936         # read
17937         cancel_lru_locks osc
17938         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17939         verify_jobstats "$cmd" "ost1"
17940         # truncate
17941         cmd="$TRUNCATE $DIR/$tfile 0"
17942         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17943         # rename
17944         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17945         verify_jobstats "$cmd" "$SINGLEMDS"
17946         # jobstats expiry - sleep until old stats should be expired
17947         local left=$((new_interval + 5 - (SECONDS - start)))
17948         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17949                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17950                         "0" $left
17951         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17952         verify_jobstats "$cmd" "$SINGLEMDS"
17953         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17954             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17955
17956         # Ensure that jobid are present in changelog (if supported by MDS)
17957         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17958                 changelog_dump | tail -10
17959                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17960                 [ $jobids -eq 9 ] ||
17961                         error "Wrong changelog jobid count $jobids != 9"
17962
17963                 # LU-5862
17964                 JOBENV="disable"
17965                 jobstats_set $JOBENV
17966                 touch $DIR/$tfile
17967                 changelog_dump | grep $tfile
17968                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17969                 [ $jobids -eq 0 ] ||
17970                         error "Unexpected jobids when jobid_var=$JOBENV"
17971         fi
17972
17973         # test '%j' access to environment variable - if supported
17974         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17975                 JOBENV="JOBCOMPLEX"
17976                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17977
17978                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17979         fi
17980
17981         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17982                 JOBENV="JOBCOMPLEX"
17983                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17984
17985                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17986         fi
17987
17988         # test '%j' access to per-session jobid - if supported
17989         if lctl list_param jobid_this_session > /dev/null 2>&1
17990         then
17991                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17992                 lctl set_param jobid_this_session=$USER
17993
17994                 JOBENV="JOBCOMPLEX"
17995                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17996
17997                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17998         fi
17999 }
18000 run_test 205a "Verify job stats"
18001
18002 # LU-13117, LU-13597
18003 test_205b() {
18004         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18005                 skip "Need MDS version at least 2.13.54.91"
18006
18007         job_stats="mdt.*.job_stats"
18008         $LCTL set_param $job_stats=clear
18009         # Setting jobid_var to USER might not be supported
18010         $LCTL set_param jobid_var=USER || true
18011         $LCTL set_param jobid_name="%e.%u"
18012         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18013         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18014                 grep "job_id:.*foolish" &&
18015                         error "Unexpected jobid found"
18016         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18017                 grep "open:.*min.*max.*sum" ||
18018                         error "wrong job_stats format found"
18019 }
18020 run_test 205b "Verify job stats jobid and output format"
18021
18022 # LU-13733
18023 test_205c() {
18024         $LCTL set_param llite.*.stats=0
18025         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18026         $LCTL get_param llite.*.stats
18027         $LCTL get_param llite.*.stats | grep \
18028                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18029                         error "wrong client stats format found"
18030 }
18031 run_test 205c "Verify client stats format"
18032
18033 # LU-1480, LU-1773 and LU-1657
18034 test_206() {
18035         mkdir -p $DIR/$tdir
18036         $LFS setstripe -c -1 $DIR/$tdir
18037 #define OBD_FAIL_LOV_INIT 0x1403
18038         $LCTL set_param fail_loc=0xa0001403
18039         $LCTL set_param fail_val=1
18040         touch $DIR/$tdir/$tfile || true
18041 }
18042 run_test 206 "fail lov_init_raid0() doesn't lbug"
18043
18044 test_207a() {
18045         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18046         local fsz=`stat -c %s $DIR/$tfile`
18047         cancel_lru_locks mdc
18048
18049         # do not return layout in getattr intent
18050 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18051         $LCTL set_param fail_loc=0x170
18052         local sz=`stat -c %s $DIR/$tfile`
18053
18054         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18055
18056         rm -rf $DIR/$tfile
18057 }
18058 run_test 207a "can refresh layout at glimpse"
18059
18060 test_207b() {
18061         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18062         local cksum=`md5sum $DIR/$tfile`
18063         local fsz=`stat -c %s $DIR/$tfile`
18064         cancel_lru_locks mdc
18065         cancel_lru_locks osc
18066
18067         # do not return layout in getattr intent
18068 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18069         $LCTL set_param fail_loc=0x171
18070
18071         # it will refresh layout after the file is opened but before read issues
18072         echo checksum is "$cksum"
18073         echo "$cksum" |md5sum -c --quiet || error "file differs"
18074
18075         rm -rf $DIR/$tfile
18076 }
18077 run_test 207b "can refresh layout at open"
18078
18079 test_208() {
18080         # FIXME: in this test suite, only RD lease is used. This is okay
18081         # for now as only exclusive open is supported. After generic lease
18082         # is done, this test suite should be revised. - Jinshan
18083
18084         remote_mds_nodsh && skip "remote MDS with nodsh"
18085         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18086                 skip "Need MDS version at least 2.4.52"
18087
18088         echo "==== test 1: verify get lease work"
18089         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18090
18091         echo "==== test 2: verify lease can be broken by upcoming open"
18092         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18093         local PID=$!
18094         sleep 1
18095
18096         $MULTIOP $DIR/$tfile oO_RDONLY:c
18097         kill -USR1 $PID && wait $PID || error "break lease error"
18098
18099         echo "==== test 3: verify lease can't be granted if an open already exists"
18100         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
18101         local PID=$!
18102         sleep 1
18103
18104         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
18105         kill -USR1 $PID && wait $PID || error "open file error"
18106
18107         echo "==== test 4: lease can sustain over recovery"
18108         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18109         PID=$!
18110         sleep 1
18111
18112         fail mds1
18113
18114         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18115
18116         echo "==== test 5: lease broken can't be regained by replay"
18117         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18118         PID=$!
18119         sleep 1
18120
18121         # open file to break lease and then recovery
18122         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18123         fail mds1
18124
18125         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18126
18127         rm -f $DIR/$tfile
18128 }
18129 run_test 208 "Exclusive open"
18130
18131 test_209() {
18132         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18133                 skip_env "must have disp_stripe"
18134
18135         touch $DIR/$tfile
18136         sync; sleep 5; sync;
18137
18138         echo 3 > /proc/sys/vm/drop_caches
18139         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18140                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18141         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18142
18143         # open/close 500 times
18144         for i in $(seq 500); do
18145                 cat $DIR/$tfile
18146         done
18147
18148         echo 3 > /proc/sys/vm/drop_caches
18149         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18150                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18151         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18152
18153         echo "before: $req_before, after: $req_after"
18154         [ $((req_after - req_before)) -ge 300 ] &&
18155                 error "open/close requests are not freed"
18156         return 0
18157 }
18158 run_test 209 "read-only open/close requests should be freed promptly"
18159
18160 test_210() {
18161         local pid
18162
18163         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18164         pid=$!
18165         sleep 1
18166
18167         $LFS getstripe $DIR/$tfile
18168         kill -USR1 $pid
18169         wait $pid || error "multiop failed"
18170
18171         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18172         pid=$!
18173         sleep 1
18174
18175         $LFS getstripe $DIR/$tfile
18176         kill -USR1 $pid
18177         wait $pid || error "multiop failed"
18178 }
18179 run_test 210 "lfs getstripe does not break leases"
18180
18181 test_212() {
18182         size=`date +%s`
18183         size=$((size % 8192 + 1))
18184         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18185         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18186         rm -f $DIR/f212 $DIR/f212.xyz
18187 }
18188 run_test 212 "Sendfile test ============================================"
18189
18190 test_213() {
18191         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18192         cancel_lru_locks osc
18193         lctl set_param fail_loc=0x8000040f
18194         # generate a read lock
18195         cat $DIR/$tfile > /dev/null
18196         # write to the file, it will try to cancel the above read lock.
18197         cat /etc/hosts >> $DIR/$tfile
18198 }
18199 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18200
18201 test_214() { # for bug 20133
18202         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18203         for (( i=0; i < 340; i++ )) ; do
18204                 touch $DIR/$tdir/d214c/a$i
18205         done
18206
18207         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18208         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18209         ls $DIR/d214c || error "ls $DIR/d214c failed"
18210         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18211         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18212 }
18213 run_test 214 "hash-indexed directory test - bug 20133"
18214
18215 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18216 create_lnet_proc_files() {
18217         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18218 }
18219
18220 # counterpart of create_lnet_proc_files
18221 remove_lnet_proc_files() {
18222         rm -f $TMP/lnet_$1.sys
18223 }
18224
18225 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18226 # 3rd arg as regexp for body
18227 check_lnet_proc_stats() {
18228         local l=$(cat "$TMP/lnet_$1" |wc -l)
18229         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18230
18231         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18232 }
18233
18234 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18235 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18236 # optional and can be regexp for 2nd line (lnet.routes case)
18237 check_lnet_proc_entry() {
18238         local blp=2          # blp stands for 'position of 1st line of body'
18239         [ -z "$5" ] || blp=3 # lnet.routes case
18240
18241         local l=$(cat "$TMP/lnet_$1" |wc -l)
18242         # subtracting one from $blp because the body can be empty
18243         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18244
18245         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18246                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18247
18248         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18249                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18250
18251         # bail out if any unexpected line happened
18252         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18253         [ "$?" != 0 ] || error "$2 misformatted"
18254 }
18255
18256 test_215() { # for bugs 18102, 21079, 21517
18257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18258
18259         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18260         local P='[1-9][0-9]*'           # positive numeric
18261         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18262         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18263         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18264         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18265
18266         local L1 # regexp for 1st line
18267         local L2 # regexp for 2nd line (optional)
18268         local BR # regexp for the rest (body)
18269
18270         # lnet.stats should look as 11 space-separated non-negative numerics
18271         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18272         create_lnet_proc_files "stats"
18273         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18274         remove_lnet_proc_files "stats"
18275
18276         # lnet.routes should look like this:
18277         # Routing disabled/enabled
18278         # net hops priority state router
18279         # where net is a string like tcp0, hops > 0, priority >= 0,
18280         # state is up/down,
18281         # router is a string like 192.168.1.1@tcp2
18282         L1="^Routing (disabled|enabled)$"
18283         L2="^net +hops +priority +state +router$"
18284         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18285         create_lnet_proc_files "routes"
18286         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18287         remove_lnet_proc_files "routes"
18288
18289         # lnet.routers should look like this:
18290         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18291         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18292         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18293         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18294         L1="^ref +rtr_ref +alive +router$"
18295         BR="^$P +$P +(up|down) +$NID$"
18296         create_lnet_proc_files "routers"
18297         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18298         remove_lnet_proc_files "routers"
18299
18300         # lnet.peers should look like this:
18301         # nid refs state last max rtr min tx min queue
18302         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18303         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18304         # numeric (0 or >0 or <0), queue >= 0.
18305         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18306         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18307         create_lnet_proc_files "peers"
18308         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18309         remove_lnet_proc_files "peers"
18310
18311         # lnet.buffers  should look like this:
18312         # pages count credits min
18313         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18314         L1="^pages +count +credits +min$"
18315         BR="^ +$N +$N +$I +$I$"
18316         create_lnet_proc_files "buffers"
18317         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18318         remove_lnet_proc_files "buffers"
18319
18320         # lnet.nis should look like this:
18321         # nid status alive refs peer rtr max tx min
18322         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18323         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18324         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18325         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18326         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18327         create_lnet_proc_files "nis"
18328         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18329         remove_lnet_proc_files "nis"
18330
18331         # can we successfully write to lnet.stats?
18332         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18333 }
18334 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18335
18336 test_216() { # bug 20317
18337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18338         remote_ost_nodsh && skip "remote OST with nodsh"
18339
18340         local node
18341         local facets=$(get_facets OST)
18342         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18343
18344         save_lustre_params client "osc.*.contention_seconds" > $p
18345         save_lustre_params $facets \
18346                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18347         save_lustre_params $facets \
18348                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18349         save_lustre_params $facets \
18350                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18351         clear_stats osc.*.osc_stats
18352
18353         # agressive lockless i/o settings
18354         do_nodes $(comma_list $(osts_nodes)) \
18355                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18356                         ldlm.namespaces.filter-*.contended_locks=0 \
18357                         ldlm.namespaces.filter-*.contention_seconds=60"
18358         lctl set_param -n osc.*.contention_seconds=60
18359
18360         $DIRECTIO write $DIR/$tfile 0 10 4096
18361         $CHECKSTAT -s 40960 $DIR/$tfile
18362
18363         # disable lockless i/o
18364         do_nodes $(comma_list $(osts_nodes)) \
18365                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18366                         ldlm.namespaces.filter-*.contended_locks=32 \
18367                         ldlm.namespaces.filter-*.contention_seconds=0"
18368         lctl set_param -n osc.*.contention_seconds=0
18369         clear_stats osc.*.osc_stats
18370
18371         dd if=/dev/zero of=$DIR/$tfile count=0
18372         $CHECKSTAT -s 0 $DIR/$tfile
18373
18374         restore_lustre_params <$p
18375         rm -f $p
18376         rm $DIR/$tfile
18377 }
18378 run_test 216 "check lockless direct write updates file size and kms correctly"
18379
18380 test_217() { # bug 22430
18381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18382
18383         local node
18384         local nid
18385
18386         for node in $(nodes_list); do
18387                 nid=$(host_nids_address $node $NETTYPE)
18388                 if [[ $nid = *-* ]] ; then
18389                         echo "lctl ping $(h2nettype $nid)"
18390                         lctl ping $(h2nettype $nid)
18391                 else
18392                         echo "skipping $node (no hyphen detected)"
18393                 fi
18394         done
18395 }
18396 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18397
18398 test_218() {
18399        # do directio so as not to populate the page cache
18400        log "creating a 10 Mb file"
18401        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18402        log "starting reads"
18403        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18404        log "truncating the file"
18405        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18406        log "killing dd"
18407        kill %+ || true # reads might have finished
18408        echo "wait until dd is finished"
18409        wait
18410        log "removing the temporary file"
18411        rm -rf $DIR/$tfile || error "tmp file removal failed"
18412 }
18413 run_test 218 "parallel read and truncate should not deadlock"
18414
18415 test_219() {
18416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18417
18418         # write one partial page
18419         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18420         # set no grant so vvp_io_commit_write will do sync write
18421         $LCTL set_param fail_loc=0x411
18422         # write a full page at the end of file
18423         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18424
18425         $LCTL set_param fail_loc=0
18426         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18427         $LCTL set_param fail_loc=0x411
18428         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18429
18430         # LU-4201
18431         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18432         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18433 }
18434 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18435
18436 test_220() { #LU-325
18437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18438         remote_ost_nodsh && skip "remote OST with nodsh"
18439         remote_mds_nodsh && skip "remote MDS with nodsh"
18440         remote_mgs_nodsh && skip "remote MGS with nodsh"
18441
18442         local OSTIDX=0
18443
18444         # create on MDT0000 so the last_id and next_id are correct
18445         mkdir_on_mdt0 $DIR/$tdir
18446         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18447         OST=${OST%_UUID}
18448
18449         # on the mdt's osc
18450         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18451         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18452                         osp.$mdtosc_proc1.prealloc_last_id)
18453         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18454                         osp.$mdtosc_proc1.prealloc_next_id)
18455
18456         $LFS df -i
18457
18458         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18459         #define OBD_FAIL_OST_ENOINO              0x229
18460         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18461         create_pool $FSNAME.$TESTNAME || return 1
18462         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18463
18464         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18465
18466         MDSOBJS=$((last_id - next_id))
18467         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18468
18469         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18470         echo "OST still has $count kbytes free"
18471
18472         echo "create $MDSOBJS files @next_id..."
18473         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18474
18475         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18476                         osp.$mdtosc_proc1.prealloc_last_id)
18477         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18478                         osp.$mdtosc_proc1.prealloc_next_id)
18479
18480         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18481         $LFS df -i
18482
18483         echo "cleanup..."
18484
18485         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18486         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18487
18488         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18489                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18490         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18491                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18492         echo "unlink $MDSOBJS files @$next_id..."
18493         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18494 }
18495 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18496
18497 test_221() {
18498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18499
18500         dd if=`which date` of=$MOUNT/date oflag=sync
18501         chmod +x $MOUNT/date
18502
18503         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18504         $LCTL set_param fail_loc=0x80001401
18505
18506         $MOUNT/date > /dev/null
18507         rm -f $MOUNT/date
18508 }
18509 run_test 221 "make sure fault and truncate race to not cause OOM"
18510
18511 test_222a () {
18512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18513
18514         rm -rf $DIR/$tdir
18515         test_mkdir $DIR/$tdir
18516         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18517         createmany -o $DIR/$tdir/$tfile 10
18518         cancel_lru_locks mdc
18519         cancel_lru_locks osc
18520         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18521         $LCTL set_param fail_loc=0x31a
18522         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18523         $LCTL set_param fail_loc=0
18524         rm -r $DIR/$tdir
18525 }
18526 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18527
18528 test_222b () {
18529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18530
18531         rm -rf $DIR/$tdir
18532         test_mkdir $DIR/$tdir
18533         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18534         createmany -o $DIR/$tdir/$tfile 10
18535         cancel_lru_locks mdc
18536         cancel_lru_locks osc
18537         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18538         $LCTL set_param fail_loc=0x31a
18539         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18540         $LCTL set_param fail_loc=0
18541 }
18542 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18543
18544 test_223 () {
18545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18546
18547         rm -rf $DIR/$tdir
18548         test_mkdir $DIR/$tdir
18549         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18550         createmany -o $DIR/$tdir/$tfile 10
18551         cancel_lru_locks mdc
18552         cancel_lru_locks osc
18553         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18554         $LCTL set_param fail_loc=0x31b
18555         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18556         $LCTL set_param fail_loc=0
18557         rm -r $DIR/$tdir
18558 }
18559 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18560
18561 test_224a() { # LU-1039, MRP-303
18562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18563
18564         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18565         $LCTL set_param fail_loc=0x508
18566         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18567         $LCTL set_param fail_loc=0
18568         df $DIR
18569 }
18570 run_test 224a "Don't panic on bulk IO failure"
18571
18572 test_224b() { # LU-1039, MRP-303
18573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18574
18575         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18576         cancel_lru_locks osc
18577         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18578         $LCTL set_param fail_loc=0x515
18579         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18580         $LCTL set_param fail_loc=0
18581         df $DIR
18582 }
18583 run_test 224b "Don't panic on bulk IO failure"
18584
18585 test_224c() { # LU-6441
18586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18587         remote_mds_nodsh && skip "remote MDS with nodsh"
18588
18589         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18590         save_writethrough $p
18591         set_cache writethrough on
18592
18593         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18594         local at_max=$($LCTL get_param -n at_max)
18595         local timeout=$($LCTL get_param -n timeout)
18596         local test_at="at_max"
18597         local param_at="$FSNAME.sys.at_max"
18598         local test_timeout="timeout"
18599         local param_timeout="$FSNAME.sys.timeout"
18600
18601         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18602
18603         set_persistent_param_and_check client "$test_at" "$param_at" 0
18604         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18605
18606         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18607         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18608         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18609         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18610         sync
18611         do_facet ost1 "$LCTL set_param fail_loc=0"
18612
18613         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18614         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18615                 $timeout
18616
18617         $LCTL set_param -n $pages_per_rpc
18618         restore_lustre_params < $p
18619         rm -f $p
18620 }
18621 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18622
18623 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18624 test_225a () {
18625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18626         if [ -z ${MDSSURVEY} ]; then
18627                 skip_env "mds-survey not found"
18628         fi
18629         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18630                 skip "Need MDS version at least 2.2.51"
18631
18632         local mds=$(facet_host $SINGLEMDS)
18633         local target=$(do_nodes $mds 'lctl dl' |
18634                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18635
18636         local cmd1="file_count=1000 thrhi=4"
18637         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18638         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18639         local cmd="$cmd1 $cmd2 $cmd3"
18640
18641         rm -f ${TMP}/mds_survey*
18642         echo + $cmd
18643         eval $cmd || error "mds-survey with zero-stripe failed"
18644         cat ${TMP}/mds_survey*
18645         rm -f ${TMP}/mds_survey*
18646 }
18647 run_test 225a "Metadata survey sanity with zero-stripe"
18648
18649 test_225b () {
18650         if [ -z ${MDSSURVEY} ]; then
18651                 skip_env "mds-survey not found"
18652         fi
18653         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18654                 skip "Need MDS version at least 2.2.51"
18655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18656         remote_mds_nodsh && skip "remote MDS with nodsh"
18657         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18658                 skip_env "Need to mount OST to test"
18659         fi
18660
18661         local mds=$(facet_host $SINGLEMDS)
18662         local target=$(do_nodes $mds 'lctl dl' |
18663                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18664
18665         local cmd1="file_count=1000 thrhi=4"
18666         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18667         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18668         local cmd="$cmd1 $cmd2 $cmd3"
18669
18670         rm -f ${TMP}/mds_survey*
18671         echo + $cmd
18672         eval $cmd || error "mds-survey with stripe_count failed"
18673         cat ${TMP}/mds_survey*
18674         rm -f ${TMP}/mds_survey*
18675 }
18676 run_test 225b "Metadata survey sanity with stripe_count = 1"
18677
18678 mcreate_path2fid () {
18679         local mode=$1
18680         local major=$2
18681         local minor=$3
18682         local name=$4
18683         local desc=$5
18684         local path=$DIR/$tdir/$name
18685         local fid
18686         local rc
18687         local fid_path
18688
18689         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18690                 error "cannot create $desc"
18691
18692         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18693         rc=$?
18694         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18695
18696         fid_path=$($LFS fid2path $MOUNT $fid)
18697         rc=$?
18698         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18699
18700         [ "$path" == "$fid_path" ] ||
18701                 error "fid2path returned $fid_path, expected $path"
18702
18703         echo "pass with $path and $fid"
18704 }
18705
18706 test_226a () {
18707         rm -rf $DIR/$tdir
18708         mkdir -p $DIR/$tdir
18709
18710         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18711         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18712         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18713         mcreate_path2fid 0040666 0 0 dir "directory"
18714         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18715         mcreate_path2fid 0100666 0 0 file "regular file"
18716         mcreate_path2fid 0120666 0 0 link "symbolic link"
18717         mcreate_path2fid 0140666 0 0 sock "socket"
18718 }
18719 run_test 226a "call path2fid and fid2path on files of all type"
18720
18721 test_226b () {
18722         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18723
18724         local MDTIDX=1
18725
18726         rm -rf $DIR/$tdir
18727         mkdir -p $DIR/$tdir
18728         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18729                 error "create remote directory failed"
18730         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18731         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18732                                 "character special file (null)"
18733         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18734                                 "character special file (no device)"
18735         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18736         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18737                                 "block special file (loop)"
18738         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18739         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18740         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18741 }
18742 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18743
18744 test_226c () {
18745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18746         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18747                 skip "Need MDS version at least 2.13.55"
18748
18749         local submnt=/mnt/submnt
18750         local srcfile=/etc/passwd
18751         local dstfile=$submnt/passwd
18752         local path
18753         local fid
18754
18755         rm -rf $DIR/$tdir
18756         rm -rf $submnt
18757         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18758                 error "create remote directory failed"
18759         mkdir -p $submnt || error "create $submnt failed"
18760         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18761                 error "mount $submnt failed"
18762         stack_trap "umount $submnt" EXIT
18763
18764         cp $srcfile $dstfile
18765         fid=$($LFS path2fid $dstfile)
18766         path=$($LFS fid2path $submnt "$fid")
18767         [ "$path" = "$dstfile" ] ||
18768                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18769 }
18770 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18771
18772 # LU-1299 Executing or running ldd on a truncated executable does not
18773 # cause an out-of-memory condition.
18774 test_227() {
18775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18776         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18777
18778         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18779         chmod +x $MOUNT/date
18780
18781         $MOUNT/date > /dev/null
18782         ldd $MOUNT/date > /dev/null
18783         rm -f $MOUNT/date
18784 }
18785 run_test 227 "running truncated executable does not cause OOM"
18786
18787 # LU-1512 try to reuse idle OI blocks
18788 test_228a() {
18789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18790         remote_mds_nodsh && skip "remote MDS with nodsh"
18791         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18792
18793         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18794         local myDIR=$DIR/$tdir
18795
18796         mkdir -p $myDIR
18797         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18798         $LCTL set_param fail_loc=0x80001002
18799         createmany -o $myDIR/t- 10000
18800         $LCTL set_param fail_loc=0
18801         # The guard is current the largest FID holder
18802         touch $myDIR/guard
18803         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18804                     tr -d '[')
18805         local IDX=$(($SEQ % 64))
18806
18807         do_facet $SINGLEMDS sync
18808         # Make sure journal flushed.
18809         sleep 6
18810         local blk1=$(do_facet $SINGLEMDS \
18811                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18812                      grep Blockcount | awk '{print $4}')
18813
18814         # Remove old files, some OI blocks will become idle.
18815         unlinkmany $myDIR/t- 10000
18816         # Create new files, idle OI blocks should be reused.
18817         createmany -o $myDIR/t- 2000
18818         do_facet $SINGLEMDS sync
18819         # Make sure journal flushed.
18820         sleep 6
18821         local blk2=$(do_facet $SINGLEMDS \
18822                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18823                      grep Blockcount | awk '{print $4}')
18824
18825         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18826 }
18827 run_test 228a "try to reuse idle OI blocks"
18828
18829 test_228b() {
18830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18831         remote_mds_nodsh && skip "remote MDS with nodsh"
18832         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18833
18834         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18835         local myDIR=$DIR/$tdir
18836
18837         mkdir -p $myDIR
18838         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18839         $LCTL set_param fail_loc=0x80001002
18840         createmany -o $myDIR/t- 10000
18841         $LCTL set_param fail_loc=0
18842         # The guard is current the largest FID holder
18843         touch $myDIR/guard
18844         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18845                     tr -d '[')
18846         local IDX=$(($SEQ % 64))
18847
18848         do_facet $SINGLEMDS sync
18849         # Make sure journal flushed.
18850         sleep 6
18851         local blk1=$(do_facet $SINGLEMDS \
18852                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18853                      grep Blockcount | awk '{print $4}')
18854
18855         # Remove old files, some OI blocks will become idle.
18856         unlinkmany $myDIR/t- 10000
18857
18858         # stop the MDT
18859         stop $SINGLEMDS || error "Fail to stop MDT."
18860         # remount the MDT
18861         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18862
18863         df $MOUNT || error "Fail to df."
18864         # Create new files, idle OI blocks should be reused.
18865         createmany -o $myDIR/t- 2000
18866         do_facet $SINGLEMDS sync
18867         # Make sure journal flushed.
18868         sleep 6
18869         local blk2=$(do_facet $SINGLEMDS \
18870                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18871                      grep Blockcount | awk '{print $4}')
18872
18873         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18874 }
18875 run_test 228b "idle OI blocks can be reused after MDT restart"
18876
18877 #LU-1881
18878 test_228c() {
18879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18880         remote_mds_nodsh && skip "remote MDS with nodsh"
18881         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18882
18883         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18884         local myDIR=$DIR/$tdir
18885
18886         mkdir -p $myDIR
18887         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18888         $LCTL set_param fail_loc=0x80001002
18889         # 20000 files can guarantee there are index nodes in the OI file
18890         createmany -o $myDIR/t- 20000
18891         $LCTL set_param fail_loc=0
18892         # The guard is current the largest FID holder
18893         touch $myDIR/guard
18894         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18895                     tr -d '[')
18896         local IDX=$(($SEQ % 64))
18897
18898         do_facet $SINGLEMDS sync
18899         # Make sure journal flushed.
18900         sleep 6
18901         local blk1=$(do_facet $SINGLEMDS \
18902                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18903                      grep Blockcount | awk '{print $4}')
18904
18905         # Remove old files, some OI blocks will become idle.
18906         unlinkmany $myDIR/t- 20000
18907         rm -f $myDIR/guard
18908         # The OI file should become empty now
18909
18910         # Create new files, idle OI blocks should be reused.
18911         createmany -o $myDIR/t- 2000
18912         do_facet $SINGLEMDS sync
18913         # Make sure journal flushed.
18914         sleep 6
18915         local blk2=$(do_facet $SINGLEMDS \
18916                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18917                      grep Blockcount | awk '{print $4}')
18918
18919         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18920 }
18921 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18922
18923 test_229() { # LU-2482, LU-3448
18924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18925         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18926         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18927                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18928
18929         rm -f $DIR/$tfile
18930
18931         # Create a file with a released layout and stripe count 2.
18932         $MULTIOP $DIR/$tfile H2c ||
18933                 error "failed to create file with released layout"
18934
18935         $LFS getstripe -v $DIR/$tfile
18936
18937         local pattern=$($LFS getstripe -L $DIR/$tfile)
18938         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18939
18940         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18941                 error "getstripe"
18942         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18943         stat $DIR/$tfile || error "failed to stat released file"
18944
18945         chown $RUNAS_ID $DIR/$tfile ||
18946                 error "chown $RUNAS_ID $DIR/$tfile failed"
18947
18948         chgrp $RUNAS_ID $DIR/$tfile ||
18949                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18950
18951         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18952         rm $DIR/$tfile || error "failed to remove released file"
18953 }
18954 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18955
18956 test_230a() {
18957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18959         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18960                 skip "Need MDS version at least 2.11.52"
18961
18962         local MDTIDX=1
18963
18964         test_mkdir $DIR/$tdir
18965         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18966         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18967         [ $mdt_idx -ne 0 ] &&
18968                 error "create local directory on wrong MDT $mdt_idx"
18969
18970         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18971                         error "create remote directory failed"
18972         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18973         [ $mdt_idx -ne $MDTIDX ] &&
18974                 error "create remote directory on wrong MDT $mdt_idx"
18975
18976         createmany -o $DIR/$tdir/test_230/t- 10 ||
18977                 error "create files on remote directory failed"
18978         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18979         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18980         rm -r $DIR/$tdir || error "unlink remote directory failed"
18981 }
18982 run_test 230a "Create remote directory and files under the remote directory"
18983
18984 test_230b() {
18985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18987         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18988                 skip "Need MDS version at least 2.11.52"
18989
18990         local MDTIDX=1
18991         local mdt_index
18992         local i
18993         local file
18994         local pid
18995         local stripe_count
18996         local migrate_dir=$DIR/$tdir/migrate_dir
18997         local other_dir=$DIR/$tdir/other_dir
18998
18999         test_mkdir $DIR/$tdir
19000         test_mkdir -i0 -c1 $migrate_dir
19001         test_mkdir -i0 -c1 $other_dir
19002         for ((i=0; i<10; i++)); do
19003                 mkdir -p $migrate_dir/dir_${i}
19004                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19005                         error "create files under remote dir failed $i"
19006         done
19007
19008         cp /etc/passwd $migrate_dir/$tfile
19009         cp /etc/passwd $other_dir/$tfile
19010         chattr +SAD $migrate_dir
19011         chattr +SAD $migrate_dir/$tfile
19012
19013         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19014         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19015         local old_dir_mode=$(stat -c%f $migrate_dir)
19016         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19017
19018         mkdir -p $migrate_dir/dir_default_stripe2
19019         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19020         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19021
19022         mkdir -p $other_dir
19023         ln $migrate_dir/$tfile $other_dir/luna
19024         ln $migrate_dir/$tfile $migrate_dir/sofia
19025         ln $other_dir/$tfile $migrate_dir/david
19026         ln -s $migrate_dir/$tfile $other_dir/zachary
19027         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19028         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19029
19030         local len
19031         local lnktgt
19032
19033         # inline symlink
19034         for len in 58 59 60; do
19035                 lnktgt=$(str_repeat 'l' $len)
19036                 touch $migrate_dir/$lnktgt
19037                 ln -s $lnktgt $migrate_dir/${len}char_ln
19038         done
19039
19040         # PATH_MAX
19041         for len in 4094 4095; do
19042                 lnktgt=$(str_repeat 'l' $len)
19043                 ln -s $lnktgt $migrate_dir/${len}char_ln
19044         done
19045
19046         # NAME_MAX
19047         for len in 254 255; do
19048                 touch $migrate_dir/$(str_repeat 'l' $len)
19049         done
19050
19051         $LFS migrate -m $MDTIDX $migrate_dir ||
19052                 error "fails on migrating remote dir to MDT1"
19053
19054         echo "migratate to MDT1, then checking.."
19055         for ((i = 0; i < 10; i++)); do
19056                 for file in $(find $migrate_dir/dir_${i}); do
19057                         mdt_index=$($LFS getstripe -m $file)
19058                         # broken symlink getstripe will fail
19059                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19060                                 error "$file is not on MDT${MDTIDX}"
19061                 done
19062         done
19063
19064         # the multiple link file should still in MDT0
19065         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19066         [ $mdt_index == 0 ] ||
19067                 error "$file is not on MDT${MDTIDX}"
19068
19069         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19070         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19071                 error " expect $old_dir_flag get $new_dir_flag"
19072
19073         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19074         [ "$old_file_flag" = "$new_file_flag" ] ||
19075                 error " expect $old_file_flag get $new_file_flag"
19076
19077         local new_dir_mode=$(stat -c%f $migrate_dir)
19078         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19079                 error "expect mode $old_dir_mode get $new_dir_mode"
19080
19081         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19082         [ "$old_file_mode" = "$new_file_mode" ] ||
19083                 error "expect mode $old_file_mode get $new_file_mode"
19084
19085         diff /etc/passwd $migrate_dir/$tfile ||
19086                 error "$tfile different after migration"
19087
19088         diff /etc/passwd $other_dir/luna ||
19089                 error "luna different after migration"
19090
19091         diff /etc/passwd $migrate_dir/sofia ||
19092                 error "sofia different after migration"
19093
19094         diff /etc/passwd $migrate_dir/david ||
19095                 error "david different after migration"
19096
19097         diff /etc/passwd $other_dir/zachary ||
19098                 error "zachary different after migration"
19099
19100         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19101                 error "${tfile}_ln different after migration"
19102
19103         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19104                 error "${tfile}_ln_other different after migration"
19105
19106         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19107         [ $stripe_count = 2 ] ||
19108                 error "dir strpe_count $d != 2 after migration."
19109
19110         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19111         [ $stripe_count = 2 ] ||
19112                 error "file strpe_count $d != 2 after migration."
19113
19114         #migrate back to MDT0
19115         MDTIDX=0
19116
19117         $LFS migrate -m $MDTIDX $migrate_dir ||
19118                 error "fails on migrating remote dir to MDT0"
19119
19120         echo "migrate back to MDT0, checking.."
19121         for file in $(find $migrate_dir); do
19122                 mdt_index=$($LFS getstripe -m $file)
19123                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19124                         error "$file is not on MDT${MDTIDX}"
19125         done
19126
19127         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19128         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19129                 error " expect $old_dir_flag get $new_dir_flag"
19130
19131         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19132         [ "$old_file_flag" = "$new_file_flag" ] ||
19133                 error " expect $old_file_flag get $new_file_flag"
19134
19135         local new_dir_mode=$(stat -c%f $migrate_dir)
19136         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19137                 error "expect mode $old_dir_mode get $new_dir_mode"
19138
19139         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19140         [ "$old_file_mode" = "$new_file_mode" ] ||
19141                 error "expect mode $old_file_mode get $new_file_mode"
19142
19143         diff /etc/passwd ${migrate_dir}/$tfile ||
19144                 error "$tfile different after migration"
19145
19146         diff /etc/passwd ${other_dir}/luna ||
19147                 error "luna different after migration"
19148
19149         diff /etc/passwd ${migrate_dir}/sofia ||
19150                 error "sofia different after migration"
19151
19152         diff /etc/passwd ${other_dir}/zachary ||
19153                 error "zachary different after migration"
19154
19155         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19156                 error "${tfile}_ln different after migration"
19157
19158         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19159                 error "${tfile}_ln_other different after migration"
19160
19161         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19162         [ $stripe_count = 2 ] ||
19163                 error "dir strpe_count $d != 2 after migration."
19164
19165         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19166         [ $stripe_count = 2 ] ||
19167                 error "file strpe_count $d != 2 after migration."
19168
19169         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19170 }
19171 run_test 230b "migrate directory"
19172
19173 test_230c() {
19174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19176         remote_mds_nodsh && skip "remote MDS with nodsh"
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 total=3
19182         local mdt_index
19183         local file
19184         local migrate_dir=$DIR/$tdir/migrate_dir
19185
19186         #If migrating directory fails in the middle, all entries of
19187         #the directory is still accessiable.
19188         test_mkdir $DIR/$tdir
19189         test_mkdir -i0 -c1 $migrate_dir
19190         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19191         stat $migrate_dir
19192         createmany -o $migrate_dir/f $total ||
19193                 error "create files under ${migrate_dir} failed"
19194
19195         # fail after migrating top dir, and this will fail only once, so the
19196         # first sub file migration will fail (currently f3), others succeed.
19197         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19198         do_facet mds1 lctl set_param fail_loc=0x1801
19199         local t=$(ls $migrate_dir | wc -l)
19200         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19201                 error "migrate should fail"
19202         local u=$(ls $migrate_dir | wc -l)
19203         [ "$u" == "$t" ] || error "$u != $t during migration"
19204
19205         # add new dir/file should succeed
19206         mkdir $migrate_dir/dir ||
19207                 error "mkdir failed under migrating directory"
19208         touch $migrate_dir/file ||
19209                 error "create file failed under migrating directory"
19210
19211         # add file with existing name should fail
19212         for file in $migrate_dir/f*; do
19213                 stat $file > /dev/null || error "stat $file failed"
19214                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19215                         error "open(O_CREAT|O_EXCL) $file should fail"
19216                 $MULTIOP $file m && error "create $file should fail"
19217                 touch $DIR/$tdir/remote_dir/$tfile ||
19218                         error "touch $tfile failed"
19219                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19220                         error "link $file should fail"
19221                 mdt_index=$($LFS getstripe -m $file)
19222                 if [ $mdt_index == 0 ]; then
19223                         # file failed to migrate is not allowed to rename to
19224                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19225                                 error "rename to $file should fail"
19226                 else
19227                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19228                                 error "rename to $file failed"
19229                 fi
19230                 echo hello >> $file || error "write $file failed"
19231         done
19232
19233         # resume migration with different options should fail
19234         $LFS migrate -m 0 $migrate_dir &&
19235                 error "migrate -m 0 $migrate_dir should fail"
19236
19237         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19238                 error "migrate -c 2 $migrate_dir should fail"
19239
19240         # resume migration should succeed
19241         $LFS migrate -m $MDTIDX $migrate_dir ||
19242                 error "migrate $migrate_dir failed"
19243
19244         echo "Finish migration, then checking.."
19245         for file in $(find $migrate_dir); do
19246                 mdt_index=$($LFS getstripe -m $file)
19247                 [ $mdt_index == $MDTIDX ] ||
19248                         error "$file is not on MDT${MDTIDX}"
19249         done
19250
19251         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19252 }
19253 run_test 230c "check directory accessiblity if migration failed"
19254
19255 test_230d() {
19256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19257         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19258         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19259                 skip "Need MDS version at least 2.11.52"
19260         # LU-11235
19261         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19262
19263         local migrate_dir=$DIR/$tdir/migrate_dir
19264         local old_index
19265         local new_index
19266         local old_count
19267         local new_count
19268         local new_hash
19269         local mdt_index
19270         local i
19271         local j
19272
19273         old_index=$((RANDOM % MDSCOUNT))
19274         old_count=$((MDSCOUNT - old_index))
19275         new_index=$((RANDOM % MDSCOUNT))
19276         new_count=$((MDSCOUNT - new_index))
19277         new_hash=1 # for all_char
19278
19279         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19280         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19281
19282         test_mkdir $DIR/$tdir
19283         test_mkdir -i $old_index -c $old_count $migrate_dir
19284
19285         for ((i=0; i<100; i++)); do
19286                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19287                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19288                         error "create files under remote dir failed $i"
19289         done
19290
19291         echo -n "Migrate from MDT$old_index "
19292         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19293         echo -n "to MDT$new_index"
19294         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19295         echo
19296
19297         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19298         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19299                 error "migrate remote dir error"
19300
19301         echo "Finish migration, then checking.."
19302         for file in $(find $migrate_dir); do
19303                 mdt_index=$($LFS getstripe -m $file)
19304                 if [ $mdt_index -lt $new_index ] ||
19305                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19306                         error "$file is on MDT$mdt_index"
19307                 fi
19308         done
19309
19310         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19311 }
19312 run_test 230d "check migrate big directory"
19313
19314 test_230e() {
19315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19317         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19318                 skip "Need MDS version at least 2.11.52"
19319
19320         local i
19321         local j
19322         local a_fid
19323         local b_fid
19324
19325         mkdir_on_mdt0 $DIR/$tdir
19326         mkdir $DIR/$tdir/migrate_dir
19327         mkdir $DIR/$tdir/other_dir
19328         touch $DIR/$tdir/migrate_dir/a
19329         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19330         ls $DIR/$tdir/other_dir
19331
19332         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19333                 error "migrate dir fails"
19334
19335         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19336         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19337
19338         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19339         [ $mdt_index == 0 ] || error "a is not on MDT0"
19340
19341         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19342                 error "migrate dir fails"
19343
19344         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19345         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19346
19347         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19348         [ $mdt_index == 1 ] || error "a is not on MDT1"
19349
19350         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19351         [ $mdt_index == 1 ] || error "b is not on MDT1"
19352
19353         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19354         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19355
19356         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19357
19358         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19359 }
19360 run_test 230e "migrate mulitple local link files"
19361
19362 test_230f() {
19363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19364         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19365         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19366                 skip "Need MDS version at least 2.11.52"
19367
19368         local a_fid
19369         local ln_fid
19370
19371         mkdir -p $DIR/$tdir
19372         mkdir $DIR/$tdir/migrate_dir
19373         $LFS mkdir -i1 $DIR/$tdir/other_dir
19374         touch $DIR/$tdir/migrate_dir/a
19375         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19376         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19377         ls $DIR/$tdir/other_dir
19378
19379         # a should be migrated to MDT1, since no other links on MDT0
19380         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19381                 error "#1 migrate dir fails"
19382         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19383         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19384         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19385         [ $mdt_index == 1 ] || error "a is not on MDT1"
19386
19387         # a should stay on MDT1, because it is a mulitple link file
19388         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19389                 error "#2 migrate dir fails"
19390         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19391         [ $mdt_index == 1 ] || error "a is not on MDT1"
19392
19393         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19394                 error "#3 migrate dir fails"
19395
19396         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19397         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19398         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19399
19400         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19401         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19402
19403         # a should be migrated to MDT0, since no other links on MDT1
19404         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19405                 error "#4 migrate dir fails"
19406         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19407         [ $mdt_index == 0 ] || error "a is not on MDT0"
19408
19409         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19410 }
19411 run_test 230f "migrate mulitple remote link files"
19412
19413 test_230g() {
19414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19415         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19416         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19417                 skip "Need MDS version at least 2.11.52"
19418
19419         mkdir -p $DIR/$tdir/migrate_dir
19420
19421         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19422                 error "migrating dir to non-exist MDT succeeds"
19423         true
19424 }
19425 run_test 230g "migrate dir to non-exist MDT"
19426
19427 test_230h() {
19428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19430         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19431                 skip "Need MDS version at least 2.11.52"
19432
19433         local mdt_index
19434
19435         mkdir -p $DIR/$tdir/migrate_dir
19436
19437         $LFS migrate -m1 $DIR &&
19438                 error "migrating mountpoint1 should fail"
19439
19440         $LFS migrate -m1 $DIR/$tdir/.. &&
19441                 error "migrating mountpoint2 should fail"
19442
19443         # same as mv
19444         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19445                 error "migrating $tdir/migrate_dir/.. should fail"
19446
19447         true
19448 }
19449 run_test 230h "migrate .. and root"
19450
19451 test_230i() {
19452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19453         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19454         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19455                 skip "Need MDS version at least 2.11.52"
19456
19457         mkdir -p $DIR/$tdir/migrate_dir
19458
19459         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19460                 error "migration fails with a tailing slash"
19461
19462         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19463                 error "migration fails with two tailing slashes"
19464 }
19465 run_test 230i "lfs migrate -m tolerates trailing slashes"
19466
19467 test_230j() {
19468         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19469         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19470                 skip "Need MDS version at least 2.11.52"
19471
19472         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19473         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19474                 error "create $tfile failed"
19475         cat /etc/passwd > $DIR/$tdir/$tfile
19476
19477         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19478
19479         cmp /etc/passwd $DIR/$tdir/$tfile ||
19480                 error "DoM file mismatch after migration"
19481 }
19482 run_test 230j "DoM file data not changed after dir migration"
19483
19484 test_230k() {
19485         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19486         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19487                 skip "Need MDS version at least 2.11.56"
19488
19489         local total=20
19490         local files_on_starting_mdt=0
19491
19492         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19493         $LFS getdirstripe $DIR/$tdir
19494         for i in $(seq $total); do
19495                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19496                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19497                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19498         done
19499
19500         echo "$files_on_starting_mdt files on MDT0"
19501
19502         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19503         $LFS getdirstripe $DIR/$tdir
19504
19505         files_on_starting_mdt=0
19506         for i in $(seq $total); do
19507                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19508                         error "file $tfile.$i mismatch after migration"
19509                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19510                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19511         done
19512
19513         echo "$files_on_starting_mdt files on MDT1 after migration"
19514         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19515
19516         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19517         $LFS getdirstripe $DIR/$tdir
19518
19519         files_on_starting_mdt=0
19520         for i in $(seq $total); do
19521                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19522                         error "file $tfile.$i mismatch after 2nd migration"
19523                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19524                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19525         done
19526
19527         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19528         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19529
19530         true
19531 }
19532 run_test 230k "file data not changed after dir migration"
19533
19534 test_230l() {
19535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19536         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19537                 skip "Need MDS version at least 2.11.56"
19538
19539         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19540         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19541                 error "create files under remote dir failed $i"
19542         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19543 }
19544 run_test 230l "readdir between MDTs won't crash"
19545
19546 test_230m() {
19547         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19548         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19549                 skip "Need MDS version at least 2.11.56"
19550
19551         local MDTIDX=1
19552         local mig_dir=$DIR/$tdir/migrate_dir
19553         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19554         local shortstr="b"
19555         local val
19556
19557         echo "Creating files and dirs with xattrs"
19558         test_mkdir $DIR/$tdir
19559         test_mkdir -i0 -c1 $mig_dir
19560         mkdir $mig_dir/dir
19561         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19562                 error "cannot set xattr attr1 on dir"
19563         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19564                 error "cannot set xattr attr2 on dir"
19565         touch $mig_dir/dir/f0
19566         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19567                 error "cannot set xattr attr1 on file"
19568         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19569                 error "cannot set xattr attr2 on file"
19570         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19571         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19572         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19573         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19574         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19575         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19576         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19577         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19578         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19579
19580         echo "Migrating to MDT1"
19581         $LFS migrate -m $MDTIDX $mig_dir ||
19582                 error "fails on migrating dir to MDT1"
19583
19584         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19585         echo "Checking xattrs"
19586         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19587         [ "$val" = $longstr ] ||
19588                 error "expecting xattr1 $longstr on dir, found $val"
19589         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19590         [ "$val" = $shortstr ] ||
19591                 error "expecting xattr2 $shortstr on dir, found $val"
19592         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19593         [ "$val" = $longstr ] ||
19594                 error "expecting xattr1 $longstr on file, found $val"
19595         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19596         [ "$val" = $shortstr ] ||
19597                 error "expecting xattr2 $shortstr on file, found $val"
19598 }
19599 run_test 230m "xattrs not changed after dir migration"
19600
19601 test_230n() {
19602         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19603         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19604                 skip "Need MDS version at least 2.13.53"
19605
19606         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19607         cat /etc/hosts > $DIR/$tdir/$tfile
19608         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19609         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19610
19611         cmp /etc/hosts $DIR/$tdir/$tfile ||
19612                 error "File data mismatch after migration"
19613 }
19614 run_test 230n "Dir migration with mirrored file"
19615
19616 test_230o() {
19617         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19618         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19619                 skip "Need MDS version at least 2.13.52"
19620
19621         local mdts=$(comma_list $(mdts_nodes))
19622         local timeout=100
19623         local restripe_status
19624         local delta
19625         local i
19626
19627         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19628
19629         # in case "crush" hash type is not set
19630         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19631
19632         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19633                            mdt.*MDT0000.enable_dir_restripe)
19634         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19635         stack_trap "do_nodes $mdts $LCTL set_param \
19636                     mdt.*.enable_dir_restripe=$restripe_status"
19637
19638         mkdir $DIR/$tdir
19639         createmany -m $DIR/$tdir/f 100 ||
19640                 error "create files under remote dir failed $i"
19641         createmany -d $DIR/$tdir/d 100 ||
19642                 error "create dirs under remote dir failed $i"
19643
19644         for i in $(seq 2 $MDSCOUNT); do
19645                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19646                 $LFS setdirstripe -c $i $DIR/$tdir ||
19647                         error "split -c $i $tdir failed"
19648                 wait_update $HOSTNAME \
19649                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19650                         error "dir split not finished"
19651                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19652                         awk '/migrate/ {sum += $2} END { print sum }')
19653                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19654                 # delta is around total_files/stripe_count
19655                 (( $delta < 200 / (i - 1) + 4 )) ||
19656                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19657         done
19658 }
19659 run_test 230o "dir split"
19660
19661 test_230p() {
19662         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19663         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19664                 skip "Need MDS version at least 2.13.52"
19665
19666         local mdts=$(comma_list $(mdts_nodes))
19667         local timeout=100
19668         local restripe_status
19669         local delta
19670         local c
19671
19672         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19673
19674         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19675
19676         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19677                            mdt.*MDT0000.enable_dir_restripe)
19678         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19679         stack_trap "do_nodes $mdts $LCTL set_param \
19680                     mdt.*.enable_dir_restripe=$restripe_status"
19681
19682         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19683         createmany -m $DIR/$tdir/f 100 ||
19684                 error "create files under remote dir failed"
19685         createmany -d $DIR/$tdir/d 100 ||
19686                 error "create dirs under remote dir failed"
19687
19688         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19689                 local mdt_hash="crush"
19690
19691                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19692                 $LFS setdirstripe -c $c $DIR/$tdir ||
19693                         error "split -c $c $tdir failed"
19694                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19695                         mdt_hash="$mdt_hash,fixed"
19696                 elif [ $c -eq 1 ]; then
19697                         mdt_hash="none"
19698                 fi
19699                 wait_update $HOSTNAME \
19700                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19701                         error "dir merge not finished"
19702                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19703                         awk '/migrate/ {sum += $2} END { print sum }')
19704                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19705                 # delta is around total_files/stripe_count
19706                 (( delta < 200 / c + 4 )) ||
19707                         error "$delta files migrated >= $((200 / c + 4))"
19708         done
19709 }
19710 run_test 230p "dir merge"
19711
19712 test_230q() {
19713         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19714         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19715                 skip "Need MDS version at least 2.13.52"
19716
19717         local mdts=$(comma_list $(mdts_nodes))
19718         local saved_threshold=$(do_facet mds1 \
19719                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19720         local saved_delta=$(do_facet mds1 \
19721                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19722         local threshold=100
19723         local delta=2
19724         local total=0
19725         local stripe_count=0
19726         local stripe_index
19727         local nr_files
19728         local create
19729
19730         # test with fewer files on ZFS
19731         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19732
19733         stack_trap "do_nodes $mdts $LCTL set_param \
19734                     mdt.*.dir_split_count=$saved_threshold"
19735         stack_trap "do_nodes $mdts $LCTL set_param \
19736                     mdt.*.dir_split_delta=$saved_delta"
19737         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19738         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19739         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19740         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19741         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19742         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19743
19744         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19745         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19746
19747         create=$((threshold * 3 / 2))
19748         while [ $stripe_count -lt $MDSCOUNT ]; do
19749                 createmany -m $DIR/$tdir/f $total $create ||
19750                         error "create sub files failed"
19751                 stat $DIR/$tdir > /dev/null
19752                 total=$((total + create))
19753                 stripe_count=$((stripe_count + delta))
19754                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19755
19756                 wait_update $HOSTNAME \
19757                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19758                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19759
19760                 wait_update $HOSTNAME \
19761                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19762                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19763
19764                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19765                 echo "$nr_files/$total files on MDT$stripe_index after split"
19766                 # allow 10% margin of imbalance with crush hash
19767                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19768                         error "$nr_files files on MDT$stripe_index after split"
19769
19770                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19771                 [ $nr_files -eq $total ] ||
19772                         error "total sub files $nr_files != $total"
19773         done
19774
19775         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19776
19777         echo "fixed layout directory won't auto split"
19778         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19779         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19780                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19781         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19782                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19783 }
19784 run_test 230q "dir auto split"
19785
19786 test_230r() {
19787         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19788         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19789         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19790                 skip "Need MDS version at least 2.13.54"
19791
19792         # maximum amount of local locks:
19793         # parent striped dir - 2 locks
19794         # new stripe in parent to migrate to - 1 lock
19795         # source and target - 2 locks
19796         # Total 5 locks for regular file
19797         mkdir -p $DIR/$tdir
19798         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19799         touch $DIR/$tdir/dir1/eee
19800
19801         # create 4 hardlink for 4 more locks
19802         # Total: 9 locks > RS_MAX_LOCKS (8)
19803         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19804         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19805         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19806         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19807         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19808         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19809         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19810         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19811
19812         cancel_lru_locks mdc
19813
19814         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19815                 error "migrate dir fails"
19816
19817         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19818 }
19819 run_test 230r "migrate with too many local locks"
19820
19821 test_230s() {
19822         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19823                 skip "Need MDS version at least 2.13.57"
19824
19825         local mdts=$(comma_list $(mdts_nodes))
19826         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19827                                 mdt.*MDT0000.enable_dir_restripe)
19828
19829         stack_trap "do_nodes $mdts $LCTL set_param \
19830                     mdt.*.enable_dir_restripe=$restripe_status"
19831
19832         local st
19833         for st in 0 1; do
19834                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19835                 test_mkdir $DIR/$tdir
19836                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19837                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19838                 rmdir $DIR/$tdir
19839         done
19840 }
19841 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19842
19843 test_230t()
19844 {
19845         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19846         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19847                 skip "Need MDS version at least 2.14.50"
19848
19849         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19850         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19851         $LFS project -p 1 -s $DIR/$tdir ||
19852                 error "set $tdir project id failed"
19853         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19854                 error "set subdir project id failed"
19855         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19856 }
19857 run_test 230t "migrate directory with project ID set"
19858
19859 test_231a()
19860 {
19861         # For simplicity this test assumes that max_pages_per_rpc
19862         # is the same across all OSCs
19863         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19864         local bulk_size=$((max_pages * PAGE_SIZE))
19865         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19866                                        head -n 1)
19867
19868         mkdir -p $DIR/$tdir
19869         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19870                 error "failed to set stripe with -S ${brw_size}M option"
19871
19872         # clear the OSC stats
19873         $LCTL set_param osc.*.stats=0 &>/dev/null
19874         stop_writeback
19875
19876         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19877         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19878                 oflag=direct &>/dev/null || error "dd failed"
19879
19880         sync; sleep 1; sync # just to be safe
19881         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19882         if [ x$nrpcs != "x1" ]; then
19883                 $LCTL get_param osc.*.stats
19884                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19885         fi
19886
19887         start_writeback
19888         # Drop the OSC cache, otherwise we will read from it
19889         cancel_lru_locks osc
19890
19891         # clear the OSC stats
19892         $LCTL set_param osc.*.stats=0 &>/dev/null
19893
19894         # Client reads $bulk_size.
19895         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19896                 iflag=direct &>/dev/null || error "dd failed"
19897
19898         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19899         if [ x$nrpcs != "x1" ]; then
19900                 $LCTL get_param osc.*.stats
19901                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19902         fi
19903 }
19904 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19905
19906 test_231b() {
19907         mkdir -p $DIR/$tdir
19908         local i
19909         for i in {0..1023}; do
19910                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19911                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19912                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19913         done
19914         sync
19915 }
19916 run_test 231b "must not assert on fully utilized OST request buffer"
19917
19918 test_232a() {
19919         mkdir -p $DIR/$tdir
19920         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19921
19922         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19923         do_facet ost1 $LCTL set_param fail_loc=0x31c
19924
19925         # ignore dd failure
19926         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19927
19928         do_facet ost1 $LCTL set_param fail_loc=0
19929         umount_client $MOUNT || error "umount failed"
19930         mount_client $MOUNT || error "mount failed"
19931         stop ost1 || error "cannot stop ost1"
19932         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19933 }
19934 run_test 232a "failed lock should not block umount"
19935
19936 test_232b() {
19937         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19938                 skip "Need MDS version at least 2.10.58"
19939
19940         mkdir -p $DIR/$tdir
19941         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19942         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19943         sync
19944         cancel_lru_locks osc
19945
19946         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19947         do_facet ost1 $LCTL set_param fail_loc=0x31c
19948
19949         # ignore failure
19950         $LFS data_version $DIR/$tdir/$tfile || true
19951
19952         do_facet ost1 $LCTL set_param fail_loc=0
19953         umount_client $MOUNT || error "umount failed"
19954         mount_client $MOUNT || error "mount failed"
19955         stop ost1 || error "cannot stop ost1"
19956         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19957 }
19958 run_test 232b "failed data version lock should not block umount"
19959
19960 test_233a() {
19961         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19962                 skip "Need MDS version at least 2.3.64"
19963         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19964
19965         local fid=$($LFS path2fid $MOUNT)
19966
19967         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19968                 error "cannot access $MOUNT using its FID '$fid'"
19969 }
19970 run_test 233a "checking that OBF of the FS root succeeds"
19971
19972 test_233b() {
19973         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19974                 skip "Need MDS version at least 2.5.90"
19975         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19976
19977         local fid=$($LFS path2fid $MOUNT/.lustre)
19978
19979         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19980                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19981
19982         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19983         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19984                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19985 }
19986 run_test 233b "checking that OBF of the FS .lustre succeeds"
19987
19988 test_234() {
19989         local p="$TMP/sanityN-$TESTNAME.parameters"
19990         save_lustre_params client "llite.*.xattr_cache" > $p
19991         lctl set_param llite.*.xattr_cache 1 ||
19992                 skip_env "xattr cache is not supported"
19993
19994         mkdir -p $DIR/$tdir || error "mkdir failed"
19995         touch $DIR/$tdir/$tfile || error "touch failed"
19996         # OBD_FAIL_LLITE_XATTR_ENOMEM
19997         $LCTL set_param fail_loc=0x1405
19998         getfattr -n user.attr $DIR/$tdir/$tfile &&
19999                 error "getfattr should have failed with ENOMEM"
20000         $LCTL set_param fail_loc=0x0
20001         rm -rf $DIR/$tdir
20002
20003         restore_lustre_params < $p
20004         rm -f $p
20005 }
20006 run_test 234 "xattr cache should not crash on ENOMEM"
20007
20008 test_235() {
20009         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20010                 skip "Need MDS version at least 2.4.52"
20011
20012         flock_deadlock $DIR/$tfile
20013         local RC=$?
20014         case $RC in
20015                 0)
20016                 ;;
20017                 124) error "process hangs on a deadlock"
20018                 ;;
20019                 *) error "error executing flock_deadlock $DIR/$tfile"
20020                 ;;
20021         esac
20022 }
20023 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20024
20025 #LU-2935
20026 test_236() {
20027         check_swap_layouts_support
20028
20029         local ref1=/etc/passwd
20030         local ref2=/etc/group
20031         local file1=$DIR/$tdir/f1
20032         local file2=$DIR/$tdir/f2
20033
20034         test_mkdir -c1 $DIR/$tdir
20035         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20036         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20037         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20038         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20039         local fd=$(free_fd)
20040         local cmd="exec $fd<>$file2"
20041         eval $cmd
20042         rm $file2
20043         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20044                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20045         cmd="exec $fd>&-"
20046         eval $cmd
20047         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20048
20049         #cleanup
20050         rm -rf $DIR/$tdir
20051 }
20052 run_test 236 "Layout swap on open unlinked file"
20053
20054 # LU-4659 linkea consistency
20055 test_238() {
20056         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20057                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20058                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20059                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20060
20061         touch $DIR/$tfile
20062         ln $DIR/$tfile $DIR/$tfile.lnk
20063         touch $DIR/$tfile.new
20064         mv $DIR/$tfile.new $DIR/$tfile
20065         local fid1=$($LFS path2fid $DIR/$tfile)
20066         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20067         local path1=$($LFS fid2path $FSNAME "$fid1")
20068         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20069         local path2=$($LFS fid2path $FSNAME "$fid2")
20070         [ $tfile.lnk == $path2 ] ||
20071                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20072         rm -f $DIR/$tfile*
20073 }
20074 run_test 238 "Verify linkea consistency"
20075
20076 test_239A() { # was test_239
20077         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20078                 skip "Need MDS version at least 2.5.60"
20079
20080         local list=$(comma_list $(mdts_nodes))
20081
20082         mkdir -p $DIR/$tdir
20083         createmany -o $DIR/$tdir/f- 5000
20084         unlinkmany $DIR/$tdir/f- 5000
20085         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20086                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20087         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20088                         osp.*MDT*.sync_in_flight" | calc_sum)
20089         [ "$changes" -eq 0 ] || error "$changes not synced"
20090 }
20091 run_test 239A "osp_sync test"
20092
20093 test_239a() { #LU-5297
20094         remote_mds_nodsh && skip "remote MDS with nodsh"
20095
20096         touch $DIR/$tfile
20097         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20098         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20099         chgrp $RUNAS_GID $DIR/$tfile
20100         wait_delete_completed
20101 }
20102 run_test 239a "process invalid osp sync record correctly"
20103
20104 test_239b() { #LU-5297
20105         remote_mds_nodsh && skip "remote MDS with nodsh"
20106
20107         touch $DIR/$tfile1
20108         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20109         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20110         chgrp $RUNAS_GID $DIR/$tfile1
20111         wait_delete_completed
20112         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20113         touch $DIR/$tfile2
20114         chgrp $RUNAS_GID $DIR/$tfile2
20115         wait_delete_completed
20116 }
20117 run_test 239b "process osp sync record with ENOMEM error correctly"
20118
20119 test_240() {
20120         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20121         remote_mds_nodsh && skip "remote MDS with nodsh"
20122
20123         mkdir -p $DIR/$tdir
20124
20125         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20126                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20127         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20128                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20129
20130         umount_client $MOUNT || error "umount failed"
20131         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20132         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20133         mount_client $MOUNT || error "failed to mount client"
20134
20135         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20136         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20137 }
20138 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20139
20140 test_241_bio() {
20141         local count=$1
20142         local bsize=$2
20143
20144         for LOOP in $(seq $count); do
20145                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20146                 cancel_lru_locks $OSC || true
20147         done
20148 }
20149
20150 test_241_dio() {
20151         local count=$1
20152         local bsize=$2
20153
20154         for LOOP in $(seq $1); do
20155                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20156                         2>/dev/null
20157         done
20158 }
20159
20160 test_241a() { # was test_241
20161         local bsize=$PAGE_SIZE
20162
20163         (( bsize < 40960 )) && bsize=40960
20164         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20165         ls -la $DIR/$tfile
20166         cancel_lru_locks $OSC
20167         test_241_bio 1000 $bsize &
20168         PID=$!
20169         test_241_dio 1000 $bsize
20170         wait $PID
20171 }
20172 run_test 241a "bio vs dio"
20173
20174 test_241b() {
20175         local bsize=$PAGE_SIZE
20176
20177         (( bsize < 40960 )) && bsize=40960
20178         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20179         ls -la $DIR/$tfile
20180         test_241_dio 1000 $bsize &
20181         PID=$!
20182         test_241_dio 1000 $bsize
20183         wait $PID
20184 }
20185 run_test 241b "dio vs dio"
20186
20187 test_242() {
20188         remote_mds_nodsh && skip "remote MDS with nodsh"
20189
20190         mkdir_on_mdt0 $DIR/$tdir
20191         touch $DIR/$tdir/$tfile
20192
20193         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20194         do_facet mds1 lctl set_param fail_loc=0x105
20195         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20196
20197         do_facet mds1 lctl set_param fail_loc=0
20198         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20199 }
20200 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20201
20202 test_243()
20203 {
20204         test_mkdir $DIR/$tdir
20205         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20206 }
20207 run_test 243 "various group lock tests"
20208
20209 test_244a()
20210 {
20211         test_mkdir $DIR/$tdir
20212         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20213         sendfile_grouplock $DIR/$tdir/$tfile || \
20214                 error "sendfile+grouplock failed"
20215         rm -rf $DIR/$tdir
20216 }
20217 run_test 244a "sendfile with group lock tests"
20218
20219 test_244b()
20220 {
20221         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20222
20223         local threads=50
20224         local size=$((1024*1024))
20225
20226         test_mkdir $DIR/$tdir
20227         for i in $(seq 1 $threads); do
20228                 local file=$DIR/$tdir/file_$((i / 10))
20229                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20230                 local pids[$i]=$!
20231         done
20232         for i in $(seq 1 $threads); do
20233                 wait ${pids[$i]}
20234         done
20235 }
20236 run_test 244b "multi-threaded write with group lock"
20237
20238 test_245() {
20239         local flagname="multi_mod_rpcs"
20240         local connect_data_name="max_mod_rpcs"
20241         local out
20242
20243         # check if multiple modify RPCs flag is set
20244         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20245                 grep "connect_flags:")
20246         echo "$out"
20247
20248         echo "$out" | grep -qw $flagname
20249         if [ $? -ne 0 ]; then
20250                 echo "connect flag $flagname is not set"
20251                 return
20252         fi
20253
20254         # check if multiple modify RPCs data is set
20255         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20256         echo "$out"
20257
20258         echo "$out" | grep -qw $connect_data_name ||
20259                 error "import should have connect data $connect_data_name"
20260 }
20261 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20262
20263 cleanup_247() {
20264         local submount=$1
20265
20266         trap 0
20267         umount_client $submount
20268         rmdir $submount
20269 }
20270
20271 test_247a() {
20272         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20273                 grep -q subtree ||
20274                 skip_env "Fileset feature is not supported"
20275
20276         local submount=${MOUNT}_$tdir
20277
20278         mkdir $MOUNT/$tdir
20279         mkdir -p $submount || error "mkdir $submount failed"
20280         FILESET="$FILESET/$tdir" mount_client $submount ||
20281                 error "mount $submount failed"
20282         trap "cleanup_247 $submount" EXIT
20283         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20284         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20285                 error "read $MOUNT/$tdir/$tfile failed"
20286         cleanup_247 $submount
20287 }
20288 run_test 247a "mount subdir as fileset"
20289
20290 test_247b() {
20291         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20292                 skip_env "Fileset feature is not supported"
20293
20294         local submount=${MOUNT}_$tdir
20295
20296         rm -rf $MOUNT/$tdir
20297         mkdir -p $submount || error "mkdir $submount failed"
20298         SKIP_FILESET=1
20299         FILESET="$FILESET/$tdir" mount_client $submount &&
20300                 error "mount $submount should fail"
20301         rmdir $submount
20302 }
20303 run_test 247b "mount subdir that dose not exist"
20304
20305 test_247c() {
20306         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20307                 skip_env "Fileset feature is not supported"
20308
20309         local submount=${MOUNT}_$tdir
20310
20311         mkdir -p $MOUNT/$tdir/dir1
20312         mkdir -p $submount || error "mkdir $submount failed"
20313         trap "cleanup_247 $submount" EXIT
20314         FILESET="$FILESET/$tdir" mount_client $submount ||
20315                 error "mount $submount failed"
20316         local fid=$($LFS path2fid $MOUNT/)
20317         $LFS fid2path $submount $fid && error "fid2path should fail"
20318         cleanup_247 $submount
20319 }
20320 run_test 247c "running fid2path outside subdirectory root"
20321
20322 test_247d() {
20323         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20324                 skip "Fileset feature is not supported"
20325
20326         local submount=${MOUNT}_$tdir
20327
20328         mkdir -p $MOUNT/$tdir/dir1
20329         mkdir -p $submount || error "mkdir $submount failed"
20330         FILESET="$FILESET/$tdir" mount_client $submount ||
20331                 error "mount $submount failed"
20332         trap "cleanup_247 $submount" EXIT
20333
20334         local td=$submount/dir1
20335         local fid=$($LFS path2fid $td)
20336         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20337
20338         # check that we get the same pathname back
20339         local rootpath
20340         local found
20341         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20342                 echo "$rootpath $fid"
20343                 found=$($LFS fid2path $rootpath "$fid")
20344                 [ -n "found" ] || error "fid2path should succeed"
20345                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20346         done
20347         # check wrong root path format
20348         rootpath=$submount"_wrong"
20349         found=$($LFS fid2path $rootpath "$fid")
20350         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20351
20352         cleanup_247 $submount
20353 }
20354 run_test 247d "running fid2path inside subdirectory root"
20355
20356 # LU-8037
20357 test_247e() {
20358         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20359                 grep -q subtree ||
20360                 skip "Fileset feature is not supported"
20361
20362         local submount=${MOUNT}_$tdir
20363
20364         mkdir $MOUNT/$tdir
20365         mkdir -p $submount || error "mkdir $submount failed"
20366         FILESET="$FILESET/.." mount_client $submount &&
20367                 error "mount $submount should fail"
20368         rmdir $submount
20369 }
20370 run_test 247e "mount .. as fileset"
20371
20372 test_247f() {
20373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20374         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20375                 skip "Need at least version 2.13.52"
20376         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20377                 skip "Need at least version 2.14.50"
20378         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20379                 grep -q subtree ||
20380                 skip "Fileset feature is not supported"
20381
20382         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20383         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20384                 error "mkdir remote failed"
20385         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20386                 error "mkdir remote/subdir failed"
20387         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20388                 error "mkdir striped failed"
20389         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20390
20391         local submount=${MOUNT}_$tdir
20392
20393         mkdir -p $submount || error "mkdir $submount failed"
20394         stack_trap "rmdir $submount"
20395
20396         local dir
20397         local stat
20398         local fileset=$FILESET
20399         local mdts=$(comma_list $(mdts_nodes))
20400
20401         stat=$(do_facet mds1 $LCTL get_param -n \
20402                 mdt.*MDT0000.enable_remote_subdir_mount)
20403         stack_trap "do_nodes $mdts $LCTL set_param \
20404                 mdt.*.enable_remote_subdir_mount=$stat"
20405
20406         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20407         stack_trap "umount_client $submount"
20408         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20409                 error "mount remote dir $dir should fail"
20410
20411         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20412                 $tdir/striped/. ; do
20413                 FILESET="$fileset/$dir" mount_client $submount ||
20414                         error "mount $dir failed"
20415                 umount_client $submount
20416         done
20417
20418         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20419         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20420                 error "mount $tdir/remote failed"
20421 }
20422 run_test 247f "mount striped or remote directory as fileset"
20423
20424 test_247g() {
20425         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20426         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20427                 skip "Need at least version 2.14.50"
20428
20429         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20430                 error "mkdir $tdir failed"
20431         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20432
20433         local submount=${MOUNT}_$tdir
20434
20435         mkdir -p $submount || error "mkdir $submount failed"
20436         stack_trap "rmdir $submount"
20437
20438         FILESET="$fileset/$tdir" mount_client $submount ||
20439                 error "mount $dir failed"
20440         stack_trap "umount $submount"
20441
20442         local mdts=$(comma_list $(mdts_nodes))
20443
20444         local nrpcs
20445
20446         stat $submount > /dev/null
20447         cancel_lru_locks $MDC
20448         stat $submount > /dev/null
20449         stat $submount/$tfile > /dev/null
20450         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20451         stat $submount/$tfile > /dev/null
20452         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20453                 awk '/getattr/ {sum += $2} END {print sum}')
20454
20455         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20456 }
20457 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20458
20459 test_248a() {
20460         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20461         [ -z "$fast_read_sav" ] && skip "no fast read support"
20462
20463         # create a large file for fast read verification
20464         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20465
20466         # make sure the file is created correctly
20467         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20468                 { rm -f $DIR/$tfile; skip "file creation error"; }
20469
20470         echo "Test 1: verify that fast read is 4 times faster on cache read"
20471
20472         # small read with fast read enabled
20473         $LCTL set_param -n llite.*.fast_read=1
20474         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20475                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20476                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20477         # small read with fast read disabled
20478         $LCTL set_param -n llite.*.fast_read=0
20479         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20480                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20481                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20482
20483         # verify that fast read is 4 times faster for cache read
20484         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20485                 error_not_in_vm "fast read was not 4 times faster: " \
20486                            "$t_fast vs $t_slow"
20487
20488         echo "Test 2: verify the performance between big and small read"
20489         $LCTL set_param -n llite.*.fast_read=1
20490
20491         # 1k non-cache read
20492         cancel_lru_locks osc
20493         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20494                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20495                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20496
20497         # 1M non-cache read
20498         cancel_lru_locks osc
20499         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20500                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20501                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20502
20503         # verify that big IO is not 4 times faster than small IO
20504         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20505                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20506
20507         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20508         rm -f $DIR/$tfile
20509 }
20510 run_test 248a "fast read verification"
20511
20512 test_248b() {
20513         # Default short_io_bytes=16384, try both smaller and larger sizes.
20514         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20515         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20516         echo "bs=53248 count=113 normal buffered write"
20517         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20518                 error "dd of initial data file failed"
20519         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20520
20521         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20522         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20523                 error "dd with sync normal writes failed"
20524         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20525
20526         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20527         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20528                 error "dd with sync small writes failed"
20529         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20530
20531         cancel_lru_locks osc
20532
20533         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20534         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20535         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20536         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20537                 iflag=direct || error "dd with O_DIRECT small read failed"
20538         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20539         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20540                 error "compare $TMP/$tfile.1 failed"
20541
20542         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20543         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20544
20545         # just to see what the maximum tunable value is, and test parsing
20546         echo "test invalid parameter 2MB"
20547         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20548                 error "too-large short_io_bytes allowed"
20549         echo "test maximum parameter 512KB"
20550         # if we can set a larger short_io_bytes, run test regardless of version
20551         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20552                 # older clients may not allow setting it this large, that's OK
20553                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20554                         skip "Need at least client version 2.13.50"
20555                 error "medium short_io_bytes failed"
20556         fi
20557         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20558         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20559
20560         echo "test large parameter 64KB"
20561         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20562         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20563
20564         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20565         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20566                 error "dd with sync large writes failed"
20567         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20568
20569         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20570         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20571         num=$((113 * 4096 / PAGE_SIZE))
20572         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20573         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20574                 error "dd with O_DIRECT large writes failed"
20575         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20576                 error "compare $DIR/$tfile.3 failed"
20577
20578         cancel_lru_locks osc
20579
20580         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20581         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20582                 error "dd with O_DIRECT large read failed"
20583         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20584                 error "compare $TMP/$tfile.2 failed"
20585
20586         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20587         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20588                 error "dd with O_DIRECT large read failed"
20589         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20590                 error "compare $TMP/$tfile.3 failed"
20591 }
20592 run_test 248b "test short_io read and write for both small and large sizes"
20593
20594 test_249() { # LU-7890
20595         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20596                 skip "Need at least version 2.8.54"
20597
20598         rm -f $DIR/$tfile
20599         $LFS setstripe -c 1 $DIR/$tfile
20600         # Offset 2T == 4k * 512M
20601         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20602                 error "dd to 2T offset failed"
20603 }
20604 run_test 249 "Write above 2T file size"
20605
20606 test_250() {
20607         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20608          && skip "no 16TB file size limit on ZFS"
20609
20610         $LFS setstripe -c 1 $DIR/$tfile
20611         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20612         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20613         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20614         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20615                 conv=notrunc,fsync && error "append succeeded"
20616         return 0
20617 }
20618 run_test 250 "Write above 16T limit"
20619
20620 test_251() {
20621         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20622
20623         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20624         #Skip once - writing the first stripe will succeed
20625         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20626         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20627                 error "short write happened"
20628
20629         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20630         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20631                 error "short read happened"
20632
20633         rm -f $DIR/$tfile
20634 }
20635 run_test 251 "Handling short read and write correctly"
20636
20637 test_252() {
20638         remote_mds_nodsh && skip "remote MDS with nodsh"
20639         remote_ost_nodsh && skip "remote OST with nodsh"
20640         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20641                 skip_env "ldiskfs only test"
20642         fi
20643
20644         local tgt
20645         local dev
20646         local out
20647         local uuid
20648         local num
20649         local gen
20650
20651         # check lr_reader on OST0000
20652         tgt=ost1
20653         dev=$(facet_device $tgt)
20654         out=$(do_facet $tgt $LR_READER $dev)
20655         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20656         echo "$out"
20657         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20658         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20659                 error "Invalid uuid returned by $LR_READER on target $tgt"
20660         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20661
20662         # check lr_reader -c on MDT0000
20663         tgt=mds1
20664         dev=$(facet_device $tgt)
20665         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20666                 skip "$LR_READER does not support additional options"
20667         fi
20668         out=$(do_facet $tgt $LR_READER -c $dev)
20669         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20670         echo "$out"
20671         num=$(echo "$out" | grep -c "mdtlov")
20672         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20673                 error "Invalid number of mdtlov clients returned by $LR_READER"
20674         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20675
20676         # check lr_reader -cr on MDT0000
20677         out=$(do_facet $tgt $LR_READER -cr $dev)
20678         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20679         echo "$out"
20680         echo "$out" | grep -q "^reply_data:$" ||
20681                 error "$LR_READER should have returned 'reply_data' section"
20682         num=$(echo "$out" | grep -c "client_generation")
20683         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20684 }
20685 run_test 252 "check lr_reader tool"
20686
20687 test_253() {
20688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20689         remote_mds_nodsh && skip "remote MDS with nodsh"
20690         remote_mgs_nodsh && skip "remote MGS with nodsh"
20691
20692         local ostidx=0
20693         local rc=0
20694         local ost_name=$(ostname_from_index $ostidx)
20695
20696         # on the mdt's osc
20697         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20698         do_facet $SINGLEMDS $LCTL get_param -n \
20699                 osp.$mdtosc_proc1.reserved_mb_high ||
20700                 skip  "remote MDS does not support reserved_mb_high"
20701
20702         rm -rf $DIR/$tdir
20703         wait_mds_ost_sync
20704         wait_delete_completed
20705         mkdir $DIR/$tdir
20706
20707         pool_add $TESTNAME || error "Pool creation failed"
20708         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20709
20710         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20711                 error "Setstripe failed"
20712
20713         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20714
20715         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20716                     grep "watermarks")
20717         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20718
20719         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20720                         osp.$mdtosc_proc1.prealloc_status)
20721         echo "prealloc_status $oa_status"
20722
20723         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20724                 error "File creation should fail"
20725
20726         #object allocation was stopped, but we still able to append files
20727         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20728                 oflag=append || error "Append failed"
20729
20730         rm -f $DIR/$tdir/$tfile.0
20731
20732         # For this test, we want to delete the files we created to go out of
20733         # space but leave the watermark, so we remain nearly out of space
20734         ost_watermarks_enospc_delete_files $tfile $ostidx
20735
20736         wait_delete_completed
20737
20738         sleep_maxage
20739
20740         for i in $(seq 10 12); do
20741                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20742                         2>/dev/null || error "File creation failed after rm"
20743         done
20744
20745         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20746                         osp.$mdtosc_proc1.prealloc_status)
20747         echo "prealloc_status $oa_status"
20748
20749         if (( oa_status != 0 )); then
20750                 error "Object allocation still disable after rm"
20751         fi
20752 }
20753 run_test 253 "Check object allocation limit"
20754
20755 test_254() {
20756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20757         remote_mds_nodsh && skip "remote MDS with nodsh"
20758         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20759                 skip "MDS does not support changelog_size"
20760
20761         local cl_user
20762         local MDT0=$(facet_svc $SINGLEMDS)
20763
20764         changelog_register || error "changelog_register failed"
20765
20766         changelog_clear 0 || error "changelog_clear failed"
20767
20768         local size1=$(do_facet $SINGLEMDS \
20769                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20770         echo "Changelog size $size1"
20771
20772         rm -rf $DIR/$tdir
20773         $LFS mkdir -i 0 $DIR/$tdir
20774         # change something
20775         mkdir -p $DIR/$tdir/pics/2008/zachy
20776         touch $DIR/$tdir/pics/2008/zachy/timestamp
20777         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20778         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20779         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20780         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20781         rm $DIR/$tdir/pics/desktop.jpg
20782
20783         local size2=$(do_facet $SINGLEMDS \
20784                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20785         echo "Changelog size after work $size2"
20786
20787         (( $size2 > $size1 )) ||
20788                 error "new Changelog size=$size2 less than old size=$size1"
20789 }
20790 run_test 254 "Check changelog size"
20791
20792 ladvise_no_type()
20793 {
20794         local type=$1
20795         local file=$2
20796
20797         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20798                 awk -F: '{print $2}' | grep $type > /dev/null
20799         if [ $? -ne 0 ]; then
20800                 return 0
20801         fi
20802         return 1
20803 }
20804
20805 ladvise_no_ioctl()
20806 {
20807         local file=$1
20808
20809         lfs ladvise -a willread $file > /dev/null 2>&1
20810         if [ $? -eq 0 ]; then
20811                 return 1
20812         fi
20813
20814         lfs ladvise -a willread $file 2>&1 |
20815                 grep "Inappropriate ioctl for device" > /dev/null
20816         if [ $? -eq 0 ]; then
20817                 return 0
20818         fi
20819         return 1
20820 }
20821
20822 percent() {
20823         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20824 }
20825
20826 # run a random read IO workload
20827 # usage: random_read_iops <filename> <filesize> <iosize>
20828 random_read_iops() {
20829         local file=$1
20830         local fsize=$2
20831         local iosize=${3:-4096}
20832
20833         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20834                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20835 }
20836
20837 drop_file_oss_cache() {
20838         local file="$1"
20839         local nodes="$2"
20840
20841         $LFS ladvise -a dontneed $file 2>/dev/null ||
20842                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20843 }
20844
20845 ladvise_willread_performance()
20846 {
20847         local repeat=10
20848         local average_origin=0
20849         local average_cache=0
20850         local average_ladvise=0
20851
20852         for ((i = 1; i <= $repeat; i++)); do
20853                 echo "Iter $i/$repeat: reading without willread hint"
20854                 cancel_lru_locks osc
20855                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20856                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20857                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20858                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20859
20860                 cancel_lru_locks osc
20861                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20862                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20863                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20864
20865                 cancel_lru_locks osc
20866                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20867                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20868                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20869                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20870                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20871         done
20872         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20873         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20874         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20875
20876         speedup_cache=$(percent $average_cache $average_origin)
20877         speedup_ladvise=$(percent $average_ladvise $average_origin)
20878
20879         echo "Average uncached read: $average_origin"
20880         echo "Average speedup with OSS cached read: " \
20881                 "$average_cache = +$speedup_cache%"
20882         echo "Average speedup with ladvise willread: " \
20883                 "$average_ladvise = +$speedup_ladvise%"
20884
20885         local lowest_speedup=20
20886         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20887                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20888                         "got $average_cache%. Skipping ladvise willread check."
20889                 return 0
20890         fi
20891
20892         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20893         # it is still good to run until then to exercise 'ladvise willread'
20894         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20895                 [ "$ost1_FSTYPE" = "zfs" ] &&
20896                 echo "osd-zfs does not support dontneed or drop_caches" &&
20897                 return 0
20898
20899         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20900         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20901                 error_not_in_vm "Speedup with willread is less than " \
20902                         "$lowest_speedup%, got $average_ladvise%"
20903 }
20904
20905 test_255a() {
20906         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20907                 skip "lustre < 2.8.54 does not support ladvise "
20908         remote_ost_nodsh && skip "remote OST with nodsh"
20909
20910         stack_trap "rm -f $DIR/$tfile"
20911         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20912
20913         ladvise_no_type willread $DIR/$tfile &&
20914                 skip "willread ladvise is not supported"
20915
20916         ladvise_no_ioctl $DIR/$tfile &&
20917                 skip "ladvise ioctl is not supported"
20918
20919         local size_mb=100
20920         local size=$((size_mb * 1048576))
20921         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20922                 error "dd to $DIR/$tfile failed"
20923
20924         lfs ladvise -a willread $DIR/$tfile ||
20925                 error "Ladvise failed with no range argument"
20926
20927         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20928                 error "Ladvise failed with no -l or -e argument"
20929
20930         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20931                 error "Ladvise failed with only -e argument"
20932
20933         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20934                 error "Ladvise failed with only -l argument"
20935
20936         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20937                 error "End offset should not be smaller than start offset"
20938
20939         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20940                 error "End offset should not be equal to start offset"
20941
20942         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20943                 error "Ladvise failed with overflowing -s argument"
20944
20945         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20946                 error "Ladvise failed with overflowing -e argument"
20947
20948         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20949                 error "Ladvise failed with overflowing -l argument"
20950
20951         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20952                 error "Ladvise succeeded with conflicting -l and -e arguments"
20953
20954         echo "Synchronous ladvise should wait"
20955         local delay=4
20956 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20957         do_nodes $(comma_list $(osts_nodes)) \
20958                 $LCTL set_param fail_val=$delay fail_loc=0x237
20959
20960         local start_ts=$SECONDS
20961         lfs ladvise -a willread $DIR/$tfile ||
20962                 error "Ladvise failed with no range argument"
20963         local end_ts=$SECONDS
20964         local inteval_ts=$((end_ts - start_ts))
20965
20966         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20967                 error "Synchronous advice didn't wait reply"
20968         fi
20969
20970         echo "Asynchronous ladvise shouldn't wait"
20971         local start_ts=$SECONDS
20972         lfs ladvise -a willread -b $DIR/$tfile ||
20973                 error "Ladvise failed with no range argument"
20974         local end_ts=$SECONDS
20975         local inteval_ts=$((end_ts - start_ts))
20976
20977         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20978                 error "Asynchronous advice blocked"
20979         fi
20980
20981         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20982         ladvise_willread_performance
20983 }
20984 run_test 255a "check 'lfs ladvise -a willread'"
20985
20986 facet_meminfo() {
20987         local facet=$1
20988         local info=$2
20989
20990         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20991 }
20992
20993 test_255b() {
20994         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20995                 skip "lustre < 2.8.54 does not support ladvise "
20996         remote_ost_nodsh && skip "remote OST with nodsh"
20997
20998         stack_trap "rm -f $DIR/$tfile"
20999         lfs setstripe -c 1 -i 0 $DIR/$tfile
21000
21001         ladvise_no_type dontneed $DIR/$tfile &&
21002                 skip "dontneed ladvise is not supported"
21003
21004         ladvise_no_ioctl $DIR/$tfile &&
21005                 skip "ladvise ioctl is not supported"
21006
21007         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21008                 [ "$ost1_FSTYPE" = "zfs" ] &&
21009                 skip "zfs-osd does not support 'ladvise dontneed'"
21010
21011         local size_mb=100
21012         local size=$((size_mb * 1048576))
21013         # In order to prevent disturbance of other processes, only check 3/4
21014         # of the memory usage
21015         local kibibytes=$((size_mb * 1024 * 3 / 4))
21016
21017         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21018                 error "dd to $DIR/$tfile failed"
21019
21020         #force write to complete before dropping OST cache & checking memory
21021         sync
21022
21023         local total=$(facet_meminfo ost1 MemTotal)
21024         echo "Total memory: $total KiB"
21025
21026         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21027         local before_read=$(facet_meminfo ost1 Cached)
21028         echo "Cache used before read: $before_read KiB"
21029
21030         lfs ladvise -a willread $DIR/$tfile ||
21031                 error "Ladvise willread failed"
21032         local after_read=$(facet_meminfo ost1 Cached)
21033         echo "Cache used after read: $after_read KiB"
21034
21035         lfs ladvise -a dontneed $DIR/$tfile ||
21036                 error "Ladvise dontneed again failed"
21037         local no_read=$(facet_meminfo ost1 Cached)
21038         echo "Cache used after dontneed ladvise: $no_read KiB"
21039
21040         if [ $total -lt $((before_read + kibibytes)) ]; then
21041                 echo "Memory is too small, abort checking"
21042                 return 0
21043         fi
21044
21045         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21046                 error "Ladvise willread should use more memory" \
21047                         "than $kibibytes KiB"
21048         fi
21049
21050         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21051                 error "Ladvise dontneed should release more memory" \
21052                         "than $kibibytes KiB"
21053         fi
21054 }
21055 run_test 255b "check 'lfs ladvise -a dontneed'"
21056
21057 test_255c() {
21058         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21059                 skip "lustre < 2.10.50 does not support lockahead"
21060
21061         local ost1_imp=$(get_osc_import_name client ost1)
21062         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21063                          cut -d'.' -f2)
21064         local count
21065         local new_count
21066         local difference
21067         local i
21068         local rc
21069
21070         test_mkdir -p $DIR/$tdir
21071         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21072
21073         #test 10 returns only success/failure
21074         i=10
21075         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21076         rc=$?
21077         if [ $rc -eq 255 ]; then
21078                 error "Ladvise test${i} failed, ${rc}"
21079         fi
21080
21081         #test 11 counts lock enqueue requests, all others count new locks
21082         i=11
21083         count=$(do_facet ost1 \
21084                 $LCTL get_param -n ost.OSS.ost.stats)
21085         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21086
21087         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21088         rc=$?
21089         if [ $rc -eq 255 ]; then
21090                 error "Ladvise test${i} failed, ${rc}"
21091         fi
21092
21093         new_count=$(do_facet ost1 \
21094                 $LCTL get_param -n ost.OSS.ost.stats)
21095         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21096                    awk '{ print $2 }')
21097
21098         difference="$((new_count - count))"
21099         if [ $difference -ne $rc ]; then
21100                 error "Ladvise test${i}, bad enqueue count, returned " \
21101                       "${rc}, actual ${difference}"
21102         fi
21103
21104         for i in $(seq 12 21); do
21105                 # If we do not do this, we run the risk of having too many
21106                 # locks and starting lock cancellation while we are checking
21107                 # lock counts.
21108                 cancel_lru_locks osc
21109
21110                 count=$($LCTL get_param -n \
21111                        ldlm.namespaces.$imp_name.lock_unused_count)
21112
21113                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21114                 rc=$?
21115                 if [ $rc -eq 255 ]; then
21116                         error "Ladvise test ${i} failed, ${rc}"
21117                 fi
21118
21119                 new_count=$($LCTL get_param -n \
21120                        ldlm.namespaces.$imp_name.lock_unused_count)
21121                 difference="$((new_count - count))"
21122
21123                 # Test 15 output is divided by 100 to map down to valid return
21124                 if [ $i -eq 15 ]; then
21125                         rc="$((rc * 100))"
21126                 fi
21127
21128                 if [ $difference -ne $rc ]; then
21129                         error "Ladvise test ${i}, bad lock count, returned " \
21130                               "${rc}, actual ${difference}"
21131                 fi
21132         done
21133
21134         #test 22 returns only success/failure
21135         i=22
21136         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21137         rc=$?
21138         if [ $rc -eq 255 ]; then
21139                 error "Ladvise test${i} failed, ${rc}"
21140         fi
21141 }
21142 run_test 255c "suite of ladvise lockahead tests"
21143
21144 test_256() {
21145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21146         remote_mds_nodsh && skip "remote MDS with nodsh"
21147         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21148         changelog_users $SINGLEMDS | grep "^cl" &&
21149                 skip "active changelog user"
21150
21151         local cl_user
21152         local cat_sl
21153         local mdt_dev
21154
21155         mdt_dev=$(mdsdevname 1)
21156         echo $mdt_dev
21157
21158         changelog_register || error "changelog_register failed"
21159
21160         rm -rf $DIR/$tdir
21161         mkdir_on_mdt0 $DIR/$tdir
21162
21163         changelog_clear 0 || error "changelog_clear failed"
21164
21165         # change something
21166         touch $DIR/$tdir/{1..10}
21167
21168         # stop the MDT
21169         stop $SINGLEMDS || error "Fail to stop MDT"
21170
21171         # remount the MDT
21172
21173         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21174
21175         #after mount new plainllog is used
21176         touch $DIR/$tdir/{11..19}
21177         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21178         stack_trap "rm -f $tmpfile"
21179         cat_sl=$(do_facet $SINGLEMDS "sync; \
21180                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21181                  llog_reader $tmpfile | grep -c type=1064553b")
21182         do_facet $SINGLEMDS llog_reader $tmpfile
21183
21184         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21185
21186         changelog_clear 0 || error "changelog_clear failed"
21187
21188         cat_sl=$(do_facet $SINGLEMDS "sync; \
21189                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21190                  llog_reader $tmpfile | grep -c type=1064553b")
21191
21192         if (( cat_sl == 2 )); then
21193                 error "Empty plain llog was not deleted from changelog catalog"
21194         elif (( cat_sl != 1 )); then
21195                 error "Active plain llog shouldn't be deleted from catalog"
21196         fi
21197 }
21198 run_test 256 "Check llog delete for empty and not full state"
21199
21200 test_257() {
21201         remote_mds_nodsh && skip "remote MDS with nodsh"
21202         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21203                 skip "Need MDS version at least 2.8.55"
21204
21205         test_mkdir $DIR/$tdir
21206
21207         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21208                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21209         stat $DIR/$tdir
21210
21211 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21212         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21213         local facet=mds$((mdtidx + 1))
21214         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21215         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21216
21217         stop $facet || error "stop MDS failed"
21218         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21219                 error "start MDS fail"
21220         wait_recovery_complete $facet
21221 }
21222 run_test 257 "xattr locks are not lost"
21223
21224 # Verify we take the i_mutex when security requires it
21225 test_258a() {
21226 #define OBD_FAIL_IMUTEX_SEC 0x141c
21227         $LCTL set_param fail_loc=0x141c
21228         touch $DIR/$tfile
21229         chmod u+s $DIR/$tfile
21230         chmod a+rwx $DIR/$tfile
21231         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21232         RC=$?
21233         if [ $RC -ne 0 ]; then
21234                 error "error, failed to take i_mutex, rc=$?"
21235         fi
21236         rm -f $DIR/$tfile
21237 }
21238 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21239
21240 # Verify we do NOT take the i_mutex in the normal case
21241 test_258b() {
21242 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21243         $LCTL set_param fail_loc=0x141d
21244         touch $DIR/$tfile
21245         chmod a+rwx $DIR
21246         chmod a+rw $DIR/$tfile
21247         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21248         RC=$?
21249         if [ $RC -ne 0 ]; then
21250                 error "error, took i_mutex unnecessarily, rc=$?"
21251         fi
21252         rm -f $DIR/$tfile
21253
21254 }
21255 run_test 258b "verify i_mutex security behavior"
21256
21257 test_259() {
21258         local file=$DIR/$tfile
21259         local before
21260         local after
21261
21262         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21263
21264         stack_trap "rm -f $file" EXIT
21265
21266         wait_delete_completed
21267         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21268         echo "before: $before"
21269
21270         $LFS setstripe -i 0 -c 1 $file
21271         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21272         sync_all_data
21273         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21274         echo "after write: $after"
21275
21276 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21277         do_facet ost1 $LCTL set_param fail_loc=0x2301
21278         $TRUNCATE $file 0
21279         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21280         echo "after truncate: $after"
21281
21282         stop ost1
21283         do_facet ost1 $LCTL set_param fail_loc=0
21284         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21285         sleep 2
21286         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21287         echo "after restart: $after"
21288         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21289                 error "missing truncate?"
21290
21291         return 0
21292 }
21293 run_test 259 "crash at delayed truncate"
21294
21295 test_260() {
21296 #define OBD_FAIL_MDC_CLOSE               0x806
21297         $LCTL set_param fail_loc=0x80000806
21298         touch $DIR/$tfile
21299
21300 }
21301 run_test 260 "Check mdc_close fail"
21302
21303 ### Data-on-MDT sanity tests ###
21304 test_270a() {
21305         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21306                 skip "Need MDS version at least 2.10.55 for DoM"
21307
21308         # create DoM file
21309         local dom=$DIR/$tdir/dom_file
21310         local tmp=$DIR/$tdir/tmp_file
21311
21312         mkdir_on_mdt0 $DIR/$tdir
21313
21314         # basic checks for DoM component creation
21315         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21316                 error "Can set MDT layout to non-first entry"
21317
21318         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21319                 error "Can define multiple entries as MDT layout"
21320
21321         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21322
21323         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21324         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21325         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21326
21327         local mdtidx=$($LFS getstripe -m $dom)
21328         local mdtname=MDT$(printf %04x $mdtidx)
21329         local facet=mds$((mdtidx + 1))
21330         local space_check=1
21331
21332         # Skip free space checks with ZFS
21333         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21334
21335         # write
21336         sync
21337         local size_tmp=$((65536 * 3))
21338         local mdtfree1=$(do_facet $facet \
21339                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21340
21341         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21342         # check also direct IO along write
21343         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21344         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21345         sync
21346         cmp $tmp $dom || error "file data is different"
21347         [ $(stat -c%s $dom) == $size_tmp ] ||
21348                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21349         if [ $space_check == 1 ]; then
21350                 local mdtfree2=$(do_facet $facet \
21351                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21352
21353                 # increase in usage from by $size_tmp
21354                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21355                         error "MDT free space wrong after write: " \
21356                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21357         fi
21358
21359         # truncate
21360         local size_dom=10000
21361
21362         $TRUNCATE $dom $size_dom
21363         [ $(stat -c%s $dom) == $size_dom ] ||
21364                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21365         if [ $space_check == 1 ]; then
21366                 mdtfree1=$(do_facet $facet \
21367                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21368                 # decrease in usage from $size_tmp to new $size_dom
21369                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21370                   $(((size_tmp - size_dom) / 1024)) ] ||
21371                         error "MDT free space is wrong after truncate: " \
21372                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21373         fi
21374
21375         # append
21376         cat $tmp >> $dom
21377         sync
21378         size_dom=$((size_dom + size_tmp))
21379         [ $(stat -c%s $dom) == $size_dom ] ||
21380                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21381         if [ $space_check == 1 ]; then
21382                 mdtfree2=$(do_facet $facet \
21383                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21384                 # increase in usage by $size_tmp from previous
21385                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21386                         error "MDT free space is wrong after append: " \
21387                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21388         fi
21389
21390         # delete
21391         rm $dom
21392         if [ $space_check == 1 ]; then
21393                 mdtfree1=$(do_facet $facet \
21394                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21395                 # decrease in usage by $size_dom from previous
21396                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21397                         error "MDT free space is wrong after removal: " \
21398                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21399         fi
21400
21401         # combined striping
21402         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21403                 error "Can't create DoM + OST striping"
21404
21405         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21406         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21407         # check also direct IO along write
21408         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21409         sync
21410         cmp $tmp $dom || error "file data is different"
21411         [ $(stat -c%s $dom) == $size_tmp ] ||
21412                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21413         rm $dom $tmp
21414
21415         return 0
21416 }
21417 run_test 270a "DoM: basic functionality tests"
21418
21419 test_270b() {
21420         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21421                 skip "Need MDS version at least 2.10.55"
21422
21423         local dom=$DIR/$tdir/dom_file
21424         local max_size=1048576
21425
21426         mkdir -p $DIR/$tdir
21427         $LFS setstripe -E $max_size -L mdt $dom
21428
21429         # truncate over the limit
21430         $TRUNCATE $dom $(($max_size + 1)) &&
21431                 error "successful truncate over the maximum size"
21432         # write over the limit
21433         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21434                 error "successful write over the maximum size"
21435         # append over the limit
21436         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21437         echo "12345" >> $dom && error "successful append over the maximum size"
21438         rm $dom
21439
21440         return 0
21441 }
21442 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21443
21444 test_270c() {
21445         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21446                 skip "Need MDS version at least 2.10.55"
21447
21448         mkdir -p $DIR/$tdir
21449         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21450
21451         # check files inherit DoM EA
21452         touch $DIR/$tdir/first
21453         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21454                 error "bad pattern"
21455         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21456                 error "bad stripe count"
21457         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21458                 error "bad stripe size"
21459
21460         # check directory inherits DoM EA and uses it as default
21461         mkdir $DIR/$tdir/subdir
21462         touch $DIR/$tdir/subdir/second
21463         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21464                 error "bad pattern in sub-directory"
21465         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21466                 error "bad stripe count in sub-directory"
21467         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21468                 error "bad stripe size in sub-directory"
21469         return 0
21470 }
21471 run_test 270c "DoM: DoM EA inheritance tests"
21472
21473 test_270d() {
21474         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21475                 skip "Need MDS version at least 2.10.55"
21476
21477         mkdir -p $DIR/$tdir
21478         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21479
21480         # inherit default DoM striping
21481         mkdir $DIR/$tdir/subdir
21482         touch $DIR/$tdir/subdir/f1
21483
21484         # change default directory striping
21485         $LFS setstripe -c 1 $DIR/$tdir/subdir
21486         touch $DIR/$tdir/subdir/f2
21487         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21488                 error "wrong default striping in file 2"
21489         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21490                 error "bad pattern in file 2"
21491         return 0
21492 }
21493 run_test 270d "DoM: change striping from DoM to RAID0"
21494
21495 test_270e() {
21496         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21497                 skip "Need MDS version at least 2.10.55"
21498
21499         mkdir -p $DIR/$tdir/dom
21500         mkdir -p $DIR/$tdir/norm
21501         DOMFILES=20
21502         NORMFILES=10
21503         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21504         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21505
21506         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21507         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21508
21509         # find DoM files by layout
21510         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21511         [ $NUM -eq  $DOMFILES ] ||
21512                 error "lfs find -L: found $NUM, expected $DOMFILES"
21513         echo "Test 1: lfs find 20 DOM files by layout: OK"
21514
21515         # there should be 1 dir with default DOM striping
21516         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21517         [ $NUM -eq  1 ] ||
21518                 error "lfs find -L: found $NUM, expected 1 dir"
21519         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21520
21521         # find DoM files by stripe size
21522         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21523         [ $NUM -eq  $DOMFILES ] ||
21524                 error "lfs find -S: found $NUM, expected $DOMFILES"
21525         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21526
21527         # find files by stripe offset except DoM files
21528         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21529         [ $NUM -eq  $NORMFILES ] ||
21530                 error "lfs find -i: found $NUM, expected $NORMFILES"
21531         echo "Test 5: lfs find no DOM files by stripe index: OK"
21532         return 0
21533 }
21534 run_test 270e "DoM: lfs find with DoM files test"
21535
21536 test_270f() {
21537         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21538                 skip "Need MDS version at least 2.10.55"
21539
21540         local mdtname=${FSNAME}-MDT0000-mdtlov
21541         local dom=$DIR/$tdir/dom_file
21542         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21543                                                 lod.$mdtname.dom_stripesize)
21544         local dom_limit=131072
21545
21546         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21547         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21548                                                 lod.$mdtname.dom_stripesize)
21549         [ ${dom_limit} -eq ${dom_current} ] ||
21550                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21551
21552         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21553         $LFS setstripe -d $DIR/$tdir
21554         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21555                 error "Can't set directory default striping"
21556
21557         # exceed maximum stripe size
21558         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21559                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21560         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21561                 error "Able to create DoM component size more than LOD limit"
21562
21563         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21564         dom_current=$(do_facet mds1 $LCTL get_param -n \
21565                                                 lod.$mdtname.dom_stripesize)
21566         [ 0 -eq ${dom_current} ] ||
21567                 error "Can't set zero DoM stripe limit"
21568         rm $dom
21569
21570         # attempt to create DoM file on server with disabled DoM should
21571         # remove DoM entry from layout and be succeed
21572         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21573                 error "Can't create DoM file (DoM is disabled)"
21574         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21575                 error "File has DoM component while DoM is disabled"
21576         rm $dom
21577
21578         # attempt to create DoM file with only DoM stripe should return error
21579         $LFS setstripe -E $dom_limit -L mdt $dom &&
21580                 error "Able to create DoM-only file while DoM is disabled"
21581
21582         # too low values to be aligned with smallest stripe size 64K
21583         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21584         dom_current=$(do_facet mds1 $LCTL get_param -n \
21585                                                 lod.$mdtname.dom_stripesize)
21586         [ 30000 -eq ${dom_current} ] &&
21587                 error "Can set too small DoM stripe limit"
21588
21589         # 64K is a minimal stripe size in Lustre, expect limit of that size
21590         [ 65536 -eq ${dom_current} ] ||
21591                 error "Limit is not set to 64K but ${dom_current}"
21592
21593         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21594         dom_current=$(do_facet mds1 $LCTL get_param -n \
21595                                                 lod.$mdtname.dom_stripesize)
21596         echo $dom_current
21597         [ 2147483648 -eq ${dom_current} ] &&
21598                 error "Can set too large DoM stripe limit"
21599
21600         do_facet mds1 $LCTL set_param -n \
21601                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21602         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21603                 error "Can't create DoM component size after limit change"
21604         do_facet mds1 $LCTL set_param -n \
21605                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21606         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21607                 error "Can't create DoM file after limit decrease"
21608         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21609                 error "Can create big DoM component after limit decrease"
21610         touch ${dom}_def ||
21611                 error "Can't create file with old default layout"
21612
21613         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21614         return 0
21615 }
21616 run_test 270f "DoM: maximum DoM stripe size checks"
21617
21618 test_270g() {
21619         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21620                 skip "Need MDS version at least 2.13.52"
21621         local dom=$DIR/$tdir/$tfile
21622
21623         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21624         local lodname=${FSNAME}-MDT0000-mdtlov
21625
21626         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21627         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21628         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21629         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21630
21631         local dom_limit=1024
21632         local dom_threshold="50%"
21633
21634         $LFS setstripe -d $DIR/$tdir
21635         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21636                 error "Can't set directory default striping"
21637
21638         do_facet mds1 $LCTL set_param -n \
21639                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21640         # set 0 threshold and create DOM file to change tunable stripesize
21641         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21642         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21643                 error "Failed to create $dom file"
21644         # now tunable dom_cur_stripesize should reach maximum
21645         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21646                                         lod.${lodname}.dom_stripesize_cur_kb)
21647         [[ $dom_current == $dom_limit ]] ||
21648                 error "Current DOM stripesize is not maximum"
21649         rm $dom
21650
21651         # set threshold for further tests
21652         do_facet mds1 $LCTL set_param -n \
21653                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21654         echo "DOM threshold is $dom_threshold free space"
21655         local dom_def
21656         local dom_set
21657         # Spoof bfree to exceed threshold
21658         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21659         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21660         for spfree in 40 20 0 15 30 55; do
21661                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21662                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21663                         error "Failed to create $dom file"
21664                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21665                                         lod.${lodname}.dom_stripesize_cur_kb)
21666                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21667                 [[ $dom_def != $dom_current ]] ||
21668                         error "Default stripe size was not changed"
21669                 if [[ $spfree > 0 ]] ; then
21670                         dom_set=$($LFS getstripe -S $dom)
21671                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21672                                 error "DOM component size is still old"
21673                 else
21674                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21675                                 error "DoM component is set with no free space"
21676                 fi
21677                 rm $dom
21678                 dom_current=$dom_def
21679         done
21680 }
21681 run_test 270g "DoM: default DoM stripe size depends on free space"
21682
21683 test_270h() {
21684         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21685                 skip "Need MDS version at least 2.13.53"
21686
21687         local mdtname=${FSNAME}-MDT0000-mdtlov
21688         local dom=$DIR/$tdir/$tfile
21689         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21690
21691         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21692         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21693
21694         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21695         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21696                 error "can't create OST file"
21697         # mirrored file with DOM entry in the second mirror
21698         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21699                 error "can't create mirror with DoM component"
21700
21701         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21702
21703         # DOM component in the middle and has other enries in the same mirror,
21704         # should succeed but lost DoM component
21705         $LFS setstripe --copy=${dom}_1 $dom ||
21706                 error "Can't create file from OST|DOM mirror layout"
21707         # check new file has no DoM layout after all
21708         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21709                 error "File has DoM component while DoM is disabled"
21710 }
21711 run_test 270h "DoM: DoM stripe removal when disabled on server"
21712
21713 test_271a() {
21714         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21715                 skip "Need MDS version at least 2.10.55"
21716
21717         local dom=$DIR/$tdir/dom
21718
21719         mkdir -p $DIR/$tdir
21720
21721         $LFS setstripe -E 1024K -L mdt $dom
21722
21723         lctl set_param -n mdc.*.stats=clear
21724         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21725         cat $dom > /dev/null
21726         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21727         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21728         ls $dom
21729         rm -f $dom
21730 }
21731 run_test 271a "DoM: data is cached for read after write"
21732
21733 test_271b() {
21734         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21735                 skip "Need MDS version at least 2.10.55"
21736
21737         local dom=$DIR/$tdir/dom
21738
21739         mkdir -p $DIR/$tdir
21740
21741         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21742
21743         lctl set_param -n mdc.*.stats=clear
21744         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21745         cancel_lru_locks mdc
21746         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21747         # second stat to check size is cached on client
21748         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21749         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21750         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21751         rm -f $dom
21752 }
21753 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21754
21755 test_271ba() {
21756         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21757                 skip "Need MDS version at least 2.10.55"
21758
21759         local dom=$DIR/$tdir/dom
21760
21761         mkdir -p $DIR/$tdir
21762
21763         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21764
21765         lctl set_param -n mdc.*.stats=clear
21766         lctl set_param -n osc.*.stats=clear
21767         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21768         cancel_lru_locks mdc
21769         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21770         # second stat to check size is cached on client
21771         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21772         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21773         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21774         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21775         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21776         rm -f $dom
21777 }
21778 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21779
21780
21781 get_mdc_stats() {
21782         local mdtidx=$1
21783         local param=$2
21784         local mdt=MDT$(printf %04x $mdtidx)
21785
21786         if [ -z $param ]; then
21787                 lctl get_param -n mdc.*$mdt*.stats
21788         else
21789                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21790         fi
21791 }
21792
21793 test_271c() {
21794         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21795                 skip "Need MDS version at least 2.10.55"
21796
21797         local dom=$DIR/$tdir/dom
21798
21799         mkdir -p $DIR/$tdir
21800
21801         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21802
21803         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21804         local facet=mds$((mdtidx + 1))
21805
21806         cancel_lru_locks mdc
21807         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21808         createmany -o $dom 1000
21809         lctl set_param -n mdc.*.stats=clear
21810         smalliomany -w $dom 1000 200
21811         get_mdc_stats $mdtidx
21812         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21813         # Each file has 1 open, 1 IO enqueues, total 2000
21814         # but now we have also +1 getxattr for security.capability, total 3000
21815         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21816         unlinkmany $dom 1000
21817
21818         cancel_lru_locks mdc
21819         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21820         createmany -o $dom 1000
21821         lctl set_param -n mdc.*.stats=clear
21822         smalliomany -w $dom 1000 200
21823         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21824         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21825         # for OPEN and IO lock.
21826         [ $((enq - enq_2)) -ge 1000 ] ||
21827                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21828         unlinkmany $dom 1000
21829         return 0
21830 }
21831 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21832
21833 cleanup_271def_tests() {
21834         trap 0
21835         rm -f $1
21836 }
21837
21838 test_271d() {
21839         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21840                 skip "Need MDS version at least 2.10.57"
21841
21842         local dom=$DIR/$tdir/dom
21843         local tmp=$TMP/$tfile
21844         trap "cleanup_271def_tests $tmp" EXIT
21845
21846         mkdir -p $DIR/$tdir
21847
21848         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21849
21850         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21851
21852         cancel_lru_locks mdc
21853         dd if=/dev/urandom of=$tmp bs=1000 count=1
21854         dd if=$tmp of=$dom bs=1000 count=1
21855         cancel_lru_locks mdc
21856
21857         cat /etc/hosts >> $tmp
21858         lctl set_param -n mdc.*.stats=clear
21859
21860         # append data to the same file it should update local page
21861         echo "Append to the same page"
21862         cat /etc/hosts >> $dom
21863         local num=$(get_mdc_stats $mdtidx ost_read)
21864         local ra=$(get_mdc_stats $mdtidx req_active)
21865         local rw=$(get_mdc_stats $mdtidx req_waittime)
21866
21867         [ -z $num ] || error "$num READ RPC occured"
21868         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21869         echo "... DONE"
21870
21871         # compare content
21872         cmp $tmp $dom || error "file miscompare"
21873
21874         cancel_lru_locks mdc
21875         lctl set_param -n mdc.*.stats=clear
21876
21877         echo "Open and read file"
21878         cat $dom > /dev/null
21879         local num=$(get_mdc_stats $mdtidx ost_read)
21880         local ra=$(get_mdc_stats $mdtidx req_active)
21881         local rw=$(get_mdc_stats $mdtidx req_waittime)
21882
21883         [ -z $num ] || error "$num READ RPC occured"
21884         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21885         echo "... DONE"
21886
21887         # compare content
21888         cmp $tmp $dom || error "file miscompare"
21889
21890         return 0
21891 }
21892 run_test 271d "DoM: read on open (1K file in reply buffer)"
21893
21894 test_271f() {
21895         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21896                 skip "Need MDS version at least 2.10.57"
21897
21898         local dom=$DIR/$tdir/dom
21899         local tmp=$TMP/$tfile
21900         trap "cleanup_271def_tests $tmp" EXIT
21901
21902         mkdir -p $DIR/$tdir
21903
21904         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21905
21906         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21907
21908         cancel_lru_locks mdc
21909         dd if=/dev/urandom of=$tmp bs=265000 count=1
21910         dd if=$tmp of=$dom bs=265000 count=1
21911         cancel_lru_locks mdc
21912         cat /etc/hosts >> $tmp
21913         lctl set_param -n mdc.*.stats=clear
21914
21915         echo "Append to the same page"
21916         cat /etc/hosts >> $dom
21917         local num=$(get_mdc_stats $mdtidx ost_read)
21918         local ra=$(get_mdc_stats $mdtidx req_active)
21919         local rw=$(get_mdc_stats $mdtidx req_waittime)
21920
21921         [ -z $num ] || error "$num READ RPC occured"
21922         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21923         echo "... DONE"
21924
21925         # compare content
21926         cmp $tmp $dom || error "file miscompare"
21927
21928         cancel_lru_locks mdc
21929         lctl set_param -n mdc.*.stats=clear
21930
21931         echo "Open and read file"
21932         cat $dom > /dev/null
21933         local num=$(get_mdc_stats $mdtidx ost_read)
21934         local ra=$(get_mdc_stats $mdtidx req_active)
21935         local rw=$(get_mdc_stats $mdtidx req_waittime)
21936
21937         [ -z $num ] && num=0
21938         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21939         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21940         echo "... DONE"
21941
21942         # compare content
21943         cmp $tmp $dom || error "file miscompare"
21944
21945         return 0
21946 }
21947 run_test 271f "DoM: read on open (200K file and read tail)"
21948
21949 test_271g() {
21950         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21951                 skip "Skipping due to old client or server version"
21952
21953         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21954         # to get layout
21955         $CHECKSTAT -t file $DIR1/$tfile
21956
21957         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21958         MULTIOP_PID=$!
21959         sleep 1
21960         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21961         $LCTL set_param fail_loc=0x80000314
21962         rm $DIR1/$tfile || error "Unlink fails"
21963         RC=$?
21964         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21965         [ $RC -eq 0 ] || error "Failed write to stale object"
21966 }
21967 run_test 271g "Discard DoM data vs client flush race"
21968
21969 test_272a() {
21970         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21971                 skip "Need MDS version at least 2.11.50"
21972
21973         local dom=$DIR/$tdir/dom
21974         mkdir -p $DIR/$tdir
21975
21976         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21977         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21978                 error "failed to write data into $dom"
21979         local old_md5=$(md5sum $dom)
21980
21981         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21982                 error "failed to migrate to the same DoM component"
21983
21984         local new_md5=$(md5sum $dom)
21985
21986         [ "$old_md5" == "$new_md5" ] ||
21987                 error "md5sum differ: $old_md5, $new_md5"
21988
21989         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21990                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21991 }
21992 run_test 272a "DoM migration: new layout with the same DOM component"
21993
21994 test_272b() {
21995         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21996                 skip "Need MDS version at least 2.11.50"
21997
21998         local dom=$DIR/$tdir/dom
21999         mkdir -p $DIR/$tdir
22000         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22001
22002         local mdtidx=$($LFS getstripe -m $dom)
22003         local mdtname=MDT$(printf %04x $mdtidx)
22004         local facet=mds$((mdtidx + 1))
22005
22006         local mdtfree1=$(do_facet $facet \
22007                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22008         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22009                 error "failed to write data into $dom"
22010         local old_md5=$(md5sum $dom)
22011         cancel_lru_locks mdc
22012         local mdtfree1=$(do_facet $facet \
22013                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22014
22015         $LFS migrate -c2 $dom ||
22016                 error "failed to migrate to the new composite layout"
22017         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22018                 error "MDT stripe was not removed"
22019
22020         cancel_lru_locks mdc
22021         local new_md5=$(md5sum $dom)
22022         [ "$old_md5" == "$new_md5" ] ||
22023                 error "$old_md5 != $new_md5"
22024
22025         # Skip free space checks with ZFS
22026         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22027                 local mdtfree2=$(do_facet $facet \
22028                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22029                 [ $mdtfree2 -gt $mdtfree1 ] ||
22030                         error "MDT space is not freed after migration"
22031         fi
22032         return 0
22033 }
22034 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22035
22036 test_272c() {
22037         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22038                 skip "Need MDS version at least 2.11.50"
22039
22040         local dom=$DIR/$tdir/$tfile
22041         mkdir -p $DIR/$tdir
22042         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22043
22044         local mdtidx=$($LFS getstripe -m $dom)
22045         local mdtname=MDT$(printf %04x $mdtidx)
22046         local facet=mds$((mdtidx + 1))
22047
22048         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22049                 error "failed to write data into $dom"
22050         local old_md5=$(md5sum $dom)
22051         cancel_lru_locks mdc
22052         local mdtfree1=$(do_facet $facet \
22053                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22054
22055         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22056                 error "failed to migrate to the new composite layout"
22057         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22058                 error "MDT stripe was not removed"
22059
22060         cancel_lru_locks mdc
22061         local new_md5=$(md5sum $dom)
22062         [ "$old_md5" == "$new_md5" ] ||
22063                 error "$old_md5 != $new_md5"
22064
22065         # Skip free space checks with ZFS
22066         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22067                 local mdtfree2=$(do_facet $facet \
22068                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22069                 [ $mdtfree2 -gt $mdtfree1 ] ||
22070                         error "MDS space is not freed after migration"
22071         fi
22072         return 0
22073 }
22074 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22075
22076 test_272d() {
22077         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22078                 skip "Need MDS version at least 2.12.55"
22079
22080         local dom=$DIR/$tdir/$tfile
22081         mkdir -p $DIR/$tdir
22082         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22083
22084         local mdtidx=$($LFS getstripe -m $dom)
22085         local mdtname=MDT$(printf %04x $mdtidx)
22086         local facet=mds$((mdtidx + 1))
22087
22088         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22089                 error "failed to write data into $dom"
22090         local old_md5=$(md5sum $dom)
22091         cancel_lru_locks mdc
22092         local mdtfree1=$(do_facet $facet \
22093                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22094
22095         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22096                 error "failed mirroring to the new composite layout"
22097         $LFS mirror resync $dom ||
22098                 error "failed mirror resync"
22099         $LFS mirror split --mirror-id 1 -d $dom ||
22100                 error "failed mirror split"
22101
22102         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22103                 error "MDT stripe was not removed"
22104
22105         cancel_lru_locks mdc
22106         local new_md5=$(md5sum $dom)
22107         [ "$old_md5" == "$new_md5" ] ||
22108                 error "$old_md5 != $new_md5"
22109
22110         # Skip free space checks with ZFS
22111         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22112                 local mdtfree2=$(do_facet $facet \
22113                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22114                 [ $mdtfree2 -gt $mdtfree1 ] ||
22115                         error "MDS space is not freed after DOM mirror deletion"
22116         fi
22117         return 0
22118 }
22119 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22120
22121 test_272e() {
22122         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22123                 skip "Need MDS version at least 2.12.55"
22124
22125         local dom=$DIR/$tdir/$tfile
22126         mkdir -p $DIR/$tdir
22127         $LFS setstripe -c 2 $dom
22128
22129         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22130                 error "failed to write data into $dom"
22131         local old_md5=$(md5sum $dom)
22132         cancel_lru_locks mdc
22133
22134         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22135                 error "failed mirroring to the DOM layout"
22136         $LFS mirror resync $dom ||
22137                 error "failed mirror resync"
22138         $LFS mirror split --mirror-id 1 -d $dom ||
22139                 error "failed mirror split"
22140
22141         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22142                 error "MDT stripe was not removed"
22143
22144         cancel_lru_locks mdc
22145         local new_md5=$(md5sum $dom)
22146         [ "$old_md5" == "$new_md5" ] ||
22147                 error "$old_md5 != $new_md5"
22148
22149         return 0
22150 }
22151 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22152
22153 test_272f() {
22154         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22155                 skip "Need MDS version at least 2.12.55"
22156
22157         local dom=$DIR/$tdir/$tfile
22158         mkdir -p $DIR/$tdir
22159         $LFS setstripe -c 2 $dom
22160
22161         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22162                 error "failed to write data into $dom"
22163         local old_md5=$(md5sum $dom)
22164         cancel_lru_locks mdc
22165
22166         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22167                 error "failed migrating to the DOM file"
22168
22169         cancel_lru_locks mdc
22170         local new_md5=$(md5sum $dom)
22171         [ "$old_md5" != "$new_md5" ] &&
22172                 error "$old_md5 != $new_md5"
22173
22174         return 0
22175 }
22176 run_test 272f "DoM migration: OST-striped file to DOM file"
22177
22178 test_273a() {
22179         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22180                 skip "Need MDS version at least 2.11.50"
22181
22182         # Layout swap cannot be done if either file has DOM component,
22183         # this will never be supported, migration should be used instead
22184
22185         local dom=$DIR/$tdir/$tfile
22186         mkdir -p $DIR/$tdir
22187
22188         $LFS setstripe -c2 ${dom}_plain
22189         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22190         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22191                 error "can swap layout with DoM component"
22192         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22193                 error "can swap layout with DoM component"
22194
22195         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22196         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22197                 error "can swap layout with DoM component"
22198         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22199                 error "can swap layout with DoM component"
22200         return 0
22201 }
22202 run_test 273a "DoM: layout swapping should fail with DOM"
22203
22204 test_273b() {
22205         mkdir -p $DIR/$tdir
22206         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22207
22208 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22209         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22210
22211         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22212 }
22213 run_test 273b "DoM: race writeback and object destroy"
22214
22215 test_275() {
22216         remote_ost_nodsh && skip "remote OST with nodsh"
22217         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22218                 skip "Need OST version >= 2.10.57"
22219
22220         local file=$DIR/$tfile
22221         local oss
22222
22223         oss=$(comma_list $(osts_nodes))
22224
22225         dd if=/dev/urandom of=$file bs=1M count=2 ||
22226                 error "failed to create a file"
22227         cancel_lru_locks osc
22228
22229         #lock 1
22230         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22231                 error "failed to read a file"
22232
22233 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22234         $LCTL set_param fail_loc=0x8000031f
22235
22236         cancel_lru_locks osc &
22237         sleep 1
22238
22239 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22240         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22241         #IO takes another lock, but matches the PENDING one
22242         #and places it to the IO RPC
22243         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22244                 error "failed to read a file with PENDING lock"
22245 }
22246 run_test 275 "Read on a canceled duplicate lock"
22247
22248 test_276() {
22249         remote_ost_nodsh && skip "remote OST with nodsh"
22250         local pid
22251
22252         do_facet ost1 "(while true; do \
22253                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22254                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22255         pid=$!
22256
22257         for LOOP in $(seq 20); do
22258                 stop ost1
22259                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22260         done
22261         kill -9 $pid
22262         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22263                 rm $TMP/sanity_276_pid"
22264 }
22265 run_test 276 "Race between mount and obd_statfs"
22266
22267 test_277() {
22268         $LCTL set_param ldlm.namespaces.*.lru_size=0
22269         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22270         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22271                         grep ^used_mb | awk '{print $2}')
22272         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22273         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22274                 oflag=direct conv=notrunc
22275         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22276                         grep ^used_mb | awk '{print $2}')
22277         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22278 }
22279 run_test 277 "Direct IO shall drop page cache"
22280
22281 test_278() {
22282         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22283         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22284         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22285                 skip "needs the same host for mdt1 mdt2" && return
22286
22287         local pid1
22288         local pid2
22289
22290 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22291         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22292         stop mds2 &
22293         pid2=$!
22294
22295         stop mds1
22296
22297         echo "Starting MDTs"
22298         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22299         wait $pid2
22300 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22301 #will return NULL
22302         do_facet mds2 $LCTL set_param fail_loc=0
22303
22304         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22305         wait_recovery_complete mds2
22306 }
22307 run_test 278 "Race starting MDS between MDTs stop/start"
22308
22309 test_280() {
22310         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22311                 skip "Need MGS version at least 2.13.52"
22312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22313         combined_mgs_mds || skip "needs combined MGS/MDT"
22314
22315         umount_client $MOUNT
22316 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22317         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22318
22319         mount_client $MOUNT &
22320         sleep 1
22321         stop mgs || error "stop mgs failed"
22322         #for a race mgs would crash
22323         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22324         # make sure we unmount client before remounting
22325         wait
22326         umount_client $MOUNT
22327         mount_client $MOUNT || error "mount client failed"
22328 }
22329 run_test 280 "Race between MGS umount and client llog processing"
22330
22331 cleanup_test_300() {
22332         trap 0
22333         umask $SAVE_UMASK
22334 }
22335 test_striped_dir() {
22336         local mdt_index=$1
22337         local stripe_count
22338         local stripe_index
22339
22340         mkdir -p $DIR/$tdir
22341
22342         SAVE_UMASK=$(umask)
22343         trap cleanup_test_300 RETURN EXIT
22344
22345         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22346                                                 $DIR/$tdir/striped_dir ||
22347                 error "set striped dir error"
22348
22349         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22350         [ "$mode" = "755" ] || error "expect 755 got $mode"
22351
22352         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22353                 error "getdirstripe failed"
22354         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22355         if [ "$stripe_count" != "2" ]; then
22356                 error "1:stripe_count is $stripe_count, expect 2"
22357         fi
22358         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22359         if [ "$stripe_count" != "2" ]; then
22360                 error "2:stripe_count is $stripe_count, expect 2"
22361         fi
22362
22363         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22364         if [ "$stripe_index" != "$mdt_index" ]; then
22365                 error "stripe_index is $stripe_index, expect $mdt_index"
22366         fi
22367
22368         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22369                 error "nlink error after create striped dir"
22370
22371         mkdir $DIR/$tdir/striped_dir/a
22372         mkdir $DIR/$tdir/striped_dir/b
22373
22374         stat $DIR/$tdir/striped_dir/a ||
22375                 error "create dir under striped dir failed"
22376         stat $DIR/$tdir/striped_dir/b ||
22377                 error "create dir under striped dir failed"
22378
22379         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22380                 error "nlink error after mkdir"
22381
22382         rmdir $DIR/$tdir/striped_dir/a
22383         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22384                 error "nlink error after rmdir"
22385
22386         rmdir $DIR/$tdir/striped_dir/b
22387         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22388                 error "nlink error after rmdir"
22389
22390         chattr +i $DIR/$tdir/striped_dir
22391         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22392                 error "immutable flags not working under striped dir!"
22393         chattr -i $DIR/$tdir/striped_dir
22394
22395         rmdir $DIR/$tdir/striped_dir ||
22396                 error "rmdir striped dir error"
22397
22398         cleanup_test_300
22399
22400         true
22401 }
22402
22403 test_300a() {
22404         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22405                 skip "skipped for lustre < 2.7.0"
22406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22408
22409         test_striped_dir 0 || error "failed on striped dir on MDT0"
22410         test_striped_dir 1 || error "failed on striped dir on MDT0"
22411 }
22412 run_test 300a "basic striped dir sanity test"
22413
22414 test_300b() {
22415         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22416                 skip "skipped for lustre < 2.7.0"
22417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22419
22420         local i
22421         local mtime1
22422         local mtime2
22423         local mtime3
22424
22425         test_mkdir $DIR/$tdir || error "mkdir fail"
22426         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22427                 error "set striped dir error"
22428         for i in {0..9}; do
22429                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22430                 sleep 1
22431                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22432                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22433                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22434                 sleep 1
22435                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22436                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22437                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22438         done
22439         true
22440 }
22441 run_test 300b "check ctime/mtime for striped dir"
22442
22443 test_300c() {
22444         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22445                 skip "skipped for lustre < 2.7.0"
22446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22447         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22448
22449         local file_count
22450
22451         mkdir_on_mdt0 $DIR/$tdir
22452         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22453                 error "set striped dir error"
22454
22455         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22456                 error "chown striped dir failed"
22457
22458         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22459                 error "create 5k files failed"
22460
22461         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22462
22463         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22464
22465         rm -rf $DIR/$tdir
22466 }
22467 run_test 300c "chown && check ls under striped directory"
22468
22469 test_300d() {
22470         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22471                 skip "skipped for lustre < 2.7.0"
22472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22474
22475         local stripe_count
22476         local file
22477
22478         mkdir -p $DIR/$tdir
22479         $LFS setstripe -c 2 $DIR/$tdir
22480
22481         #local striped directory
22482         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22483                 error "set striped dir error"
22484         #look at the directories for debug purposes
22485         ls -l $DIR/$tdir
22486         $LFS getdirstripe $DIR/$tdir
22487         ls -l $DIR/$tdir/striped_dir
22488         $LFS getdirstripe $DIR/$tdir/striped_dir
22489         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22490                 error "create 10 files failed"
22491
22492         #remote striped directory
22493         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22494                 error "set striped dir error"
22495         #look at the directories for debug purposes
22496         ls -l $DIR/$tdir
22497         $LFS getdirstripe $DIR/$tdir
22498         ls -l $DIR/$tdir/remote_striped_dir
22499         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22500         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22501                 error "create 10 files failed"
22502
22503         for file in $(find $DIR/$tdir); do
22504                 stripe_count=$($LFS getstripe -c $file)
22505                 [ $stripe_count -eq 2 ] ||
22506                         error "wrong stripe $stripe_count for $file"
22507         done
22508
22509         rm -rf $DIR/$tdir
22510 }
22511 run_test 300d "check default stripe under striped directory"
22512
22513 test_300e() {
22514         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22515                 skip "Need MDS version at least 2.7.55"
22516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22518
22519         local stripe_count
22520         local file
22521
22522         mkdir -p $DIR/$tdir
22523
22524         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22525                 error "set striped dir error"
22526
22527         touch $DIR/$tdir/striped_dir/a
22528         touch $DIR/$tdir/striped_dir/b
22529         touch $DIR/$tdir/striped_dir/c
22530
22531         mkdir $DIR/$tdir/striped_dir/dir_a
22532         mkdir $DIR/$tdir/striped_dir/dir_b
22533         mkdir $DIR/$tdir/striped_dir/dir_c
22534
22535         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22536                 error "set striped adir under striped dir error"
22537
22538         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22539                 error "set striped bdir under striped dir error"
22540
22541         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22542                 error "set striped cdir under striped dir error"
22543
22544         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22545                 error "rename dir under striped dir fails"
22546
22547         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22548                 error "rename dir under different stripes fails"
22549
22550         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22551                 error "rename file under striped dir should succeed"
22552
22553         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22554                 error "rename dir under striped dir should succeed"
22555
22556         rm -rf $DIR/$tdir
22557 }
22558 run_test 300e "check rename under striped directory"
22559
22560 test_300f() {
22561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22563         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22564                 skip "Need MDS version at least 2.7.55"
22565
22566         local stripe_count
22567         local file
22568
22569         rm -rf $DIR/$tdir
22570         mkdir -p $DIR/$tdir
22571
22572         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22573                 error "set striped dir error"
22574
22575         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22576                 error "set striped dir error"
22577
22578         touch $DIR/$tdir/striped_dir/a
22579         mkdir $DIR/$tdir/striped_dir/dir_a
22580         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22581                 error "create striped dir under striped dir fails"
22582
22583         touch $DIR/$tdir/striped_dir1/b
22584         mkdir $DIR/$tdir/striped_dir1/dir_b
22585         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22586                 error "create striped dir under striped dir fails"
22587
22588         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22589                 error "rename dir under different striped dir should fail"
22590
22591         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22592                 error "rename striped dir under diff striped dir should fail"
22593
22594         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22595                 error "rename file under diff striped dirs fails"
22596
22597         rm -rf $DIR/$tdir
22598 }
22599 run_test 300f "check rename cross striped directory"
22600
22601 test_300_check_default_striped_dir()
22602 {
22603         local dirname=$1
22604         local default_count=$2
22605         local default_index=$3
22606         local stripe_count
22607         local stripe_index
22608         local dir_stripe_index
22609         local dir
22610
22611         echo "checking $dirname $default_count $default_index"
22612         $LFS setdirstripe -D -c $default_count -i $default_index \
22613                                 -H all_char $DIR/$tdir/$dirname ||
22614                 error "set default stripe on striped dir error"
22615         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22616         [ $stripe_count -eq $default_count ] ||
22617                 error "expect $default_count get $stripe_count for $dirname"
22618
22619         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22620         [ $stripe_index -eq $default_index ] ||
22621                 error "expect $default_index get $stripe_index for $dirname"
22622
22623         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22624                                                 error "create dirs failed"
22625
22626         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22627         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22628         for dir in $(find $DIR/$tdir/$dirname/*); do
22629                 stripe_count=$($LFS getdirstripe -c $dir)
22630                 (( $stripe_count == $default_count )) ||
22631                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22632                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22633                 error "stripe count $default_count != $stripe_count for $dir"
22634
22635                 stripe_index=$($LFS getdirstripe -i $dir)
22636                 [ $default_index -eq -1 ] ||
22637                         [ $stripe_index -eq $default_index ] ||
22638                         error "$stripe_index != $default_index for $dir"
22639
22640                 #check default stripe
22641                 stripe_count=$($LFS getdirstripe -D -c $dir)
22642                 [ $stripe_count -eq $default_count ] ||
22643                 error "default count $default_count != $stripe_count for $dir"
22644
22645                 stripe_index=$($LFS getdirstripe -D -i $dir)
22646                 [ $stripe_index -eq $default_index ] ||
22647                 error "default index $default_index != $stripe_index for $dir"
22648         done
22649         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22650 }
22651
22652 test_300g() {
22653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22654         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22655                 skip "Need MDS version at least 2.7.55"
22656
22657         local dir
22658         local stripe_count
22659         local stripe_index
22660
22661         mkdir_on_mdt0 $DIR/$tdir
22662         mkdir $DIR/$tdir/normal_dir
22663
22664         #Checking when client cache stripe index
22665         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22666         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22667                 error "create striped_dir failed"
22668
22669         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22670                 error "create dir0 fails"
22671         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22672         [ $stripe_index -eq 0 ] ||
22673                 error "dir0 expect index 0 got $stripe_index"
22674
22675         mkdir $DIR/$tdir/striped_dir/dir1 ||
22676                 error "create dir1 fails"
22677         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22678         [ $stripe_index -eq 1 ] ||
22679                 error "dir1 expect index 1 got $stripe_index"
22680
22681         #check default stripe count/stripe index
22682         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22683         test_300_check_default_striped_dir normal_dir 1 0
22684         test_300_check_default_striped_dir normal_dir -1 1
22685         test_300_check_default_striped_dir normal_dir 2 -1
22686
22687         #delete default stripe information
22688         echo "delete default stripeEA"
22689         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22690                 error "set default stripe on striped dir error"
22691
22692         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22693         for dir in $(find $DIR/$tdir/normal_dir/*); do
22694                 stripe_count=$($LFS getdirstripe -c $dir)
22695                 [ $stripe_count -eq 0 ] ||
22696                         error "expect 1 get $stripe_count for $dir"
22697         done
22698 }
22699 run_test 300g "check default striped directory for normal directory"
22700
22701 test_300h() {
22702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22703         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22704                 skip "Need MDS version at least 2.7.55"
22705
22706         local dir
22707         local stripe_count
22708
22709         mkdir $DIR/$tdir
22710         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22711                 error "set striped dir error"
22712
22713         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22714         test_300_check_default_striped_dir striped_dir 1 0
22715         test_300_check_default_striped_dir striped_dir -1 1
22716         test_300_check_default_striped_dir striped_dir 2 -1
22717
22718         #delete default stripe information
22719         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22720                 error "set default stripe on striped dir error"
22721
22722         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22723         for dir in $(find $DIR/$tdir/striped_dir/*); do
22724                 stripe_count=$($LFS getdirstripe -c $dir)
22725                 [ $stripe_count -eq 0 ] ||
22726                         error "expect 1 get $stripe_count for $dir"
22727         done
22728 }
22729 run_test 300h "check default striped directory for striped directory"
22730
22731 test_300i() {
22732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22733         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22734         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22735                 skip "Need MDS version at least 2.7.55"
22736
22737         local stripe_count
22738         local file
22739
22740         mkdir $DIR/$tdir
22741
22742         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22743                 error "set striped dir error"
22744
22745         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22746                 error "create files under striped dir failed"
22747
22748         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22749                 error "set striped hashdir error"
22750
22751         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22752                 error "create dir0 under hash dir failed"
22753         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22754                 error "create dir1 under hash dir failed"
22755         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22756                 error "create dir2 under hash dir failed"
22757
22758         # unfortunately, we need to umount to clear dir layout cache for now
22759         # once we fully implement dir layout, we can drop this
22760         umount_client $MOUNT || error "umount failed"
22761         mount_client $MOUNT || error "mount failed"
22762
22763         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22764         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22765         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22766
22767         #set the stripe to be unknown hash type
22768         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22769         $LCTL set_param fail_loc=0x1901
22770         for ((i = 0; i < 10; i++)); do
22771                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22772                         error "stat f-$i failed"
22773                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22774         done
22775
22776         touch $DIR/$tdir/striped_dir/f0 &&
22777                 error "create under striped dir with unknown hash should fail"
22778
22779         $LCTL set_param fail_loc=0
22780
22781         umount_client $MOUNT || error "umount failed"
22782         mount_client $MOUNT || error "mount failed"
22783
22784         return 0
22785 }
22786 run_test 300i "client handle unknown hash type striped directory"
22787
22788 test_300j() {
22789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22791         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22792                 skip "Need MDS version at least 2.7.55"
22793
22794         local stripe_count
22795         local file
22796
22797         mkdir $DIR/$tdir
22798
22799         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22800         $LCTL set_param fail_loc=0x1702
22801         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22802                 error "set striped dir error"
22803
22804         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22805                 error "create files under striped dir failed"
22806
22807         $LCTL set_param fail_loc=0
22808
22809         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22810
22811         return 0
22812 }
22813 run_test 300j "test large update record"
22814
22815 test_300k() {
22816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22817         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22818         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22819                 skip "Need MDS version at least 2.7.55"
22820
22821         # this test needs a huge transaction
22822         local kb
22823         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22824              osd*.$FSNAME-MDT0000.kbytestotal")
22825         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22826
22827         local stripe_count
22828         local file
22829
22830         mkdir $DIR/$tdir
22831
22832         #define OBD_FAIL_LARGE_STRIPE   0x1703
22833         $LCTL set_param fail_loc=0x1703
22834         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22835                 error "set striped dir error"
22836         $LCTL set_param fail_loc=0
22837
22838         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22839                 error "getstripeddir fails"
22840         rm -rf $DIR/$tdir/striped_dir ||
22841                 error "unlink striped dir fails"
22842
22843         return 0
22844 }
22845 run_test 300k "test large striped directory"
22846
22847 test_300l() {
22848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22850         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22851                 skip "Need MDS version at least 2.7.55"
22852
22853         local stripe_index
22854
22855         test_mkdir -p $DIR/$tdir/striped_dir
22856         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22857                         error "chown $RUNAS_ID failed"
22858         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22859                 error "set default striped dir failed"
22860
22861         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22862         $LCTL set_param fail_loc=0x80000158
22863         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22864
22865         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22866         [ $stripe_index -eq 1 ] ||
22867                 error "expect 1 get $stripe_index for $dir"
22868 }
22869 run_test 300l "non-root user to create dir under striped dir with stale layout"
22870
22871 test_300m() {
22872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22873         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22874         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22875                 skip "Need MDS version at least 2.7.55"
22876
22877         mkdir -p $DIR/$tdir/striped_dir
22878         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22879                 error "set default stripes dir error"
22880
22881         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22882
22883         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22884         [ $stripe_count -eq 0 ] ||
22885                         error "expect 0 get $stripe_count for a"
22886
22887         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22888                 error "set default stripes dir error"
22889
22890         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22891
22892         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22893         [ $stripe_count -eq 0 ] ||
22894                         error "expect 0 get $stripe_count for b"
22895
22896         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22897                 error "set default stripes dir error"
22898
22899         mkdir $DIR/$tdir/striped_dir/c &&
22900                 error "default stripe_index is invalid, mkdir c should fails"
22901
22902         rm -rf $DIR/$tdir || error "rmdir fails"
22903 }
22904 run_test 300m "setstriped directory on single MDT FS"
22905
22906 cleanup_300n() {
22907         local list=$(comma_list $(mdts_nodes))
22908
22909         trap 0
22910         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22911 }
22912
22913 test_300n() {
22914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22916         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22917                 skip "Need MDS version at least 2.7.55"
22918         remote_mds_nodsh && skip "remote MDS with nodsh"
22919
22920         local stripe_index
22921         local list=$(comma_list $(mdts_nodes))
22922
22923         trap cleanup_300n RETURN EXIT
22924         mkdir -p $DIR/$tdir
22925         chmod 777 $DIR/$tdir
22926         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22927                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22928                 error "create striped dir succeeds with gid=0"
22929
22930         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22931         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22932                 error "create striped dir fails with gid=-1"
22933
22934         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22935         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22936                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22937                 error "set default striped dir succeeds with gid=0"
22938
22939
22940         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22941         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22942                 error "set default striped dir fails with gid=-1"
22943
22944
22945         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22946         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22947                                         error "create test_dir fails"
22948         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22949                                         error "create test_dir1 fails"
22950         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22951                                         error "create test_dir2 fails"
22952         cleanup_300n
22953 }
22954 run_test 300n "non-root user to create dir under striped dir with default EA"
22955
22956 test_300o() {
22957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22959         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22960                 skip "Need MDS version at least 2.7.55"
22961
22962         local numfree1
22963         local numfree2
22964
22965         mkdir -p $DIR/$tdir
22966
22967         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22968         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22969         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22970                 skip "not enough free inodes $numfree1 $numfree2"
22971         fi
22972
22973         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22974         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22975         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22976                 skip "not enough free space $numfree1 $numfree2"
22977         fi
22978
22979         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22980                 error "setdirstripe fails"
22981
22982         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22983                 error "create dirs fails"
22984
22985         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22986         ls $DIR/$tdir/striped_dir > /dev/null ||
22987                 error "ls striped dir fails"
22988         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22989                 error "unlink big striped dir fails"
22990 }
22991 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22992
22993 test_300p() {
22994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22995         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22996         remote_mds_nodsh && skip "remote MDS with nodsh"
22997
22998         mkdir_on_mdt0 $DIR/$tdir
22999
23000         #define OBD_FAIL_OUT_ENOSPC     0x1704
23001         do_facet mds2 lctl set_param fail_loc=0x80001704
23002         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23003                  && error "create striped directory should fail"
23004
23005         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23006
23007         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23008         true
23009 }
23010 run_test 300p "create striped directory without space"
23011
23012 test_300q() {
23013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23014         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23015
23016         local fd=$(free_fd)
23017         local cmd="exec $fd<$tdir"
23018         cd $DIR
23019         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23020         eval $cmd
23021         cmd="exec $fd<&-"
23022         trap "eval $cmd" EXIT
23023         cd $tdir || error "cd $tdir fails"
23024         rmdir  ../$tdir || error "rmdir $tdir fails"
23025         mkdir local_dir && error "create dir succeeds"
23026         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23027         eval $cmd
23028         return 0
23029 }
23030 run_test 300q "create remote directory under orphan directory"
23031
23032 test_300r() {
23033         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23034                 skip "Need MDS version at least 2.7.55" && return
23035         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23036
23037         mkdir $DIR/$tdir
23038
23039         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23040                 error "set striped dir error"
23041
23042         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23043                 error "getstripeddir fails"
23044
23045         local stripe_count
23046         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23047                       awk '/lmv_stripe_count:/ { print $2 }')
23048
23049         [ $MDSCOUNT -ne $stripe_count ] &&
23050                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23051
23052         rm -rf $DIR/$tdir/striped_dir ||
23053                 error "unlink striped dir fails"
23054 }
23055 run_test 300r "test -1 striped directory"
23056
23057 test_300s_helper() {
23058         local count=$1
23059
23060         local stripe_dir=$DIR/$tdir/striped_dir.$count
23061
23062         $LFS mkdir -c $count $stripe_dir ||
23063                 error "lfs mkdir -c error"
23064
23065         $LFS getdirstripe $stripe_dir ||
23066                 error "lfs getdirstripe fails"
23067
23068         local stripe_count
23069         stripe_count=$($LFS getdirstripe $stripe_dir |
23070                       awk '/lmv_stripe_count:/ { print $2 }')
23071
23072         [ $count -ne $stripe_count ] &&
23073                 error_noexit "bad stripe count $stripe_count expected $count"
23074
23075         local dupe_stripes
23076         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23077                 awk '/0x/ {count[$1] += 1}; END {
23078                         for (idx in count) {
23079                                 if (count[idx]>1) {
23080                                         print "index " idx " count " count[idx]
23081                                 }
23082                         }
23083                 }')
23084
23085         if [[ -n "$dupe_stripes" ]] ; then
23086                 lfs getdirstripe $stripe_dir
23087                 error_noexit "Dupe MDT above: $dupe_stripes "
23088         fi
23089
23090         rm -rf $stripe_dir ||
23091                 error_noexit "unlink $stripe_dir fails"
23092 }
23093
23094 test_300s() {
23095         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23096                 skip "Need MDS version at least 2.7.55" && return
23097         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23098
23099         mkdir $DIR/$tdir
23100         for count in $(seq 2 $MDSCOUNT); do
23101                 test_300s_helper $count
23102         done
23103 }
23104 run_test 300s "test lfs mkdir -c without -i"
23105
23106
23107 prepare_remote_file() {
23108         mkdir $DIR/$tdir/src_dir ||
23109                 error "create remote source failed"
23110
23111         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23112                  error "cp to remote source failed"
23113         touch $DIR/$tdir/src_dir/a
23114
23115         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23116                 error "create remote target dir failed"
23117
23118         touch $DIR/$tdir/tgt_dir/b
23119
23120         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23121                 error "rename dir cross MDT failed!"
23122
23123         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23124                 error "src_child still exists after rename"
23125
23126         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23127                 error "missing file(a) after rename"
23128
23129         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23130                 error "diff after rename"
23131 }
23132
23133 test_310a() {
23134         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23136
23137         local remote_file=$DIR/$tdir/tgt_dir/b
23138
23139         mkdir -p $DIR/$tdir
23140
23141         prepare_remote_file || error "prepare remote file failed"
23142
23143         #open-unlink file
23144         $OPENUNLINK $remote_file $remote_file ||
23145                 error "openunlink $remote_file failed"
23146         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23147 }
23148 run_test 310a "open unlink remote file"
23149
23150 test_310b() {
23151         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23153
23154         local remote_file=$DIR/$tdir/tgt_dir/b
23155
23156         mkdir -p $DIR/$tdir
23157
23158         prepare_remote_file || error "prepare remote file failed"
23159
23160         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23161         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23162         $CHECKSTAT -t file $remote_file || error "check file failed"
23163 }
23164 run_test 310b "unlink remote file with multiple links while open"
23165
23166 test_310c() {
23167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23168         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23169
23170         local remote_file=$DIR/$tdir/tgt_dir/b
23171
23172         mkdir -p $DIR/$tdir
23173
23174         prepare_remote_file || error "prepare remote file failed"
23175
23176         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23177         multiop_bg_pause $remote_file O_uc ||
23178                         error "mulitop failed for remote file"
23179         MULTIPID=$!
23180         $MULTIOP $DIR/$tfile Ouc
23181         kill -USR1 $MULTIPID
23182         wait $MULTIPID
23183 }
23184 run_test 310c "open-unlink remote file with multiple links"
23185
23186 #LU-4825
23187 test_311() {
23188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23189         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23190         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23191                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23192         remote_mds_nodsh && skip "remote MDS with nodsh"
23193
23194         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23195         local mdts=$(comma_list $(mdts_nodes))
23196
23197         mkdir -p $DIR/$tdir
23198         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23199         createmany -o $DIR/$tdir/$tfile. 1000
23200
23201         # statfs data is not real time, let's just calculate it
23202         old_iused=$((old_iused + 1000))
23203
23204         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23205                         osp.*OST0000*MDT0000.create_count")
23206         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23207                                 osp.*OST0000*MDT0000.max_create_count")
23208         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23209
23210         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23211         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23212         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23213
23214         unlinkmany $DIR/$tdir/$tfile. 1000
23215
23216         do_nodes $mdts "$LCTL set_param -n \
23217                         osp.*OST0000*.max_create_count=$max_count"
23218         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23219                 do_nodes $mdts "$LCTL set_param -n \
23220                                 osp.*OST0000*.create_count=$count"
23221         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23222                         grep "=0" && error "create_count is zero"
23223
23224         local new_iused
23225         for i in $(seq 120); do
23226                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23227                 # system may be too busy to destroy all objs in time, use
23228                 # a somewhat small value to not fail autotest
23229                 [ $((old_iused - new_iused)) -gt 400 ] && break
23230                 sleep 1
23231         done
23232
23233         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23234         [ $((old_iused - new_iused)) -gt 400 ] ||
23235                 error "objs not destroyed after unlink"
23236 }
23237 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23238
23239 zfs_oid_to_objid()
23240 {
23241         local ost=$1
23242         local objid=$2
23243
23244         local vdevdir=$(dirname $(facet_vdevice $ost))
23245         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23246         local zfs_zapid=$(do_facet $ost $cmd |
23247                           grep -w "/O/0/d$((objid%32))" -C 5 |
23248                           awk '/Object/{getline; print $1}')
23249         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23250                           awk "/$objid = /"'{printf $3}')
23251
23252         echo $zfs_objid
23253 }
23254
23255 zfs_object_blksz() {
23256         local ost=$1
23257         local objid=$2
23258
23259         local vdevdir=$(dirname $(facet_vdevice $ost))
23260         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23261         local blksz=$(do_facet $ost $cmd $objid |
23262                       awk '/dblk/{getline; printf $4}')
23263
23264         case "${blksz: -1}" in
23265                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23266                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23267                 *) ;;
23268         esac
23269
23270         echo $blksz
23271 }
23272
23273 test_312() { # LU-4856
23274         remote_ost_nodsh && skip "remote OST with nodsh"
23275         [ "$ost1_FSTYPE" = "zfs" ] ||
23276                 skip_env "the test only applies to zfs"
23277
23278         local max_blksz=$(do_facet ost1 \
23279                           $ZFS get -p recordsize $(facet_device ost1) |
23280                           awk '!/VALUE/{print $3}')
23281
23282         # to make life a little bit easier
23283         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23284         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23285
23286         local tf=$DIR/$tdir/$tfile
23287         touch $tf
23288         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23289
23290         # Get ZFS object id
23291         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23292         # block size change by sequential overwrite
23293         local bs
23294
23295         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23296                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23297
23298                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23299                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23300         done
23301         rm -f $tf
23302
23303         # block size change by sequential append write
23304         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23305         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23306         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23307         local count
23308
23309         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23310                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23311                         oflag=sync conv=notrunc
23312
23313                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23314                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23315                         error "blksz error, actual $blksz, " \
23316                                 "expected: 2 * $count * $PAGE_SIZE"
23317         done
23318         rm -f $tf
23319
23320         # random write
23321         touch $tf
23322         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23323         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23324
23325         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23326         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23327         [ $blksz -eq $PAGE_SIZE ] ||
23328                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23329
23330         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23331         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23332         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23333
23334         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23335         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23336         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23337 }
23338 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23339
23340 test_313() {
23341         remote_ost_nodsh && skip "remote OST with nodsh"
23342
23343         local file=$DIR/$tfile
23344
23345         rm -f $file
23346         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23347
23348         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23349         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23350         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23351                 error "write should failed"
23352         do_facet ost1 "$LCTL set_param fail_loc=0"
23353         rm -f $file
23354 }
23355 run_test 313 "io should fail after last_rcvd update fail"
23356
23357 test_314() {
23358         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23359
23360         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23361         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23362         rm -f $DIR/$tfile
23363         wait_delete_completed
23364         do_facet ost1 "$LCTL set_param fail_loc=0"
23365 }
23366 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23367
23368 test_315() { # LU-618
23369         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23370
23371         local file=$DIR/$tfile
23372         rm -f $file
23373
23374         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23375                 error "multiop file write failed"
23376         $MULTIOP $file oO_RDONLY:r4063232_c &
23377         PID=$!
23378
23379         sleep 2
23380
23381         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23382         kill -USR1 $PID
23383
23384         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23385         rm -f $file
23386 }
23387 run_test 315 "read should be accounted"
23388
23389 test_316() {
23390         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23391         large_xattr_enabled || skip_env "ea_inode feature disabled"
23392
23393         rm -rf $DIR/$tdir/d
23394         mkdir -p $DIR/$tdir/d
23395         chown nobody $DIR/$tdir/d
23396         touch $DIR/$tdir/d/file
23397
23398         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23399 }
23400 run_test 316 "lfs mv"
23401
23402 test_317() {
23403         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23404                 skip "Need MDS version at least 2.11.53"
23405         if [ "$ost1_FSTYPE" == "zfs" ]; then
23406                 skip "LU-10370: no implementation for ZFS"
23407         fi
23408
23409         local trunc_sz
23410         local grant_blk_size
23411
23412         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23413                         awk '/grant_block_size:/ { print $2; exit; }')
23414         #
23415         # Create File of size 5M. Truncate it to below size's and verify
23416         # blocks count.
23417         #
23418         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23419                 error "Create file $DIR/$tfile failed"
23420         stack_trap "rm -f $DIR/$tfile" EXIT
23421
23422         for trunc_sz in 2097152 4097 4000 509 0; do
23423                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23424                         error "truncate $tfile to $trunc_sz failed"
23425                 local sz=$(stat --format=%s $DIR/$tfile)
23426                 local blk=$(stat --format=%b $DIR/$tfile)
23427                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23428                                      grant_blk_size) * 8))
23429
23430                 if [[ $blk -ne $trunc_blk ]]; then
23431                         $(which stat) $DIR/$tfile
23432                         error "Expected Block $trunc_blk got $blk for $tfile"
23433                 fi
23434
23435                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23436                         error "Expected Size $trunc_sz got $sz for $tfile"
23437         done
23438
23439         #
23440         # sparse file test
23441         # Create file with a hole and write actual two blocks. Block count
23442         # must be 16.
23443         #
23444         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23445                 conv=fsync || error "Create file : $DIR/$tfile"
23446
23447         # Calculate the final truncate size.
23448         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23449
23450         #
23451         # truncate to size $trunc_sz bytes. Strip the last block
23452         # The block count must drop to 8
23453         #
23454         $TRUNCATE $DIR/$tfile $trunc_sz ||
23455                 error "truncate $tfile to $trunc_sz failed"
23456
23457         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23458         sz=$(stat --format=%s $DIR/$tfile)
23459         blk=$(stat --format=%b $DIR/$tfile)
23460
23461         if [[ $blk -ne $trunc_bsz ]]; then
23462                 $(which stat) $DIR/$tfile
23463                 error "Expected Block $trunc_bsz got $blk for $tfile"
23464         fi
23465
23466         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23467                 error "Expected Size $trunc_sz got $sz for $tfile"
23468 }
23469 run_test 317 "Verify blocks get correctly update after truncate"
23470
23471 test_318() {
23472         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23473         local old_max_active=$($LCTL get_param -n \
23474                             ${llite_name}.max_read_ahead_async_active \
23475                             2>/dev/null)
23476
23477         $LCTL set_param llite.*.max_read_ahead_async_active=256
23478         local max_active=$($LCTL get_param -n \
23479                            ${llite_name}.max_read_ahead_async_active \
23480                            2>/dev/null)
23481         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23482
23483         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23484                 error "set max_read_ahead_async_active should succeed"
23485
23486         $LCTL set_param llite.*.max_read_ahead_async_active=512
23487         max_active=$($LCTL get_param -n \
23488                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23489         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23490
23491         # restore @max_active
23492         [ $old_max_active -ne 0 ] && $LCTL set_param \
23493                 llite.*.max_read_ahead_async_active=$old_max_active
23494
23495         local old_threshold=$($LCTL get_param -n \
23496                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23497         local max_per_file_mb=$($LCTL get_param -n \
23498                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23499
23500         local invalid=$(($max_per_file_mb + 1))
23501         $LCTL set_param \
23502                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23503                         && error "set $invalid should fail"
23504
23505         local valid=$(($invalid - 1))
23506         $LCTL set_param \
23507                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23508                         error "set $valid should succeed"
23509         local threshold=$($LCTL get_param -n \
23510                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23511         [ $threshold -eq $valid ] || error \
23512                 "expect threshold $valid got $threshold"
23513         $LCTL set_param \
23514                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23515 }
23516 run_test 318 "Verify async readahead tunables"
23517
23518 test_319() {
23519         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23520
23521         local before=$(date +%s)
23522         local evict
23523         local mdir=$DIR/$tdir
23524         local file=$mdir/xxx
23525
23526         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23527         touch $file
23528
23529 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23530         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23531         $LFS mv -m1 $file &
23532
23533         sleep 1
23534         dd if=$file of=/dev/null
23535         wait
23536         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23537           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23538
23539         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23540 }
23541 run_test 319 "lost lease lock on migrate error"
23542
23543 test_398a() { # LU-4198
23544         local ost1_imp=$(get_osc_import_name client ost1)
23545         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23546                          cut -d'.' -f2)
23547
23548         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23549         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23550
23551         # request a new lock on client
23552         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23553
23554         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23555         local lock_count=$($LCTL get_param -n \
23556                            ldlm.namespaces.$imp_name.lru_size)
23557         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23558
23559         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23560
23561         # no lock cached, should use lockless IO and not enqueue new lock
23562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23563         lock_count=$($LCTL get_param -n \
23564                      ldlm.namespaces.$imp_name.lru_size)
23565         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23566 }
23567 run_test 398a "direct IO should cancel lock otherwise lockless"
23568
23569 test_398b() { # LU-4198
23570         which fio || skip_env "no fio installed"
23571         $LFS setstripe -c -1 $DIR/$tfile
23572
23573         local size=12
23574         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23575
23576         local njobs=4
23577         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23578         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23579                 --numjobs=$njobs --fallocate=none \
23580                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23581                 --filename=$DIR/$tfile &
23582         bg_pid=$!
23583
23584         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23585         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23586                 --numjobs=$njobs --fallocate=none \
23587                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23588                 --filename=$DIR/$tfile || true
23589         wait $bg_pid
23590
23591         rm -f $DIR/$tfile
23592 }
23593 run_test 398b "DIO and buffer IO race"
23594
23595 test_398c() { # LU-4198
23596         local ost1_imp=$(get_osc_import_name client ost1)
23597         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23598                          cut -d'.' -f2)
23599
23600         which fio || skip_env "no fio installed"
23601
23602         saved_debug=$($LCTL get_param -n debug)
23603         $LCTL set_param debug=0
23604
23605         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23606         ((size /= 1024)) # by megabytes
23607         ((size /= 2)) # write half of the OST at most
23608         [ $size -gt 40 ] && size=40 #reduce test time anyway
23609
23610         $LFS setstripe -c 1 $DIR/$tfile
23611
23612         # it seems like ldiskfs reserves more space than necessary if the
23613         # writing blocks are not mapped, so it extends the file firstly
23614         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23615         cancel_lru_locks osc
23616
23617         # clear and verify rpc_stats later
23618         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23619
23620         local njobs=4
23621         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23622         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23623                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23624                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23625                 --filename=$DIR/$tfile
23626         [ $? -eq 0 ] || error "fio write error"
23627
23628         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23629                 error "Locks were requested while doing AIO"
23630
23631         # get the percentage of 1-page I/O
23632         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23633                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23634                 awk '{print $7}')
23635         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23636
23637         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23638         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23639                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23640                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23641                 --filename=$DIR/$tfile
23642         [ $? -eq 0 ] || error "fio mixed read write error"
23643
23644         echo "AIO with large block size ${size}M"
23645         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23646                 --numjobs=1 --fallocate=none --ioengine=libaio \
23647                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23648                 --filename=$DIR/$tfile
23649         [ $? -eq 0 ] || error "fio large block size failed"
23650
23651         rm -f $DIR/$tfile
23652         $LCTL set_param debug="$saved_debug"
23653 }
23654 run_test 398c "run fio to test AIO"
23655
23656 test_398d() { #  LU-13846
23657         which aiocp || skip_env "no aiocp installed"
23658         local aio_file=$DIR/$tfile.aio
23659
23660         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23661
23662         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23663         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23664         stack_trap "rm -f $DIR/$tfile $aio_file"
23665
23666         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23667
23668         # make sure we don't crash and fail properly
23669         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23670                 error "aio not aligned with PAGE SIZE should fail"
23671
23672         rm -f $DIR/$tfile $aio_file
23673 }
23674 run_test 398d "run aiocp to verify block size > stripe size"
23675
23676 test_398e() {
23677         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23678         touch $DIR/$tfile.new
23679         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23680 }
23681 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23682
23683 test_398f() { #  LU-14687
23684         which aiocp || skip_env "no aiocp installed"
23685         local aio_file=$DIR/$tfile.aio
23686
23687         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23688
23689         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23690         stack_trap "rm -f $DIR/$tfile $aio_file"
23691
23692         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23693         $LCTL set_param fail_loc=0x1418
23694         # make sure we don't crash and fail properly
23695         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23696                 error "aio with page allocation failure succeeded"
23697         $LCTL set_param fail_loc=0
23698         diff $DIR/$tfile $aio_file
23699         [[ $? != 0 ]] || error "no diff after failed aiocp"
23700 }
23701 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23702
23703 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23704 # stripe and i/o size must be > stripe size
23705 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23706 # single RPC in flight.  This test shows async DIO submission is working by
23707 # showing multiple RPCs in flight.
23708 test_398g() { #  LU-13798
23709         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23710
23711         # We need to do some i/o first to acquire enough grant to put our RPCs
23712         # in flight; otherwise a new connection may not have enough grant
23713         # available
23714         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23715                 error "parallel dio failed"
23716         stack_trap "rm -f $DIR/$tfile"
23717
23718         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23719         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23720         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23721         stack_trap "$LCTL set_param -n $pages_per_rpc"
23722
23723         # Recreate file so it's empty
23724         rm -f $DIR/$tfile
23725         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23726         #Pause rpc completion to guarantee we see multiple rpcs in flight
23727         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23728         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23729         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23730
23731         # Clear rpc stats
23732         $LCTL set_param osc.*.rpc_stats=c
23733
23734         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23735                 error "parallel dio failed"
23736         stack_trap "rm -f $DIR/$tfile"
23737
23738         $LCTL get_param osc.*-OST0000-*.rpc_stats
23739         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23740                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23741                 grep "8:" | awk '{print $8}')
23742         # We look at the "8 rpcs in flight" field, and verify A) it is present
23743         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23744         # as expected for an 8M DIO to a file with 1M stripes.
23745         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23746
23747         # Verify turning off parallel dio works as expected
23748         # Clear rpc stats
23749         $LCTL set_param osc.*.rpc_stats=c
23750         $LCTL set_param llite.*.parallel_dio=0
23751         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23752
23753         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23754                 error "dio with parallel dio disabled failed"
23755
23756         # Ideally, we would see only one RPC in flight here, but there is an
23757         # unavoidable race between i/o completion and RPC in flight counting,
23758         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23759         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23760         # So instead we just verify it's always < 8.
23761         $LCTL get_param osc.*-OST0000-*.rpc_stats
23762         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23763                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23764                 grep '^$' -B1 | grep . | awk '{print $1}')
23765         [ $ret != "8:" ] ||
23766                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23767 }
23768 run_test 398g "verify parallel dio async RPC submission"
23769
23770 test_398h() { #  LU-13798
23771         local dio_file=$DIR/$tfile.dio
23772
23773         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23774
23775         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23776         stack_trap "rm -f $DIR/$tfile $dio_file"
23777
23778         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23779                 error "parallel dio failed"
23780         diff $DIR/$tfile $dio_file
23781         [[ $? == 0 ]] || error "file diff after aiocp"
23782 }
23783 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23784
23785 test_398i() { #  LU-13798
23786         local dio_file=$DIR/$tfile.dio
23787
23788         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23789
23790         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23791         stack_trap "rm -f $DIR/$tfile $dio_file"
23792
23793         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23794         $LCTL set_param fail_loc=0x1418
23795         # make sure we don't crash and fail properly
23796         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23797                 error "parallel dio page allocation failure succeeded"
23798         diff $DIR/$tfile $dio_file
23799         [[ $? != 0 ]] || error "no diff after failed aiocp"
23800 }
23801 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23802
23803 test_398j() { #  LU-13798
23804         # Stripe size > RPC size but less than i/o size tests split across
23805         # stripes and RPCs for individual i/o op
23806         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23807
23808         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23809         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23810         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23811         stack_trap "$LCTL set_param -n $pages_per_rpc"
23812
23813         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23814                 error "parallel dio write failed"
23815         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23816
23817         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23818                 error "parallel dio read failed"
23819         diff $DIR/$tfile $DIR/$tfile.2
23820         [[ $? == 0 ]] || error "file diff after parallel dio read"
23821 }
23822 run_test 398j "test parallel dio where stripe size > rpc_size"
23823
23824 test_398k() { #  LU-13798
23825         wait_delete_completed
23826         wait_mds_ost_sync
23827
23828         # 4 stripe file; we will cause out of space on OST0
23829         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23830
23831         # Fill OST0 (if it's not too large)
23832         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23833                    head -n1)
23834         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23835                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23836         fi
23837         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23838         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23839                 error "dd should fill OST0"
23840         stack_trap "rm -f $DIR/$tfile.1"
23841
23842         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23843         err=$?
23844
23845         ls -la $DIR/$tfile
23846         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23847                 error "file is not 0 bytes in size"
23848
23849         # dd above should not succeed, but don't error until here so we can
23850         # get debug info above
23851         [[ $err != 0 ]] ||
23852                 error "parallel dio write with enospc succeeded"
23853         stack_trap "rm -f $DIR/$tfile"
23854 }
23855 run_test 398k "test enospc on first stripe"
23856
23857 test_398l() { #  LU-13798
23858         wait_delete_completed
23859         wait_mds_ost_sync
23860
23861         # 4 stripe file; we will cause out of space on OST0
23862         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23863         # happens on the second i/o chunk we issue
23864         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23865
23866         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23867         stack_trap "rm -f $DIR/$tfile"
23868
23869         # Fill OST0 (if it's not too large)
23870         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23871                    head -n1)
23872         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23873                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23874         fi
23875         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23876         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23877                 error "dd should fill OST0"
23878         stack_trap "rm -f $DIR/$tfile.1"
23879
23880         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23881         err=$?
23882         stack_trap "rm -f $DIR/$tfile.2"
23883
23884         # Check that short write completed as expected
23885         ls -la $DIR/$tfile.2
23886         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23887                 error "file is not 1M in size"
23888
23889         # dd above should not succeed, but don't error until here so we can
23890         # get debug info above
23891         [[ $err != 0 ]] ||
23892                 error "parallel dio write with enospc succeeded"
23893
23894         # Truncate source file to same length as output file and diff them
23895         $TRUNCATE $DIR/$tfile 1048576
23896         diff $DIR/$tfile $DIR/$tfile.2
23897         [[ $? == 0 ]] || error "data incorrect after short write"
23898 }
23899 run_test 398l "test enospc on intermediate stripe/RPC"
23900
23901 test_398m() { #  LU-13798
23902         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23903
23904         # Set up failure on OST0, the first stripe:
23905         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23906         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23907         # So this fail_val specifies OST0
23908         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23909         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23910
23911         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23912                 error "parallel dio write with failure on first stripe succeeded"
23913         stack_trap "rm -f $DIR/$tfile"
23914         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23915
23916         # Place data in file for read
23917         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23918                 error "parallel dio write failed"
23919
23920         # Fail read on OST0, first stripe
23921         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23922         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
23923         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23924                 error "parallel dio read with error on first stripe succeeded"
23925         rm -f $DIR/$tfile.2
23926         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23927
23928         # Switch to testing on OST1, second stripe
23929         # Clear file contents, maintain striping
23930         echo > $DIR/$tfile
23931         # Set up failure on OST1, second stripe:
23932         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
23933         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23934
23935         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23936                 error "parallel dio write with failure on first stripe succeeded"
23937         stack_trap "rm -f $DIR/$tfile"
23938         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23939
23940         # Place data in file for read
23941         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23942                 error "parallel dio write failed"
23943
23944         # Fail read on OST1, second stripe
23945         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23946         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
23947         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23948                 error "parallel dio read with error on first stripe succeeded"
23949         rm -f $DIR/$tfile.2
23950         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
23951 }
23952 run_test 398m "test RPC failures with parallel dio"
23953
23954 # Parallel submission of DIO should not cause problems for append, but it's
23955 # important to verify.
23956 test_398n() { #  LU-13798
23957         $LFS setstripe -C 2 -S 1M $DIR/$tfile
23958
23959         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
23960                 error "dd to create source file failed"
23961         stack_trap "rm -f $DIR/$tfile"
23962
23963         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
23964                 error "parallel dio write with failure on second stripe succeeded"
23965         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
23966         diff $DIR/$tfile $DIR/$tfile.1
23967         [[ $? == 0 ]] || error "data incorrect after append"
23968
23969 }
23970 run_test 398n "test append with parallel DIO"
23971
23972 test_fake_rw() {
23973         local read_write=$1
23974         if [ "$read_write" = "write" ]; then
23975                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23976         elif [ "$read_write" = "read" ]; then
23977                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23978         else
23979                 error "argument error"
23980         fi
23981
23982         # turn off debug for performance testing
23983         local saved_debug=$($LCTL get_param -n debug)
23984         $LCTL set_param debug=0
23985
23986         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23987
23988         # get ost1 size - $FSNAME-OST0000
23989         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23990         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23991         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23992
23993         if [ "$read_write" = "read" ]; then
23994                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23995         fi
23996
23997         local start_time=$(date +%s.%N)
23998         $dd_cmd bs=1M count=$blocks oflag=sync ||
23999                 error "real dd $read_write error"
24000         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24001
24002         if [ "$read_write" = "write" ]; then
24003                 rm -f $DIR/$tfile
24004         fi
24005
24006         # define OBD_FAIL_OST_FAKE_RW           0x238
24007         do_facet ost1 $LCTL set_param fail_loc=0x238
24008
24009         local start_time=$(date +%s.%N)
24010         $dd_cmd bs=1M count=$blocks oflag=sync ||
24011                 error "fake dd $read_write error"
24012         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24013
24014         if [ "$read_write" = "write" ]; then
24015                 # verify file size
24016                 cancel_lru_locks osc
24017                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24018                         error "$tfile size not $blocks MB"
24019         fi
24020         do_facet ost1 $LCTL set_param fail_loc=0
24021
24022         echo "fake $read_write $duration_fake vs. normal $read_write" \
24023                 "$duration in seconds"
24024         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24025                 error_not_in_vm "fake write is slower"
24026
24027         $LCTL set_param -n debug="$saved_debug"
24028         rm -f $DIR/$tfile
24029 }
24030 test_399a() { # LU-7655 for OST fake write
24031         remote_ost_nodsh && skip "remote OST with nodsh"
24032
24033         test_fake_rw write
24034 }
24035 run_test 399a "fake write should not be slower than normal write"
24036
24037 test_399b() { # LU-8726 for OST fake read
24038         remote_ost_nodsh && skip "remote OST with nodsh"
24039         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24040                 skip_env "ldiskfs only test"
24041         fi
24042
24043         test_fake_rw read
24044 }
24045 run_test 399b "fake read should not be slower than normal read"
24046
24047 test_400a() { # LU-1606, was conf-sanity test_74
24048         if ! which $CC > /dev/null 2>&1; then
24049                 skip_env "$CC is not installed"
24050         fi
24051
24052         local extra_flags=''
24053         local out=$TMP/$tfile
24054         local prefix=/usr/include/lustre
24055         local prog
24056
24057         # Oleg removes c files in his test rig so test if any c files exist
24058         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24059                 skip_env "Needed c test files are missing"
24060
24061         if ! [[ -d $prefix ]]; then
24062                 # Assume we're running in tree and fixup the include path.
24063                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24064                 extra_flags+=" -L$LUSTRE/utils/.lib"
24065         fi
24066
24067         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24068                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24069                         error "client api broken"
24070         done
24071         rm -f $out
24072 }
24073 run_test 400a "Lustre client api program can compile and link"
24074
24075 test_400b() { # LU-1606, LU-5011
24076         local header
24077         local out=$TMP/$tfile
24078         local prefix=/usr/include/linux/lustre
24079
24080         # We use a hard coded prefix so that this test will not fail
24081         # when run in tree. There are headers in lustre/include/lustre/
24082         # that are not packaged (like lustre_idl.h) and have more
24083         # complicated include dependencies (like config.h and lnet/types.h).
24084         # Since this test about correct packaging we just skip them when
24085         # they don't exist (see below) rather than try to fixup cppflags.
24086
24087         if ! which $CC > /dev/null 2>&1; then
24088                 skip_env "$CC is not installed"
24089         fi
24090
24091         for header in $prefix/*.h; do
24092                 if ! [[ -f "$header" ]]; then
24093                         continue
24094                 fi
24095
24096                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24097                         continue # lustre_ioctl.h is internal header
24098                 fi
24099
24100                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24101                         error "cannot compile '$header'"
24102         done
24103         rm -f $out
24104 }
24105 run_test 400b "packaged headers can be compiled"
24106
24107 test_401a() { #LU-7437
24108         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24109         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24110
24111         #count the number of parameters by "list_param -R"
24112         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24113         #count the number of parameters by listing proc files
24114         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24115         echo "proc_dirs='$proc_dirs'"
24116         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24117         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24118                       sort -u | wc -l)
24119
24120         [ $params -eq $procs ] ||
24121                 error "found $params parameters vs. $procs proc files"
24122
24123         # test the list_param -D option only returns directories
24124         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24125         #count the number of parameters by listing proc directories
24126         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24127                 sort -u | wc -l)
24128
24129         [ $params -eq $procs ] ||
24130                 error "found $params parameters vs. $procs proc files"
24131 }
24132 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24133
24134 test_401b() {
24135         # jobid_var may not allow arbitrary values, so use jobid_name
24136         # if available
24137         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24138                 local testname=jobid_name tmp='testing%p'
24139         else
24140                 local testname=jobid_var tmp=testing
24141         fi
24142
24143         local save=$($LCTL get_param -n $testname)
24144
24145         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24146                 error "no error returned when setting bad parameters"
24147
24148         local jobid_new=$($LCTL get_param -n foe $testname baz)
24149         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24150
24151         $LCTL set_param -n fog=bam $testname=$save bat=fog
24152         local jobid_old=$($LCTL get_param -n foe $testname bag)
24153         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24154 }
24155 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24156
24157 test_401c() {
24158         # jobid_var may not allow arbitrary values, so use jobid_name
24159         # if available
24160         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24161                 local testname=jobid_name
24162         else
24163                 local testname=jobid_var
24164         fi
24165
24166         local jobid_var_old=$($LCTL get_param -n $testname)
24167         local jobid_var_new
24168
24169         $LCTL set_param $testname= &&
24170                 error "no error returned for 'set_param a='"
24171
24172         jobid_var_new=$($LCTL get_param -n $testname)
24173         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24174                 error "$testname was changed by setting without value"
24175
24176         $LCTL set_param $testname &&
24177                 error "no error returned for 'set_param a'"
24178
24179         jobid_var_new=$($LCTL get_param -n $testname)
24180         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24181                 error "$testname was changed by setting without value"
24182 }
24183 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24184
24185 test_401d() {
24186         # jobid_var may not allow arbitrary values, so use jobid_name
24187         # if available
24188         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24189                 local testname=jobid_name new_value='foo=bar%p'
24190         else
24191                 local testname=jobid_var new_valuie=foo=bar
24192         fi
24193
24194         local jobid_var_old=$($LCTL get_param -n $testname)
24195         local jobid_var_new
24196
24197         $LCTL set_param $testname=$new_value ||
24198                 error "'set_param a=b' did not accept a value containing '='"
24199
24200         jobid_var_new=$($LCTL get_param -n $testname)
24201         [[ "$jobid_var_new" == "$new_value" ]] ||
24202                 error "'set_param a=b' failed on a value containing '='"
24203
24204         # Reset the $testname to test the other format
24205         $LCTL set_param $testname=$jobid_var_old
24206         jobid_var_new=$($LCTL get_param -n $testname)
24207         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24208                 error "failed to reset $testname"
24209
24210         $LCTL set_param $testname $new_value ||
24211                 error "'set_param a b' did not accept a value containing '='"
24212
24213         jobid_var_new=$($LCTL get_param -n $testname)
24214         [[ "$jobid_var_new" == "$new_value" ]] ||
24215                 error "'set_param a b' failed on a value containing '='"
24216
24217         $LCTL set_param $testname $jobid_var_old
24218         jobid_var_new=$($LCTL get_param -n $testname)
24219         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24220                 error "failed to reset $testname"
24221 }
24222 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24223
24224 test_401e() { # LU-14779
24225         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24226                 error "lctl list_param MGC* failed"
24227         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24228         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24229                 error "lctl get_param lru_size failed"
24230 }
24231 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24232
24233 test_402() {
24234         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24235         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24236                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24237         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24238                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24239                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24240         remote_mds_nodsh && skip "remote MDS with nodsh"
24241
24242         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24243 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24244         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24245         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24246                 echo "Touch failed - OK"
24247 }
24248 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24249
24250 test_403() {
24251         local file1=$DIR/$tfile.1
24252         local file2=$DIR/$tfile.2
24253         local tfile=$TMP/$tfile
24254
24255         rm -f $file1 $file2 $tfile
24256
24257         touch $file1
24258         ln $file1 $file2
24259
24260         # 30 sec OBD_TIMEOUT in ll_getattr()
24261         # right before populating st_nlink
24262         $LCTL set_param fail_loc=0x80001409
24263         stat -c %h $file1 > $tfile &
24264
24265         # create an alias, drop all locks and reclaim the dentry
24266         < $file2
24267         cancel_lru_locks mdc
24268         cancel_lru_locks osc
24269         sysctl -w vm.drop_caches=2
24270
24271         wait
24272
24273         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24274
24275         rm -f $tfile $file1 $file2
24276 }
24277 run_test 403 "i_nlink should not drop to zero due to aliasing"
24278
24279 test_404() { # LU-6601
24280         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24281                 skip "Need server version newer than 2.8.52"
24282         remote_mds_nodsh && skip "remote MDS with nodsh"
24283
24284         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24285                 awk '/osp .*-osc-MDT/ { print $4}')
24286
24287         local osp
24288         for osp in $mosps; do
24289                 echo "Deactivate: " $osp
24290                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24291                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24292                         awk -vp=$osp '$4 == p { print $2 }')
24293                 [ $stat = IN ] || {
24294                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24295                         error "deactivate error"
24296                 }
24297                 echo "Activate: " $osp
24298                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24299                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24300                         awk -vp=$osp '$4 == p { print $2 }')
24301                 [ $stat = UP ] || {
24302                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24303                         error "activate error"
24304                 }
24305         done
24306 }
24307 run_test 404 "validate manual {de}activated works properly for OSPs"
24308
24309 test_405() {
24310         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24311         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24312                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24313                         skip "Layout swap lock is not supported"
24314
24315         check_swap_layouts_support
24316         check_swap_layout_no_dom $DIR
24317
24318         test_mkdir $DIR/$tdir
24319         swap_lock_test -d $DIR/$tdir ||
24320                 error "One layout swap locked test failed"
24321 }
24322 run_test 405 "Various layout swap lock tests"
24323
24324 test_406() {
24325         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24326         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24327         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24329         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24330                 skip "Need MDS version at least 2.8.50"
24331
24332         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24333         local test_pool=$TESTNAME
24334
24335         pool_add $test_pool || error "pool_add failed"
24336         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24337                 error "pool_add_targets failed"
24338
24339         save_layout_restore_at_exit $MOUNT
24340
24341         # parent set default stripe count only, child will stripe from both
24342         # parent and fs default
24343         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24344                 error "setstripe $MOUNT failed"
24345         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24346         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24347         for i in $(seq 10); do
24348                 local f=$DIR/$tdir/$tfile.$i
24349                 touch $f || error "touch failed"
24350                 local count=$($LFS getstripe -c $f)
24351                 [ $count -eq $OSTCOUNT ] ||
24352                         error "$f stripe count $count != $OSTCOUNT"
24353                 local offset=$($LFS getstripe -i $f)
24354                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24355                 local size=$($LFS getstripe -S $f)
24356                 [ $size -eq $((def_stripe_size * 2)) ] ||
24357                         error "$f stripe size $size != $((def_stripe_size * 2))"
24358                 local pool=$($LFS getstripe -p $f)
24359                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24360         done
24361
24362         # change fs default striping, delete parent default striping, now child
24363         # will stripe from new fs default striping only
24364         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24365                 error "change $MOUNT default stripe failed"
24366         $LFS setstripe -c 0 $DIR/$tdir ||
24367                 error "delete $tdir default stripe failed"
24368         for i in $(seq 11 20); do
24369                 local f=$DIR/$tdir/$tfile.$i
24370                 touch $f || error "touch $f failed"
24371                 local count=$($LFS getstripe -c $f)
24372                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24373                 local offset=$($LFS getstripe -i $f)
24374                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24375                 local size=$($LFS getstripe -S $f)
24376                 [ $size -eq $def_stripe_size ] ||
24377                         error "$f stripe size $size != $def_stripe_size"
24378                 local pool=$($LFS getstripe -p $f)
24379                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24380         done
24381
24382         unlinkmany $DIR/$tdir/$tfile. 1 20
24383
24384         local f=$DIR/$tdir/$tfile
24385         pool_remove_all_targets $test_pool $f
24386         pool_remove $test_pool $f
24387 }
24388 run_test 406 "DNE support fs default striping"
24389
24390 test_407() {
24391         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24392         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24393                 skip "Need MDS version at least 2.8.55"
24394         remote_mds_nodsh && skip "remote MDS with nodsh"
24395
24396         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24397                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24398         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24399                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24400         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24401
24402         #define OBD_FAIL_DT_TXN_STOP    0x2019
24403         for idx in $(seq $MDSCOUNT); do
24404                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24405         done
24406         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24407         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24408                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24409         true
24410 }
24411 run_test 407 "transaction fail should cause operation fail"
24412
24413 test_408() {
24414         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24415
24416         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24417         lctl set_param fail_loc=0x8000040a
24418         # let ll_prepare_partial_page() fail
24419         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24420
24421         rm -f $DIR/$tfile
24422
24423         # create at least 100 unused inodes so that
24424         # shrink_icache_memory(0) should not return 0
24425         touch $DIR/$tfile-{0..100}
24426         rm -f $DIR/$tfile-{0..100}
24427         sync
24428
24429         echo 2 > /proc/sys/vm/drop_caches
24430 }
24431 run_test 408 "drop_caches should not hang due to page leaks"
24432
24433 test_409()
24434 {
24435         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24436
24437         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24438         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24439         touch $DIR/$tdir/guard || error "(2) Fail to create"
24440
24441         local PREFIX=$(str_repeat 'A' 128)
24442         echo "Create 1K hard links start at $(date)"
24443         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24444                 error "(3) Fail to hard link"
24445
24446         echo "Links count should be right although linkEA overflow"
24447         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24448         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24449         [ $linkcount -eq 1001 ] ||
24450                 error "(5) Unexpected hard links count: $linkcount"
24451
24452         echo "List all links start at $(date)"
24453         ls -l $DIR/$tdir/foo > /dev/null ||
24454                 error "(6) Fail to list $DIR/$tdir/foo"
24455
24456         echo "Unlink hard links start at $(date)"
24457         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24458                 error "(7) Fail to unlink"
24459         echo "Unlink hard links finished at $(date)"
24460 }
24461 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24462
24463 test_410()
24464 {
24465         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24466                 skip "Need client version at least 2.9.59"
24467         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24468                 skip "Need MODULES build"
24469
24470         # Create a file, and stat it from the kernel
24471         local testfile=$DIR/$tfile
24472         touch $testfile
24473
24474         local run_id=$RANDOM
24475         local my_ino=$(stat --format "%i" $testfile)
24476
24477         # Try to insert the module. This will always fail as the
24478         # module is designed to not be inserted.
24479         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24480             &> /dev/null
24481
24482         # Anything but success is a test failure
24483         dmesg | grep -q \
24484             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24485             error "no inode match"
24486 }
24487 run_test 410 "Test inode number returned from kernel thread"
24488
24489 cleanup_test411_cgroup() {
24490         trap 0
24491         rmdir "$1"
24492 }
24493
24494 test_411() {
24495         local cg_basedir=/sys/fs/cgroup/memory
24496         # LU-9966
24497         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24498                 skip "no setup for cgroup"
24499
24500         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24501                 error "test file creation failed"
24502         cancel_lru_locks osc
24503
24504         # Create a very small memory cgroup to force a slab allocation error
24505         local cgdir=$cg_basedir/osc_slab_alloc
24506         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24507         trap "cleanup_test411_cgroup $cgdir" EXIT
24508         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24509         echo 1M > $cgdir/memory.limit_in_bytes
24510
24511         # Should not LBUG, just be killed by oom-killer
24512         # dd will return 0 even allocation failure in some environment.
24513         # So don't check return value
24514         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24515         cleanup_test411_cgroup $cgdir
24516
24517         return 0
24518 }
24519 run_test 411 "Slab allocation error with cgroup does not LBUG"
24520
24521 test_412() {
24522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24523         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24524                 skip "Need server version at least 2.10.55"
24525         fi
24526
24527         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24528                 error "mkdir failed"
24529         $LFS getdirstripe $DIR/$tdir
24530         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24531         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24532                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24533         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24534         [ $stripe_count -eq 2 ] ||
24535                 error "expect 2 get $stripe_count"
24536 }
24537 run_test 412 "mkdir on specific MDTs"
24538
24539 generate_uneven_mdts() {
24540         local threshold=$1
24541         local ffree
24542         local bavail
24543         local max
24544         local min
24545         local max_index
24546         local min_index
24547         local tmp
24548         local i
24549
24550         echo
24551         echo "Check for uneven MDTs: "
24552
24553         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24554         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24555         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24556
24557         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24558         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24559         max_index=0
24560         min_index=0
24561         for ((i = 1; i < ${#ffree[@]}; i++)); do
24562                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24563                 if [ $tmp -gt $max ]; then
24564                         max=$tmp
24565                         max_index=$i
24566                 fi
24567                 if [ $tmp -lt $min ]; then
24568                         min=$tmp
24569                         min_index=$i
24570                 fi
24571         done
24572
24573         # Check if we need to generate uneven MDTs
24574         local diff=$(((max - min) * 100 / min))
24575         local testdir=$DIR/$tdir-fillmdt
24576
24577         mkdir -p $testdir
24578
24579         i=0
24580         while (( diff < threshold )); do
24581                 # generate uneven MDTs, create till $threshold% diff
24582                 echo -n "weight diff=$diff% must be > $threshold% ..."
24583                 echo "Fill MDT$min_index with 100 files: loop $i"
24584                 testdir=$DIR/$tdir-fillmdt/$i
24585                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24586                         error "mkdir $testdir failed"
24587                 $LFS setstripe -E 1M -L mdt $testdir ||
24588                         error "setstripe $testdir failed"
24589                 for F in f.{0..99}; do
24590                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24591                                 /dev/null 2>&1 || error "dd $F failed"
24592                 done
24593
24594                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24595                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24596                 max=$(((${ffree[max_index]} >> 8) * \
24597                         (${bavail[max_index]} * bsize >> 16)))
24598                 min=$(((${ffree[min_index]} >> 8) * \
24599                         (${bavail[min_index]} * bsize >> 16)))
24600                 diff=$(((max - min) * 100 / min))
24601                 i=$((i + 1))
24602         done
24603
24604         echo "MDT filesfree available: ${ffree[@]}"
24605         echo "MDT blocks available: ${bavail[@]}"
24606         echo "weight diff=$diff%"
24607 }
24608
24609 test_qos_mkdir() {
24610         local mkdir_cmd=$1
24611         local stripe_count=$2
24612         local mdts=$(comma_list $(mdts_nodes))
24613
24614         local testdir
24615         local lmv_qos_prio_free
24616         local lmv_qos_threshold_rr
24617         local lmv_qos_maxage
24618         local lod_qos_prio_free
24619         local lod_qos_threshold_rr
24620         local lod_qos_maxage
24621         local count
24622         local i
24623
24624         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24625         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24626         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24627                 head -n1)
24628         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24629         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24630         stack_trap "$LCTL set_param \
24631                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24632         stack_trap "$LCTL set_param \
24633                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24634         stack_trap "$LCTL set_param \
24635                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24636
24637         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24638                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24639         lod_qos_prio_free=${lod_qos_prio_free%%%}
24640         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24641                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24642         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24643         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24644                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24645         stack_trap "do_nodes $mdts $LCTL set_param \
24646                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24647         stack_trap "do_nodes $mdts $LCTL set_param \
24648                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24649         stack_trap "do_nodes $mdts $LCTL set_param \
24650                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24651
24652         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24653         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24654
24655         testdir=$DIR/$tdir-s$stripe_count/rr
24656
24657         local stripe_index=$($LFS getstripe -m $testdir)
24658         local test_mkdir_rr=true
24659
24660         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24661         getfattr -d -m dmv -e hex $testdir | grep dmv
24662         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24663                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24664                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24665                         test_mkdir_rr=false
24666         fi
24667
24668         echo
24669         $test_mkdir_rr &&
24670                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24671                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24672
24673         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24674         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24675                 eval $mkdir_cmd $testdir/subdir$i ||
24676                         error "$mkdir_cmd subdir$i failed"
24677         done
24678
24679         for (( i = 0; i < $MDSCOUNT; i++ )); do
24680                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24681                 echo "$count directories created on MDT$i"
24682                 if $test_mkdir_rr; then
24683                         (( $count == 100 )) ||
24684                                 error "subdirs are not evenly distributed"
24685                 elif (( $i == $stripe_index )); then
24686                         (( $count == 100 * MDSCOUNT )) ||
24687                                 error "$count subdirs created on MDT$i"
24688                 else
24689                         (( $count == 0 )) ||
24690                                 error "$count subdirs created on MDT$i"
24691                 fi
24692
24693                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24694                         count=$($LFS getdirstripe $testdir/* |
24695                                 grep -c -P "^\s+$i\t")
24696                         echo "$count stripes created on MDT$i"
24697                         # deviation should < 5% of average
24698                         (( $count >= 95 * stripe_count &&
24699                            $count <= 105 * stripe_count)) ||
24700                                 error "stripes are not evenly distributed"
24701                 fi
24702         done
24703
24704         echo
24705         echo "Check for uneven MDTs: "
24706
24707         local ffree
24708         local bavail
24709         local max
24710         local min
24711         local max_index
24712         local min_index
24713         local tmp
24714
24715         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24716         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24717         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24718
24719         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24720         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24721         max_index=0
24722         min_index=0
24723         for ((i = 1; i < ${#ffree[@]}; i++)); do
24724                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24725                 if [ $tmp -gt $max ]; then
24726                         max=$tmp
24727                         max_index=$i
24728                 fi
24729                 if [ $tmp -lt $min ]; then
24730                         min=$tmp
24731                         min_index=$i
24732                 fi
24733         done
24734
24735         (( ${ffree[min_index]} > 0 )) ||
24736                 skip "no free files in MDT$min_index"
24737         (( ${ffree[min_index]} < 100000000 )) ||
24738                 skip "too many free files in MDT$min_index"
24739
24740         echo "MDT filesfree available: ${ffree[@]}"
24741         echo "MDT blocks available: ${bavail[@]}"
24742         echo "weight diff=$(((max - min) * 100 / min))%"
24743         echo
24744         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24745
24746         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24747         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24748         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24749         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24750         # decrease statfs age, so that it can be updated in time
24751         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24752         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24753
24754         sleep 1
24755
24756         testdir=$DIR/$tdir-s$stripe_count/qos
24757         local num=200
24758
24759         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24760         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24761                 eval $mkdir_cmd $testdir/subdir$i ||
24762                         error "$mkdir_cmd subdir$i failed"
24763         done
24764
24765         for (( i = 0; i < $MDSCOUNT; i++ )); do
24766                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24767                 echo "$count directories created on MDT$i"
24768
24769                 if [ $stripe_count -gt 1 ]; then
24770                         count=$($LFS getdirstripe $testdir/* |
24771                                 grep -c -P "^\s+$i\t")
24772                         echo "$count stripes created on MDT$i"
24773                 fi
24774         done
24775
24776         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24777         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24778
24779         # D-value should > 10% of averge
24780         (( max - min >= num / 10 )) ||
24781                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24782
24783         # 5% for stripes
24784         if (( stripe_count > 1 )); then
24785                 max=$($LFS getdirstripe $testdir/* |
24786                       grep -c -P "^\s+$max_index\t")
24787                 min=$($LFS getdirstripe $testdir/* |
24788                         grep -c -P "^\s+$min_index\t")
24789                 (( max - min >= num * stripe_count / 20 )) ||
24790                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24791         fi
24792 }
24793
24794 most_full_mdt() {
24795         local ffree
24796         local bavail
24797         local bsize
24798         local min
24799         local min_index
24800         local tmp
24801
24802         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24803         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24804         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24805
24806         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24807         min_index=0
24808         for ((i = 1; i < ${#ffree[@]}; i++)); do
24809                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24810                 (( tmp < min )) && min=$tmp && min_index=$i
24811         done
24812
24813         echo -n $min_index
24814 }
24815
24816 test_413a() {
24817         [ $MDSCOUNT -lt 2 ] &&
24818                 skip "We need at least 2 MDTs for this test"
24819
24820         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24821                 skip "Need server version at least 2.12.52"
24822
24823         local stripe_count
24824
24825         generate_uneven_mdts 100
24826         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24827                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24828                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24829                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
24830                         error "mkdir failed"
24831                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
24832         done
24833 }
24834 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24835
24836 test_413b() {
24837         [ $MDSCOUNT -lt 2 ] &&
24838                 skip "We need at least 2 MDTs for this test"
24839
24840         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24841                 skip "Need server version at least 2.12.52"
24842
24843         local testdir
24844         local stripe_count
24845
24846         generate_uneven_mdts 100
24847         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24848                 testdir=$DIR/$tdir-s$stripe_count
24849                 mkdir $testdir || error "mkdir $testdir failed"
24850                 mkdir $testdir/rr || error "mkdir rr failed"
24851                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
24852                         error "mkdir qos failed"
24853                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24854                         $testdir/rr || error "setdirstripe rr failed"
24855                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24856                         error "setdirstripe failed"
24857                 test_qos_mkdir "mkdir" $stripe_count
24858         done
24859 }
24860 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24861
24862 test_413c() {
24863         (( $MDSCOUNT >= 2 )) ||
24864                 skip "We need at least 2 MDTs for this test"
24865
24866         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
24867                 skip "Need server version at least 2.14.51"
24868
24869         local testdir
24870         local inherit
24871         local inherit_rr
24872
24873         testdir=$DIR/${tdir}-s1
24874         mkdir $testdir || error "mkdir $testdir failed"
24875         mkdir $testdir/rr || error "mkdir rr failed"
24876         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
24877         # default max_inherit is -1, default max_inherit_rr is 0
24878         $LFS setdirstripe -D -c 1 $testdir/rr ||
24879                 error "setdirstripe rr failed"
24880         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24881                 error "setdirstripe qos failed"
24882         test_qos_mkdir "mkdir" 1
24883
24884         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24885         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24886         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24887         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24888         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
24889
24890         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24891         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24892         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24893         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24894         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
24895         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24896         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
24897                 error "level2 shouldn't have default LMV" || true
24898 }
24899 run_test 413c "mkdir with default LMV max inherit rr"
24900
24901 test_413d() {
24902         (( MDSCOUNT >= 2 )) ||
24903                 skip "We need at least 2 MDTs for this test"
24904
24905         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
24906                 skip "Need server version at least 2.14.51"
24907
24908         local lmv_qos_threshold_rr
24909
24910         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24911                 head -n1)
24912         stack_trap "$LCTL set_param \
24913                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24914
24915         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24916         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24917         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
24918                 error "$tdir shouldn't have default LMV"
24919         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
24920                 error "mkdir sub failed"
24921
24922         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
24923
24924         (( count == 100 )) || error "$count subdirs on MDT0"
24925 }
24926 run_test 413d "inherit ROOT default LMV"
24927
24928 test_413z() {
24929         local pids=""
24930         local subdir
24931         local pid
24932
24933         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
24934                 unlinkmany $subdir/f. 100 &
24935                 pids="$pids $!"
24936         done
24937
24938         for pid in $pids; do
24939                 wait $pid
24940         done
24941 }
24942 run_test 413z "413 test cleanup"
24943
24944 test_414() {
24945 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24946         $LCTL set_param fail_loc=0x80000521
24947         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24948         rm -f $DIR/$tfile
24949 }
24950 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24951
24952 test_415() {
24953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24954         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24955                 skip "Need server version at least 2.11.52"
24956
24957         # LU-11102
24958         local total
24959         local setattr_pid
24960         local start_time
24961         local end_time
24962         local duration
24963
24964         total=500
24965         # this test may be slow on ZFS
24966         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24967
24968         # though this test is designed for striped directory, let's test normal
24969         # directory too since lock is always saved as CoS lock.
24970         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24971         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24972
24973         (
24974                 while true; do
24975                         touch $DIR/$tdir
24976                 done
24977         ) &
24978         setattr_pid=$!
24979
24980         start_time=$(date +%s)
24981         for i in $(seq $total); do
24982                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24983                         > /dev/null
24984         done
24985         end_time=$(date +%s)
24986         duration=$((end_time - start_time))
24987
24988         kill -9 $setattr_pid
24989
24990         echo "rename $total files took $duration sec"
24991         [ $duration -lt 100 ] || error "rename took $duration sec"
24992 }
24993 run_test 415 "lock revoke is not missing"
24994
24995 test_416() {
24996         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24997                 skip "Need server version at least 2.11.55"
24998
24999         # define OBD_FAIL_OSD_TXN_START    0x19a
25000         do_facet mds1 lctl set_param fail_loc=0x19a
25001
25002         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25003
25004         true
25005 }
25006 run_test 416 "transaction start failure won't cause system hung"
25007
25008 cleanup_417() {
25009         trap 0
25010         do_nodes $(comma_list $(mdts_nodes)) \
25011                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25012         do_nodes $(comma_list $(mdts_nodes)) \
25013                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25014         do_nodes $(comma_list $(mdts_nodes)) \
25015                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25016 }
25017
25018 test_417() {
25019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25020         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25021                 skip "Need MDS version at least 2.11.56"
25022
25023         trap cleanup_417 RETURN EXIT
25024
25025         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25026         do_nodes $(comma_list $(mdts_nodes)) \
25027                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25028         $LFS migrate -m 0 $DIR/$tdir.1 &&
25029                 error "migrate dir $tdir.1 should fail"
25030
25031         do_nodes $(comma_list $(mdts_nodes)) \
25032                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25033         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25034                 error "create remote dir $tdir.2 should fail"
25035
25036         do_nodes $(comma_list $(mdts_nodes)) \
25037                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25038         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25039                 error "create striped dir $tdir.3 should fail"
25040         true
25041 }
25042 run_test 417 "disable remote dir, striped dir and dir migration"
25043
25044 # Checks that the outputs of df [-i] and lfs df [-i] match
25045 #
25046 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25047 check_lfs_df() {
25048         local dir=$2
25049         local inodes
25050         local df_out
25051         local lfs_df_out
25052         local count
25053         local passed=false
25054
25055         # blocks or inodes
25056         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25057
25058         for count in {1..100}; do
25059                 cancel_lru_locks
25060                 sync; sleep 0.2
25061
25062                 # read the lines of interest
25063                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25064                         error "df $inodes $dir | tail -n +2 failed"
25065                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25066                         error "lfs df $inodes $dir | grep summary: failed"
25067
25068                 # skip first substrings of each output as they are different
25069                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25070                 # compare the two outputs
25071                 passed=true
25072                 for i in {1..5}; do
25073                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25074                 done
25075                 $passed && break
25076         done
25077
25078         if ! $passed; then
25079                 df -P $inodes $dir
25080                 echo
25081                 lfs df $inodes $dir
25082                 error "df and lfs df $1 output mismatch: "      \
25083                       "df ${inodes}: ${df_out[*]}, "            \
25084                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25085         fi
25086 }
25087
25088 test_418() {
25089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25090
25091         local dir=$DIR/$tdir
25092         local numfiles=$((RANDOM % 4096 + 2))
25093         local numblocks=$((RANDOM % 256 + 1))
25094
25095         wait_delete_completed
25096         test_mkdir $dir
25097
25098         # check block output
25099         check_lfs_df blocks $dir
25100         # check inode output
25101         check_lfs_df inodes $dir
25102
25103         # create a single file and retest
25104         echo "Creating a single file and testing"
25105         createmany -o $dir/$tfile- 1 &>/dev/null ||
25106                 error "creating 1 file in $dir failed"
25107         check_lfs_df blocks $dir
25108         check_lfs_df inodes $dir
25109
25110         # create a random number of files
25111         echo "Creating $((numfiles - 1)) files and testing"
25112         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25113                 error "creating $((numfiles - 1)) files in $dir failed"
25114
25115         # write a random number of blocks to the first test file
25116         echo "Writing $numblocks 4K blocks and testing"
25117         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25118                 count=$numblocks &>/dev/null ||
25119                 error "dd to $dir/${tfile}-0 failed"
25120
25121         # retest
25122         check_lfs_df blocks $dir
25123         check_lfs_df inodes $dir
25124
25125         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25126                 error "unlinking $numfiles files in $dir failed"
25127 }
25128 run_test 418 "df and lfs df outputs match"
25129
25130 test_419()
25131 {
25132         local dir=$DIR/$tdir
25133
25134         mkdir -p $dir
25135         touch $dir/file
25136
25137         cancel_lru_locks mdc
25138
25139         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25140         $LCTL set_param fail_loc=0x1410
25141         cat $dir/file
25142         $LCTL set_param fail_loc=0
25143         rm -rf $dir
25144 }
25145 run_test 419 "Verify open file by name doesn't crash kernel"
25146
25147 test_420()
25148 {
25149         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25150                 skip "Need MDS version at least 2.12.53"
25151
25152         local SAVE_UMASK=$(umask)
25153         local dir=$DIR/$tdir
25154         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25155
25156         mkdir -p $dir
25157         umask 0000
25158         mkdir -m03777 $dir/testdir
25159         ls -dn $dir/testdir
25160         # Need to remove trailing '.' when SELinux is enabled
25161         local dirperms=$(ls -dn $dir/testdir |
25162                          awk '{ sub(/\.$/, "", $1); print $1}')
25163         [ $dirperms == "drwxrwsrwt" ] ||
25164                 error "incorrect perms on $dir/testdir"
25165
25166         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25167                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25168         ls -n $dir/testdir/testfile
25169         local fileperms=$(ls -n $dir/testdir/testfile |
25170                           awk '{ sub(/\.$/, "", $1); print $1}')
25171         [ $fileperms == "-rwxr-xr-x" ] ||
25172                 error "incorrect perms on $dir/testdir/testfile"
25173
25174         umask $SAVE_UMASK
25175 }
25176 run_test 420 "clear SGID bit on non-directories for non-members"
25177
25178 test_421a() {
25179         local cnt
25180         local fid1
25181         local fid2
25182
25183         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25184                 skip "Need MDS version at least 2.12.54"
25185
25186         test_mkdir $DIR/$tdir
25187         createmany -o $DIR/$tdir/f 3
25188         cnt=$(ls -1 $DIR/$tdir | wc -l)
25189         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25190
25191         fid1=$(lfs path2fid $DIR/$tdir/f1)
25192         fid2=$(lfs path2fid $DIR/$tdir/f2)
25193         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25194
25195         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25196         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25197
25198         cnt=$(ls -1 $DIR/$tdir | wc -l)
25199         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25200
25201         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25202         createmany -o $DIR/$tdir/f 3
25203         cnt=$(ls -1 $DIR/$tdir | wc -l)
25204         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25205
25206         fid1=$(lfs path2fid $DIR/$tdir/f1)
25207         fid2=$(lfs path2fid $DIR/$tdir/f2)
25208         echo "remove using fsname $FSNAME"
25209         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25210
25211         cnt=$(ls -1 $DIR/$tdir | wc -l)
25212         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25213 }
25214 run_test 421a "simple rm by fid"
25215
25216 test_421b() {
25217         local cnt
25218         local FID1
25219         local FID2
25220
25221         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25222                 skip "Need MDS version at least 2.12.54"
25223
25224         test_mkdir $DIR/$tdir
25225         createmany -o $DIR/$tdir/f 3
25226         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25227         MULTIPID=$!
25228
25229         FID1=$(lfs path2fid $DIR/$tdir/f1)
25230         FID2=$(lfs path2fid $DIR/$tdir/f2)
25231         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25232
25233         kill -USR1 $MULTIPID
25234         wait
25235
25236         cnt=$(ls $DIR/$tdir | wc -l)
25237         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25238 }
25239 run_test 421b "rm by fid on open file"
25240
25241 test_421c() {
25242         local cnt
25243         local FIDS
25244
25245         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25246                 skip "Need MDS version at least 2.12.54"
25247
25248         test_mkdir $DIR/$tdir
25249         createmany -o $DIR/$tdir/f 3
25250         touch $DIR/$tdir/$tfile
25251         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25252         cnt=$(ls -1 $DIR/$tdir | wc -l)
25253         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25254
25255         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25256         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25257
25258         cnt=$(ls $DIR/$tdir | wc -l)
25259         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25260 }
25261 run_test 421c "rm by fid against hardlinked files"
25262
25263 test_421d() {
25264         local cnt
25265         local FIDS
25266
25267         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25268                 skip "Need MDS version at least 2.12.54"
25269
25270         test_mkdir $DIR/$tdir
25271         createmany -o $DIR/$tdir/f 4097
25272         cnt=$(ls -1 $DIR/$tdir | wc -l)
25273         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25274
25275         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25276         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25277
25278         cnt=$(ls $DIR/$tdir | wc -l)
25279         rm -rf $DIR/$tdir
25280         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25281 }
25282 run_test 421d "rmfid en masse"
25283
25284 test_421e() {
25285         local cnt
25286         local FID
25287
25288         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25289         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25290                 skip "Need MDS version at least 2.12.54"
25291
25292         mkdir -p $DIR/$tdir
25293         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25294         createmany -o $DIR/$tdir/striped_dir/f 512
25295         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25296         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25297
25298         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25299                 sed "s/[/][^:]*://g")
25300         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25301
25302         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25303         rm -rf $DIR/$tdir
25304         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25305 }
25306 run_test 421e "rmfid in DNE"
25307
25308 test_421f() {
25309         local cnt
25310         local FID
25311
25312         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25313                 skip "Need MDS version at least 2.12.54"
25314
25315         test_mkdir $DIR/$tdir
25316         touch $DIR/$tdir/f
25317         cnt=$(ls -1 $DIR/$tdir | wc -l)
25318         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25319
25320         FID=$(lfs path2fid $DIR/$tdir/f)
25321         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25322         # rmfid should fail
25323         cnt=$(ls -1 $DIR/$tdir | wc -l)
25324         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25325
25326         chmod a+rw $DIR/$tdir
25327         ls -la $DIR/$tdir
25328         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25329         # rmfid should fail
25330         cnt=$(ls -1 $DIR/$tdir | wc -l)
25331         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25332
25333         rm -f $DIR/$tdir/f
25334         $RUNAS touch $DIR/$tdir/f
25335         FID=$(lfs path2fid $DIR/$tdir/f)
25336         echo "rmfid as root"
25337         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25338         cnt=$(ls -1 $DIR/$tdir | wc -l)
25339         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25340
25341         rm -f $DIR/$tdir/f
25342         $RUNAS touch $DIR/$tdir/f
25343         cnt=$(ls -1 $DIR/$tdir | wc -l)
25344         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25345         FID=$(lfs path2fid $DIR/$tdir/f)
25346         # rmfid w/o user_fid2path mount option should fail
25347         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25348         cnt=$(ls -1 $DIR/$tdir | wc -l)
25349         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25350
25351         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25352         stack_trap "rmdir $tmpdir"
25353         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25354                 error "failed to mount client'"
25355         stack_trap "umount_client $tmpdir"
25356
25357         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25358         # rmfid should succeed
25359         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25360         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25361
25362         # rmfid shouldn't allow to remove files due to dir's permission
25363         chmod a+rwx $tmpdir/$tdir
25364         touch $tmpdir/$tdir/f
25365         ls -la $tmpdir/$tdir
25366         FID=$(lfs path2fid $tmpdir/$tdir/f)
25367         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25368         return 0
25369 }
25370 run_test 421f "rmfid checks permissions"
25371
25372 test_421g() {
25373         local cnt
25374         local FIDS
25375
25376         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25377         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25378                 skip "Need MDS version at least 2.12.54"
25379
25380         mkdir -p $DIR/$tdir
25381         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25382         createmany -o $DIR/$tdir/striped_dir/f 512
25383         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25384         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25385
25386         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25387                 sed "s/[/][^:]*://g")
25388
25389         rm -f $DIR/$tdir/striped_dir/f1*
25390         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25391         removed=$((512 - cnt))
25392
25393         # few files have been just removed, so we expect
25394         # rmfid to fail on their fids
25395         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25396         [ $removed != $errors ] && error "$errors != $removed"
25397
25398         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25399         rm -rf $DIR/$tdir
25400         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25401 }
25402 run_test 421g "rmfid to return errors properly"
25403
25404 test_422() {
25405         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25406         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25407         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25408         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25409         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25410
25411         local amc=$(at_max_get client)
25412         local amo=$(at_max_get mds1)
25413         local timeout=`lctl get_param -n timeout`
25414
25415         at_max_set 0 client
25416         at_max_set 0 mds1
25417
25418 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25419         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25420                         fail_val=$(((2*timeout + 10)*1000))
25421         touch $DIR/$tdir/d3/file &
25422         sleep 2
25423 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25424         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25425                         fail_val=$((2*timeout + 5))
25426         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25427         local pid=$!
25428         sleep 1
25429         kill -9 $pid
25430         sleep $((2 * timeout))
25431         echo kill $pid
25432         kill -9 $pid
25433         lctl mark touch
25434         touch $DIR/$tdir/d2/file3
25435         touch $DIR/$tdir/d2/file4
25436         touch $DIR/$tdir/d2/file5
25437
25438         wait
25439         at_max_set $amc client
25440         at_max_set $amo mds1
25441
25442         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25443         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25444                 error "Watchdog is always throttled"
25445 }
25446 run_test 422 "kill a process with RPC in progress"
25447
25448 stat_test() {
25449     df -h $MOUNT &
25450     df -h $MOUNT &
25451     df -h $MOUNT &
25452     df -h $MOUNT &
25453     df -h $MOUNT &
25454     df -h $MOUNT &
25455 }
25456
25457 test_423() {
25458     local _stats
25459     # ensure statfs cache is expired
25460     sleep 2;
25461
25462     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25463     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25464
25465     return 0
25466 }
25467 run_test 423 "statfs should return a right data"
25468
25469 test_424() {
25470 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25471         $LCTL set_param fail_loc=0x80000522
25472         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25473         rm -f $DIR/$tfile
25474 }
25475 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25476
25477 test_425() {
25478         test_mkdir -c -1 $DIR/$tdir
25479         $LFS setstripe -c -1 $DIR/$tdir
25480
25481         lru_resize_disable "" 100
25482         stack_trap "lru_resize_enable" EXIT
25483
25484         sleep 5
25485
25486         for i in $(seq $((MDSCOUNT * 125))); do
25487                 local t=$DIR/$tdir/$tfile_$i
25488
25489                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25490                         error_noexit "Create file $t"
25491         done
25492         stack_trap "rm -rf $DIR/$tdir" EXIT
25493
25494         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25495                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25496                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25497
25498                 [ $lock_count -le $lru_size ] ||
25499                         error "osc lock count $lock_count > lru size $lru_size"
25500         done
25501
25502         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25503                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25504                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25505
25506                 [ $lock_count -le $lru_size ] ||
25507                         error "mdc lock count $lock_count > lru size $lru_size"
25508         done
25509 }
25510 run_test 425 "lock count should not exceed lru size"
25511
25512 test_426() {
25513         splice-test -r $DIR/$tfile
25514         splice-test -rd $DIR/$tfile
25515         splice-test $DIR/$tfile
25516         splice-test -d $DIR/$tfile
25517 }
25518 run_test 426 "splice test on Lustre"
25519
25520 test_427() {
25521         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25522         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25523                 skip "Need MDS version at least 2.12.4"
25524         local log
25525
25526         mkdir $DIR/$tdir
25527         mkdir $DIR/$tdir/1
25528         mkdir $DIR/$tdir/2
25529         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25530         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25531
25532         $LFS getdirstripe $DIR/$tdir/1/dir
25533
25534         #first setfattr for creating updatelog
25535         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25536
25537 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25538         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25539         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25540         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25541
25542         sleep 2
25543         fail mds2
25544         wait_recovery_complete mds2 $((2*TIMEOUT))
25545
25546         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25547         echo $log | grep "get update log failed" &&
25548                 error "update log corruption is detected" || true
25549 }
25550 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25551
25552 test_428() {
25553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25554         local cache_limit=$CACHE_MAX
25555
25556         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25557         $LCTL set_param -n llite.*.max_cached_mb=64
25558
25559         mkdir $DIR/$tdir
25560         $LFS setstripe -c 1 $DIR/$tdir
25561         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25562         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25563         #test write
25564         for f in $(seq 4); do
25565                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25566         done
25567         wait
25568
25569         cancel_lru_locks osc
25570         # Test read
25571         for f in $(seq 4); do
25572                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25573         done
25574         wait
25575 }
25576 run_test 428 "large block size IO should not hang"
25577
25578 test_429() { # LU-7915 / LU-10948
25579         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25580         local testfile=$DIR/$tfile
25581         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25582         local new_flag=1
25583         local first_rpc
25584         local second_rpc
25585         local third_rpc
25586
25587         $LCTL get_param $ll_opencache_threshold_count ||
25588                 skip "client does not have opencache parameter"
25589
25590         set_opencache $new_flag
25591         stack_trap "restore_opencache"
25592         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25593                 error "enable opencache failed"
25594         touch $testfile
25595         # drop MDC DLM locks
25596         cancel_lru_locks mdc
25597         # clear MDC RPC stats counters
25598         $LCTL set_param $mdc_rpcstats=clear
25599
25600         # According to the current implementation, we need to run 3 times
25601         # open & close file to verify if opencache is enabled correctly.
25602         # 1st, RPCs are sent for lookup/open and open handle is released on
25603         #      close finally.
25604         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25605         #      so open handle won't be released thereafter.
25606         # 3rd, No RPC is sent out.
25607         $MULTIOP $testfile oc || error "multiop failed"
25608         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25609         echo "1st: $first_rpc RPCs in flight"
25610
25611         $MULTIOP $testfile oc || error "multiop failed"
25612         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25613         echo "2nd: $second_rpc RPCs in flight"
25614
25615         $MULTIOP $testfile oc || error "multiop failed"
25616         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25617         echo "3rd: $third_rpc RPCs in flight"
25618
25619         #verify no MDC RPC is sent
25620         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25621 }
25622 run_test 429 "verify if opencache flag on client side does work"
25623
25624 lseek_test_430() {
25625         local offset
25626         local file=$1
25627
25628         # data at [200K, 400K)
25629         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25630                 error "256K->512K dd fails"
25631         # data at [2M, 3M)
25632         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25633                 error "2M->3M dd fails"
25634         # data at [4M, 5M)
25635         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25636                 error "4M->5M dd fails"
25637         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25638         # start at first component hole #1
25639         printf "Seeking hole from 1000 ... "
25640         offset=$(lseek_test -l 1000 $file)
25641         echo $offset
25642         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25643         printf "Seeking data from 1000 ... "
25644         offset=$(lseek_test -d 1000 $file)
25645         echo $offset
25646         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25647
25648         # start at first component data block
25649         printf "Seeking hole from 300000 ... "
25650         offset=$(lseek_test -l 300000 $file)
25651         echo $offset
25652         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25653         printf "Seeking data from 300000 ... "
25654         offset=$(lseek_test -d 300000 $file)
25655         echo $offset
25656         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25657
25658         # start at the first component but beyond end of object size
25659         printf "Seeking hole from 1000000 ... "
25660         offset=$(lseek_test -l 1000000 $file)
25661         echo $offset
25662         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25663         printf "Seeking data from 1000000 ... "
25664         offset=$(lseek_test -d 1000000 $file)
25665         echo $offset
25666         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25667
25668         # start at second component stripe 2 (empty file)
25669         printf "Seeking hole from 1500000 ... "
25670         offset=$(lseek_test -l 1500000 $file)
25671         echo $offset
25672         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25673         printf "Seeking data from 1500000 ... "
25674         offset=$(lseek_test -d 1500000 $file)
25675         echo $offset
25676         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25677
25678         # start at second component stripe 1 (all data)
25679         printf "Seeking hole from 3000000 ... "
25680         offset=$(lseek_test -l 3000000 $file)
25681         echo $offset
25682         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25683         printf "Seeking data from 3000000 ... "
25684         offset=$(lseek_test -d 3000000 $file)
25685         echo $offset
25686         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25687
25688         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25689                 error "2nd dd fails"
25690         echo "Add data block at 640K...1280K"
25691
25692         # start at before new data block, in hole
25693         printf "Seeking hole from 600000 ... "
25694         offset=$(lseek_test -l 600000 $file)
25695         echo $offset
25696         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25697         printf "Seeking data from 600000 ... "
25698         offset=$(lseek_test -d 600000 $file)
25699         echo $offset
25700         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25701
25702         # start at the first component new data block
25703         printf "Seeking hole from 1000000 ... "
25704         offset=$(lseek_test -l 1000000 $file)
25705         echo $offset
25706         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25707         printf "Seeking data from 1000000 ... "
25708         offset=$(lseek_test -d 1000000 $file)
25709         echo $offset
25710         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25711
25712         # start at second component stripe 2, new data
25713         printf "Seeking hole from 1200000 ... "
25714         offset=$(lseek_test -l 1200000 $file)
25715         echo $offset
25716         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25717         printf "Seeking data from 1200000 ... "
25718         offset=$(lseek_test -d 1200000 $file)
25719         echo $offset
25720         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25721
25722         # start beyond file end
25723         printf "Using offset > filesize ... "
25724         lseek_test -l 4000000 $file && error "lseek should fail"
25725         printf "Using offset > filesize ... "
25726         lseek_test -d 4000000 $file && error "lseek should fail"
25727
25728         printf "Done\n\n"
25729 }
25730
25731 test_430a() {
25732         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25733                 skip "MDT does not support SEEK_HOLE"
25734
25735         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25736                 skip "OST does not support SEEK_HOLE"
25737
25738         local file=$DIR/$tdir/$tfile
25739
25740         mkdir -p $DIR/$tdir
25741
25742         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25743         # OST stripe #1 will have continuous data at [1M, 3M)
25744         # OST stripe #2 is empty
25745         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25746         lseek_test_430 $file
25747         rm $file
25748         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25749         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25750         lseek_test_430 $file
25751         rm $file
25752         $LFS setstripe -c2 -S 512K $file
25753         echo "Two stripes, stripe size 512K"
25754         lseek_test_430 $file
25755         rm $file
25756         # FLR with stale mirror
25757         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25758                        -N -c2 -S 1M $file
25759         echo "Mirrored file:"
25760         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25761         echo "Plain 2 stripes 1M"
25762         lseek_test_430 $file
25763         rm $file
25764 }
25765 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25766
25767 test_430b() {
25768         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25769                 skip "OST does not support SEEK_HOLE"
25770
25771         local offset
25772         local file=$DIR/$tdir/$tfile
25773
25774         mkdir -p $DIR/$tdir
25775         # Empty layout lseek should fail
25776         $MCREATE $file
25777         # seek from 0
25778         printf "Seeking hole from 0 ... "
25779         lseek_test -l 0 $file && error "lseek should fail"
25780         printf "Seeking data from 0 ... "
25781         lseek_test -d 0 $file && error "lseek should fail"
25782         rm $file
25783
25784         # 1M-hole file
25785         $LFS setstripe -E 1M -c2 -E eof $file
25786         $TRUNCATE $file 1048576
25787         printf "Seeking hole from 1000000 ... "
25788         offset=$(lseek_test -l 1000000 $file)
25789         echo $offset
25790         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25791         printf "Seeking data from 1000000 ... "
25792         lseek_test -d 1000000 $file && error "lseek should fail"
25793         rm $file
25794
25795         # full component followed by non-inited one
25796         $LFS setstripe -E 1M -c2 -E eof $file
25797         dd if=/dev/urandom of=$file bs=1M count=1
25798         printf "Seeking hole from 1000000 ... "
25799         offset=$(lseek_test -l 1000000 $file)
25800         echo $offset
25801         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25802         printf "Seeking hole from 1048576 ... "
25803         lseek_test -l 1048576 $file && error "lseek should fail"
25804         # init second component and truncate back
25805         echo "123" >> $file
25806         $TRUNCATE $file 1048576
25807         printf "Seeking hole from 1000000 ... "
25808         offset=$(lseek_test -l 1000000 $file)
25809         echo $offset
25810         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25811         printf "Seeking hole from 1048576 ... "
25812         lseek_test -l 1048576 $file && error "lseek should fail"
25813         # boundary checks for big values
25814         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25815         offset=$(lseek_test -d 0 $file.10g)
25816         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25817         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25818         offset=$(lseek_test -d 0 $file.100g)
25819         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25820         return 0
25821 }
25822 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25823
25824 test_430c() {
25825         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25826                 skip "OST does not support SEEK_HOLE"
25827
25828         local file=$DIR/$tdir/$tfile
25829         local start
25830
25831         mkdir -p $DIR/$tdir
25832         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25833
25834         # cp version 8.33+ prefers lseek over fiemap
25835         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25836                 start=$SECONDS
25837                 time cp $file /dev/null
25838                 (( SECONDS - start < 5 )) ||
25839                         error "cp: too long runtime $((SECONDS - start))"
25840
25841         fi
25842         # tar version 1.29+ supports SEEK_HOLE/DATA
25843         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25844                 start=$SECONDS
25845                 time tar cS $file - | cat > /dev/null
25846                 (( SECONDS - start < 5 )) ||
25847                         error "tar: too long runtime $((SECONDS - start))"
25848         fi
25849 }
25850 run_test 430c "lseek: external tools check"
25851
25852 test_431() { # LU-14187
25853         local file=$DIR/$tdir/$tfile
25854
25855         mkdir -p $DIR/$tdir
25856         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25857         dd if=/dev/urandom of=$file bs=4k count=1
25858         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25859         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25860         #define OBD_FAIL_OST_RESTART_IO 0x251
25861         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25862         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25863         cp $file $file.0
25864         cancel_lru_locks
25865         sync_all_data
25866         echo 3 > /proc/sys/vm/drop_caches
25867         diff  $file $file.0 || error "data diff"
25868 }
25869 run_test 431 "Restart transaction for IO"
25870
25871 cleanup_test_432() {
25872         do_facet mgs $LCTL nodemap_activate 0
25873         wait_nm_sync active
25874 }
25875
25876 test_432() {
25877         local tmpdir=$TMP/dir432
25878
25879         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
25880                 skip "Need MDS version at least 2.14.52"
25881
25882         stack_trap cleanup_test_432 EXIT
25883         mkdir $DIR/$tdir
25884         mkdir $tmpdir
25885
25886         do_facet mgs $LCTL nodemap_activate 1
25887         wait_nm_sync active
25888         do_facet mgs $LCTL nodemap_modify --name default \
25889                 --property admin --value 1
25890         do_facet mgs $LCTL nodemap_modify --name default \
25891                 --property trusted --value 1
25892         cancel_lru_locks mdc
25893         wait_nm_sync default admin_nodemap
25894         wait_nm_sync default trusted_nodemap
25895
25896         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
25897                grep -ci "Operation not permitted") -ne 0 ]; then
25898                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
25899         fi
25900 }
25901 run_test 432 "mv dir from outside Lustre"
25902
25903 prep_801() {
25904         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25905         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25906                 skip "Need server version at least 2.9.55"
25907
25908         start_full_debug_logging
25909 }
25910
25911 post_801() {
25912         stop_full_debug_logging
25913 }
25914
25915 barrier_stat() {
25916         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25917                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25918                            awk '/The barrier for/ { print $7 }')
25919                 echo $st
25920         else
25921                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25922                 echo \'$st\'
25923         fi
25924 }
25925
25926 barrier_expired() {
25927         local expired
25928
25929         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25930                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25931                           awk '/will be expired/ { print $7 }')
25932         else
25933                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25934         fi
25935
25936         echo $expired
25937 }
25938
25939 test_801a() {
25940         prep_801
25941
25942         echo "Start barrier_freeze at: $(date)"
25943         #define OBD_FAIL_BARRIER_DELAY          0x2202
25944         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25945         # Do not reduce barrier time - See LU-11873
25946         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25947
25948         sleep 2
25949         local b_status=$(barrier_stat)
25950         echo "Got barrier status at: $(date)"
25951         [ "$b_status" = "'freezing_p1'" ] ||
25952                 error "(1) unexpected barrier status $b_status"
25953
25954         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25955         wait
25956         b_status=$(barrier_stat)
25957         [ "$b_status" = "'frozen'" ] ||
25958                 error "(2) unexpected barrier status $b_status"
25959
25960         local expired=$(barrier_expired)
25961         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25962         sleep $((expired + 3))
25963
25964         b_status=$(barrier_stat)
25965         [ "$b_status" = "'expired'" ] ||
25966                 error "(3) unexpected barrier status $b_status"
25967
25968         # Do not reduce barrier time - See LU-11873
25969         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25970                 error "(4) fail to freeze barrier"
25971
25972         b_status=$(barrier_stat)
25973         [ "$b_status" = "'frozen'" ] ||
25974                 error "(5) unexpected barrier status $b_status"
25975
25976         echo "Start barrier_thaw at: $(date)"
25977         #define OBD_FAIL_BARRIER_DELAY          0x2202
25978         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25979         do_facet mgs $LCTL barrier_thaw $FSNAME &
25980
25981         sleep 2
25982         b_status=$(barrier_stat)
25983         echo "Got barrier status at: $(date)"
25984         [ "$b_status" = "'thawing'" ] ||
25985                 error "(6) unexpected barrier status $b_status"
25986
25987         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25988         wait
25989         b_status=$(barrier_stat)
25990         [ "$b_status" = "'thawed'" ] ||
25991                 error "(7) unexpected barrier status $b_status"
25992
25993         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25994         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25995         do_facet mgs $LCTL barrier_freeze $FSNAME
25996
25997         b_status=$(barrier_stat)
25998         [ "$b_status" = "'failed'" ] ||
25999                 error "(8) unexpected barrier status $b_status"
26000
26001         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26002         do_facet mgs $LCTL barrier_thaw $FSNAME
26003
26004         post_801
26005 }
26006 run_test 801a "write barrier user interfaces and stat machine"
26007
26008 test_801b() {
26009         prep_801
26010
26011         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26012         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26013         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26014         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26015         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26016
26017         cancel_lru_locks mdc
26018
26019         # 180 seconds should be long enough
26020         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26021
26022         local b_status=$(barrier_stat)
26023         [ "$b_status" = "'frozen'" ] ||
26024                 error "(6) unexpected barrier status $b_status"
26025
26026         mkdir $DIR/$tdir/d0/d10 &
26027         mkdir_pid=$!
26028
26029         touch $DIR/$tdir/d1/f13 &
26030         touch_pid=$!
26031
26032         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26033         ln_pid=$!
26034
26035         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26036         mv_pid=$!
26037
26038         rm -f $DIR/$tdir/d4/f12 &
26039         rm_pid=$!
26040
26041         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26042
26043         # To guarantee taht the 'stat' is not blocked
26044         b_status=$(barrier_stat)
26045         [ "$b_status" = "'frozen'" ] ||
26046                 error "(8) unexpected barrier status $b_status"
26047
26048         # let above commands to run at background
26049         sleep 5
26050
26051         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26052         ps -p $touch_pid || error "(10) touch should be blocked"
26053         ps -p $ln_pid || error "(11) link should be blocked"
26054         ps -p $mv_pid || error "(12) rename should be blocked"
26055         ps -p $rm_pid || error "(13) unlink should be blocked"
26056
26057         b_status=$(barrier_stat)
26058         [ "$b_status" = "'frozen'" ] ||
26059                 error "(14) unexpected barrier status $b_status"
26060
26061         do_facet mgs $LCTL barrier_thaw $FSNAME
26062         b_status=$(barrier_stat)
26063         [ "$b_status" = "'thawed'" ] ||
26064                 error "(15) unexpected barrier status $b_status"
26065
26066         wait $mkdir_pid || error "(16) mkdir should succeed"
26067         wait $touch_pid || error "(17) touch should succeed"
26068         wait $ln_pid || error "(18) link should succeed"
26069         wait $mv_pid || error "(19) rename should succeed"
26070         wait $rm_pid || error "(20) unlink should succeed"
26071
26072         post_801
26073 }
26074 run_test 801b "modification will be blocked by write barrier"
26075
26076 test_801c() {
26077         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26078
26079         prep_801
26080
26081         stop mds2 || error "(1) Fail to stop mds2"
26082
26083         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26084
26085         local b_status=$(barrier_stat)
26086         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26087                 do_facet mgs $LCTL barrier_thaw $FSNAME
26088                 error "(2) unexpected barrier status $b_status"
26089         }
26090
26091         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26092                 error "(3) Fail to rescan barrier bitmap"
26093
26094         # Do not reduce barrier time - See LU-11873
26095         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26096
26097         b_status=$(barrier_stat)
26098         [ "$b_status" = "'frozen'" ] ||
26099                 error "(4) unexpected barrier status $b_status"
26100
26101         do_facet mgs $LCTL barrier_thaw $FSNAME
26102         b_status=$(barrier_stat)
26103         [ "$b_status" = "'thawed'" ] ||
26104                 error "(5) unexpected barrier status $b_status"
26105
26106         local devname=$(mdsdevname 2)
26107
26108         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26109
26110         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26111                 error "(7) Fail to rescan barrier bitmap"
26112
26113         post_801
26114 }
26115 run_test 801c "rescan barrier bitmap"
26116
26117 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26118 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26119 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26120 saved_MOUNT_OPTS=$MOUNT_OPTS
26121
26122 cleanup_802a() {
26123         trap 0
26124
26125         stopall
26126         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26127         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26128         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26129         MOUNT_OPTS=$saved_MOUNT_OPTS
26130         setupall
26131 }
26132
26133 test_802a() {
26134         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26135         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26136         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26137                 skip "Need server version at least 2.9.55"
26138
26139         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26140
26141         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26142
26143         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26144                 error "(2) Fail to copy"
26145
26146         trap cleanup_802a EXIT
26147
26148         # sync by force before remount as readonly
26149         sync; sync_all_data; sleep 3; sync_all_data
26150
26151         stopall
26152
26153         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26154         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26155         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26156
26157         echo "Mount the server as read only"
26158         setupall server_only || error "(3) Fail to start servers"
26159
26160         echo "Mount client without ro should fail"
26161         mount_client $MOUNT &&
26162                 error "(4) Mount client without 'ro' should fail"
26163
26164         echo "Mount client with ro should succeed"
26165         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26166         mount_client $MOUNT ||
26167                 error "(5) Mount client with 'ro' should succeed"
26168
26169         echo "Modify should be refused"
26170         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26171
26172         echo "Read should be allowed"
26173         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26174                 error "(7) Read should succeed under ro mode"
26175
26176         cleanup_802a
26177 }
26178 run_test 802a "simulate readonly device"
26179
26180 test_802b() {
26181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26182         remote_mds_nodsh && skip "remote MDS with nodsh"
26183
26184         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26185                 skip "readonly option not available"
26186
26187         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26188
26189         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26190                 error "(2) Fail to copy"
26191
26192         # write back all cached data before setting MDT to readonly
26193         cancel_lru_locks
26194         sync_all_data
26195
26196         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26197         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26198
26199         echo "Modify should be refused"
26200         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26201
26202         echo "Read should be allowed"
26203         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26204                 error "(7) Read should succeed under ro mode"
26205
26206         # disable readonly
26207         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26208 }
26209 run_test 802b "be able to set MDTs to readonly"
26210
26211 test_803a() {
26212         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26213         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26214                 skip "MDS needs to be newer than 2.10.54"
26215
26216         mkdir_on_mdt0 $DIR/$tdir
26217         # Create some objects on all MDTs to trigger related logs objects
26218         for idx in $(seq $MDSCOUNT); do
26219                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26220                         $DIR/$tdir/dir${idx} ||
26221                         error "Fail to create $DIR/$tdir/dir${idx}"
26222         done
26223
26224         sync; sleep 3
26225         wait_delete_completed # ensure old test cleanups are finished
26226         echo "before create:"
26227         $LFS df -i $MOUNT
26228         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26229
26230         for i in {1..10}; do
26231                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26232                         error "Fail to create $DIR/$tdir/foo$i"
26233         done
26234
26235         sync; sleep 3
26236         echo "after create:"
26237         $LFS df -i $MOUNT
26238         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26239
26240         # allow for an llog to be cleaned up during the test
26241         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26242                 error "before ($before_used) + 10 > after ($after_used)"
26243
26244         for i in {1..10}; do
26245                 rm -rf $DIR/$tdir/foo$i ||
26246                         error "Fail to remove $DIR/$tdir/foo$i"
26247         done
26248
26249         sleep 3 # avoid MDT return cached statfs
26250         wait_delete_completed
26251         echo "after unlink:"
26252         $LFS df -i $MOUNT
26253         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26254
26255         # allow for an llog to be created during the test
26256         [ $after_used -le $((before_used + 1)) ] ||
26257                 error "after ($after_used) > before ($before_used) + 1"
26258 }
26259 run_test 803a "verify agent object for remote object"
26260
26261 test_803b() {
26262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26263         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26264                 skip "MDS needs to be newer than 2.13.56"
26265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26266
26267         for i in $(seq 0 $((MDSCOUNT - 1))); do
26268                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26269         done
26270
26271         local before=0
26272         local after=0
26273
26274         local tmp
26275
26276         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26277         for i in $(seq 0 $((MDSCOUNT - 1))); do
26278                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26279                         awk '/getattr/ { print $2 }')
26280                 before=$((before + tmp))
26281         done
26282         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26283         for i in $(seq 0 $((MDSCOUNT - 1))); do
26284                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26285                         awk '/getattr/ { print $2 }')
26286                 after=$((after + tmp))
26287         done
26288
26289         [ $before -eq $after ] || error "getattr count $before != $after"
26290 }
26291 run_test 803b "remote object can getattr from cache"
26292
26293 test_804() {
26294         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26295         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26296                 skip "MDS needs to be newer than 2.10.54"
26297         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26298
26299         mkdir -p $DIR/$tdir
26300         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26301                 error "Fail to create $DIR/$tdir/dir0"
26302
26303         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26304         local dev=$(mdsdevname 2)
26305
26306         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26307                 grep ${fid} || error "NOT found agent entry for dir0"
26308
26309         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26310                 error "Fail to create $DIR/$tdir/dir1"
26311
26312         touch $DIR/$tdir/dir1/foo0 ||
26313                 error "Fail to create $DIR/$tdir/dir1/foo0"
26314         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26315         local rc=0
26316
26317         for idx in $(seq $MDSCOUNT); do
26318                 dev=$(mdsdevname $idx)
26319                 do_facet mds${idx} \
26320                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26321                         grep ${fid} && rc=$idx
26322         done
26323
26324         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26325                 error "Fail to rename foo0 to foo1"
26326         if [ $rc -eq 0 ]; then
26327                 for idx in $(seq $MDSCOUNT); do
26328                         dev=$(mdsdevname $idx)
26329                         do_facet mds${idx} \
26330                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26331                         grep ${fid} && rc=$idx
26332                 done
26333         fi
26334
26335         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26336                 error "Fail to rename foo1 to foo2"
26337         if [ $rc -eq 0 ]; then
26338                 for idx in $(seq $MDSCOUNT); do
26339                         dev=$(mdsdevname $idx)
26340                         do_facet mds${idx} \
26341                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26342                         grep ${fid} && rc=$idx
26343                 done
26344         fi
26345
26346         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26347
26348         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26349                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26350         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26351                 error "Fail to rename foo2 to foo0"
26352         unlink $DIR/$tdir/dir1/foo0 ||
26353                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26354         rm -rf $DIR/$tdir/dir0 ||
26355                 error "Fail to rm $DIR/$tdir/dir0"
26356
26357         for idx in $(seq $MDSCOUNT); do
26358                 dev=$(mdsdevname $idx)
26359                 rc=0
26360
26361                 stop mds${idx}
26362                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26363                         rc=$?
26364                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26365                         error "mount mds$idx failed"
26366                 df $MOUNT > /dev/null 2>&1
26367
26368                 # e2fsck should not return error
26369                 [ $rc -eq 0 ] ||
26370                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26371         done
26372 }
26373 run_test 804 "verify agent entry for remote entry"
26374
26375 cleanup_805() {
26376         do_facet $SINGLEMDS zfs set quota=$old $fsset
26377         unlinkmany $DIR/$tdir/f- 1000000
26378         trap 0
26379 }
26380
26381 test_805() {
26382         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26383         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26384         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26385                 skip "netfree not implemented before 0.7"
26386         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26387                 skip "Need MDS version at least 2.10.57"
26388
26389         local fsset
26390         local freekb
26391         local usedkb
26392         local old
26393         local quota
26394         local pref="osd-zfs.$FSNAME-MDT0000."
26395
26396         # limit available space on MDS dataset to meet nospace issue
26397         # quickly. then ZFS 0.7.2 can use reserved space if asked
26398         # properly (using netfree flag in osd_declare_destroy()
26399         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26400         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26401                 gawk '{print $3}')
26402         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26403         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26404         let "usedkb=usedkb-freekb"
26405         let "freekb=freekb/2"
26406         if let "freekb > 5000"; then
26407                 let "freekb=5000"
26408         fi
26409         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26410         trap cleanup_805 EXIT
26411         mkdir_on_mdt0 $DIR/$tdir
26412         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26413                 error "Can't set PFL layout"
26414         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26415         rm -rf $DIR/$tdir || error "not able to remove"
26416         do_facet $SINGLEMDS zfs set quota=$old $fsset
26417         trap 0
26418 }
26419 run_test 805 "ZFS can remove from full fs"
26420
26421 # Size-on-MDS test
26422 check_lsom_data()
26423 {
26424         local file=$1
26425         local expect=$(stat -c %s $file)
26426
26427         check_lsom_size $1 $expect
26428
26429         local blocks=$($LFS getsom -b $file)
26430         expect=$(stat -c %b $file)
26431         [[ $blocks == $expect ]] ||
26432                 error "$file expected blocks: $expect, got: $blocks"
26433 }
26434
26435 check_lsom_size()
26436 {
26437         local size
26438         local expect=$2
26439
26440         cancel_lru_locks mdc
26441
26442         size=$($LFS getsom -s $1)
26443         [[ $size == $expect ]] ||
26444                 error "$file expected size: $expect, got: $size"
26445 }
26446
26447 test_806() {
26448         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26449                 skip "Need MDS version at least 2.11.52"
26450
26451         local bs=1048576
26452
26453         touch $DIR/$tfile || error "touch $tfile failed"
26454
26455         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26456         save_lustre_params client "llite.*.xattr_cache" > $save
26457         lctl set_param llite.*.xattr_cache=0
26458         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26459
26460         # single-threaded write
26461         echo "Test SOM for single-threaded write"
26462         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26463                 error "write $tfile failed"
26464         check_lsom_size $DIR/$tfile $bs
26465
26466         local num=32
26467         local size=$(($num * $bs))
26468         local offset=0
26469         local i
26470
26471         echo "Test SOM for single client multi-threaded($num) write"
26472         $TRUNCATE $DIR/$tfile 0
26473         for ((i = 0; i < $num; i++)); do
26474                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26475                 local pids[$i]=$!
26476                 offset=$((offset + $bs))
26477         done
26478         for (( i=0; i < $num; i++ )); do
26479                 wait ${pids[$i]}
26480         done
26481         check_lsom_size $DIR/$tfile $size
26482
26483         $TRUNCATE $DIR/$tfile 0
26484         for ((i = 0; i < $num; i++)); do
26485                 offset=$((offset - $bs))
26486                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26487                 local pids[$i]=$!
26488         done
26489         for (( i=0; i < $num; i++ )); do
26490                 wait ${pids[$i]}
26491         done
26492         check_lsom_size $DIR/$tfile $size
26493
26494         # multi-client writes
26495         num=$(get_node_count ${CLIENTS//,/ })
26496         size=$(($num * $bs))
26497         offset=0
26498         i=0
26499
26500         echo "Test SOM for multi-client ($num) writes"
26501         $TRUNCATE $DIR/$tfile 0
26502         for client in ${CLIENTS//,/ }; do
26503                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26504                 local pids[$i]=$!
26505                 i=$((i + 1))
26506                 offset=$((offset + $bs))
26507         done
26508         for (( i=0; i < $num; i++ )); do
26509                 wait ${pids[$i]}
26510         done
26511         check_lsom_size $DIR/$tfile $offset
26512
26513         i=0
26514         $TRUNCATE $DIR/$tfile 0
26515         for client in ${CLIENTS//,/ }; do
26516                 offset=$((offset - $bs))
26517                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26518                 local pids[$i]=$!
26519                 i=$((i + 1))
26520         done
26521         for (( i=0; i < $num; i++ )); do
26522                 wait ${pids[$i]}
26523         done
26524         check_lsom_size $DIR/$tfile $size
26525
26526         # verify truncate
26527         echo "Test SOM for truncate"
26528         $TRUNCATE $DIR/$tfile 1048576
26529         check_lsom_size $DIR/$tfile 1048576
26530         $TRUNCATE $DIR/$tfile 1234
26531         check_lsom_size $DIR/$tfile 1234
26532
26533         # verify SOM blocks count
26534         echo "Verify SOM block count"
26535         $TRUNCATE $DIR/$tfile 0
26536         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26537                 error "failed to write file $tfile"
26538         check_lsom_data $DIR/$tfile
26539 }
26540 run_test 806 "Verify Lazy Size on MDS"
26541
26542 test_807() {
26543         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26544         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26545                 skip "Need MDS version at least 2.11.52"
26546
26547         # Registration step
26548         changelog_register || error "changelog_register failed"
26549         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26550         changelog_users $SINGLEMDS | grep -q $cl_user ||
26551                 error "User $cl_user not found in changelog_users"
26552
26553         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26554         save_lustre_params client "llite.*.xattr_cache" > $save
26555         lctl set_param llite.*.xattr_cache=0
26556         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26557
26558         rm -rf $DIR/$tdir || error "rm $tdir failed"
26559         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26560         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26561         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26562         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26563                 error "truncate $tdir/trunc failed"
26564
26565         local bs=1048576
26566         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26567                 error "write $tfile failed"
26568
26569         # multi-client wirtes
26570         local num=$(get_node_count ${CLIENTS//,/ })
26571         local offset=0
26572         local i=0
26573
26574         echo "Test SOM for multi-client ($num) writes"
26575         touch $DIR/$tfile || error "touch $tfile failed"
26576         $TRUNCATE $DIR/$tfile 0
26577         for client in ${CLIENTS//,/ }; do
26578                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26579                 local pids[$i]=$!
26580                 i=$((i + 1))
26581                 offset=$((offset + $bs))
26582         done
26583         for (( i=0; i < $num; i++ )); do
26584                 wait ${pids[$i]}
26585         done
26586
26587         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26588         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26589         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26590         check_lsom_data $DIR/$tdir/trunc
26591         check_lsom_data $DIR/$tdir/single_dd
26592         check_lsom_data $DIR/$tfile
26593
26594         rm -rf $DIR/$tdir
26595         # Deregistration step
26596         changelog_deregister || error "changelog_deregister failed"
26597 }
26598 run_test 807 "verify LSOM syncing tool"
26599
26600 check_som_nologged()
26601 {
26602         local lines=$($LFS changelog $FSNAME-MDT0000 |
26603                 grep 'x=trusted.som' | wc -l)
26604         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26605 }
26606
26607 test_808() {
26608         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26609                 skip "Need MDS version at least 2.11.55"
26610
26611         # Registration step
26612         changelog_register || error "changelog_register failed"
26613
26614         touch $DIR/$tfile || error "touch $tfile failed"
26615         check_som_nologged
26616
26617         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26618                 error "write $tfile failed"
26619         check_som_nologged
26620
26621         $TRUNCATE $DIR/$tfile 1234
26622         check_som_nologged
26623
26624         $TRUNCATE $DIR/$tfile 1048576
26625         check_som_nologged
26626
26627         # Deregistration step
26628         changelog_deregister || error "changelog_deregister failed"
26629 }
26630 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26631
26632 check_som_nodata()
26633 {
26634         $LFS getsom $1
26635         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26636 }
26637
26638 test_809() {
26639         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26640                 skip "Need MDS version at least 2.11.56"
26641
26642         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26643                 error "failed to create DoM-only file $DIR/$tfile"
26644         touch $DIR/$tfile || error "touch $tfile failed"
26645         check_som_nodata $DIR/$tfile
26646
26647         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26648                 error "write $tfile failed"
26649         check_som_nodata $DIR/$tfile
26650
26651         $TRUNCATE $DIR/$tfile 1234
26652         check_som_nodata $DIR/$tfile
26653
26654         $TRUNCATE $DIR/$tfile 4097
26655         check_som_nodata $DIR/$file
26656 }
26657 run_test 809 "Verify no SOM xattr store for DoM-only files"
26658
26659 test_810() {
26660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26661         $GSS && skip_env "could not run with gss"
26662         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26663                 skip "OST < 2.12.58 doesn't align checksum"
26664
26665         set_checksums 1
26666         stack_trap "set_checksums $ORIG_CSUM" EXIT
26667         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26668
26669         local csum
26670         local before
26671         local after
26672         for csum in $CKSUM_TYPES; do
26673                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26674                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26675                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26676                         eval set -- $i
26677                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26678                         before=$(md5sum $DIR/$tfile)
26679                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26680                         after=$(md5sum $DIR/$tfile)
26681                         [ "$before" == "$after" ] ||
26682                                 error "$csum: $before != $after bs=$1 seek=$2"
26683                 done
26684         done
26685 }
26686 run_test 810 "partial page writes on ZFS (LU-11663)"
26687
26688 test_812a() {
26689         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26690                 skip "OST < 2.12.51 doesn't support this fail_loc"
26691
26692         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26693         # ensure ost1 is connected
26694         stat $DIR/$tfile >/dev/null || error "can't stat"
26695         wait_osc_import_state client ost1 FULL
26696         # no locks, no reqs to let the connection idle
26697         cancel_lru_locks osc
26698
26699         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26700 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26701         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26702         wait_osc_import_state client ost1 CONNECTING
26703         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26704
26705         stat $DIR/$tfile >/dev/null || error "can't stat file"
26706 }
26707 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26708
26709 test_812b() { # LU-12378
26710         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26711                 skip "OST < 2.12.51 doesn't support this fail_loc"
26712
26713         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26714         # ensure ost1 is connected
26715         stat $DIR/$tfile >/dev/null || error "can't stat"
26716         wait_osc_import_state client ost1 FULL
26717         # no locks, no reqs to let the connection idle
26718         cancel_lru_locks osc
26719
26720         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26721 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26722         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26723         wait_osc_import_state client ost1 CONNECTING
26724         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26725
26726         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26727         wait_osc_import_state client ost1 IDLE
26728 }
26729 run_test 812b "do not drop no resend request for idle connect"
26730
26731 test_812c() {
26732         local old
26733
26734         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26735
26736         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26737         $LFS getstripe $DIR/$tfile
26738         $LCTL set_param osc.*.idle_timeout=10
26739         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26740         # ensure ost1 is connected
26741         stat $DIR/$tfile >/dev/null || error "can't stat"
26742         wait_osc_import_state client ost1 FULL
26743         # no locks, no reqs to let the connection idle
26744         cancel_lru_locks osc
26745
26746 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26747         $LCTL set_param fail_loc=0x80000533
26748         sleep 15
26749         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26750 }
26751 run_test 812c "idle import vs lock enqueue race"
26752
26753 test_813() {
26754         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26755         [ -z "$file_heat_sav" ] && skip "no file heat support"
26756
26757         local readsample
26758         local writesample
26759         local readbyte
26760         local writebyte
26761         local readsample1
26762         local writesample1
26763         local readbyte1
26764         local writebyte1
26765
26766         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26767         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26768
26769         $LCTL set_param -n llite.*.file_heat=1
26770         echo "Turn on file heat"
26771         echo "Period second: $period_second, Decay percentage: $decay_pct"
26772
26773         echo "QQQQ" > $DIR/$tfile
26774         echo "QQQQ" > $DIR/$tfile
26775         echo "QQQQ" > $DIR/$tfile
26776         cat $DIR/$tfile > /dev/null
26777         cat $DIR/$tfile > /dev/null
26778         cat $DIR/$tfile > /dev/null
26779         cat $DIR/$tfile > /dev/null
26780
26781         local out=$($LFS heat_get $DIR/$tfile)
26782
26783         $LFS heat_get $DIR/$tfile
26784         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26785         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26786         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26787         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26788
26789         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26790         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26791         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26792         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26793
26794         sleep $((period_second + 3))
26795         echo "Sleep $((period_second + 3)) seconds..."
26796         # The recursion formula to calculate the heat of the file f is as
26797         # follow:
26798         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26799         # Where Hi is the heat value in the period between time points i*I and
26800         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26801         # to the weight of Ci.
26802         out=$($LFS heat_get $DIR/$tfile)
26803         $LFS heat_get $DIR/$tfile
26804         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26805         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26806         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26807         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26808
26809         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26810                 error "read sample ($readsample) is wrong"
26811         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26812                 error "write sample ($writesample) is wrong"
26813         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26814                 error "read bytes ($readbyte) is wrong"
26815         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26816                 error "write bytes ($writebyte) is wrong"
26817
26818         echo "QQQQ" > $DIR/$tfile
26819         echo "QQQQ" > $DIR/$tfile
26820         echo "QQQQ" > $DIR/$tfile
26821         cat $DIR/$tfile > /dev/null
26822         cat $DIR/$tfile > /dev/null
26823         cat $DIR/$tfile > /dev/null
26824         cat $DIR/$tfile > /dev/null
26825
26826         sleep $((period_second + 3))
26827         echo "Sleep $((period_second + 3)) seconds..."
26828
26829         out=$($LFS heat_get $DIR/$tfile)
26830         $LFS heat_get $DIR/$tfile
26831         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26832         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26833         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26834         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26835
26836         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26837                 4 * $decay_pct) / 100") -eq 1 ] ||
26838                 error "read sample ($readsample1) is wrong"
26839         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26840                 3 * $decay_pct) / 100") -eq 1 ] ||
26841                 error "write sample ($writesample1) is wrong"
26842         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26843                 20 * $decay_pct) / 100") -eq 1 ] ||
26844                 error "read bytes ($readbyte1) is wrong"
26845         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26846                 15 * $decay_pct) / 100") -eq 1 ] ||
26847                 error "write bytes ($writebyte1) is wrong"
26848
26849         echo "Turn off file heat for the file $DIR/$tfile"
26850         $LFS heat_set -o $DIR/$tfile
26851
26852         echo "QQQQ" > $DIR/$tfile
26853         echo "QQQQ" > $DIR/$tfile
26854         echo "QQQQ" > $DIR/$tfile
26855         cat $DIR/$tfile > /dev/null
26856         cat $DIR/$tfile > /dev/null
26857         cat $DIR/$tfile > /dev/null
26858         cat $DIR/$tfile > /dev/null
26859
26860         out=$($LFS heat_get $DIR/$tfile)
26861         $LFS heat_get $DIR/$tfile
26862         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26863         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26864         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26865         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26866
26867         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26868         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26869         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26870         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26871
26872         echo "Trun on file heat for the file $DIR/$tfile"
26873         $LFS heat_set -O $DIR/$tfile
26874
26875         echo "QQQQ" > $DIR/$tfile
26876         echo "QQQQ" > $DIR/$tfile
26877         echo "QQQQ" > $DIR/$tfile
26878         cat $DIR/$tfile > /dev/null
26879         cat $DIR/$tfile > /dev/null
26880         cat $DIR/$tfile > /dev/null
26881         cat $DIR/$tfile > /dev/null
26882
26883         out=$($LFS heat_get $DIR/$tfile)
26884         $LFS heat_get $DIR/$tfile
26885         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26886         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26887         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26888         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26889
26890         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26891         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26892         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26893         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26894
26895         $LFS heat_set -c $DIR/$tfile
26896         $LCTL set_param -n llite.*.file_heat=0
26897         echo "Turn off file heat support for the Lustre filesystem"
26898
26899         echo "QQQQ" > $DIR/$tfile
26900         echo "QQQQ" > $DIR/$tfile
26901         echo "QQQQ" > $DIR/$tfile
26902         cat $DIR/$tfile > /dev/null
26903         cat $DIR/$tfile > /dev/null
26904         cat $DIR/$tfile > /dev/null
26905         cat $DIR/$tfile > /dev/null
26906
26907         out=$($LFS heat_get $DIR/$tfile)
26908         $LFS heat_get $DIR/$tfile
26909         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26910         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26911         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26912         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26913
26914         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26915         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26916         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26917         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26918
26919         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26920         rm -f $DIR/$tfile
26921 }
26922 run_test 813 "File heat verfication"
26923
26924 test_814()
26925 {
26926         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26927         echo -n y >> $DIR/$tfile
26928         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26929         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26930 }
26931 run_test 814 "sparse cp works as expected (LU-12361)"
26932
26933 test_815()
26934 {
26935         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26936         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26937 }
26938 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26939
26940 test_816() {
26941         local ost1_imp=$(get_osc_import_name client ost1)
26942         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26943                          cut -d'.' -f2)
26944
26945         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26946         # ensure ost1 is connected
26947
26948         stat $DIR/$tfile >/dev/null || error "can't stat"
26949         wait_osc_import_state client ost1 FULL
26950         # no locks, no reqs to let the connection idle
26951         cancel_lru_locks osc
26952         lru_resize_disable osc
26953         local before
26954         local now
26955         before=$($LCTL get_param -n \
26956                  ldlm.namespaces.$imp_name.lru_size)
26957
26958         wait_osc_import_state client ost1 IDLE
26959         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26960         now=$($LCTL get_param -n \
26961               ldlm.namespaces.$imp_name.lru_size)
26962         [ $before == $now ] || error "lru_size changed $before != $now"
26963 }
26964 run_test 816 "do not reset lru_resize on idle reconnect"
26965
26966 cleanup_817() {
26967         umount $tmpdir
26968         exportfs -u localhost:$DIR/nfsexp
26969         rm -rf $DIR/nfsexp
26970 }
26971
26972 test_817() {
26973         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26974
26975         mkdir -p $DIR/nfsexp
26976         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26977                 error "failed to export nfs"
26978
26979         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26980         stack_trap cleanup_817 EXIT
26981
26982         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26983                 error "failed to mount nfs to $tmpdir"
26984
26985         cp /bin/true $tmpdir
26986         $DIR/nfsexp/true || error "failed to execute 'true' command"
26987 }
26988 run_test 817 "nfsd won't cache write lock for exec file"
26989
26990 test_818() {
26991         mkdir $DIR/$tdir
26992         $LFS setstripe -c1 -i0 $DIR/$tfile
26993         $LFS setstripe -c1 -i1 $DIR/$tfile
26994         stop $SINGLEMDS
26995         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26996         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26997         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26998                 error "start $SINGLEMDS failed"
26999         rm -rf $DIR/$tdir
27000 }
27001 run_test 818 "unlink with failed llog"
27002
27003 test_819a() {
27004         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27005         cancel_lru_locks osc
27006         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27007         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27008         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27009         rm -f $TDIR/$tfile
27010 }
27011 run_test 819a "too big niobuf in read"
27012
27013 test_819b() {
27014         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27015         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27017         cancel_lru_locks osc
27018         sleep 1
27019         rm -f $TDIR/$tfile
27020 }
27021 run_test 819b "too big niobuf in write"
27022
27023
27024 function test_820_start_ost() {
27025         sleep 5
27026
27027         for num in $(seq $OSTCOUNT); do
27028                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27029         done
27030 }
27031
27032 test_820() {
27033         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27034
27035         mkdir $DIR/$tdir
27036         umount_client $MOUNT || error "umount failed"
27037         for num in $(seq $OSTCOUNT); do
27038                 stop ost$num
27039         done
27040
27041         # mount client with no active OSTs
27042         # so that the client can't initialize max LOV EA size
27043         # from OSC notifications
27044         mount_client $MOUNT || error "mount failed"
27045         # delay OST starting to keep this 0 max EA size for a while
27046         test_820_start_ost &
27047
27048         # create a directory on MDS2
27049         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27050                 error "Failed to create directory"
27051         # open intent should update default EA size
27052         # see mdc_update_max_ea_from_body()
27053         # notice this is the very first RPC to MDS2
27054         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27055         ret=$?
27056         echo $out
27057         # With SSK, this situation can lead to -EPERM being returned.
27058         # In that case, simply retry.
27059         if [ $ret -ne 0 ] && $SHARED_KEY; then
27060                 if echo "$out" | grep -q "not permitted"; then
27061                         cp /etc/services $DIR/$tdir/mds2
27062                         ret=$?
27063                 fi
27064         fi
27065         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27066 }
27067 run_test 820 "update max EA from open intent"
27068
27069 test_822() {
27070         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27071
27072         save_lustre_params mds1 \
27073                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27074         do_facet $SINGLEMDS "$LCTL set_param -n \
27075                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27076         do_facet $SINGLEMDS "$LCTL set_param -n \
27077                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27078
27079         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27080         local maxage=$(do_facet mds1 $LCTL get_param -n \
27081                        osp.$FSNAME-OST0000*MDT0000.maxage)
27082         sleep $((maxage + 1))
27083
27084         #define OBD_FAIL_NET_ERROR_RPC          0x532
27085         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27086
27087         stack_trap "restore_lustre_params < $p; rm $p"
27088
27089         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27090                       osp.$FSNAME-OST0000*MDT0000.create_count")
27091         for i in $(seq 1 $count); do
27092                 touch $DIR/$tfile.${i} || error "touch failed"
27093         done
27094 }
27095 run_test 822 "test precreate failure"
27096
27097 #
27098 # tests that do cleanup/setup should be run at the end
27099 #
27100
27101 test_900() {
27102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27103         local ls
27104
27105         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27106         $LCTL set_param fail_loc=0x903
27107
27108         cancel_lru_locks MGC
27109
27110         FAIL_ON_ERROR=true cleanup
27111         FAIL_ON_ERROR=true setup
27112 }
27113 run_test 900 "umount should not race with any mgc requeue thread"
27114
27115 # LUS-6253/LU-11185
27116 test_901() {
27117         local oldc
27118         local newc
27119         local olds
27120         local news
27121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27122
27123         # some get_param have a bug to handle dot in param name
27124         cancel_lru_locks MGC
27125         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27126         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27127         umount_client $MOUNT || error "umount failed"
27128         mount_client $MOUNT || error "mount failed"
27129         cancel_lru_locks MGC
27130         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27131         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27132
27133         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27134         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27135
27136         return 0
27137 }
27138 run_test 901 "don't leak a mgc lock on client umount"
27139
27140 # LU-13377
27141 test_902() {
27142         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27143                 skip "client does not have LU-13377 fix"
27144         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27145         $LCTL set_param fail_loc=0x1415
27146         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27147         cancel_lru_locks osc
27148         rm -f $DIR/$tfile
27149 }
27150 run_test 902 "test short write doesn't hang lustre"
27151
27152 complete $SECONDS
27153 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27154 check_and_cleanup_lustre
27155 if [ "$I_MOUNTED" != "yes" ]; then
27156         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27157 fi
27158 exit_status