Whamcloud - gitweb
cd08cde7bbea7ca173c2769fc44b1cfe2e19a0fb
[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
14188         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14189         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14190         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14191         sync; sync_all_data
14192         cancel_lru_locks $OSC
14193         sleep 5
14194         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14195         want=$((OSTCOUNT * 1048576))
14196
14197         # Must allocate all requested space, not more than 5% extra
14198         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14199                 error "bytes $bytes is not $want"
14200
14201         rm -f $DIR/$tfile
14202         # verify fallocate on PFL file
14203         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14204                 error "Create $DIR/$tfile failed"
14205         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
14206                         error "fallocate failed"
14207         sync; sync_all_data
14208         cancel_lru_locks $OSC
14209         sleep 5
14210         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14211         local want=$((1024 * 1048576))
14212
14213         # Must allocate all requested space, not more than 5% extra
14214         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14215                 error "bytes $bytes is not $want"
14216 }
14217 run_test 150c "Verify fallocate Size and Blocks"
14218
14219 test_150d() {
14220         check_set_fallocate_or_skip
14221
14222         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14223         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
14224         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14225         sync; sync_all_data
14226         cancel_lru_locks $OSC
14227         sleep 5
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         echo "Verify fallocate punch: Range within the file range"
14305         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14306                 error "dd failed for bs 4096 and count 5"
14307
14308         # Call fallocate with punch range which is within the file range
14309         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14310                 error "fallocate failed: offset 4096 and length $length"
14311         # client must see changes immediately after fallocate
14312         size=$(stat -c '%s' $DIR/$tfile)
14313         blocks=$(stat -c '%b' $DIR/$tfile)
14314
14315         # Verify punch worked.
14316         (( blocks == want_blocks_after )) ||
14317                 error "punch failed: blocks $blocks != $want_blocks_after"
14318
14319         (( size == want_size_before )) ||
14320                 error "punch failed: size $size != $want_size_before"
14321
14322         # Verify there is hole in file
14323         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14324         # precomputed md5sum
14325         local expect="4a9a834a2db02452929c0a348273b4aa"
14326
14327         cksum=($(md5sum $DIR/$tfile))
14328         [[ "${cksum[0]}" == "$expect" ]] ||
14329                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14330
14331         # Start second sub-case for fallocate punch.
14332         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14333         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14334                 error "dd failed for bs 4096 and count 5"
14335
14336         # Punch range less than block size will have no change in block count
14337         want_blocks_after=40  # 512 sized blocks
14338
14339         # Punch overlaps two blocks and less than blocksize
14340         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14341                 error "fallocate failed: offset 4000 length 3000"
14342         size=$(stat -c '%s' $DIR/$tfile)
14343         blocks=$(stat -c '%b' $DIR/$tfile)
14344
14345         # Verify punch worked.
14346         (( blocks == want_blocks_after )) ||
14347                 error "punch failed: blocks $blocks != $want_blocks_after"
14348
14349         (( size == want_size_before )) ||
14350                 error "punch failed: size $size != $want_size_before"
14351
14352         # Verify if range is really zero'ed out. We expect Zeros.
14353         # precomputed md5sum
14354         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14355         cksum=($(md5sum $DIR/$tfile))
14356         [[ "${cksum[0]}" == "$expect" ]] ||
14357                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14358 }
14359 run_test 150f "Verify fallocate punch functionality"
14360
14361 test_150g() {
14362         local space
14363         local size
14364         local blocks
14365         local blocks_after
14366         local size_after
14367         local BS=4096 # Block size in bytes
14368
14369         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14370                 skip "need at least 2.14.0 for fallocate punch"
14371
14372         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14373                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14374         fi
14375
14376         check_set_fallocate_or_skip
14377         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14378
14379         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14380                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14381
14382         # Get 100MB per OST of the available space to reduce run time
14383         # else 60% of the available space if we are running SLOW tests
14384         if [ $SLOW == "no" ]; then
14385                 space=$((1024 * 100 * OSTCOUNT))
14386         else
14387                 # Find OST with Minimum Size
14388                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14389                         sort -un | head -1)
14390                 echo "min size OST: $space"
14391                 space=$(((space * 60)/100 * OSTCOUNT))
14392         fi
14393         # space in 1k units, round to 4k blocks
14394         local blkcount=$((space * 1024 / $BS))
14395
14396         echo "Verify fallocate punch: Very large Range"
14397         fallocate -l${space}k $DIR/$tfile ||
14398                 error "fallocate ${space}k $DIR/$tfile failed"
14399         # write 1M at the end, start and in the middle
14400         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14401                 error "dd failed: bs $BS count 256"
14402         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14403                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14404         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14405                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14406
14407         # Gather stats.
14408         size=$(stat -c '%s' $DIR/$tfile)
14409
14410         # gather punch length.
14411         local punch_size=$((size - (BS * 2)))
14412
14413         echo "punch_size = $punch_size"
14414         echo "size - punch_size: $((size - punch_size))"
14415         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14416
14417         # Call fallocate to punch all except 2 blocks. We leave the
14418         # first and the last block
14419         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14420         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14421                 error "fallocate failed: offset $BS length $punch_size"
14422
14423         size_after=$(stat -c '%s' $DIR/$tfile)
14424         blocks_after=$(stat -c '%b' $DIR/$tfile)
14425
14426         # Verify punch worked.
14427         # Size should be kept
14428         (( size == size_after )) ||
14429                 error "punch failed: size $size != $size_after"
14430
14431         # two 4k data blocks to remain plus possible 1 extra extent block
14432         (( blocks_after <= ((BS / 512) * 3) )) ||
14433                 error "too many blocks remains: $blocks_after"
14434
14435         # Verify that file has hole between the first and the last blocks
14436         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14437         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14438
14439         echo "Hole at [$hole_start, $hole_end)"
14440         (( hole_start == BS )) ||
14441                 error "no hole at offset $BS after punch"
14442
14443         (( hole_end == BS + punch_size )) ||
14444                 error "data at offset $hole_end < $((BS + punch_size))"
14445 }
14446 run_test 150g "Verify fallocate punch on large range"
14447
14448 #LU-2902 roc_hit was not able to read all values from lproc
14449 function roc_hit_init() {
14450         local list=$(comma_list $(osts_nodes))
14451         local dir=$DIR/$tdir-check
14452         local file=$dir/$tfile
14453         local BEFORE
14454         local AFTER
14455         local idx
14456
14457         test_mkdir $dir
14458         #use setstripe to do a write to every ost
14459         for i in $(seq 0 $((OSTCOUNT-1))); do
14460                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14461                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14462                 idx=$(printf %04x $i)
14463                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14464                         awk '$1 == "cache_access" {sum += $7}
14465                                 END { printf("%0.0f", sum) }')
14466
14467                 cancel_lru_locks osc
14468                 cat $file >/dev/null
14469
14470                 AFTER=$(get_osd_param $list *OST*$idx stats |
14471                         awk '$1 == "cache_access" {sum += $7}
14472                                 END { printf("%0.0f", sum) }')
14473
14474                 echo BEFORE:$BEFORE AFTER:$AFTER
14475                 if ! let "AFTER - BEFORE == 4"; then
14476                         rm -rf $dir
14477                         error "roc_hit is not safe to use"
14478                 fi
14479                 rm $file
14480         done
14481
14482         rm -rf $dir
14483 }
14484
14485 function roc_hit() {
14486         local list=$(comma_list $(osts_nodes))
14487         echo $(get_osd_param $list '' stats |
14488                 awk '$1 == "cache_hit" {sum += $7}
14489                         END { printf("%0.0f", sum) }')
14490 }
14491
14492 function set_cache() {
14493         local on=1
14494
14495         if [ "$2" == "off" ]; then
14496                 on=0;
14497         fi
14498         local list=$(comma_list $(osts_nodes))
14499         set_osd_param $list '' $1_cache_enable $on
14500
14501         cancel_lru_locks osc
14502 }
14503
14504 test_151() {
14505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14506         remote_ost_nodsh && skip "remote OST with nodsh"
14507
14508         local CPAGES=3
14509         local list=$(comma_list $(osts_nodes))
14510
14511         # check whether obdfilter is cache capable at all
14512         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14513                 skip "not cache-capable obdfilter"
14514         fi
14515
14516         # check cache is enabled on all obdfilters
14517         if get_osd_param $list '' read_cache_enable | grep 0; then
14518                 skip "oss cache is disabled"
14519         fi
14520
14521         set_osd_param $list '' writethrough_cache_enable 1
14522
14523         # check write cache is enabled on all obdfilters
14524         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14525                 skip "oss write cache is NOT enabled"
14526         fi
14527
14528         roc_hit_init
14529
14530         #define OBD_FAIL_OBD_NO_LRU  0x609
14531         do_nodes $list $LCTL set_param fail_loc=0x609
14532
14533         # pages should be in the case right after write
14534         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14535                 error "dd failed"
14536
14537         local BEFORE=$(roc_hit)
14538         cancel_lru_locks osc
14539         cat $DIR/$tfile >/dev/null
14540         local AFTER=$(roc_hit)
14541
14542         do_nodes $list $LCTL set_param fail_loc=0
14543
14544         if ! let "AFTER - BEFORE == CPAGES"; then
14545                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14546         fi
14547
14548         cancel_lru_locks osc
14549         # invalidates OST cache
14550         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14551         set_osd_param $list '' read_cache_enable 0
14552         cat $DIR/$tfile >/dev/null
14553
14554         # now data shouldn't be found in the cache
14555         BEFORE=$(roc_hit)
14556         cancel_lru_locks osc
14557         cat $DIR/$tfile >/dev/null
14558         AFTER=$(roc_hit)
14559         if let "AFTER - BEFORE != 0"; then
14560                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14561         fi
14562
14563         set_osd_param $list '' read_cache_enable 1
14564         rm -f $DIR/$tfile
14565 }
14566 run_test 151 "test cache on oss and controls ==============================="
14567
14568 test_152() {
14569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14570
14571         local TF="$TMP/$tfile"
14572
14573         # simulate ENOMEM during write
14574 #define OBD_FAIL_OST_NOMEM      0x226
14575         lctl set_param fail_loc=0x80000226
14576         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14577         cp $TF $DIR/$tfile
14578         sync || error "sync failed"
14579         lctl set_param fail_loc=0
14580
14581         # discard client's cache
14582         cancel_lru_locks osc
14583
14584         # simulate ENOMEM during read
14585         lctl set_param fail_loc=0x80000226
14586         cmp $TF $DIR/$tfile || error "cmp failed"
14587         lctl set_param fail_loc=0
14588
14589         rm -f $TF
14590 }
14591 run_test 152 "test read/write with enomem ============================"
14592
14593 test_153() {
14594         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14595 }
14596 run_test 153 "test if fdatasync does not crash ======================="
14597
14598 dot_lustre_fid_permission_check() {
14599         local fid=$1
14600         local ffid=$MOUNT/.lustre/fid/$fid
14601         local test_dir=$2
14602
14603         echo "stat fid $fid"
14604         stat $ffid > /dev/null || error "stat $ffid failed."
14605         echo "touch fid $fid"
14606         touch $ffid || error "touch $ffid failed."
14607         echo "write to fid $fid"
14608         cat /etc/hosts > $ffid || error "write $ffid failed."
14609         echo "read fid $fid"
14610         diff /etc/hosts $ffid || error "read $ffid failed."
14611         echo "append write to fid $fid"
14612         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14613         echo "rename fid $fid"
14614         mv $ffid $test_dir/$tfile.1 &&
14615                 error "rename $ffid to $tfile.1 should fail."
14616         touch $test_dir/$tfile.1
14617         mv $test_dir/$tfile.1 $ffid &&
14618                 error "rename $tfile.1 to $ffid should fail."
14619         rm -f $test_dir/$tfile.1
14620         echo "truncate fid $fid"
14621         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14622         echo "link fid $fid"
14623         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14624         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14625                 echo "setfacl fid $fid"
14626                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14627                 echo "getfacl fid $fid"
14628                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14629         fi
14630         echo "unlink fid $fid"
14631         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14632         echo "mknod fid $fid"
14633         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14634
14635         fid=[0xf00000400:0x1:0x0]
14636         ffid=$MOUNT/.lustre/fid/$fid
14637
14638         echo "stat non-exist fid $fid"
14639         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14640         echo "write to non-exist fid $fid"
14641         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14642         echo "link new fid $fid"
14643         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14644
14645         mkdir -p $test_dir/$tdir
14646         touch $test_dir/$tdir/$tfile
14647         fid=$($LFS path2fid $test_dir/$tdir)
14648         rc=$?
14649         [ $rc -ne 0 ] &&
14650                 error "error: could not get fid for $test_dir/$dir/$tfile."
14651
14652         ffid=$MOUNT/.lustre/fid/$fid
14653
14654         echo "ls $fid"
14655         ls $ffid > /dev/null || error "ls $ffid failed."
14656         echo "touch $fid/$tfile.1"
14657         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14658
14659         echo "touch $MOUNT/.lustre/fid/$tfile"
14660         touch $MOUNT/.lustre/fid/$tfile && \
14661                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14662
14663         echo "setxattr to $MOUNT/.lustre/fid"
14664         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14665
14666         echo "listxattr for $MOUNT/.lustre/fid"
14667         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14668
14669         echo "delxattr from $MOUNT/.lustre/fid"
14670         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14671
14672         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14673         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14674                 error "touch invalid fid should fail."
14675
14676         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14677         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14678                 error "touch non-normal fid should fail."
14679
14680         echo "rename $tdir to $MOUNT/.lustre/fid"
14681         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14682                 error "rename to $MOUNT/.lustre/fid should fail."
14683
14684         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14685         then            # LU-3547
14686                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14687                 local new_obf_mode=777
14688
14689                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14690                 chmod $new_obf_mode $DIR/.lustre/fid ||
14691                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14692
14693                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14694                 [ $obf_mode -eq $new_obf_mode ] ||
14695                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14696
14697                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14698                 chmod $old_obf_mode $DIR/.lustre/fid ||
14699                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14700         fi
14701
14702         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14703         fid=$($LFS path2fid $test_dir/$tfile-2)
14704
14705         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14706         then # LU-5424
14707                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14708                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14709                         error "create lov data thru .lustre failed"
14710         fi
14711         echo "cp /etc/passwd $test_dir/$tfile-2"
14712         cp /etc/passwd $test_dir/$tfile-2 ||
14713                 error "copy to $test_dir/$tfile-2 failed."
14714         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14715         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14716                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14717
14718         rm -rf $test_dir/tfile.lnk
14719         rm -rf $test_dir/$tfile-2
14720 }
14721
14722 test_154A() {
14723         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14724                 skip "Need MDS version at least 2.4.1"
14725
14726         local tf=$DIR/$tfile
14727         touch $tf
14728
14729         local fid=$($LFS path2fid $tf)
14730         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14731
14732         # check that we get the same pathname back
14733         local rootpath
14734         local found
14735         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14736                 echo "$rootpath $fid"
14737                 found=$($LFS fid2path $rootpath "$fid")
14738                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14739                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14740         done
14741
14742         # check wrong root path format
14743         rootpath=$MOUNT"_wrong"
14744         found=$($LFS fid2path $rootpath "$fid")
14745         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14746 }
14747 run_test 154A "lfs path2fid and fid2path basic checks"
14748
14749 test_154B() {
14750         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14751                 skip "Need MDS version at least 2.4.1"
14752
14753         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14754         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14755         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14756         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14757
14758         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14759         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14760
14761         # check that we get the same pathname
14762         echo "PFID: $PFID, name: $name"
14763         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14764         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14765         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14766                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14767
14768         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14769 }
14770 run_test 154B "verify the ll_decode_linkea tool"
14771
14772 test_154a() {
14773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14774         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14775         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14776                 skip "Need MDS version at least 2.2.51"
14777         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14778
14779         cp /etc/hosts $DIR/$tfile
14780
14781         fid=$($LFS path2fid $DIR/$tfile)
14782         rc=$?
14783         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14784
14785         dot_lustre_fid_permission_check "$fid" $DIR ||
14786                 error "dot lustre permission check $fid failed"
14787
14788         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14789
14790         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14791
14792         touch $MOUNT/.lustre/file &&
14793                 error "creation is not allowed under .lustre"
14794
14795         mkdir $MOUNT/.lustre/dir &&
14796                 error "mkdir is not allowed under .lustre"
14797
14798         rm -rf $DIR/$tfile
14799 }
14800 run_test 154a "Open-by-FID"
14801
14802 test_154b() {
14803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14804         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14806         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14807                 skip "Need MDS version at least 2.2.51"
14808
14809         local remote_dir=$DIR/$tdir/remote_dir
14810         local MDTIDX=1
14811         local rc=0
14812
14813         mkdir -p $DIR/$tdir
14814         $LFS mkdir -i $MDTIDX $remote_dir ||
14815                 error "create remote directory failed"
14816
14817         cp /etc/hosts $remote_dir/$tfile
14818
14819         fid=$($LFS path2fid $remote_dir/$tfile)
14820         rc=$?
14821         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14822
14823         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14824                 error "dot lustre permission check $fid failed"
14825         rm -rf $DIR/$tdir
14826 }
14827 run_test 154b "Open-by-FID for remote directory"
14828
14829 test_154c() {
14830         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14831                 skip "Need MDS version at least 2.4.1"
14832
14833         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14834         local FID1=$($LFS path2fid $DIR/$tfile.1)
14835         local FID2=$($LFS path2fid $DIR/$tfile.2)
14836         local FID3=$($LFS path2fid $DIR/$tfile.3)
14837
14838         local N=1
14839         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14840                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14841                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14842                 local want=FID$N
14843                 [ "$FID" = "${!want}" ] ||
14844                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14845                 N=$((N + 1))
14846         done
14847
14848         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14849         do
14850                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14851                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14852                 N=$((N + 1))
14853         done
14854 }
14855 run_test 154c "lfs path2fid and fid2path multiple arguments"
14856
14857 test_154d() {
14858         remote_mds_nodsh && skip "remote MDS with nodsh"
14859         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14860                 skip "Need MDS version at least 2.5.53"
14861
14862         if remote_mds; then
14863                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14864         else
14865                 nid="0@lo"
14866         fi
14867         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14868         local fd
14869         local cmd
14870
14871         rm -f $DIR/$tfile
14872         touch $DIR/$tfile
14873
14874         local fid=$($LFS path2fid $DIR/$tfile)
14875         # Open the file
14876         fd=$(free_fd)
14877         cmd="exec $fd<$DIR/$tfile"
14878         eval $cmd
14879         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14880         echo "$fid_list" | grep "$fid"
14881         rc=$?
14882
14883         cmd="exec $fd>/dev/null"
14884         eval $cmd
14885         if [ $rc -ne 0 ]; then
14886                 error "FID $fid not found in open files list $fid_list"
14887         fi
14888 }
14889 run_test 154d "Verify open file fid"
14890
14891 test_154e()
14892 {
14893         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14894                 skip "Need MDS version at least 2.6.50"
14895
14896         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14897                 error ".lustre returned by readdir"
14898         fi
14899 }
14900 run_test 154e ".lustre is not returned by readdir"
14901
14902 test_154f() {
14903         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14904
14905         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14906         mkdir_on_mdt0 $DIR/$tdir
14907         # test dirs inherit from its stripe
14908         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
14909         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
14910         cp /etc/hosts $DIR/$tdir/foo1/$tfile
14911         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
14912         touch $DIR/f
14913
14914         # get fid of parents
14915         local FID0=$($LFS path2fid $DIR/$tdir)
14916         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
14917         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
14918         local FID3=$($LFS path2fid $DIR)
14919
14920         # check that path2fid --parents returns expected <parent_fid>/name
14921         # 1) test for a directory (single parent)
14922         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
14923         [ "$parent" == "$FID0/foo1" ] ||
14924                 error "expected parent: $FID0/foo1, got: $parent"
14925
14926         # 2) test for a file with nlink > 1 (multiple parents)
14927         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
14928         echo "$parent" | grep -F "$FID1/$tfile" ||
14929                 error "$FID1/$tfile not returned in parent list"
14930         echo "$parent" | grep -F "$FID2/link" ||
14931                 error "$FID2/link not returned in parent list"
14932
14933         # 3) get parent by fid
14934         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
14935         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14936         echo "$parent" | grep -F "$FID1/$tfile" ||
14937                 error "$FID1/$tfile not returned in parent list (by fid)"
14938         echo "$parent" | grep -F "$FID2/link" ||
14939                 error "$FID2/link not returned in parent list (by fid)"
14940
14941         # 4) test for entry in root directory
14942         parent=$($LFS path2fid --parents $DIR/f)
14943         echo "$parent" | grep -F "$FID3/f" ||
14944                 error "$FID3/f not returned in parent list"
14945
14946         # 5) test it on root directory
14947         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14948                 error "$MOUNT should not have parents"
14949
14950         # enable xattr caching and check that linkea is correctly updated
14951         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14952         save_lustre_params client "llite.*.xattr_cache" > $save
14953         lctl set_param llite.*.xattr_cache 1
14954
14955         # 6.1) linkea update on rename
14956         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
14957
14958         # get parents by fid
14959         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14960         # foo1 should no longer be returned in parent list
14961         echo "$parent" | grep -F "$FID1" &&
14962                 error "$FID1 should no longer be in parent list"
14963         # the new path should appear
14964         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14965                 error "$FID2/$tfile.moved is not in parent list"
14966
14967         # 6.2) linkea update on unlink
14968         rm -f $DIR/$tdir/foo2/link
14969         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14970         # foo2/link should no longer be returned in parent list
14971         echo "$parent" | grep -F "$FID2/link" &&
14972                 error "$FID2/link should no longer be in parent list"
14973         true
14974
14975         rm -f $DIR/f
14976         restore_lustre_params < $save
14977         rm -f $save
14978 }
14979 run_test 154f "get parent fids by reading link ea"
14980
14981 test_154g()
14982 {
14983         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14984         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14985            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14986                 skip "Need MDS version at least 2.6.92"
14987
14988         mkdir_on_mdt0 $DIR/$tdir
14989         llapi_fid_test -d $DIR/$tdir
14990 }
14991 run_test 154g "various llapi FID tests"
14992
14993 test_155_small_load() {
14994     local temp=$TMP/$tfile
14995     local file=$DIR/$tfile
14996
14997     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14998         error "dd of=$temp bs=6096 count=1 failed"
14999     cp $temp $file
15000     cancel_lru_locks $OSC
15001     cmp $temp $file || error "$temp $file differ"
15002
15003     $TRUNCATE $temp 6000
15004     $TRUNCATE $file 6000
15005     cmp $temp $file || error "$temp $file differ (truncate1)"
15006
15007     echo "12345" >>$temp
15008     echo "12345" >>$file
15009     cmp $temp $file || error "$temp $file differ (append1)"
15010
15011     echo "12345" >>$temp
15012     echo "12345" >>$file
15013     cmp $temp $file || error "$temp $file differ (append2)"
15014
15015     rm -f $temp $file
15016     true
15017 }
15018
15019 test_155_big_load() {
15020         remote_ost_nodsh && skip "remote OST with nodsh"
15021
15022         local temp=$TMP/$tfile
15023         local file=$DIR/$tfile
15024
15025         free_min_max
15026         local cache_size=$(do_facet ost$((MAXI+1)) \
15027                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15028         local large_file_size=$((cache_size * 2))
15029
15030         echo "OSS cache size: $cache_size KB"
15031         echo "Large file size: $large_file_size KB"
15032
15033         [ $MAXV -le $large_file_size ] &&
15034                 skip_env "max available OST size needs > $large_file_size KB"
15035
15036         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15037
15038         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15039                 error "dd of=$temp bs=$large_file_size count=1k failed"
15040         cp $temp $file
15041         ls -lh $temp $file
15042         cancel_lru_locks osc
15043         cmp $temp $file || error "$temp $file differ"
15044
15045         rm -f $temp $file
15046         true
15047 }
15048
15049 save_writethrough() {
15050         local facets=$(get_facets OST)
15051
15052         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15053 }
15054
15055 test_155a() {
15056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15057
15058         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15059
15060         save_writethrough $p
15061
15062         set_cache read on
15063         set_cache writethrough on
15064         test_155_small_load
15065         restore_lustre_params < $p
15066         rm -f $p
15067 }
15068 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15069
15070 test_155b() {
15071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15072
15073         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15074
15075         save_writethrough $p
15076
15077         set_cache read on
15078         set_cache writethrough off
15079         test_155_small_load
15080         restore_lustre_params < $p
15081         rm -f $p
15082 }
15083 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15084
15085 test_155c() {
15086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15087
15088         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15089
15090         save_writethrough $p
15091
15092         set_cache read off
15093         set_cache writethrough on
15094         test_155_small_load
15095         restore_lustre_params < $p
15096         rm -f $p
15097 }
15098 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15099
15100 test_155d() {
15101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15102
15103         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15104
15105         save_writethrough $p
15106
15107         set_cache read off
15108         set_cache writethrough off
15109         test_155_small_load
15110         restore_lustre_params < $p
15111         rm -f $p
15112 }
15113 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15114
15115 test_155e() {
15116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15117
15118         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15119
15120         save_writethrough $p
15121
15122         set_cache read on
15123         set_cache writethrough on
15124         test_155_big_load
15125         restore_lustre_params < $p
15126         rm -f $p
15127 }
15128 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15129
15130 test_155f() {
15131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15132
15133         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15134
15135         save_writethrough $p
15136
15137         set_cache read on
15138         set_cache writethrough off
15139         test_155_big_load
15140         restore_lustre_params < $p
15141         rm -f $p
15142 }
15143 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15144
15145 test_155g() {
15146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15147
15148         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15149
15150         save_writethrough $p
15151
15152         set_cache read off
15153         set_cache writethrough on
15154         test_155_big_load
15155         restore_lustre_params < $p
15156         rm -f $p
15157 }
15158 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15159
15160 test_155h() {
15161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15162
15163         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15164
15165         save_writethrough $p
15166
15167         set_cache read off
15168         set_cache writethrough off
15169         test_155_big_load
15170         restore_lustre_params < $p
15171         rm -f $p
15172 }
15173 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15174
15175 test_156() {
15176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15177         remote_ost_nodsh && skip "remote OST with nodsh"
15178         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15179                 skip "stats not implemented on old servers"
15180         [ "$ost1_FSTYPE" = "zfs" ] &&
15181                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15182
15183         local CPAGES=3
15184         local BEFORE
15185         local AFTER
15186         local file="$DIR/$tfile"
15187         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15188
15189         save_writethrough $p
15190         roc_hit_init
15191
15192         log "Turn on read and write cache"
15193         set_cache read on
15194         set_cache writethrough on
15195
15196         log "Write data and read it back."
15197         log "Read should be satisfied from the cache."
15198         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15199         BEFORE=$(roc_hit)
15200         cancel_lru_locks osc
15201         cat $file >/dev/null
15202         AFTER=$(roc_hit)
15203         if ! let "AFTER - BEFORE == CPAGES"; then
15204                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15205         else
15206                 log "cache hits: before: $BEFORE, after: $AFTER"
15207         fi
15208
15209         log "Read again; it should be satisfied from the cache."
15210         BEFORE=$AFTER
15211         cancel_lru_locks osc
15212         cat $file >/dev/null
15213         AFTER=$(roc_hit)
15214         if ! let "AFTER - BEFORE == CPAGES"; then
15215                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15216         else
15217                 log "cache hits:: before: $BEFORE, after: $AFTER"
15218         fi
15219
15220         log "Turn off the read cache and turn on the write cache"
15221         set_cache read off
15222         set_cache writethrough on
15223
15224         log "Read again; it should be satisfied from the cache."
15225         BEFORE=$(roc_hit)
15226         cancel_lru_locks osc
15227         cat $file >/dev/null
15228         AFTER=$(roc_hit)
15229         if ! let "AFTER - BEFORE == CPAGES"; then
15230                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15231         else
15232                 log "cache hits:: before: $BEFORE, after: $AFTER"
15233         fi
15234
15235         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15236                 # > 2.12.56 uses pagecache if cached
15237                 log "Read again; it should not be satisfied from the cache."
15238                 BEFORE=$AFTER
15239                 cancel_lru_locks osc
15240                 cat $file >/dev/null
15241                 AFTER=$(roc_hit)
15242                 if ! let "AFTER - BEFORE == 0"; then
15243                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15244                 else
15245                         log "cache hits:: before: $BEFORE, after: $AFTER"
15246                 fi
15247         fi
15248
15249         log "Write data and read it back."
15250         log "Read should be satisfied from the cache."
15251         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15252         BEFORE=$(roc_hit)
15253         cancel_lru_locks osc
15254         cat $file >/dev/null
15255         AFTER=$(roc_hit)
15256         if ! let "AFTER - BEFORE == CPAGES"; then
15257                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15258         else
15259                 log "cache hits:: before: $BEFORE, after: $AFTER"
15260         fi
15261
15262         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15263                 # > 2.12.56 uses pagecache if cached
15264                 log "Read again; it should not be satisfied from the cache."
15265                 BEFORE=$AFTER
15266                 cancel_lru_locks osc
15267                 cat $file >/dev/null
15268                 AFTER=$(roc_hit)
15269                 if ! let "AFTER - BEFORE == 0"; then
15270                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15271                 else
15272                         log "cache hits:: before: $BEFORE, after: $AFTER"
15273                 fi
15274         fi
15275
15276         log "Turn off read and write cache"
15277         set_cache read off
15278         set_cache writethrough off
15279
15280         log "Write data and read it back"
15281         log "It should not be satisfied from the cache."
15282         rm -f $file
15283         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15284         cancel_lru_locks osc
15285         BEFORE=$(roc_hit)
15286         cat $file >/dev/null
15287         AFTER=$(roc_hit)
15288         if ! let "AFTER - BEFORE == 0"; then
15289                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15290         else
15291                 log "cache hits:: before: $BEFORE, after: $AFTER"
15292         fi
15293
15294         log "Turn on the read cache and turn off the write cache"
15295         set_cache read on
15296         set_cache writethrough off
15297
15298         log "Write data and read it back"
15299         log "It should not be satisfied from the cache."
15300         rm -f $file
15301         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15302         BEFORE=$(roc_hit)
15303         cancel_lru_locks osc
15304         cat $file >/dev/null
15305         AFTER=$(roc_hit)
15306         if ! let "AFTER - BEFORE == 0"; then
15307                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15308         else
15309                 log "cache hits:: before: $BEFORE, after: $AFTER"
15310         fi
15311
15312         log "Read again; it should be satisfied from the cache."
15313         BEFORE=$(roc_hit)
15314         cancel_lru_locks osc
15315         cat $file >/dev/null
15316         AFTER=$(roc_hit)
15317         if ! let "AFTER - BEFORE == CPAGES"; then
15318                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15319         else
15320                 log "cache hits:: before: $BEFORE, after: $AFTER"
15321         fi
15322
15323         restore_lustre_params < $p
15324         rm -f $p $file
15325 }
15326 run_test 156 "Verification of tunables"
15327
15328 test_160a() {
15329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15330         remote_mds_nodsh && skip "remote MDS with nodsh"
15331         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15332                 skip "Need MDS version at least 2.2.0"
15333
15334         changelog_register || error "changelog_register failed"
15335         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15336         changelog_users $SINGLEMDS | grep -q $cl_user ||
15337                 error "User $cl_user not found in changelog_users"
15338
15339         mkdir_on_mdt0 $DIR/$tdir
15340
15341         # change something
15342         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15343         changelog_clear 0 || error "changelog_clear failed"
15344         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15345         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15346         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15347         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15348         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15349         rm $DIR/$tdir/pics/desktop.jpg
15350
15351         echo "verifying changelog mask"
15352         changelog_chmask "-MKDIR"
15353         changelog_chmask "-CLOSE"
15354
15355         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15356         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15357
15358         changelog_chmask "+MKDIR"
15359         changelog_chmask "+CLOSE"
15360
15361         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15362         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15363
15364         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15365         CLOSES=$(changelog_dump | grep -c "CLOSE")
15366         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15367         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15368
15369         # verify contents
15370         echo "verifying target fid"
15371         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15372         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15373         [ "$fidc" == "$fidf" ] ||
15374                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15375         echo "verifying parent fid"
15376         # The FID returned from the Changelog may be the directory shard on
15377         # a different MDT, and not the FID returned by path2fid on the parent.
15378         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15379         # since this is what will matter when recreating this file in the tree.
15380         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15381         local pathp=$($LFS fid2path $MOUNT "$fidp")
15382         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15383                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15384
15385         echo "getting records for $cl_user"
15386         changelog_users $SINGLEMDS
15387         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15388         local nclr=3
15389         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15390                 error "changelog_clear failed"
15391         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15392         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15393         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15394                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15395
15396         local min0_rec=$(changelog_users $SINGLEMDS |
15397                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15398         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15399                           awk '{ print $1; exit; }')
15400
15401         changelog_dump | tail -n 5
15402         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15403         [ $first_rec == $((min0_rec + 1)) ] ||
15404                 error "first index should be $min0_rec + 1 not $first_rec"
15405
15406         # LU-3446 changelog index reset on MDT restart
15407         local cur_rec1=$(changelog_users $SINGLEMDS |
15408                          awk '/^current.index:/ { print $NF }')
15409         changelog_clear 0 ||
15410                 error "clear all changelog records for $cl_user failed"
15411         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15412         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15413                 error "Fail to start $SINGLEMDS"
15414         local cur_rec2=$(changelog_users $SINGLEMDS |
15415                          awk '/^current.index:/ { print $NF }')
15416         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15417         [ $cur_rec1 == $cur_rec2 ] ||
15418                 error "current index should be $cur_rec1 not $cur_rec2"
15419
15420         echo "verifying users from this test are deregistered"
15421         changelog_deregister || error "changelog_deregister failed"
15422         changelog_users $SINGLEMDS | grep -q $cl_user &&
15423                 error "User '$cl_user' still in changelog_users"
15424
15425         # lctl get_param -n mdd.*.changelog_users
15426         # current_index: 144
15427         # ID    index (idle seconds)
15428         # cl3   144   (2) mask=<list>
15429         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15430                 # this is the normal case where all users were deregistered
15431                 # make sure no new records are added when no users are present
15432                 local last_rec1=$(changelog_users $SINGLEMDS |
15433                                   awk '/^current.index:/ { print $NF }')
15434                 touch $DIR/$tdir/chloe
15435                 local last_rec2=$(changelog_users $SINGLEMDS |
15436                                   awk '/^current.index:/ { print $NF }')
15437                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15438                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15439         else
15440                 # any changelog users must be leftovers from a previous test
15441                 changelog_users $SINGLEMDS
15442                 echo "other changelog users; can't verify off"
15443         fi
15444 }
15445 run_test 160a "changelog sanity"
15446
15447 test_160b() { # LU-3587
15448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15449         remote_mds_nodsh && skip "remote MDS with nodsh"
15450         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15451                 skip "Need MDS version at least 2.2.0"
15452
15453         changelog_register || error "changelog_register failed"
15454         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15455         changelog_users $SINGLEMDS | grep -q $cl_user ||
15456                 error "User '$cl_user' not found in changelog_users"
15457
15458         local longname1=$(str_repeat a 255)
15459         local longname2=$(str_repeat b 255)
15460
15461         cd $DIR
15462         echo "creating very long named file"
15463         touch $longname1 || error "create of '$longname1' failed"
15464         echo "renaming very long named file"
15465         mv $longname1 $longname2
15466
15467         changelog_dump | grep RENME | tail -n 5
15468         rm -f $longname2
15469 }
15470 run_test 160b "Verify that very long rename doesn't crash in changelog"
15471
15472 test_160c() {
15473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15474         remote_mds_nodsh && skip "remote MDS with nodsh"
15475
15476         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15477                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15478                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15479                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15480
15481         local rc=0
15482
15483         # Registration step
15484         changelog_register || error "changelog_register failed"
15485
15486         rm -rf $DIR/$tdir
15487         mkdir -p $DIR/$tdir
15488         $MCREATE $DIR/$tdir/foo_160c
15489         changelog_chmask "-TRUNC"
15490         $TRUNCATE $DIR/$tdir/foo_160c 200
15491         changelog_chmask "+TRUNC"
15492         $TRUNCATE $DIR/$tdir/foo_160c 199
15493         changelog_dump | tail -n 5
15494         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15495         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15496 }
15497 run_test 160c "verify that changelog log catch the truncate event"
15498
15499 test_160d() {
15500         remote_mds_nodsh && skip "remote MDS with nodsh"
15501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15503         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15504                 skip "Need MDS version at least 2.7.60"
15505
15506         # Registration step
15507         changelog_register || error "changelog_register failed"
15508
15509         mkdir -p $DIR/$tdir/migrate_dir
15510         changelog_clear 0 || error "changelog_clear failed"
15511
15512         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15513         changelog_dump | tail -n 5
15514         local migrates=$(changelog_dump | grep -c "MIGRT")
15515         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15516 }
15517 run_test 160d "verify that changelog log catch the migrate event"
15518
15519 test_160e() {
15520         remote_mds_nodsh && skip "remote MDS with nodsh"
15521
15522         # Create a user
15523         changelog_register || error "changelog_register failed"
15524
15525         # Delete a future user (expect fail)
15526         local MDT0=$(facet_svc $SINGLEMDS)
15527         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15528         local rc=$?
15529
15530         if [ $rc -eq 0 ]; then
15531                 error "Deleted non-existant user cl77"
15532         elif [ $rc -ne 2 ]; then
15533                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15534         fi
15535
15536         # Clear to a bad index (1 billion should be safe)
15537         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15538         rc=$?
15539
15540         if [ $rc -eq 0 ]; then
15541                 error "Successfully cleared to invalid CL index"
15542         elif [ $rc -ne 22 ]; then
15543                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15544         fi
15545 }
15546 run_test 160e "changelog negative testing (should return errors)"
15547
15548 test_160f() {
15549         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15550         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15551                 skip "Need MDS version at least 2.10.56"
15552
15553         local mdts=$(comma_list $(mdts_nodes))
15554
15555         # Create a user
15556         changelog_register || error "first changelog_register failed"
15557         changelog_register || error "second changelog_register failed"
15558         local cl_users
15559         declare -A cl_user1
15560         declare -A cl_user2
15561         local user_rec1
15562         local user_rec2
15563         local i
15564
15565         # generate some changelog records to accumulate on each MDT
15566         # use all_char because created files should be evenly distributed
15567         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15568                 error "test_mkdir $tdir failed"
15569         log "$(date +%s): creating first files"
15570         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15571                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15572                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15573         done
15574
15575         # check changelogs have been generated
15576         local start=$SECONDS
15577         local idle_time=$((MDSCOUNT * 5 + 5))
15578         local nbcl=$(changelog_dump | wc -l)
15579         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15580
15581         for param in "changelog_max_idle_time=$idle_time" \
15582                      "changelog_gc=1" \
15583                      "changelog_min_gc_interval=2" \
15584                      "changelog_min_free_cat_entries=3"; do
15585                 local MDT0=$(facet_svc $SINGLEMDS)
15586                 local var="${param%=*}"
15587                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15588
15589                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15590                 do_nodes $mdts $LCTL set_param mdd.*.$param
15591         done
15592
15593         # force cl_user2 to be idle (1st part), but also cancel the
15594         # cl_user1 records so that it is not evicted later in the test.
15595         local sleep1=$((idle_time / 2))
15596         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15597         sleep $sleep1
15598
15599         # simulate changelog catalog almost full
15600         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15601         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15602
15603         for i in $(seq $MDSCOUNT); do
15604                 cl_users=(${CL_USERS[mds$i]})
15605                 cl_user1[mds$i]="${cl_users[0]}"
15606                 cl_user2[mds$i]="${cl_users[1]}"
15607
15608                 [ -n "${cl_user1[mds$i]}" ] ||
15609                         error "mds$i: no user registered"
15610                 [ -n "${cl_user2[mds$i]}" ] ||
15611                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15612
15613                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15614                 [ -n "$user_rec1" ] ||
15615                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15616                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15617                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15618                 [ -n "$user_rec2" ] ||
15619                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15620                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15621                      "$user_rec1 + 2 == $user_rec2"
15622                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15623                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15624                               "$user_rec1 + 2, but is $user_rec2"
15625                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15626                 [ -n "$user_rec2" ] ||
15627                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15628                 [ $user_rec1 == $user_rec2 ] ||
15629                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15630                               "$user_rec1, but is $user_rec2"
15631         done
15632
15633         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15634         local sleep2=$((idle_time - (SECONDS - start) + 1))
15635         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15636         sleep $sleep2
15637
15638         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15639         # cl_user1 should be OK because it recently processed records.
15640         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15641         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15642                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15643                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15644         done
15645
15646         # ensure gc thread is done
15647         for i in $(mdts_nodes); do
15648                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15649                         error "$i: GC-thread not done"
15650         done
15651
15652         local first_rec
15653         for (( i = 1; i <= MDSCOUNT; i++ )); do
15654                 # check cl_user1 still registered
15655                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15656                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15657                 # check cl_user2 unregistered
15658                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15659                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15660
15661                 # check changelogs are present and starting at $user_rec1 + 1
15662                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15663                 [ -n "$user_rec1" ] ||
15664                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15665                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15666                             awk '{ print $1; exit; }')
15667
15668                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15669                 [ $((user_rec1 + 1)) == $first_rec ] ||
15670                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15671         done
15672 }
15673 run_test 160f "changelog garbage collect (timestamped users)"
15674
15675 test_160g() {
15676         remote_mds_nodsh && skip "remote MDS with nodsh"
15677         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15678                 skip "Need MDS version at least 2.10.56"
15679
15680         local mdts=$(comma_list $(mdts_nodes))
15681
15682         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15683         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15684
15685         # Create a user
15686         changelog_register || error "first changelog_register failed"
15687         changelog_register || error "second changelog_register failed"
15688         local cl_users
15689         declare -A cl_user1
15690         declare -A cl_user2
15691         local user_rec1
15692         local user_rec2
15693         local i
15694
15695         # generate some changelog records to accumulate on each MDT
15696         # use all_char because created files should be evenly distributed
15697         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15698                 error "test_mkdir $tdir failed"
15699         for ((i = 0; i < MDSCOUNT; i++)); do
15700                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15701                         error "create $DIR/$tdir/d$i.1 failed"
15702         done
15703
15704         # check changelogs have been generated
15705         local nbcl=$(changelog_dump | wc -l)
15706         (( $nbcl > 0 )) || error "no changelogs found"
15707
15708         # reduce the max_idle_indexes value to make sure we exceed it
15709         for param in "changelog_max_idle_indexes=1" \
15710                      "changelog_gc=1" \
15711                      "changelog_min_gc_interval=2" \
15712                      "changelog_min_free_cat_entries=3"; do
15713                 local MDT0=$(facet_svc $SINGLEMDS)
15714                 local var="${param%=*}"
15715                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15716
15717                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15718                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15719                         error "unable to set mdd.*.$param"
15720         done
15721
15722         # simulate changelog catalog almost full
15723         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15724         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15725
15726         local start=$SECONDS
15727         for i in $(seq $MDSCOUNT); do
15728                 cl_users=(${CL_USERS[mds$i]})
15729                 cl_user1[mds$i]="${cl_users[0]}"
15730                 cl_user2[mds$i]="${cl_users[1]}"
15731
15732                 [ -n "${cl_user1[mds$i]}" ] ||
15733                         error "mds$i: no user registered"
15734                 [ -n "${cl_user2[mds$i]}" ] ||
15735                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15736
15737                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15738                 [ -n "$user_rec1" ] ||
15739                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15740                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15741                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15742                 [ -n "$user_rec2" ] ||
15743                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15744                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15745                      "$user_rec1 + 2 == $user_rec2"
15746                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15747                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15748                               "$user_rec1 + 2, but is $user_rec2"
15749                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15750                 [ -n "$user_rec2" ] ||
15751                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15752                 [ $user_rec1 == $user_rec2 ] ||
15753                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15754                               "$user_rec1, but is $user_rec2"
15755         done
15756
15757         # ensure we are past the previous changelog_min_gc_interval set above
15758         local sleep2=$((start + 2 - SECONDS))
15759         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15760
15761         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15762         # cl_user1 should be OK because it recently processed records.
15763         for ((i = 0; i < MDSCOUNT; i++)); do
15764                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15765                         error "create $DIR/$tdir/d$i.3 failed"
15766         done
15767
15768         # ensure gc thread is done
15769         for i in $(mdts_nodes); do
15770                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15771                         error "$i: GC-thread not done"
15772         done
15773
15774         local first_rec
15775         for (( i = 1; i <= MDSCOUNT; i++ )); do
15776                 # check cl_user1 still registered
15777                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15778                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15779                 # check cl_user2 unregistered
15780                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15781                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15782
15783                 # check changelogs are present and starting at $user_rec1 + 1
15784                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15785                 [ -n "$user_rec1" ] ||
15786                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15787                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15788                             awk '{ print $1; exit; }')
15789
15790                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15791                 [ $((user_rec1 + 1)) == $first_rec ] ||
15792                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15793         done
15794 }
15795 run_test 160g "changelog garbage collect (old users)"
15796
15797 test_160h() {
15798         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15799         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15800                 skip "Need MDS version at least 2.10.56"
15801
15802         local mdts=$(comma_list $(mdts_nodes))
15803
15804         # Create a user
15805         changelog_register || error "first changelog_register failed"
15806         changelog_register || error "second changelog_register failed"
15807         local cl_users
15808         declare -A cl_user1
15809         declare -A cl_user2
15810         local user_rec1
15811         local user_rec2
15812         local i
15813
15814         # generate some changelog records to accumulate on each MDT
15815         # use all_char because created files should be evenly distributed
15816         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15817                 error "test_mkdir $tdir failed"
15818         for ((i = 0; i < MDSCOUNT; i++)); do
15819                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15820                         error "create $DIR/$tdir/d$i.1 failed"
15821         done
15822
15823         # check changelogs have been generated
15824         local nbcl=$(changelog_dump | wc -l)
15825         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15826
15827         for param in "changelog_max_idle_time=10" \
15828                      "changelog_gc=1" \
15829                      "changelog_min_gc_interval=2"; do
15830                 local MDT0=$(facet_svc $SINGLEMDS)
15831                 local var="${param%=*}"
15832                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15833
15834                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15835                 do_nodes $mdts $LCTL set_param mdd.*.$param
15836         done
15837
15838         # force cl_user2 to be idle (1st part)
15839         sleep 9
15840
15841         for i in $(seq $MDSCOUNT); do
15842                 cl_users=(${CL_USERS[mds$i]})
15843                 cl_user1[mds$i]="${cl_users[0]}"
15844                 cl_user2[mds$i]="${cl_users[1]}"
15845
15846                 [ -n "${cl_user1[mds$i]}" ] ||
15847                         error "mds$i: no user registered"
15848                 [ -n "${cl_user2[mds$i]}" ] ||
15849                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15850
15851                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15852                 [ -n "$user_rec1" ] ||
15853                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15854                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15855                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15856                 [ -n "$user_rec2" ] ||
15857                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15858                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15859                      "$user_rec1 + 2 == $user_rec2"
15860                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15861                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15862                               "$user_rec1 + 2, but is $user_rec2"
15863                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15864                 [ -n "$user_rec2" ] ||
15865                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15866                 [ $user_rec1 == $user_rec2 ] ||
15867                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15868                               "$user_rec1, but is $user_rec2"
15869         done
15870
15871         # force cl_user2 to be idle (2nd part) and to reach
15872         # changelog_max_idle_time
15873         sleep 2
15874
15875         # force each GC-thread start and block then
15876         # one per MDT/MDD, set fail_val accordingly
15877         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15878         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15879
15880         # generate more changelogs to trigger fail_loc
15881         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15882                 error "create $DIR/$tdir/${tfile}bis failed"
15883
15884         # stop MDT to stop GC-thread, should be done in back-ground as it will
15885         # block waiting for the thread to be released and exit
15886         declare -A stop_pids
15887         for i in $(seq $MDSCOUNT); do
15888                 stop mds$i &
15889                 stop_pids[mds$i]=$!
15890         done
15891
15892         for i in $(mdts_nodes); do
15893                 local facet
15894                 local nb=0
15895                 local facets=$(facets_up_on_host $i)
15896
15897                 for facet in ${facets//,/ }; do
15898                         if [[ $facet == mds* ]]; then
15899                                 nb=$((nb + 1))
15900                         fi
15901                 done
15902                 # ensure each MDS's gc threads are still present and all in "R"
15903                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15904                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15905                         error "$i: expected $nb GC-thread"
15906                 wait_update $i \
15907                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15908                         "R" 20 ||
15909                         error "$i: GC-thread not found in R-state"
15910                 # check umounts of each MDT on MDS have reached kthread_stop()
15911                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15912                         error "$i: expected $nb umount"
15913                 wait_update $i \
15914                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15915                         error "$i: umount not found in D-state"
15916         done
15917
15918         # release all GC-threads
15919         do_nodes $mdts $LCTL set_param fail_loc=0
15920
15921         # wait for MDT stop to complete
15922         for i in $(seq $MDSCOUNT); do
15923                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15924         done
15925
15926         # XXX
15927         # may try to check if any orphan changelog records are present
15928         # via ldiskfs/zfs and llog_reader...
15929
15930         # re-start/mount MDTs
15931         for i in $(seq $MDSCOUNT); do
15932                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15933                         error "Fail to start mds$i"
15934         done
15935
15936         local first_rec
15937         for i in $(seq $MDSCOUNT); do
15938                 # check cl_user1 still registered
15939                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15940                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15941                 # check cl_user2 unregistered
15942                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15943                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15944
15945                 # check changelogs are present and starting at $user_rec1 + 1
15946                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15947                 [ -n "$user_rec1" ] ||
15948                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15949                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15950                             awk '{ print $1; exit; }')
15951
15952                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15953                 [ $((user_rec1 + 1)) == $first_rec ] ||
15954                         error "mds$i: first index should be $user_rec1 + 1, " \
15955                               "but is $first_rec"
15956         done
15957 }
15958 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15959               "during mount"
15960
15961 test_160i() {
15962
15963         local mdts=$(comma_list $(mdts_nodes))
15964
15965         changelog_register || error "first changelog_register failed"
15966
15967         # generate some changelog records to accumulate on each MDT
15968         # use all_char because created files should be evenly distributed
15969         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15970                 error "test_mkdir $tdir failed"
15971         for ((i = 0; i < MDSCOUNT; i++)); do
15972                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15973                         error "create $DIR/$tdir/d$i.1 failed"
15974         done
15975
15976         # check changelogs have been generated
15977         local nbcl=$(changelog_dump | wc -l)
15978         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15979
15980         # simulate race between register and unregister
15981         # XXX as fail_loc is set per-MDS, with DNE configs the race
15982         # simulation will only occur for one MDT per MDS and for the
15983         # others the normal race scenario will take place
15984         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15985         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15986         do_nodes $mdts $LCTL set_param fail_val=1
15987
15988         # unregister 1st user
15989         changelog_deregister &
15990         local pid1=$!
15991         # wait some time for deregister work to reach race rdv
15992         sleep 2
15993         # register 2nd user
15994         changelog_register || error "2nd user register failed"
15995
15996         wait $pid1 || error "1st user deregister failed"
15997
15998         local i
15999         local last_rec
16000         declare -A LAST_REC
16001         for i in $(seq $MDSCOUNT); do
16002                 if changelog_users mds$i | grep "^cl"; then
16003                         # make sure new records are added with one user present
16004                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16005                                           awk '/^current.index:/ { print $NF }')
16006                 else
16007                         error "mds$i has no user registered"
16008                 fi
16009         done
16010
16011         # generate more changelog records to accumulate on each MDT
16012         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16013                 error "create $DIR/$tdir/${tfile}bis failed"
16014
16015         for i in $(seq $MDSCOUNT); do
16016                 last_rec=$(changelog_users $SINGLEMDS |
16017                            awk '/^current.index:/ { print $NF }')
16018                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16019                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16020                         error "changelogs are off on mds$i"
16021         done
16022 }
16023 run_test 160i "changelog user register/unregister race"
16024
16025 test_160j() {
16026         remote_mds_nodsh && skip "remote MDS with nodsh"
16027         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16028                 skip "Need MDS version at least 2.12.56"
16029
16030         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16031         stack_trap "umount $MOUNT2" EXIT
16032
16033         changelog_register || error "first changelog_register failed"
16034         stack_trap "changelog_deregister" EXIT
16035
16036         # generate some changelog
16037         # use all_char because created files should be evenly distributed
16038         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16039                 error "mkdir $tdir failed"
16040         for ((i = 0; i < MDSCOUNT; i++)); do
16041                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16042                         error "create $DIR/$tdir/d$i.1 failed"
16043         done
16044
16045         # open the changelog device
16046         exec 3>/dev/changelog-$FSNAME-MDT0000
16047         stack_trap "exec 3>&-" EXIT
16048         exec 4</dev/changelog-$FSNAME-MDT0000
16049         stack_trap "exec 4<&-" EXIT
16050
16051         # umount the first lustre mount
16052         umount $MOUNT
16053         stack_trap "mount_client $MOUNT" EXIT
16054
16055         # read changelog, which may or may not fail, but should not crash
16056         cat <&4 >/dev/null
16057
16058         # clear changelog
16059         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16060         changelog_users $SINGLEMDS | grep -q $cl_user ||
16061                 error "User $cl_user not found in changelog_users"
16062
16063         printf 'clear:'$cl_user':0' >&3
16064 }
16065 run_test 160j "client can be umounted while its chanangelog is being used"
16066
16067 test_160k() {
16068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16069         remote_mds_nodsh && skip "remote MDS with nodsh"
16070
16071         mkdir -p $DIR/$tdir/1/1
16072
16073         changelog_register || error "changelog_register failed"
16074         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16075
16076         changelog_users $SINGLEMDS | grep -q $cl_user ||
16077                 error "User '$cl_user' not found in changelog_users"
16078 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16079         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16080         rmdir $DIR/$tdir/1/1 & sleep 1
16081         mkdir $DIR/$tdir/2
16082         touch $DIR/$tdir/2/2
16083         rm -rf $DIR/$tdir/2
16084
16085         wait
16086         sleep 4
16087
16088         changelog_dump | grep rmdir || error "rmdir not recorded"
16089 }
16090 run_test 160k "Verify that changelog records are not lost"
16091
16092 # Verifies that a file passed as a parameter has recently had an operation
16093 # performed on it that has generated an MTIME changelog which contains the
16094 # correct parent FID. As files might reside on a different MDT from the
16095 # parent directory in DNE configurations, the FIDs are translated to paths
16096 # before being compared, which should be identical
16097 compare_mtime_changelog() {
16098         local file="${1}"
16099         local mdtidx
16100         local mtime
16101         local cl_fid
16102         local pdir
16103         local dir
16104
16105         mdtidx=$($LFS getstripe --mdt-index $file)
16106         mdtidx=$(printf "%04x" $mdtidx)
16107
16108         # Obtain the parent FID from the MTIME changelog
16109         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16110         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16111
16112         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16113         [ -z "$cl_fid" ] && error "parent FID not present"
16114
16115         # Verify that the path for the parent FID is the same as the path for
16116         # the test directory
16117         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16118
16119         dir=$(dirname $1)
16120
16121         [[ "${pdir%/}" == "$dir" ]] ||
16122                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16123 }
16124
16125 test_160l() {
16126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16127
16128         remote_mds_nodsh && skip "remote MDS with nodsh"
16129         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16130                 skip "Need MDS version at least 2.13.55"
16131
16132         local cl_user
16133
16134         changelog_register || error "changelog_register failed"
16135         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16136
16137         changelog_users $SINGLEMDS | grep -q $cl_user ||
16138                 error "User '$cl_user' not found in changelog_users"
16139
16140         # Clear some types so that MTIME changelogs are generated
16141         changelog_chmask "-CREAT"
16142         changelog_chmask "-CLOSE"
16143
16144         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16145
16146         # Test CL_MTIME during setattr
16147         touch $DIR/$tdir/$tfile
16148         compare_mtime_changelog $DIR/$tdir/$tfile
16149
16150         # Test CL_MTIME during close
16151         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16152         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16153 }
16154 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16155
16156 test_160m() {
16157         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16158         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16159                 skip "Need MDS version at least 2.14.51"
16160         local cl_users
16161         local cl_user1
16162         local cl_user2
16163         local pid1
16164
16165         # Create a user
16166         changelog_register || error "first changelog_register failed"
16167         changelog_register || error "second changelog_register failed"
16168
16169         cl_users=(${CL_USERS[mds1]})
16170         cl_user1="${cl_users[0]}"
16171         cl_user2="${cl_users[1]}"
16172         # generate some changelog records to accumulate on MDT0
16173         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16174         createmany -m $DIR/$tdir/$tfile 50 ||
16175                 error "create $DIR/$tdir/$tfile failed"
16176         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16177         rm -f $DIR/$tdir
16178
16179         # check changelogs have been generated
16180         local nbcl=$(changelog_dump | wc -l)
16181         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16182
16183 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16184         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16185
16186         __changelog_clear mds1 $cl_user1 +10
16187         __changelog_clear mds1 $cl_user2 0 &
16188         pid1=$!
16189         sleep 2
16190         __changelog_clear mds1 $cl_user1 0 ||
16191                 error "fail to cancel record for $cl_user1"
16192         wait $pid1
16193         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16194 }
16195 run_test 160m "Changelog clear race"
16196
16197 test_160n() {
16198         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16199         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16200                 skip "Need MDS version at least 2.14.51"
16201         local cl_users
16202         local cl_user1
16203         local cl_user2
16204         local pid1
16205         local first_rec
16206         local last_rec=0
16207
16208         # Create a user
16209         changelog_register || error "first changelog_register failed"
16210
16211         cl_users=(${CL_USERS[mds1]})
16212         cl_user1="${cl_users[0]}"
16213
16214         # generate some changelog records to accumulate on MDT0
16215         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16216         first_rec=$(changelog_users $SINGLEMDS |
16217                         awk '/^current.index:/ { print $NF }')
16218         while (( last_rec < (( first_rec + 65000)) )); do
16219                 createmany -m $DIR/$tdir/$tfile 10000 ||
16220                         error "create $DIR/$tdir/$tfile failed"
16221
16222                 for i in $(seq 0 10000); do
16223                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16224                                 > /dev/null
16225                 done
16226
16227                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16228                         error "unlinkmany failed unlink"
16229                 last_rec=$(changelog_users $SINGLEMDS |
16230                         awk '/^current.index:/ { print $NF }')
16231                 echo last record $last_rec
16232                 (( last_rec == 0 )) && error "no changelog found"
16233         done
16234
16235 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16236         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16237
16238         __changelog_clear mds1 $cl_user1 0 &
16239         pid1=$!
16240         sleep 2
16241         __changelog_clear mds1 $cl_user1 0 ||
16242                 error "fail to cancel record for $cl_user1"
16243         wait $pid1
16244         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16245 }
16246 run_test 160n "Changelog destroy race"
16247
16248 test_160o() {
16249         local mdt="$(facet_svc $SINGLEMDS)"
16250
16251         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16252         remote_mds_nodsh && skip "remote MDS with nodsh"
16253         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16254                 skip "Need MDS version at least 2.14.52"
16255
16256         changelog_register --user test_160o -m unlnk+close+open ||
16257                 error "changelog_register failed"
16258         # drop server mask so it doesn't interfere
16259         do_facet $SINGLEMDS $LCTL --device $mdt \
16260                                 changelog_register -u "Tt3_-#" &&
16261                 error "bad symbols in name should fail"
16262
16263         do_facet $SINGLEMDS $LCTL --device $mdt \
16264                                 changelog_register -u test_160o &&
16265                 error "the same name registration should fail"
16266
16267         do_facet $SINGLEMDS $LCTL --device $mdt \
16268                         changelog_register -u test_160toolongname &&
16269                 error "too long name registration should fail"
16270
16271         changelog_chmask "MARK+HSM"
16272         lctl get_param mdd.*.changelog*mask
16273         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16274         changelog_users $SINGLEMDS | grep -q $cl_user ||
16275                 error "User $cl_user not found in changelog_users"
16276         #verify username
16277         echo $cl_user | grep -q test_160o ||
16278                 error "User $cl_user has no specific name 'test160o'"
16279
16280         # change something
16281         changelog_clear 0 || error "changelog_clear failed"
16282         # generate some changelog records to accumulate on MDT0
16283         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16284         touch $DIR/$tdir/$tfile                 # open 1
16285
16286         OPENS=$(changelog_dump | grep -c "OPEN")
16287         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16288
16289         # must be no MKDIR it wasn't set as user mask
16290         MKDIR=$(changelog_dump | grep -c "MKDIR")
16291         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16292
16293         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16294                                 mdd.$mdt.changelog_current_mask -n)
16295         # register maskless user
16296         changelog_register || error "changelog_register failed"
16297         # effective mask should be not changed because it is not minimal
16298         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16299                                 mdd.$mdt.changelog_current_mask -n)
16300         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16301         # set server mask to minimal value
16302         changelog_chmask "MARK"
16303         # check effective mask again, should be treated as DEFMASK now
16304         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16305                                 mdd.$mdt.changelog_current_mask -n)
16306         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16307
16308         do_facet $SINGLEMDS $LCTL --device $mdt \
16309                                 changelog_deregister -u test_160o ||
16310                 error "cannot deregister by name"
16311 }
16312 run_test 160o "changelog user name and mask"
16313
16314 test_160p() {
16315         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16316         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16317                 skip "Need MDS version at least 2.14.51"
16318         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16319         local cl_users
16320         local cl_user1
16321         local entry_count
16322
16323         # Create a user
16324         changelog_register || error "first changelog_register failed"
16325
16326         cl_users=(${CL_USERS[mds1]})
16327         cl_user1="${cl_users[0]}"
16328
16329         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16330         createmany -m $DIR/$tdir/$tfile 50 ||
16331                 error "create $DIR/$tdir/$tfile failed"
16332         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16333         rm -rf $DIR/$tdir
16334
16335         # check changelogs have been generated
16336         entry_count=$(changelog_dump | wc -l)
16337         ((entry_count != 0)) || error "no changelog entries found"
16338
16339         # remove changelog_users and check that orphan entries are removed
16340         stop mds1
16341         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16342         start mds1 || error "cannot start mdt"
16343         entry_count=$(changelog_dump | wc -l)
16344         ((entry_count == 0)) ||
16345                 error "found $entry_count changelog entries, expected none"
16346 }
16347 run_test 160p "Changelog orphan cleanup with no users"
16348
16349 test_161a() {
16350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16351
16352         test_mkdir -c1 $DIR/$tdir
16353         cp /etc/hosts $DIR/$tdir/$tfile
16354         test_mkdir -c1 $DIR/$tdir/foo1
16355         test_mkdir -c1 $DIR/$tdir/foo2
16356         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16357         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16358         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16359         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16360         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16361         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16362                 $LFS fid2path $DIR $FID
16363                 error "bad link ea"
16364         fi
16365         # middle
16366         rm $DIR/$tdir/foo2/zachary
16367         # last
16368         rm $DIR/$tdir/foo2/thor
16369         # first
16370         rm $DIR/$tdir/$tfile
16371         # rename
16372         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16373         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16374                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16375         rm $DIR/$tdir/foo2/maggie
16376
16377         # overflow the EA
16378         local longname=$tfile.avg_len_is_thirty_two_
16379         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16380                 error_noexit 'failed to unlink many hardlinks'" EXIT
16381         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16382                 error "failed to hardlink many files"
16383         links=$($LFS fid2path $DIR $FID | wc -l)
16384         echo -n "${links}/1000 links in link EA"
16385         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16386 }
16387 run_test 161a "link ea sanity"
16388
16389 test_161b() {
16390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16391         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16392
16393         local MDTIDX=1
16394         local remote_dir=$DIR/$tdir/remote_dir
16395
16396         mkdir -p $DIR/$tdir
16397         $LFS mkdir -i $MDTIDX $remote_dir ||
16398                 error "create remote directory failed"
16399
16400         cp /etc/hosts $remote_dir/$tfile
16401         mkdir -p $remote_dir/foo1
16402         mkdir -p $remote_dir/foo2
16403         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16404         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16405         ln $remote_dir/$tfile $remote_dir/foo1/luna
16406         ln $remote_dir/$tfile $remote_dir/foo2/thor
16407
16408         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16409                      tr -d ']')
16410         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16411                 $LFS fid2path $DIR $FID
16412                 error "bad link ea"
16413         fi
16414         # middle
16415         rm $remote_dir/foo2/zachary
16416         # last
16417         rm $remote_dir/foo2/thor
16418         # first
16419         rm $remote_dir/$tfile
16420         # rename
16421         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16422         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16423         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16424                 $LFS fid2path $DIR $FID
16425                 error "bad link rename"
16426         fi
16427         rm $remote_dir/foo2/maggie
16428
16429         # overflow the EA
16430         local longname=filename_avg_len_is_thirty_two_
16431         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16432                 error "failed to hardlink many files"
16433         links=$($LFS fid2path $DIR $FID | wc -l)
16434         echo -n "${links}/1000 links in link EA"
16435         [[ ${links} -gt 60 ]] ||
16436                 error "expected at least 60 links in link EA"
16437         unlinkmany $remote_dir/foo2/$longname 1000 ||
16438         error "failed to unlink many hardlinks"
16439 }
16440 run_test 161b "link ea sanity under remote directory"
16441
16442 test_161c() {
16443         remote_mds_nodsh && skip "remote MDS with nodsh"
16444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16445         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16446                 skip "Need MDS version at least 2.1.5"
16447
16448         # define CLF_RENAME_LAST 0x0001
16449         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16450         changelog_register || error "changelog_register failed"
16451
16452         rm -rf $DIR/$tdir
16453         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16454         touch $DIR/$tdir/foo_161c
16455         touch $DIR/$tdir/bar_161c
16456         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16457         changelog_dump | grep RENME | tail -n 5
16458         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16459         changelog_clear 0 || error "changelog_clear failed"
16460         if [ x$flags != "x0x1" ]; then
16461                 error "flag $flags is not 0x1"
16462         fi
16463
16464         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16465         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16466         touch $DIR/$tdir/foo_161c
16467         touch $DIR/$tdir/bar_161c
16468         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16469         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16470         changelog_dump | grep RENME | tail -n 5
16471         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16472         changelog_clear 0 || error "changelog_clear failed"
16473         if [ x$flags != "x0x0" ]; then
16474                 error "flag $flags is not 0x0"
16475         fi
16476         echo "rename overwrite a target having nlink > 1," \
16477                 "changelog record has flags of $flags"
16478
16479         # rename doesn't overwrite a target (changelog flag 0x0)
16480         touch $DIR/$tdir/foo_161c
16481         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16482         changelog_dump | grep RENME | tail -n 5
16483         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16484         changelog_clear 0 || error "changelog_clear failed"
16485         if [ x$flags != "x0x0" ]; then
16486                 error "flag $flags is not 0x0"
16487         fi
16488         echo "rename doesn't overwrite a target," \
16489                 "changelog record has flags of $flags"
16490
16491         # define CLF_UNLINK_LAST 0x0001
16492         # unlink a file having nlink = 1 (changelog flag 0x1)
16493         rm -f $DIR/$tdir/foo2_161c
16494         changelog_dump | grep UNLNK | tail -n 5
16495         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16496         changelog_clear 0 || error "changelog_clear failed"
16497         if [ x$flags != "x0x1" ]; then
16498                 error "flag $flags is not 0x1"
16499         fi
16500         echo "unlink a file having nlink = 1," \
16501                 "changelog record has flags of $flags"
16502
16503         # unlink a file having nlink > 1 (changelog flag 0x0)
16504         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16505         rm -f $DIR/$tdir/foobar_161c
16506         changelog_dump | grep UNLNK | tail -n 5
16507         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16508         changelog_clear 0 || error "changelog_clear failed"
16509         if [ x$flags != "x0x0" ]; then
16510                 error "flag $flags is not 0x0"
16511         fi
16512         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16513 }
16514 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16515
16516 test_161d() {
16517         remote_mds_nodsh && skip "remote MDS with nodsh"
16518         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16519
16520         local pid
16521         local fid
16522
16523         changelog_register || error "changelog_register failed"
16524
16525         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16526         # interfer with $MOUNT/.lustre/fid/ access
16527         mkdir $DIR/$tdir
16528         [[ $? -eq 0 ]] || error "mkdir failed"
16529
16530         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16531         $LCTL set_param fail_loc=0x8000140c
16532         # 5s pause
16533         $LCTL set_param fail_val=5
16534
16535         # create file
16536         echo foofoo > $DIR/$tdir/$tfile &
16537         pid=$!
16538
16539         # wait for create to be delayed
16540         sleep 2
16541
16542         ps -p $pid
16543         [[ $? -eq 0 ]] || error "create should be blocked"
16544
16545         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16546         stack_trap "rm -f $tempfile"
16547         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16548         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16549         # some delay may occur during ChangeLog publishing and file read just
16550         # above, that could allow file write to happen finally
16551         [[ -s $tempfile ]] && echo "file should be empty"
16552
16553         $LCTL set_param fail_loc=0
16554
16555         wait $pid
16556         [[ $? -eq 0 ]] || error "create failed"
16557 }
16558 run_test 161d "create with concurrent .lustre/fid access"
16559
16560 check_path() {
16561         local expected="$1"
16562         shift
16563         local fid="$2"
16564
16565         local path
16566         path=$($LFS fid2path "$@")
16567         local rc=$?
16568
16569         if [ $rc -ne 0 ]; then
16570                 error "path looked up of '$expected' failed: rc=$rc"
16571         elif [ "$path" != "$expected" ]; then
16572                 error "path looked up '$path' instead of '$expected'"
16573         else
16574                 echo "FID '$fid' resolves to path '$path' as expected"
16575         fi
16576 }
16577
16578 test_162a() { # was test_162
16579         test_mkdir -p -c1 $DIR/$tdir/d2
16580         touch $DIR/$tdir/d2/$tfile
16581         touch $DIR/$tdir/d2/x1
16582         touch $DIR/$tdir/d2/x2
16583         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16584         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16585         # regular file
16586         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16587         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16588
16589         # softlink
16590         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16591         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16592         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16593
16594         # softlink to wrong file
16595         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16596         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16597         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16598
16599         # hardlink
16600         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16601         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16602         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16603         # fid2path dir/fsname should both work
16604         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16605         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16606
16607         # hardlink count: check that there are 2 links
16608         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16609         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16610
16611         # hardlink indexing: remove the first link
16612         rm $DIR/$tdir/d2/p/q/r/hlink
16613         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16614 }
16615 run_test 162a "path lookup sanity"
16616
16617 test_162b() {
16618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16619         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16620
16621         mkdir $DIR/$tdir
16622         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16623                                 error "create striped dir failed"
16624
16625         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16626                                         tail -n 1 | awk '{print $2}')
16627         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16628
16629         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16630         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16631
16632         # regular file
16633         for ((i=0;i<5;i++)); do
16634                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16635                         error "get fid for f$i failed"
16636                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16637
16638                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16639                         error "get fid for d$i failed"
16640                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16641         done
16642
16643         return 0
16644 }
16645 run_test 162b "striped directory path lookup sanity"
16646
16647 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16648 test_162c() {
16649         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16650                 skip "Need MDS version at least 2.7.51"
16651
16652         local lpath=$tdir.local
16653         local rpath=$tdir.remote
16654
16655         test_mkdir $DIR/$lpath
16656         test_mkdir $DIR/$rpath
16657
16658         for ((i = 0; i <= 101; i++)); do
16659                 lpath="$lpath/$i"
16660                 mkdir $DIR/$lpath
16661                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16662                         error "get fid for local directory $DIR/$lpath failed"
16663                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16664
16665                 rpath="$rpath/$i"
16666                 test_mkdir $DIR/$rpath
16667                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16668                         error "get fid for remote directory $DIR/$rpath failed"
16669                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16670         done
16671
16672         return 0
16673 }
16674 run_test 162c "fid2path works with paths 100 or more directories deep"
16675
16676 oalr_event_count() {
16677         local event="${1}"
16678         local trace="${2}"
16679
16680         awk -v name="${FSNAME}-OST0000" \
16681             -v event="${event}" \
16682             '$1 == "TRACE" && $2 == event && $3 == name' \
16683             "${trace}" |
16684         wc -l
16685 }
16686
16687 oalr_expect_event_count() {
16688         local event="${1}"
16689         local trace="${2}"
16690         local expect="${3}"
16691         local count
16692
16693         count=$(oalr_event_count "${event}" "${trace}")
16694         if ((count == expect)); then
16695                 return 0
16696         fi
16697
16698         error_noexit "${event} event count was '${count}', expected ${expect}"
16699         cat "${trace}" >&2
16700         exit 1
16701 }
16702
16703 cleanup_165() {
16704         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16705         stop ost1
16706         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16707 }
16708
16709 setup_165() {
16710         sync # Flush previous IOs so we can count log entries.
16711         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16712         stack_trap cleanup_165 EXIT
16713 }
16714
16715 test_165a() {
16716         local trace="/tmp/${tfile}.trace"
16717         local rc
16718         local count
16719
16720         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16721                 skip "OFD access log unsupported"
16722
16723         setup_165
16724         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16725         sleep 5
16726
16727         do_facet ost1 ofd_access_log_reader --list
16728         stop ost1
16729
16730         do_facet ost1 killall -TERM ofd_access_log_reader
16731         wait
16732         rc=$?
16733
16734         if ((rc != 0)); then
16735                 error "ofd_access_log_reader exited with rc = '${rc}'"
16736         fi
16737
16738         # Parse trace file for discovery events:
16739         oalr_expect_event_count alr_log_add "${trace}" 1
16740         oalr_expect_event_count alr_log_eof "${trace}" 1
16741         oalr_expect_event_count alr_log_free "${trace}" 1
16742 }
16743 run_test 165a "ofd access log discovery"
16744
16745 test_165b() {
16746         local trace="/tmp/${tfile}.trace"
16747         local file="${DIR}/${tfile}"
16748         local pfid1
16749         local pfid2
16750         local -a entry
16751         local rc
16752         local count
16753         local size
16754         local flags
16755
16756         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16757                 skip "OFD access log unsupported"
16758
16759         setup_165
16760         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16761         sleep 5
16762
16763         do_facet ost1 ofd_access_log_reader --list
16764
16765         lfs setstripe -c 1 -i 0 "${file}"
16766         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16767                 error "cannot create '${file}'"
16768
16769         sleep 5
16770         do_facet ost1 killall -TERM ofd_access_log_reader
16771         wait
16772         rc=$?
16773
16774         if ((rc != 0)); then
16775                 error "ofd_access_log_reader exited with rc = '${rc}'"
16776         fi
16777
16778         oalr_expect_event_count alr_log_entry "${trace}" 1
16779
16780         pfid1=$($LFS path2fid "${file}")
16781
16782         # 1     2             3   4    5     6   7    8    9     10
16783         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16784         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16785
16786         echo "entry = '${entry[*]}'" >&2
16787
16788         pfid2=${entry[4]}
16789         if [[ "${pfid1}" != "${pfid2}" ]]; then
16790                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16791         fi
16792
16793         size=${entry[8]}
16794         if ((size != 1048576)); then
16795                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16796         fi
16797
16798         flags=${entry[10]}
16799         if [[ "${flags}" != "w" ]]; then
16800                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16801         fi
16802
16803         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16804         sleep 5
16805
16806         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16807                 error "cannot read '${file}'"
16808         sleep 5
16809
16810         do_facet ost1 killall -TERM ofd_access_log_reader
16811         wait
16812         rc=$?
16813
16814         if ((rc != 0)); then
16815                 error "ofd_access_log_reader exited with rc = '${rc}'"
16816         fi
16817
16818         oalr_expect_event_count alr_log_entry "${trace}" 1
16819
16820         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16821         echo "entry = '${entry[*]}'" >&2
16822
16823         pfid2=${entry[4]}
16824         if [[ "${pfid1}" != "${pfid2}" ]]; then
16825                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16826         fi
16827
16828         size=${entry[8]}
16829         if ((size != 524288)); then
16830                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16831         fi
16832
16833         flags=${entry[10]}
16834         if [[ "${flags}" != "r" ]]; then
16835                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16836         fi
16837 }
16838 run_test 165b "ofd access log entries are produced and consumed"
16839
16840 test_165c() {
16841         local trace="/tmp/${tfile}.trace"
16842         local file="${DIR}/${tdir}/${tfile}"
16843
16844         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16845                 skip "OFD access log unsupported"
16846
16847         test_mkdir "${DIR}/${tdir}"
16848
16849         setup_165
16850         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16851         sleep 5
16852
16853         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16854
16855         # 4096 / 64 = 64. Create twice as many entries.
16856         for ((i = 0; i < 128; i++)); do
16857                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16858                         error "cannot create file"
16859         done
16860
16861         sync
16862
16863         do_facet ost1 killall -TERM ofd_access_log_reader
16864         wait
16865         rc=$?
16866         if ((rc != 0)); then
16867                 error "ofd_access_log_reader exited with rc = '${rc}'"
16868         fi
16869
16870         unlinkmany  "${file}-%d" 128
16871 }
16872 run_test 165c "full ofd access logs do not block IOs"
16873
16874 oal_get_read_count() {
16875         local stats="$1"
16876
16877         # STATS lustre-OST0001 alr_read_count 1
16878
16879         do_facet ost1 cat "${stats}" |
16880         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16881              END { print count; }'
16882 }
16883
16884 oal_expect_read_count() {
16885         local stats="$1"
16886         local count
16887         local expect="$2"
16888
16889         # Ask ofd_access_log_reader to write stats.
16890         do_facet ost1 killall -USR1 ofd_access_log_reader
16891
16892         # Allow some time for things to happen.
16893         sleep 1
16894
16895         count=$(oal_get_read_count "${stats}")
16896         if ((count == expect)); then
16897                 return 0
16898         fi
16899
16900         error_noexit "bad read count, got ${count}, expected ${expect}"
16901         do_facet ost1 cat "${stats}" >&2
16902         exit 1
16903 }
16904
16905 test_165d() {
16906         local stats="/tmp/${tfile}.stats"
16907         local file="${DIR}/${tdir}/${tfile}"
16908         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16909
16910         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16911                 skip "OFD access log unsupported"
16912
16913         test_mkdir "${DIR}/${tdir}"
16914
16915         setup_165
16916         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16917         sleep 5
16918
16919         lfs setstripe -c 1 -i 0 "${file}"
16920
16921         do_facet ost1 lctl set_param "${param}=rw"
16922         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16923                 error "cannot create '${file}'"
16924         oal_expect_read_count "${stats}" 1
16925
16926         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16927                 error "cannot read '${file}'"
16928         oal_expect_read_count "${stats}" 2
16929
16930         do_facet ost1 lctl set_param "${param}=r"
16931         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16932                 error "cannot create '${file}'"
16933         oal_expect_read_count "${stats}" 2
16934
16935         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16936                 error "cannot read '${file}'"
16937         oal_expect_read_count "${stats}" 3
16938
16939         do_facet ost1 lctl set_param "${param}=w"
16940         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16941                 error "cannot create '${file}'"
16942         oal_expect_read_count "${stats}" 4
16943
16944         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16945                 error "cannot read '${file}'"
16946         oal_expect_read_count "${stats}" 4
16947
16948         do_facet ost1 lctl set_param "${param}=0"
16949         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16950                 error "cannot create '${file}'"
16951         oal_expect_read_count "${stats}" 4
16952
16953         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
16954                 error "cannot read '${file}'"
16955         oal_expect_read_count "${stats}" 4
16956
16957         do_facet ost1 killall -TERM ofd_access_log_reader
16958         wait
16959         rc=$?
16960         if ((rc != 0)); then
16961                 error "ofd_access_log_reader exited with rc = '${rc}'"
16962         fi
16963 }
16964 run_test 165d "ofd_access_log mask works"
16965
16966 test_165e() {
16967         local stats="/tmp/${tfile}.stats"
16968         local file0="${DIR}/${tdir}-0/${tfile}"
16969         local file1="${DIR}/${tdir}-1/${tfile}"
16970
16971         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16972                 skip "OFD access log unsupported"
16973
16974         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
16975
16976         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
16977         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
16978
16979         lfs setstripe -c 1 -i 0 "${file0}"
16980         lfs setstripe -c 1 -i 0 "${file1}"
16981
16982         setup_165
16983         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
16984         sleep 5
16985
16986         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
16987                 error "cannot create '${file0}'"
16988         sync
16989         oal_expect_read_count "${stats}" 0
16990
16991         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
16992                 error "cannot create '${file1}'"
16993         sync
16994         oal_expect_read_count "${stats}" 1
16995
16996         do_facet ost1 killall -TERM ofd_access_log_reader
16997         wait
16998         rc=$?
16999         if ((rc != 0)); then
17000                 error "ofd_access_log_reader exited with rc = '${rc}'"
17001         fi
17002 }
17003 run_test 165e "ofd_access_log MDT index filter works"
17004
17005 test_165f() {
17006         local trace="/tmp/${tfile}.trace"
17007         local rc
17008         local count
17009
17010         setup_165
17011         do_facet ost1 timeout 60 ofd_access_log_reader \
17012                 --exit-on-close --debug=- --trace=- > "${trace}" &
17013         sleep 5
17014         stop ost1
17015
17016         wait
17017         rc=$?
17018
17019         if ((rc != 0)); then
17020                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17021                 cat "${trace}"
17022                 exit 1
17023         fi
17024 }
17025 run_test 165f "ofd_access_log_reader --exit-on-close works"
17026
17027 test_169() {
17028         # do directio so as not to populate the page cache
17029         log "creating a 10 Mb file"
17030         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17031                 error "multiop failed while creating a file"
17032         log "starting reads"
17033         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17034         log "truncating the file"
17035         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17036                 error "multiop failed while truncating the file"
17037         log "killing dd"
17038         kill %+ || true # reads might have finished
17039         echo "wait until dd is finished"
17040         wait
17041         log "removing the temporary file"
17042         rm -rf $DIR/$tfile || error "tmp file removal failed"
17043 }
17044 run_test 169 "parallel read and truncate should not deadlock"
17045
17046 test_170() {
17047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17048
17049         $LCTL clear     # bug 18514
17050         $LCTL debug_daemon start $TMP/${tfile}_log_good
17051         touch $DIR/$tfile
17052         $LCTL debug_daemon stop
17053         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17054                 error "sed failed to read log_good"
17055
17056         $LCTL debug_daemon start $TMP/${tfile}_log_good
17057         rm -rf $DIR/$tfile
17058         $LCTL debug_daemon stop
17059
17060         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17061                error "lctl df log_bad failed"
17062
17063         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17064         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17065
17066         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17067         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17068
17069         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17070                 error "bad_line good_line1 good_line2 are empty"
17071
17072         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17073         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17074         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17075
17076         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17077         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17078         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17079
17080         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17081                 error "bad_line_new good_line_new are empty"
17082
17083         local expected_good=$((good_line1 + good_line2*2))
17084
17085         rm -f $TMP/${tfile}*
17086         # LU-231, short malformed line may not be counted into bad lines
17087         if [ $bad_line -ne $bad_line_new ] &&
17088                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17089                 error "expected $bad_line bad lines, but got $bad_line_new"
17090                 return 1
17091         fi
17092
17093         if [ $expected_good -ne $good_line_new ]; then
17094                 error "expected $expected_good good lines, but got $good_line_new"
17095                 return 2
17096         fi
17097         true
17098 }
17099 run_test 170 "test lctl df to handle corrupted log ====================="
17100
17101 test_171() { # bug20592
17102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17103
17104         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17105         $LCTL set_param fail_loc=0x50e
17106         $LCTL set_param fail_val=3000
17107         multiop_bg_pause $DIR/$tfile O_s || true
17108         local MULTIPID=$!
17109         kill -USR1 $MULTIPID
17110         # cause log dump
17111         sleep 3
17112         wait $MULTIPID
17113         if dmesg | grep "recursive fault"; then
17114                 error "caught a recursive fault"
17115         fi
17116         $LCTL set_param fail_loc=0
17117         true
17118 }
17119 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17120
17121 # it would be good to share it with obdfilter-survey/iokit-libecho code
17122 setup_obdecho_osc () {
17123         local rc=0
17124         local ost_nid=$1
17125         local obdfilter_name=$2
17126         echo "Creating new osc for $obdfilter_name on $ost_nid"
17127         # make sure we can find loopback nid
17128         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17129
17130         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17131                            ${obdfilter_name}_osc_UUID || rc=2; }
17132         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17133                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17134         return $rc
17135 }
17136
17137 cleanup_obdecho_osc () {
17138         local obdfilter_name=$1
17139         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17140         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17141         return 0
17142 }
17143
17144 obdecho_test() {
17145         local OBD=$1
17146         local node=$2
17147         local pages=${3:-64}
17148         local rc=0
17149         local id
17150
17151         local count=10
17152         local obd_size=$(get_obd_size $node $OBD)
17153         local page_size=$(get_page_size $node)
17154         if [[ -n "$obd_size" ]]; then
17155                 local new_count=$((obd_size / (pages * page_size / 1024)))
17156                 [[ $new_count -ge $count ]] || count=$new_count
17157         fi
17158
17159         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17160         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17161                            rc=2; }
17162         if [ $rc -eq 0 ]; then
17163             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17164             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17165         fi
17166         echo "New object id is $id"
17167         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17168                            rc=4; }
17169         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17170                            "test_brw $count w v $pages $id" || rc=4; }
17171         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17172                            rc=4; }
17173         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17174                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17175         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17176                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17177         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17178         return $rc
17179 }
17180
17181 test_180a() {
17182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17183
17184         if ! [ -d /sys/fs/lustre/echo_client ] &&
17185            ! module_loaded obdecho; then
17186                 load_module obdecho/obdecho &&
17187                         stack_trap "rmmod obdecho" EXIT ||
17188                         error "unable to load obdecho on client"
17189         fi
17190
17191         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17192         local host=$($LCTL get_param -n osc.$osc.import |
17193                      awk '/current_connection:/ { print $2 }' )
17194         local target=$($LCTL get_param -n osc.$osc.import |
17195                        awk '/target:/ { print $2 }' )
17196         target=${target%_UUID}
17197
17198         if [ -n "$target" ]; then
17199                 setup_obdecho_osc $host $target &&
17200                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17201                         { error "obdecho setup failed with $?"; return; }
17202
17203                 obdecho_test ${target}_osc client ||
17204                         error "obdecho_test failed on ${target}_osc"
17205         else
17206                 $LCTL get_param osc.$osc.import
17207                 error "there is no osc.$osc.import target"
17208         fi
17209 }
17210 run_test 180a "test obdecho on osc"
17211
17212 test_180b() {
17213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17214         remote_ost_nodsh && skip "remote OST with nodsh"
17215
17216         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17217                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17218                 error "failed to load module obdecho"
17219
17220         local target=$(do_facet ost1 $LCTL dl |
17221                        awk '/obdfilter/ { print $4; exit; }')
17222
17223         if [ -n "$target" ]; then
17224                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17225         else
17226                 do_facet ost1 $LCTL dl
17227                 error "there is no obdfilter target on ost1"
17228         fi
17229 }
17230 run_test 180b "test obdecho directly on obdfilter"
17231
17232 test_180c() { # LU-2598
17233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17234         remote_ost_nodsh && skip "remote OST with nodsh"
17235         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17236                 skip "Need MDS version at least 2.4.0"
17237
17238         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17239                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17240                 error "failed to load module obdecho"
17241
17242         local target=$(do_facet ost1 $LCTL dl |
17243                        awk '/obdfilter/ { print $4; exit; }')
17244
17245         if [ -n "$target" ]; then
17246                 local pages=16384 # 64MB bulk I/O RPC size
17247
17248                 obdecho_test "$target" ost1 "$pages" ||
17249                         error "obdecho_test with pages=$pages failed with $?"
17250         else
17251                 do_facet ost1 $LCTL dl
17252                 error "there is no obdfilter target on ost1"
17253         fi
17254 }
17255 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17256
17257 test_181() { # bug 22177
17258         test_mkdir $DIR/$tdir
17259         # create enough files to index the directory
17260         createmany -o $DIR/$tdir/foobar 4000
17261         # print attributes for debug purpose
17262         lsattr -d .
17263         # open dir
17264         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17265         MULTIPID=$!
17266         # remove the files & current working dir
17267         unlinkmany $DIR/$tdir/foobar 4000
17268         rmdir $DIR/$tdir
17269         kill -USR1 $MULTIPID
17270         wait $MULTIPID
17271         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17272         return 0
17273 }
17274 run_test 181 "Test open-unlinked dir ========================"
17275
17276 test_182() {
17277         local fcount=1000
17278         local tcount=10
17279
17280         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17281
17282         $LCTL set_param mdc.*.rpc_stats=clear
17283
17284         for (( i = 0; i < $tcount; i++ )) ; do
17285                 mkdir $DIR/$tdir/$i
17286         done
17287
17288         for (( i = 0; i < $tcount; i++ )) ; do
17289                 createmany -o $DIR/$tdir/$i/f- $fcount &
17290         done
17291         wait
17292
17293         for (( i = 0; i < $tcount; i++ )) ; do
17294                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17295         done
17296         wait
17297
17298         $LCTL get_param mdc.*.rpc_stats
17299
17300         rm -rf $DIR/$tdir
17301 }
17302 run_test 182 "Test parallel modify metadata operations ================"
17303
17304 test_183() { # LU-2275
17305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17306         remote_mds_nodsh && skip "remote MDS with nodsh"
17307         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17308                 skip "Need MDS version at least 2.3.56"
17309
17310         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17311         echo aaa > $DIR/$tdir/$tfile
17312
17313 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17314         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17315
17316         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17317         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17318
17319         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17320
17321         # Flush negative dentry cache
17322         touch $DIR/$tdir/$tfile
17323
17324         # We are not checking for any leaked references here, they'll
17325         # become evident next time we do cleanup with module unload.
17326         rm -rf $DIR/$tdir
17327 }
17328 run_test 183 "No crash or request leak in case of strange dispositions ========"
17329
17330 # test suite 184 is for LU-2016, LU-2017
17331 test_184a() {
17332         check_swap_layouts_support
17333
17334         dir0=$DIR/$tdir/$testnum
17335         test_mkdir -p -c1 $dir0
17336         ref1=/etc/passwd
17337         ref2=/etc/group
17338         file1=$dir0/f1
17339         file2=$dir0/f2
17340         $LFS setstripe -c1 $file1
17341         cp $ref1 $file1
17342         $LFS setstripe -c2 $file2
17343         cp $ref2 $file2
17344         gen1=$($LFS getstripe -g $file1)
17345         gen2=$($LFS getstripe -g $file2)
17346
17347         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17348         gen=$($LFS getstripe -g $file1)
17349         [[ $gen1 != $gen ]] ||
17350                 "Layout generation on $file1 does not change"
17351         gen=$($LFS getstripe -g $file2)
17352         [[ $gen2 != $gen ]] ||
17353                 "Layout generation on $file2 does not change"
17354
17355         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17356         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17357
17358         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17359 }
17360 run_test 184a "Basic layout swap"
17361
17362 test_184b() {
17363         check_swap_layouts_support
17364
17365         dir0=$DIR/$tdir/$testnum
17366         mkdir -p $dir0 || error "creating dir $dir0"
17367         file1=$dir0/f1
17368         file2=$dir0/f2
17369         file3=$dir0/f3
17370         dir1=$dir0/d1
17371         dir2=$dir0/d2
17372         mkdir $dir1 $dir2
17373         $LFS setstripe -c1 $file1
17374         $LFS setstripe -c2 $file2
17375         $LFS setstripe -c1 $file3
17376         chown $RUNAS_ID $file3
17377         gen1=$($LFS getstripe -g $file1)
17378         gen2=$($LFS getstripe -g $file2)
17379
17380         $LFS swap_layouts $dir1 $dir2 &&
17381                 error "swap of directories layouts should fail"
17382         $LFS swap_layouts $dir1 $file1 &&
17383                 error "swap of directory and file layouts should fail"
17384         $RUNAS $LFS swap_layouts $file1 $file2 &&
17385                 error "swap of file we cannot write should fail"
17386         $LFS swap_layouts $file1 $file3 &&
17387                 error "swap of file with different owner should fail"
17388         /bin/true # to clear error code
17389 }
17390 run_test 184b "Forbidden layout swap (will generate errors)"
17391
17392 test_184c() {
17393         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17394         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17395         check_swap_layouts_support
17396         check_swap_layout_no_dom $DIR
17397
17398         local dir0=$DIR/$tdir/$testnum
17399         mkdir -p $dir0 || error "creating dir $dir0"
17400
17401         local ref1=$dir0/ref1
17402         local ref2=$dir0/ref2
17403         local file1=$dir0/file1
17404         local file2=$dir0/file2
17405         # create a file large enough for the concurrent test
17406         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17407         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17408         echo "ref file size: ref1($(stat -c %s $ref1))," \
17409              "ref2($(stat -c %s $ref2))"
17410
17411         cp $ref2 $file2
17412         dd if=$ref1 of=$file1 bs=16k &
17413         local DD_PID=$!
17414
17415         # Make sure dd starts to copy file, but wait at most 5 seconds
17416         local loops=0
17417         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17418
17419         $LFS swap_layouts $file1 $file2
17420         local rc=$?
17421         wait $DD_PID
17422         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17423         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17424
17425         # how many bytes copied before swapping layout
17426         local copied=$(stat -c %s $file2)
17427         local remaining=$(stat -c %s $ref1)
17428         remaining=$((remaining - copied))
17429         echo "Copied $copied bytes before swapping layout..."
17430
17431         cmp -n $copied $file1 $ref2 | grep differ &&
17432                 error "Content mismatch [0, $copied) of ref2 and file1"
17433         cmp -n $copied $file2 $ref1 ||
17434                 error "Content mismatch [0, $copied) of ref1 and file2"
17435         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17436                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17437
17438         # clean up
17439         rm -f $ref1 $ref2 $file1 $file2
17440 }
17441 run_test 184c "Concurrent write and layout swap"
17442
17443 test_184d() {
17444         check_swap_layouts_support
17445         check_swap_layout_no_dom $DIR
17446         [ -z "$(which getfattr 2>/dev/null)" ] &&
17447                 skip_env "no getfattr command"
17448
17449         local file1=$DIR/$tdir/$tfile-1
17450         local file2=$DIR/$tdir/$tfile-2
17451         local file3=$DIR/$tdir/$tfile-3
17452         local lovea1
17453         local lovea2
17454
17455         mkdir -p $DIR/$tdir
17456         touch $file1 || error "create $file1 failed"
17457         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17458                 error "create $file2 failed"
17459         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17460                 error "create $file3 failed"
17461         lovea1=$(get_layout_param $file1)
17462
17463         $LFS swap_layouts $file2 $file3 ||
17464                 error "swap $file2 $file3 layouts failed"
17465         $LFS swap_layouts $file1 $file2 ||
17466                 error "swap $file1 $file2 layouts failed"
17467
17468         lovea2=$(get_layout_param $file2)
17469         echo "$lovea1"
17470         echo "$lovea2"
17471         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17472
17473         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17474         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17475 }
17476 run_test 184d "allow stripeless layouts swap"
17477
17478 test_184e() {
17479         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17480                 skip "Need MDS version at least 2.6.94"
17481         check_swap_layouts_support
17482         check_swap_layout_no_dom $DIR
17483         [ -z "$(which getfattr 2>/dev/null)" ] &&
17484                 skip_env "no getfattr command"
17485
17486         local file1=$DIR/$tdir/$tfile-1
17487         local file2=$DIR/$tdir/$tfile-2
17488         local file3=$DIR/$tdir/$tfile-3
17489         local lovea
17490
17491         mkdir -p $DIR/$tdir
17492         touch $file1 || error "create $file1 failed"
17493         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17494                 error "create $file2 failed"
17495         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17496                 error "create $file3 failed"
17497
17498         $LFS swap_layouts $file1 $file2 ||
17499                 error "swap $file1 $file2 layouts failed"
17500
17501         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17502         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17503
17504         echo 123 > $file1 || error "Should be able to write into $file1"
17505
17506         $LFS swap_layouts $file1 $file3 ||
17507                 error "swap $file1 $file3 layouts failed"
17508
17509         echo 123 > $file1 || error "Should be able to write into $file1"
17510
17511         rm -rf $file1 $file2 $file3
17512 }
17513 run_test 184e "Recreate layout after stripeless layout swaps"
17514
17515 test_184f() {
17516         # Create a file with name longer than sizeof(struct stat) ==
17517         # 144 to see if we can get chars from the file name to appear
17518         # in the returned striping. Note that 'f' == 0x66.
17519         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17520
17521         mkdir -p $DIR/$tdir
17522         mcreate $DIR/$tdir/$file
17523         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17524                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17525         fi
17526 }
17527 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17528
17529 test_185() { # LU-2441
17530         # LU-3553 - no volatile file support in old servers
17531         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17532                 skip "Need MDS version at least 2.3.60"
17533
17534         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17535         touch $DIR/$tdir/spoo
17536         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17537         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17538                 error "cannot create/write a volatile file"
17539         [ "$FILESET" == "" ] &&
17540         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17541                 error "FID is still valid after close"
17542
17543         multiop_bg_pause $DIR/$tdir vVw4096_c
17544         local multi_pid=$!
17545
17546         local OLD_IFS=$IFS
17547         IFS=":"
17548         local fidv=($fid)
17549         IFS=$OLD_IFS
17550         # assume that the next FID for this client is sequential, since stdout
17551         # is unfortunately eaten by multiop_bg_pause
17552         local n=$((${fidv[1]} + 1))
17553         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17554         if [ "$FILESET" == "" ]; then
17555                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17556                         error "FID is missing before close"
17557         fi
17558         kill -USR1 $multi_pid
17559         # 1 second delay, so if mtime change we will see it
17560         sleep 1
17561         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17562         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17563 }
17564 run_test 185 "Volatile file support"
17565
17566 function create_check_volatile() {
17567         local idx=$1
17568         local tgt
17569
17570         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17571         local PID=$!
17572         sleep 1
17573         local FID=$(cat /tmp/${tfile}.fid)
17574         [ "$FID" == "" ] && error "can't get FID for volatile"
17575         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17576         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17577         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17578         kill -USR1 $PID
17579         wait
17580         sleep 1
17581         cancel_lru_locks mdc # flush opencache
17582         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17583         return 0
17584 }
17585
17586 test_185a(){
17587         # LU-12516 - volatile creation via .lustre
17588         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17589                 skip "Need MDS version at least 2.3.55"
17590
17591         create_check_volatile 0
17592         [ $MDSCOUNT -lt 2 ] && return 0
17593
17594         # DNE case
17595         create_check_volatile 1
17596
17597         return 0
17598 }
17599 run_test 185a "Volatile file creation in .lustre/fid/"
17600
17601 test_187a() {
17602         remote_mds_nodsh && skip "remote MDS with nodsh"
17603         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17604                 skip "Need MDS version at least 2.3.0"
17605
17606         local dir0=$DIR/$tdir/$testnum
17607         mkdir -p $dir0 || error "creating dir $dir0"
17608
17609         local file=$dir0/file1
17610         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17611         local dv1=$($LFS data_version $file)
17612         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17613         local dv2=$($LFS data_version $file)
17614         [[ $dv1 != $dv2 ]] ||
17615                 error "data version did not change on write $dv1 == $dv2"
17616
17617         # clean up
17618         rm -f $file1
17619 }
17620 run_test 187a "Test data version change"
17621
17622 test_187b() {
17623         remote_mds_nodsh && skip "remote MDS with nodsh"
17624         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17625                 skip "Need MDS version at least 2.3.0"
17626
17627         local dir0=$DIR/$tdir/$testnum
17628         mkdir -p $dir0 || error "creating dir $dir0"
17629
17630         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17631         [[ ${DV[0]} != ${DV[1]} ]] ||
17632                 error "data version did not change on write"\
17633                       " ${DV[0]} == ${DV[1]}"
17634
17635         # clean up
17636         rm -f $file1
17637 }
17638 run_test 187b "Test data version change on volatile file"
17639
17640 test_200() {
17641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17642         remote_mgs_nodsh && skip "remote MGS with nodsh"
17643         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17644
17645         local POOL=${POOL:-cea1}
17646         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17647         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17648         # Pool OST targets
17649         local first_ost=0
17650         local last_ost=$(($OSTCOUNT - 1))
17651         local ost_step=2
17652         local ost_list=$(seq $first_ost $ost_step $last_ost)
17653         local ost_range="$first_ost $last_ost $ost_step"
17654         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17655         local file_dir=$POOL_ROOT/file_tst
17656         local subdir=$test_path/subdir
17657         local rc=0
17658
17659         while : ; do
17660                 # former test_200a test_200b
17661                 pool_add $POOL                          || { rc=$? ; break; }
17662                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17663                 # former test_200c test_200d
17664                 mkdir -p $test_path
17665                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17666                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17667                 mkdir -p $subdir
17668                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17669                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17670                                                         || { rc=$? ; break; }
17671                 # former test_200e test_200f
17672                 local files=$((OSTCOUNT*3))
17673                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17674                                                         || { rc=$? ; break; }
17675                 pool_create_files $POOL $file_dir $files "$ost_list" \
17676                                                         || { rc=$? ; break; }
17677                 # former test_200g test_200h
17678                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17679                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17680
17681                 # former test_201a test_201b test_201c
17682                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17683
17684                 local f=$test_path/$tfile
17685                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17686                 pool_remove $POOL $f                    || { rc=$? ; break; }
17687                 break
17688         done
17689
17690         destroy_test_pools
17691
17692         return $rc
17693 }
17694 run_test 200 "OST pools"
17695
17696 # usage: default_attr <count | size | offset>
17697 default_attr() {
17698         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17699 }
17700
17701 # usage: check_default_stripe_attr
17702 check_default_stripe_attr() {
17703         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17704         case $1 in
17705         --stripe-count|-c)
17706                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17707         --stripe-size|-S)
17708                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17709         --stripe-index|-i)
17710                 EXPECTED=-1;;
17711         *)
17712                 error "unknown getstripe attr '$1'"
17713         esac
17714
17715         [ $ACTUAL == $EXPECTED ] ||
17716                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17717 }
17718
17719 test_204a() {
17720         test_mkdir $DIR/$tdir
17721         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17722
17723         check_default_stripe_attr --stripe-count
17724         check_default_stripe_attr --stripe-size
17725         check_default_stripe_attr --stripe-index
17726 }
17727 run_test 204a "Print default stripe attributes"
17728
17729 test_204b() {
17730         test_mkdir $DIR/$tdir
17731         $LFS setstripe --stripe-count 1 $DIR/$tdir
17732
17733         check_default_stripe_attr --stripe-size
17734         check_default_stripe_attr --stripe-index
17735 }
17736 run_test 204b "Print default stripe size and offset"
17737
17738 test_204c() {
17739         test_mkdir $DIR/$tdir
17740         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17741
17742         check_default_stripe_attr --stripe-count
17743         check_default_stripe_attr --stripe-index
17744 }
17745 run_test 204c "Print default stripe count and offset"
17746
17747 test_204d() {
17748         test_mkdir $DIR/$tdir
17749         $LFS setstripe --stripe-index 0 $DIR/$tdir
17750
17751         check_default_stripe_attr --stripe-count
17752         check_default_stripe_attr --stripe-size
17753 }
17754 run_test 204d "Print default stripe count and size"
17755
17756 test_204e() {
17757         test_mkdir $DIR/$tdir
17758         $LFS setstripe -d $DIR/$tdir
17759
17760         check_default_stripe_attr --stripe-count --raw
17761         check_default_stripe_attr --stripe-size --raw
17762         check_default_stripe_attr --stripe-index --raw
17763 }
17764 run_test 204e "Print raw stripe attributes"
17765
17766 test_204f() {
17767         test_mkdir $DIR/$tdir
17768         $LFS setstripe --stripe-count 1 $DIR/$tdir
17769
17770         check_default_stripe_attr --stripe-size --raw
17771         check_default_stripe_attr --stripe-index --raw
17772 }
17773 run_test 204f "Print raw stripe size and offset"
17774
17775 test_204g() {
17776         test_mkdir $DIR/$tdir
17777         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17778
17779         check_default_stripe_attr --stripe-count --raw
17780         check_default_stripe_attr --stripe-index --raw
17781 }
17782 run_test 204g "Print raw stripe count and offset"
17783
17784 test_204h() {
17785         test_mkdir $DIR/$tdir
17786         $LFS setstripe --stripe-index 0 $DIR/$tdir
17787
17788         check_default_stripe_attr --stripe-count --raw
17789         check_default_stripe_attr --stripe-size --raw
17790 }
17791 run_test 204h "Print raw stripe count and size"
17792
17793 # Figure out which job scheduler is being used, if any,
17794 # or use a fake one
17795 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17796         JOBENV=SLURM_JOB_ID
17797 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17798         JOBENV=LSB_JOBID
17799 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17800         JOBENV=PBS_JOBID
17801 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17802         JOBENV=LOADL_STEP_ID
17803 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17804         JOBENV=JOB_ID
17805 else
17806         $LCTL list_param jobid_name > /dev/null 2>&1
17807         if [ $? -eq 0 ]; then
17808                 JOBENV=nodelocal
17809         else
17810                 JOBENV=FAKE_JOBID
17811         fi
17812 fi
17813 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17814
17815 verify_jobstats() {
17816         local cmd=($1)
17817         shift
17818         local facets="$@"
17819
17820 # we don't really need to clear the stats for this test to work, since each
17821 # command has a unique jobid, but it makes debugging easier if needed.
17822 #       for facet in $facets; do
17823 #               local dev=$(convert_facet2label $facet)
17824 #               # clear old jobstats
17825 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17826 #       done
17827
17828         # use a new JobID for each test, or we might see an old one
17829         [ "$JOBENV" = "FAKE_JOBID" ] &&
17830                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17831
17832         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17833
17834         [ "$JOBENV" = "nodelocal" ] && {
17835                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17836                 $LCTL set_param jobid_name=$FAKE_JOBID
17837                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17838         }
17839
17840         log "Test: ${cmd[*]}"
17841         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17842
17843         if [ $JOBENV = "FAKE_JOBID" ]; then
17844                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17845         else
17846                 ${cmd[*]}
17847         fi
17848
17849         # all files are created on OST0000
17850         for facet in $facets; do
17851                 local stats="*.$(convert_facet2label $facet).job_stats"
17852
17853                 # strip out libtool wrappers for in-tree executables
17854                 if [ $(do_facet $facet lctl get_param $stats |
17855                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17856                         do_facet $facet lctl get_param $stats
17857                         error "No jobstats for $JOBVAL found on $facet::$stats"
17858                 fi
17859         done
17860 }
17861
17862 jobstats_set() {
17863         local new_jobenv=$1
17864
17865         set_persistent_param_and_check client "jobid_var" \
17866                 "$FSNAME.sys.jobid_var" $new_jobenv
17867 }
17868
17869 test_205a() { # Job stats
17870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17871         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17872                 skip "Need MDS version with at least 2.7.1"
17873         remote_mgs_nodsh && skip "remote MGS with nodsh"
17874         remote_mds_nodsh && skip "remote MDS with nodsh"
17875         remote_ost_nodsh && skip "remote OST with nodsh"
17876         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17877                 skip "Server doesn't support jobstats"
17878         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17879
17880         local old_jobenv=$($LCTL get_param -n jobid_var)
17881         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17882
17883         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17884                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17885         else
17886                 stack_trap "do_facet mgs $PERM_CMD \
17887                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17888         fi
17889         changelog_register
17890
17891         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17892                                 mdt.*.job_cleanup_interval | head -n 1)
17893         local new_interval=5
17894         do_facet $SINGLEMDS \
17895                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17896         stack_trap "do_facet $SINGLEMDS \
17897                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17898         local start=$SECONDS
17899
17900         local cmd
17901         # mkdir
17902         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17903         verify_jobstats "$cmd" "$SINGLEMDS"
17904         # rmdir
17905         cmd="rmdir $DIR/$tdir"
17906         verify_jobstats "$cmd" "$SINGLEMDS"
17907         # mkdir on secondary MDT
17908         if [ $MDSCOUNT -gt 1 ]; then
17909                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17910                 verify_jobstats "$cmd" "mds2"
17911         fi
17912         # mknod
17913         cmd="mknod $DIR/$tfile c 1 3"
17914         verify_jobstats "$cmd" "$SINGLEMDS"
17915         # unlink
17916         cmd="rm -f $DIR/$tfile"
17917         verify_jobstats "$cmd" "$SINGLEMDS"
17918         # create all files on OST0000 so verify_jobstats can find OST stats
17919         # open & close
17920         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17921         verify_jobstats "$cmd" "$SINGLEMDS"
17922         # setattr
17923         cmd="touch $DIR/$tfile"
17924         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17925         # write
17926         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
17927         verify_jobstats "$cmd" "ost1"
17928         # read
17929         cancel_lru_locks osc
17930         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
17931         verify_jobstats "$cmd" "ost1"
17932         # truncate
17933         cmd="$TRUNCATE $DIR/$tfile 0"
17934         verify_jobstats "$cmd" "$SINGLEMDS ost1"
17935         # rename
17936         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
17937         verify_jobstats "$cmd" "$SINGLEMDS"
17938         # jobstats expiry - sleep until old stats should be expired
17939         local left=$((new_interval + 5 - (SECONDS - start)))
17940         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
17941                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
17942                         "0" $left
17943         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
17944         verify_jobstats "$cmd" "$SINGLEMDS"
17945         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
17946             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
17947
17948         # Ensure that jobid are present in changelog (if supported by MDS)
17949         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
17950                 changelog_dump | tail -10
17951                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
17952                 [ $jobids -eq 9 ] ||
17953                         error "Wrong changelog jobid count $jobids != 9"
17954
17955                 # LU-5862
17956                 JOBENV="disable"
17957                 jobstats_set $JOBENV
17958                 touch $DIR/$tfile
17959                 changelog_dump | grep $tfile
17960                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
17961                 [ $jobids -eq 0 ] ||
17962                         error "Unexpected jobids when jobid_var=$JOBENV"
17963         fi
17964
17965         # test '%j' access to environment variable - if supported
17966         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
17967                 JOBENV="JOBCOMPLEX"
17968                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17969
17970                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17971         fi
17972
17973         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
17974                 JOBENV="JOBCOMPLEX"
17975                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
17976
17977                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17978         fi
17979
17980         # test '%j' access to per-session jobid - if supported
17981         if lctl list_param jobid_this_session > /dev/null 2>&1
17982         then
17983                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
17984                 lctl set_param jobid_this_session=$USER
17985
17986                 JOBENV="JOBCOMPLEX"
17987                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
17988
17989                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
17990         fi
17991 }
17992 run_test 205a "Verify job stats"
17993
17994 # LU-13117, LU-13597
17995 test_205b() {
17996         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
17997                 skip "Need MDS version at least 2.13.54.91"
17998
17999         job_stats="mdt.*.job_stats"
18000         $LCTL set_param $job_stats=clear
18001         # Setting jobid_var to USER might not be supported
18002         $LCTL set_param jobid_var=USER || true
18003         $LCTL set_param jobid_name="%e.%u"
18004         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18005         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18006                 grep "job_id:.*foolish" &&
18007                         error "Unexpected jobid found"
18008         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18009                 grep "open:.*min.*max.*sum" ||
18010                         error "wrong job_stats format found"
18011 }
18012 run_test 205b "Verify job stats jobid and output format"
18013
18014 # LU-13733
18015 test_205c() {
18016         $LCTL set_param llite.*.stats=0
18017         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18018         $LCTL get_param llite.*.stats
18019         $LCTL get_param llite.*.stats | grep \
18020                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18021                         error "wrong client stats format found"
18022 }
18023 run_test 205c "Verify client stats format"
18024
18025 # LU-1480, LU-1773 and LU-1657
18026 test_206() {
18027         mkdir -p $DIR/$tdir
18028         $LFS setstripe -c -1 $DIR/$tdir
18029 #define OBD_FAIL_LOV_INIT 0x1403
18030         $LCTL set_param fail_loc=0xa0001403
18031         $LCTL set_param fail_val=1
18032         touch $DIR/$tdir/$tfile || true
18033 }
18034 run_test 206 "fail lov_init_raid0() doesn't lbug"
18035
18036 test_207a() {
18037         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18038         local fsz=`stat -c %s $DIR/$tfile`
18039         cancel_lru_locks mdc
18040
18041         # do not return layout in getattr intent
18042 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18043         $LCTL set_param fail_loc=0x170
18044         local sz=`stat -c %s $DIR/$tfile`
18045
18046         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18047
18048         rm -rf $DIR/$tfile
18049 }
18050 run_test 207a "can refresh layout at glimpse"
18051
18052 test_207b() {
18053         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18054         local cksum=`md5sum $DIR/$tfile`
18055         local fsz=`stat -c %s $DIR/$tfile`
18056         cancel_lru_locks mdc
18057         cancel_lru_locks osc
18058
18059         # do not return layout in getattr intent
18060 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18061         $LCTL set_param fail_loc=0x171
18062
18063         # it will refresh layout after the file is opened but before read issues
18064         echo checksum is "$cksum"
18065         echo "$cksum" |md5sum -c --quiet || error "file differs"
18066
18067         rm -rf $DIR/$tfile
18068 }
18069 run_test 207b "can refresh layout at open"
18070
18071 test_208() {
18072         # FIXME: in this test suite, only RD lease is used. This is okay
18073         # for now as only exclusive open is supported. After generic lease
18074         # is done, this test suite should be revised. - Jinshan
18075
18076         remote_mds_nodsh && skip "remote MDS with nodsh"
18077         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18078                 skip "Need MDS version at least 2.4.52"
18079
18080         echo "==== test 1: verify get lease work"
18081         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18082
18083         echo "==== test 2: verify lease can be broken by upcoming open"
18084         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18085         local PID=$!
18086         sleep 1
18087
18088         $MULTIOP $DIR/$tfile oO_RDONLY:c
18089         kill -USR1 $PID && wait $PID || error "break lease error"
18090
18091         echo "==== test 3: verify lease can't be granted if an open already exists"
18092         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
18093         local PID=$!
18094         sleep 1
18095
18096         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
18097         kill -USR1 $PID && wait $PID || error "open file error"
18098
18099         echo "==== test 4: lease can sustain over recovery"
18100         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18101         PID=$!
18102         sleep 1
18103
18104         fail mds1
18105
18106         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18107
18108         echo "==== test 5: lease broken can't be regained by replay"
18109         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18110         PID=$!
18111         sleep 1
18112
18113         # open file to break lease and then recovery
18114         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18115         fail mds1
18116
18117         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18118
18119         rm -f $DIR/$tfile
18120 }
18121 run_test 208 "Exclusive open"
18122
18123 test_209() {
18124         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18125                 skip_env "must have disp_stripe"
18126
18127         touch $DIR/$tfile
18128         sync; sleep 5; sync;
18129
18130         echo 3 > /proc/sys/vm/drop_caches
18131         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18132                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18133         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18134
18135         # open/close 500 times
18136         for i in $(seq 500); do
18137                 cat $DIR/$tfile
18138         done
18139
18140         echo 3 > /proc/sys/vm/drop_caches
18141         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18142                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18143         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18144
18145         echo "before: $req_before, after: $req_after"
18146         [ $((req_after - req_before)) -ge 300 ] &&
18147                 error "open/close requests are not freed"
18148         return 0
18149 }
18150 run_test 209 "read-only open/close requests should be freed promptly"
18151
18152 test_210() {
18153         local pid
18154
18155         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18156         pid=$!
18157         sleep 1
18158
18159         $LFS getstripe $DIR/$tfile
18160         kill -USR1 $pid
18161         wait $pid || error "multiop failed"
18162
18163         $MULTIOP $DIR/$tfile oO_RDONLY:eR_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 run_test 210 "lfs getstripe does not break leases"
18172
18173 test_212() {
18174         size=`date +%s`
18175         size=$((size % 8192 + 1))
18176         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18177         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18178         rm -f $DIR/f212 $DIR/f212.xyz
18179 }
18180 run_test 212 "Sendfile test ============================================"
18181
18182 test_213() {
18183         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18184         cancel_lru_locks osc
18185         lctl set_param fail_loc=0x8000040f
18186         # generate a read lock
18187         cat $DIR/$tfile > /dev/null
18188         # write to the file, it will try to cancel the above read lock.
18189         cat /etc/hosts >> $DIR/$tfile
18190 }
18191 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18192
18193 test_214() { # for bug 20133
18194         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18195         for (( i=0; i < 340; i++ )) ; do
18196                 touch $DIR/$tdir/d214c/a$i
18197         done
18198
18199         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18200         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18201         ls $DIR/d214c || error "ls $DIR/d214c failed"
18202         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18203         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18204 }
18205 run_test 214 "hash-indexed directory test - bug 20133"
18206
18207 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18208 create_lnet_proc_files() {
18209         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18210 }
18211
18212 # counterpart of create_lnet_proc_files
18213 remove_lnet_proc_files() {
18214         rm -f $TMP/lnet_$1.sys
18215 }
18216
18217 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18218 # 3rd arg as regexp for body
18219 check_lnet_proc_stats() {
18220         local l=$(cat "$TMP/lnet_$1" |wc -l)
18221         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18222
18223         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18224 }
18225
18226 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18227 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18228 # optional and can be regexp for 2nd line (lnet.routes case)
18229 check_lnet_proc_entry() {
18230         local blp=2          # blp stands for 'position of 1st line of body'
18231         [ -z "$5" ] || blp=3 # lnet.routes case
18232
18233         local l=$(cat "$TMP/lnet_$1" |wc -l)
18234         # subtracting one from $blp because the body can be empty
18235         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18236
18237         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18238                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18239
18240         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18241                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18242
18243         # bail out if any unexpected line happened
18244         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18245         [ "$?" != 0 ] || error "$2 misformatted"
18246 }
18247
18248 test_215() { # for bugs 18102, 21079, 21517
18249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18250
18251         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18252         local P='[1-9][0-9]*'           # positive numeric
18253         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18254         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18255         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18256         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18257
18258         local L1 # regexp for 1st line
18259         local L2 # regexp for 2nd line (optional)
18260         local BR # regexp for the rest (body)
18261
18262         # lnet.stats should look as 11 space-separated non-negative numerics
18263         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18264         create_lnet_proc_files "stats"
18265         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18266         remove_lnet_proc_files "stats"
18267
18268         # lnet.routes should look like this:
18269         # Routing disabled/enabled
18270         # net hops priority state router
18271         # where net is a string like tcp0, hops > 0, priority >= 0,
18272         # state is up/down,
18273         # router is a string like 192.168.1.1@tcp2
18274         L1="^Routing (disabled|enabled)$"
18275         L2="^net +hops +priority +state +router$"
18276         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18277         create_lnet_proc_files "routes"
18278         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18279         remove_lnet_proc_files "routes"
18280
18281         # lnet.routers should look like this:
18282         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18283         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18284         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18285         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18286         L1="^ref +rtr_ref +alive +router$"
18287         BR="^$P +$P +(up|down) +$NID$"
18288         create_lnet_proc_files "routers"
18289         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18290         remove_lnet_proc_files "routers"
18291
18292         # lnet.peers should look like this:
18293         # nid refs state last max rtr min tx min queue
18294         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18295         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18296         # numeric (0 or >0 or <0), queue >= 0.
18297         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18298         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18299         create_lnet_proc_files "peers"
18300         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18301         remove_lnet_proc_files "peers"
18302
18303         # lnet.buffers  should look like this:
18304         # pages count credits min
18305         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18306         L1="^pages +count +credits +min$"
18307         BR="^ +$N +$N +$I +$I$"
18308         create_lnet_proc_files "buffers"
18309         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18310         remove_lnet_proc_files "buffers"
18311
18312         # lnet.nis should look like this:
18313         # nid status alive refs peer rtr max tx min
18314         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18315         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18316         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18317         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18318         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18319         create_lnet_proc_files "nis"
18320         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18321         remove_lnet_proc_files "nis"
18322
18323         # can we successfully write to lnet.stats?
18324         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18325 }
18326 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18327
18328 test_216() { # bug 20317
18329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18330         remote_ost_nodsh && skip "remote OST with nodsh"
18331
18332         local node
18333         local facets=$(get_facets OST)
18334         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18335
18336         save_lustre_params client "osc.*.contention_seconds" > $p
18337         save_lustre_params $facets \
18338                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18339         save_lustre_params $facets \
18340                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18341         save_lustre_params $facets \
18342                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18343         clear_stats osc.*.osc_stats
18344
18345         # agressive lockless i/o settings
18346         do_nodes $(comma_list $(osts_nodes)) \
18347                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18348                         ldlm.namespaces.filter-*.contended_locks=0 \
18349                         ldlm.namespaces.filter-*.contention_seconds=60"
18350         lctl set_param -n osc.*.contention_seconds=60
18351
18352         $DIRECTIO write $DIR/$tfile 0 10 4096
18353         $CHECKSTAT -s 40960 $DIR/$tfile
18354
18355         # disable lockless i/o
18356         do_nodes $(comma_list $(osts_nodes)) \
18357                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18358                         ldlm.namespaces.filter-*.contended_locks=32 \
18359                         ldlm.namespaces.filter-*.contention_seconds=0"
18360         lctl set_param -n osc.*.contention_seconds=0
18361         clear_stats osc.*.osc_stats
18362
18363         dd if=/dev/zero of=$DIR/$tfile count=0
18364         $CHECKSTAT -s 0 $DIR/$tfile
18365
18366         restore_lustre_params <$p
18367         rm -f $p
18368         rm $DIR/$tfile
18369 }
18370 run_test 216 "check lockless direct write updates file size and kms correctly"
18371
18372 test_217() { # bug 22430
18373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18374
18375         local node
18376         local nid
18377
18378         for node in $(nodes_list); do
18379                 nid=$(host_nids_address $node $NETTYPE)
18380                 if [[ $nid = *-* ]] ; then
18381                         echo "lctl ping $(h2nettype $nid)"
18382                         lctl ping $(h2nettype $nid)
18383                 else
18384                         echo "skipping $node (no hyphen detected)"
18385                 fi
18386         done
18387 }
18388 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18389
18390 test_218() {
18391        # do directio so as not to populate the page cache
18392        log "creating a 10 Mb file"
18393        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18394        log "starting reads"
18395        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18396        log "truncating the file"
18397        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18398        log "killing dd"
18399        kill %+ || true # reads might have finished
18400        echo "wait until dd is finished"
18401        wait
18402        log "removing the temporary file"
18403        rm -rf $DIR/$tfile || error "tmp file removal failed"
18404 }
18405 run_test 218 "parallel read and truncate should not deadlock"
18406
18407 test_219() {
18408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18409
18410         # write one partial page
18411         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18412         # set no grant so vvp_io_commit_write will do sync write
18413         $LCTL set_param fail_loc=0x411
18414         # write a full page at the end of file
18415         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18416
18417         $LCTL set_param fail_loc=0
18418         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18419         $LCTL set_param fail_loc=0x411
18420         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18421
18422         # LU-4201
18423         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18424         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18425 }
18426 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18427
18428 test_220() { #LU-325
18429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18430         remote_ost_nodsh && skip "remote OST with nodsh"
18431         remote_mds_nodsh && skip "remote MDS with nodsh"
18432         remote_mgs_nodsh && skip "remote MGS with nodsh"
18433
18434         local OSTIDX=0
18435
18436         # create on MDT0000 so the last_id and next_id are correct
18437         mkdir_on_mdt0 $DIR/$tdir
18438         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18439         OST=${OST%_UUID}
18440
18441         # on the mdt's osc
18442         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18443         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18444                         osp.$mdtosc_proc1.prealloc_last_id)
18445         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18446                         osp.$mdtosc_proc1.prealloc_next_id)
18447
18448         $LFS df -i
18449
18450         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18451         #define OBD_FAIL_OST_ENOINO              0x229
18452         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18453         create_pool $FSNAME.$TESTNAME || return 1
18454         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18455
18456         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18457
18458         MDSOBJS=$((last_id - next_id))
18459         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18460
18461         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18462         echo "OST still has $count kbytes free"
18463
18464         echo "create $MDSOBJS files @next_id..."
18465         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18466
18467         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18468                         osp.$mdtosc_proc1.prealloc_last_id)
18469         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18470                         osp.$mdtosc_proc1.prealloc_next_id)
18471
18472         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18473         $LFS df -i
18474
18475         echo "cleanup..."
18476
18477         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18478         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18479
18480         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18481                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18482         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18483                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18484         echo "unlink $MDSOBJS files @$next_id..."
18485         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18486 }
18487 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18488
18489 test_221() {
18490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18491
18492         dd if=`which date` of=$MOUNT/date oflag=sync
18493         chmod +x $MOUNT/date
18494
18495         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18496         $LCTL set_param fail_loc=0x80001401
18497
18498         $MOUNT/date > /dev/null
18499         rm -f $MOUNT/date
18500 }
18501 run_test 221 "make sure fault and truncate race to not cause OOM"
18502
18503 test_222a () {
18504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18505
18506         rm -rf $DIR/$tdir
18507         test_mkdir $DIR/$tdir
18508         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18509         createmany -o $DIR/$tdir/$tfile 10
18510         cancel_lru_locks mdc
18511         cancel_lru_locks osc
18512         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18513         $LCTL set_param fail_loc=0x31a
18514         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18515         $LCTL set_param fail_loc=0
18516         rm -r $DIR/$tdir
18517 }
18518 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18519
18520 test_222b () {
18521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18522
18523         rm -rf $DIR/$tdir
18524         test_mkdir $DIR/$tdir
18525         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18526         createmany -o $DIR/$tdir/$tfile 10
18527         cancel_lru_locks mdc
18528         cancel_lru_locks osc
18529         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18530         $LCTL set_param fail_loc=0x31a
18531         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18532         $LCTL set_param fail_loc=0
18533 }
18534 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18535
18536 test_223 () {
18537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18538
18539         rm -rf $DIR/$tdir
18540         test_mkdir $DIR/$tdir
18541         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18542         createmany -o $DIR/$tdir/$tfile 10
18543         cancel_lru_locks mdc
18544         cancel_lru_locks osc
18545         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18546         $LCTL set_param fail_loc=0x31b
18547         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18548         $LCTL set_param fail_loc=0
18549         rm -r $DIR/$tdir
18550 }
18551 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18552
18553 test_224a() { # LU-1039, MRP-303
18554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18555
18556         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18557         $LCTL set_param fail_loc=0x508
18558         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18559         $LCTL set_param fail_loc=0
18560         df $DIR
18561 }
18562 run_test 224a "Don't panic on bulk IO failure"
18563
18564 test_224b() { # LU-1039, MRP-303
18565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18566
18567         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18568         cancel_lru_locks osc
18569         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18570         $LCTL set_param fail_loc=0x515
18571         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18572         $LCTL set_param fail_loc=0
18573         df $DIR
18574 }
18575 run_test 224b "Don't panic on bulk IO failure"
18576
18577 test_224c() { # LU-6441
18578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18579         remote_mds_nodsh && skip "remote MDS with nodsh"
18580
18581         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18582         save_writethrough $p
18583         set_cache writethrough on
18584
18585         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18586         local at_max=$($LCTL get_param -n at_max)
18587         local timeout=$($LCTL get_param -n timeout)
18588         local test_at="at_max"
18589         local param_at="$FSNAME.sys.at_max"
18590         local test_timeout="timeout"
18591         local param_timeout="$FSNAME.sys.timeout"
18592
18593         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18594
18595         set_persistent_param_and_check client "$test_at" "$param_at" 0
18596         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18597
18598         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18599         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18600         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18601         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18602         sync
18603         do_facet ost1 "$LCTL set_param fail_loc=0"
18604
18605         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18606         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18607                 $timeout
18608
18609         $LCTL set_param -n $pages_per_rpc
18610         restore_lustre_params < $p
18611         rm -f $p
18612 }
18613 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18614
18615 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18616 test_225a () {
18617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18618         if [ -z ${MDSSURVEY} ]; then
18619                 skip_env "mds-survey not found"
18620         fi
18621         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18622                 skip "Need MDS version at least 2.2.51"
18623
18624         local mds=$(facet_host $SINGLEMDS)
18625         local target=$(do_nodes $mds 'lctl dl' |
18626                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18627
18628         local cmd1="file_count=1000 thrhi=4"
18629         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18630         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18631         local cmd="$cmd1 $cmd2 $cmd3"
18632
18633         rm -f ${TMP}/mds_survey*
18634         echo + $cmd
18635         eval $cmd || error "mds-survey with zero-stripe failed"
18636         cat ${TMP}/mds_survey*
18637         rm -f ${TMP}/mds_survey*
18638 }
18639 run_test 225a "Metadata survey sanity with zero-stripe"
18640
18641 test_225b () {
18642         if [ -z ${MDSSURVEY} ]; then
18643                 skip_env "mds-survey not found"
18644         fi
18645         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18646                 skip "Need MDS version at least 2.2.51"
18647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18648         remote_mds_nodsh && skip "remote MDS with nodsh"
18649         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18650                 skip_env "Need to mount OST to test"
18651         fi
18652
18653         local mds=$(facet_host $SINGLEMDS)
18654         local target=$(do_nodes $mds 'lctl dl' |
18655                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18656
18657         local cmd1="file_count=1000 thrhi=4"
18658         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18659         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18660         local cmd="$cmd1 $cmd2 $cmd3"
18661
18662         rm -f ${TMP}/mds_survey*
18663         echo + $cmd
18664         eval $cmd || error "mds-survey with stripe_count failed"
18665         cat ${TMP}/mds_survey*
18666         rm -f ${TMP}/mds_survey*
18667 }
18668 run_test 225b "Metadata survey sanity with stripe_count = 1"
18669
18670 mcreate_path2fid () {
18671         local mode=$1
18672         local major=$2
18673         local minor=$3
18674         local name=$4
18675         local desc=$5
18676         local path=$DIR/$tdir/$name
18677         local fid
18678         local rc
18679         local fid_path
18680
18681         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18682                 error "cannot create $desc"
18683
18684         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18685         rc=$?
18686         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18687
18688         fid_path=$($LFS fid2path $MOUNT $fid)
18689         rc=$?
18690         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18691
18692         [ "$path" == "$fid_path" ] ||
18693                 error "fid2path returned $fid_path, expected $path"
18694
18695         echo "pass with $path and $fid"
18696 }
18697
18698 test_226a () {
18699         rm -rf $DIR/$tdir
18700         mkdir -p $DIR/$tdir
18701
18702         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18703         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18704         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18705         mcreate_path2fid 0040666 0 0 dir "directory"
18706         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18707         mcreate_path2fid 0100666 0 0 file "regular file"
18708         mcreate_path2fid 0120666 0 0 link "symbolic link"
18709         mcreate_path2fid 0140666 0 0 sock "socket"
18710 }
18711 run_test 226a "call path2fid and fid2path on files of all type"
18712
18713 test_226b () {
18714         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18715
18716         local MDTIDX=1
18717
18718         rm -rf $DIR/$tdir
18719         mkdir -p $DIR/$tdir
18720         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18721                 error "create remote directory failed"
18722         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18723         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18724                                 "character special file (null)"
18725         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18726                                 "character special file (no device)"
18727         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18728         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18729                                 "block special file (loop)"
18730         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18731         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18732         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18733 }
18734 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18735
18736 test_226c () {
18737         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18738         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18739                 skip "Need MDS version at least 2.13.55"
18740
18741         local submnt=/mnt/submnt
18742         local srcfile=/etc/passwd
18743         local dstfile=$submnt/passwd
18744         local path
18745         local fid
18746
18747         rm -rf $DIR/$tdir
18748         rm -rf $submnt
18749         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18750                 error "create remote directory failed"
18751         mkdir -p $submnt || error "create $submnt failed"
18752         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18753                 error "mount $submnt failed"
18754         stack_trap "umount $submnt" EXIT
18755
18756         cp $srcfile $dstfile
18757         fid=$($LFS path2fid $dstfile)
18758         path=$($LFS fid2path $submnt "$fid")
18759         [ "$path" = "$dstfile" ] ||
18760                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18761 }
18762 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18763
18764 # LU-1299 Executing or running ldd on a truncated executable does not
18765 # cause an out-of-memory condition.
18766 test_227() {
18767         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18768         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18769
18770         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18771         chmod +x $MOUNT/date
18772
18773         $MOUNT/date > /dev/null
18774         ldd $MOUNT/date > /dev/null
18775         rm -f $MOUNT/date
18776 }
18777 run_test 227 "running truncated executable does not cause OOM"
18778
18779 # LU-1512 try to reuse idle OI blocks
18780 test_228a() {
18781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18782         remote_mds_nodsh && skip "remote MDS with nodsh"
18783         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18784
18785         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18786         local myDIR=$DIR/$tdir
18787
18788         mkdir -p $myDIR
18789         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18790         $LCTL set_param fail_loc=0x80001002
18791         createmany -o $myDIR/t- 10000
18792         $LCTL set_param fail_loc=0
18793         # The guard is current the largest FID holder
18794         touch $myDIR/guard
18795         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18796                     tr -d '[')
18797         local IDX=$(($SEQ % 64))
18798
18799         do_facet $SINGLEMDS sync
18800         # Make sure journal flushed.
18801         sleep 6
18802         local blk1=$(do_facet $SINGLEMDS \
18803                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18804                      grep Blockcount | awk '{print $4}')
18805
18806         # Remove old files, some OI blocks will become idle.
18807         unlinkmany $myDIR/t- 10000
18808         # Create new files, idle OI blocks should be reused.
18809         createmany -o $myDIR/t- 2000
18810         do_facet $SINGLEMDS sync
18811         # Make sure journal flushed.
18812         sleep 6
18813         local blk2=$(do_facet $SINGLEMDS \
18814                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18815                      grep Blockcount | awk '{print $4}')
18816
18817         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18818 }
18819 run_test 228a "try to reuse idle OI blocks"
18820
18821 test_228b() {
18822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18823         remote_mds_nodsh && skip "remote MDS with nodsh"
18824         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18825
18826         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18827         local myDIR=$DIR/$tdir
18828
18829         mkdir -p $myDIR
18830         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18831         $LCTL set_param fail_loc=0x80001002
18832         createmany -o $myDIR/t- 10000
18833         $LCTL set_param fail_loc=0
18834         # The guard is current the largest FID holder
18835         touch $myDIR/guard
18836         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18837                     tr -d '[')
18838         local IDX=$(($SEQ % 64))
18839
18840         do_facet $SINGLEMDS sync
18841         # Make sure journal flushed.
18842         sleep 6
18843         local blk1=$(do_facet $SINGLEMDS \
18844                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18845                      grep Blockcount | awk '{print $4}')
18846
18847         # Remove old files, some OI blocks will become idle.
18848         unlinkmany $myDIR/t- 10000
18849
18850         # stop the MDT
18851         stop $SINGLEMDS || error "Fail to stop MDT."
18852         # remount the MDT
18853         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18854
18855         df $MOUNT || error "Fail to df."
18856         # Create new files, idle OI blocks should be reused.
18857         createmany -o $myDIR/t- 2000
18858         do_facet $SINGLEMDS sync
18859         # Make sure journal flushed.
18860         sleep 6
18861         local blk2=$(do_facet $SINGLEMDS \
18862                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18863                      grep Blockcount | awk '{print $4}')
18864
18865         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18866 }
18867 run_test 228b "idle OI blocks can be reused after MDT restart"
18868
18869 #LU-1881
18870 test_228c() {
18871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18872         remote_mds_nodsh && skip "remote MDS with nodsh"
18873         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18874
18875         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18876         local myDIR=$DIR/$tdir
18877
18878         mkdir -p $myDIR
18879         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18880         $LCTL set_param fail_loc=0x80001002
18881         # 20000 files can guarantee there are index nodes in the OI file
18882         createmany -o $myDIR/t- 20000
18883         $LCTL set_param fail_loc=0
18884         # The guard is current the largest FID holder
18885         touch $myDIR/guard
18886         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18887                     tr -d '[')
18888         local IDX=$(($SEQ % 64))
18889
18890         do_facet $SINGLEMDS sync
18891         # Make sure journal flushed.
18892         sleep 6
18893         local blk1=$(do_facet $SINGLEMDS \
18894                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18895                      grep Blockcount | awk '{print $4}')
18896
18897         # Remove old files, some OI blocks will become idle.
18898         unlinkmany $myDIR/t- 20000
18899         rm -f $myDIR/guard
18900         # The OI file should become empty now
18901
18902         # Create new files, idle OI blocks should be reused.
18903         createmany -o $myDIR/t- 2000
18904         do_facet $SINGLEMDS sync
18905         # Make sure journal flushed.
18906         sleep 6
18907         local blk2=$(do_facet $SINGLEMDS \
18908                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18909                      grep Blockcount | awk '{print $4}')
18910
18911         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18912 }
18913 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18914
18915 test_229() { # LU-2482, LU-3448
18916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18917         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18918         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18919                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18920
18921         rm -f $DIR/$tfile
18922
18923         # Create a file with a released layout and stripe count 2.
18924         $MULTIOP $DIR/$tfile H2c ||
18925                 error "failed to create file with released layout"
18926
18927         $LFS getstripe -v $DIR/$tfile
18928
18929         local pattern=$($LFS getstripe -L $DIR/$tfile)
18930         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
18931
18932         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
18933                 error "getstripe"
18934         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
18935         stat $DIR/$tfile || error "failed to stat released file"
18936
18937         chown $RUNAS_ID $DIR/$tfile ||
18938                 error "chown $RUNAS_ID $DIR/$tfile failed"
18939
18940         chgrp $RUNAS_ID $DIR/$tfile ||
18941                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
18942
18943         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
18944         rm $DIR/$tfile || error "failed to remove released file"
18945 }
18946 run_test 229 "getstripe/stat/rm/attr changes work on released files"
18947
18948 test_230a() {
18949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18951         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18952                 skip "Need MDS version at least 2.11.52"
18953
18954         local MDTIDX=1
18955
18956         test_mkdir $DIR/$tdir
18957         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
18958         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
18959         [ $mdt_idx -ne 0 ] &&
18960                 error "create local directory on wrong MDT $mdt_idx"
18961
18962         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
18963                         error "create remote directory failed"
18964         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
18965         [ $mdt_idx -ne $MDTIDX ] &&
18966                 error "create remote directory on wrong MDT $mdt_idx"
18967
18968         createmany -o $DIR/$tdir/test_230/t- 10 ||
18969                 error "create files on remote directory failed"
18970         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
18971         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
18972         rm -r $DIR/$tdir || error "unlink remote directory failed"
18973 }
18974 run_test 230a "Create remote directory and files under the remote directory"
18975
18976 test_230b() {
18977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18978         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18979         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18980                 skip "Need MDS version at least 2.11.52"
18981
18982         local MDTIDX=1
18983         local mdt_index
18984         local i
18985         local file
18986         local pid
18987         local stripe_count
18988         local migrate_dir=$DIR/$tdir/migrate_dir
18989         local other_dir=$DIR/$tdir/other_dir
18990
18991         test_mkdir $DIR/$tdir
18992         test_mkdir -i0 -c1 $migrate_dir
18993         test_mkdir -i0 -c1 $other_dir
18994         for ((i=0; i<10; i++)); do
18995                 mkdir -p $migrate_dir/dir_${i}
18996                 createmany -o $migrate_dir/dir_${i}/f 10 ||
18997                         error "create files under remote dir failed $i"
18998         done
18999
19000         cp /etc/passwd $migrate_dir/$tfile
19001         cp /etc/passwd $other_dir/$tfile
19002         chattr +SAD $migrate_dir
19003         chattr +SAD $migrate_dir/$tfile
19004
19005         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19006         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19007         local old_dir_mode=$(stat -c%f $migrate_dir)
19008         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19009
19010         mkdir -p $migrate_dir/dir_default_stripe2
19011         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19012         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19013
19014         mkdir -p $other_dir
19015         ln $migrate_dir/$tfile $other_dir/luna
19016         ln $migrate_dir/$tfile $migrate_dir/sofia
19017         ln $other_dir/$tfile $migrate_dir/david
19018         ln -s $migrate_dir/$tfile $other_dir/zachary
19019         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19020         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19021
19022         local len
19023         local lnktgt
19024
19025         # inline symlink
19026         for len in 58 59 60; do
19027                 lnktgt=$(str_repeat 'l' $len)
19028                 touch $migrate_dir/$lnktgt
19029                 ln -s $lnktgt $migrate_dir/${len}char_ln
19030         done
19031
19032         # PATH_MAX
19033         for len in 4094 4095; do
19034                 lnktgt=$(str_repeat 'l' $len)
19035                 ln -s $lnktgt $migrate_dir/${len}char_ln
19036         done
19037
19038         # NAME_MAX
19039         for len in 254 255; do
19040                 touch $migrate_dir/$(str_repeat 'l' $len)
19041         done
19042
19043         $LFS migrate -m $MDTIDX $migrate_dir ||
19044                 error "fails on migrating remote dir to MDT1"
19045
19046         echo "migratate to MDT1, then checking.."
19047         for ((i = 0; i < 10; i++)); do
19048                 for file in $(find $migrate_dir/dir_${i}); do
19049                         mdt_index=$($LFS getstripe -m $file)
19050                         # broken symlink getstripe will fail
19051                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19052                                 error "$file is not on MDT${MDTIDX}"
19053                 done
19054         done
19055
19056         # the multiple link file should still in MDT0
19057         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19058         [ $mdt_index == 0 ] ||
19059                 error "$file is not on MDT${MDTIDX}"
19060
19061         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19062         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19063                 error " expect $old_dir_flag get $new_dir_flag"
19064
19065         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19066         [ "$old_file_flag" = "$new_file_flag" ] ||
19067                 error " expect $old_file_flag get $new_file_flag"
19068
19069         local new_dir_mode=$(stat -c%f $migrate_dir)
19070         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19071                 error "expect mode $old_dir_mode get $new_dir_mode"
19072
19073         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19074         [ "$old_file_mode" = "$new_file_mode" ] ||
19075                 error "expect mode $old_file_mode get $new_file_mode"
19076
19077         diff /etc/passwd $migrate_dir/$tfile ||
19078                 error "$tfile different after migration"
19079
19080         diff /etc/passwd $other_dir/luna ||
19081                 error "luna different after migration"
19082
19083         diff /etc/passwd $migrate_dir/sofia ||
19084                 error "sofia different after migration"
19085
19086         diff /etc/passwd $migrate_dir/david ||
19087                 error "david different after migration"
19088
19089         diff /etc/passwd $other_dir/zachary ||
19090                 error "zachary different after migration"
19091
19092         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19093                 error "${tfile}_ln different after migration"
19094
19095         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19096                 error "${tfile}_ln_other different after migration"
19097
19098         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19099         [ $stripe_count = 2 ] ||
19100                 error "dir strpe_count $d != 2 after migration."
19101
19102         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19103         [ $stripe_count = 2 ] ||
19104                 error "file strpe_count $d != 2 after migration."
19105
19106         #migrate back to MDT0
19107         MDTIDX=0
19108
19109         $LFS migrate -m $MDTIDX $migrate_dir ||
19110                 error "fails on migrating remote dir to MDT0"
19111
19112         echo "migrate back to MDT0, checking.."
19113         for file in $(find $migrate_dir); do
19114                 mdt_index=$($LFS getstripe -m $file)
19115                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19116                         error "$file is not on MDT${MDTIDX}"
19117         done
19118
19119         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19120         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19121                 error " expect $old_dir_flag get $new_dir_flag"
19122
19123         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19124         [ "$old_file_flag" = "$new_file_flag" ] ||
19125                 error " expect $old_file_flag get $new_file_flag"
19126
19127         local new_dir_mode=$(stat -c%f $migrate_dir)
19128         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19129                 error "expect mode $old_dir_mode get $new_dir_mode"
19130
19131         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19132         [ "$old_file_mode" = "$new_file_mode" ] ||
19133                 error "expect mode $old_file_mode get $new_file_mode"
19134
19135         diff /etc/passwd ${migrate_dir}/$tfile ||
19136                 error "$tfile different after migration"
19137
19138         diff /etc/passwd ${other_dir}/luna ||
19139                 error "luna different after migration"
19140
19141         diff /etc/passwd ${migrate_dir}/sofia ||
19142                 error "sofia different after migration"
19143
19144         diff /etc/passwd ${other_dir}/zachary ||
19145                 error "zachary different after migration"
19146
19147         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19148                 error "${tfile}_ln different after migration"
19149
19150         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19151                 error "${tfile}_ln_other different after migration"
19152
19153         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19154         [ $stripe_count = 2 ] ||
19155                 error "dir strpe_count $d != 2 after migration."
19156
19157         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19158         [ $stripe_count = 2 ] ||
19159                 error "file strpe_count $d != 2 after migration."
19160
19161         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19162 }
19163 run_test 230b "migrate directory"
19164
19165 test_230c() {
19166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19168         remote_mds_nodsh && skip "remote MDS with nodsh"
19169         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19170                 skip "Need MDS version at least 2.11.52"
19171
19172         local MDTIDX=1
19173         local total=3
19174         local mdt_index
19175         local file
19176         local migrate_dir=$DIR/$tdir/migrate_dir
19177
19178         #If migrating directory fails in the middle, all entries of
19179         #the directory is still accessiable.
19180         test_mkdir $DIR/$tdir
19181         test_mkdir -i0 -c1 $migrate_dir
19182         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19183         stat $migrate_dir
19184         createmany -o $migrate_dir/f $total ||
19185                 error "create files under ${migrate_dir} failed"
19186
19187         # fail after migrating top dir, and this will fail only once, so the
19188         # first sub file migration will fail (currently f3), others succeed.
19189         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19190         do_facet mds1 lctl set_param fail_loc=0x1801
19191         local t=$(ls $migrate_dir | wc -l)
19192         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19193                 error "migrate should fail"
19194         local u=$(ls $migrate_dir | wc -l)
19195         [ "$u" == "$t" ] || error "$u != $t during migration"
19196
19197         # add new dir/file should succeed
19198         mkdir $migrate_dir/dir ||
19199                 error "mkdir failed under migrating directory"
19200         touch $migrate_dir/file ||
19201                 error "create file failed under migrating directory"
19202
19203         # add file with existing name should fail
19204         for file in $migrate_dir/f*; do
19205                 stat $file > /dev/null || error "stat $file failed"
19206                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19207                         error "open(O_CREAT|O_EXCL) $file should fail"
19208                 $MULTIOP $file m && error "create $file should fail"
19209                 touch $DIR/$tdir/remote_dir/$tfile ||
19210                         error "touch $tfile failed"
19211                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19212                         error "link $file should fail"
19213                 mdt_index=$($LFS getstripe -m $file)
19214                 if [ $mdt_index == 0 ]; then
19215                         # file failed to migrate is not allowed to rename to
19216                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19217                                 error "rename to $file should fail"
19218                 else
19219                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19220                                 error "rename to $file failed"
19221                 fi
19222                 echo hello >> $file || error "write $file failed"
19223         done
19224
19225         # resume migration with different options should fail
19226         $LFS migrate -m 0 $migrate_dir &&
19227                 error "migrate -m 0 $migrate_dir should fail"
19228
19229         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19230                 error "migrate -c 2 $migrate_dir should fail"
19231
19232         # resume migration should succeed
19233         $LFS migrate -m $MDTIDX $migrate_dir ||
19234                 error "migrate $migrate_dir failed"
19235
19236         echo "Finish migration, then checking.."
19237         for file in $(find $migrate_dir); do
19238                 mdt_index=$($LFS getstripe -m $file)
19239                 [ $mdt_index == $MDTIDX ] ||
19240                         error "$file is not on MDT${MDTIDX}"
19241         done
19242
19243         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19244 }
19245 run_test 230c "check directory accessiblity if migration failed"
19246
19247 test_230d() {
19248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19250         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19251                 skip "Need MDS version at least 2.11.52"
19252         # LU-11235
19253         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19254
19255         local migrate_dir=$DIR/$tdir/migrate_dir
19256         local old_index
19257         local new_index
19258         local old_count
19259         local new_count
19260         local new_hash
19261         local mdt_index
19262         local i
19263         local j
19264
19265         old_index=$((RANDOM % MDSCOUNT))
19266         old_count=$((MDSCOUNT - old_index))
19267         new_index=$((RANDOM % MDSCOUNT))
19268         new_count=$((MDSCOUNT - new_index))
19269         new_hash=1 # for all_char
19270
19271         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19272         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19273
19274         test_mkdir $DIR/$tdir
19275         test_mkdir -i $old_index -c $old_count $migrate_dir
19276
19277         for ((i=0; i<100; i++)); do
19278                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19279                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19280                         error "create files under remote dir failed $i"
19281         done
19282
19283         echo -n "Migrate from MDT$old_index "
19284         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19285         echo -n "to MDT$new_index"
19286         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19287         echo
19288
19289         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19290         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19291                 error "migrate remote dir error"
19292
19293         echo "Finish migration, then checking.."
19294         for file in $(find $migrate_dir); do
19295                 mdt_index=$($LFS getstripe -m $file)
19296                 if [ $mdt_index -lt $new_index ] ||
19297                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19298                         error "$file is on MDT$mdt_index"
19299                 fi
19300         done
19301
19302         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19303 }
19304 run_test 230d "check migrate big directory"
19305
19306 test_230e() {
19307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19308         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19309         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19310                 skip "Need MDS version at least 2.11.52"
19311
19312         local i
19313         local j
19314         local a_fid
19315         local b_fid
19316
19317         mkdir_on_mdt0 $DIR/$tdir
19318         mkdir $DIR/$tdir/migrate_dir
19319         mkdir $DIR/$tdir/other_dir
19320         touch $DIR/$tdir/migrate_dir/a
19321         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19322         ls $DIR/$tdir/other_dir
19323
19324         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19325                 error "migrate dir fails"
19326
19327         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19328         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19329
19330         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19331         [ $mdt_index == 0 ] || error "a is not on MDT0"
19332
19333         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19334                 error "migrate dir fails"
19335
19336         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19337         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19338
19339         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19340         [ $mdt_index == 1 ] || error "a is not on MDT1"
19341
19342         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19343         [ $mdt_index == 1 ] || error "b is not on MDT1"
19344
19345         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19346         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19347
19348         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19349
19350         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19351 }
19352 run_test 230e "migrate mulitple local link files"
19353
19354 test_230f() {
19355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19357         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19358                 skip "Need MDS version at least 2.11.52"
19359
19360         local a_fid
19361         local ln_fid
19362
19363         mkdir -p $DIR/$tdir
19364         mkdir $DIR/$tdir/migrate_dir
19365         $LFS mkdir -i1 $DIR/$tdir/other_dir
19366         touch $DIR/$tdir/migrate_dir/a
19367         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19368         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19369         ls $DIR/$tdir/other_dir
19370
19371         # a should be migrated to MDT1, since no other links on MDT0
19372         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19373                 error "#1 migrate dir fails"
19374         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19375         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19376         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19377         [ $mdt_index == 1 ] || error "a is not on MDT1"
19378
19379         # a should stay on MDT1, because it is a mulitple link file
19380         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19381                 error "#2 migrate dir fails"
19382         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19383         [ $mdt_index == 1 ] || error "a is not on MDT1"
19384
19385         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19386                 error "#3 migrate dir fails"
19387
19388         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19389         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19390         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19391
19392         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19393         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19394
19395         # a should be migrated to MDT0, since no other links on MDT1
19396         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19397                 error "#4 migrate dir fails"
19398         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19399         [ $mdt_index == 0 ] || error "a is not on MDT0"
19400
19401         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19402 }
19403 run_test 230f "migrate mulitple remote link files"
19404
19405 test_230g() {
19406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19408         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19409                 skip "Need MDS version at least 2.11.52"
19410
19411         mkdir -p $DIR/$tdir/migrate_dir
19412
19413         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19414                 error "migrating dir to non-exist MDT succeeds"
19415         true
19416 }
19417 run_test 230g "migrate dir to non-exist MDT"
19418
19419 test_230h() {
19420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19422         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19423                 skip "Need MDS version at least 2.11.52"
19424
19425         local mdt_index
19426
19427         mkdir -p $DIR/$tdir/migrate_dir
19428
19429         $LFS migrate -m1 $DIR &&
19430                 error "migrating mountpoint1 should fail"
19431
19432         $LFS migrate -m1 $DIR/$tdir/.. &&
19433                 error "migrating mountpoint2 should fail"
19434
19435         # same as mv
19436         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19437                 error "migrating $tdir/migrate_dir/.. should fail"
19438
19439         true
19440 }
19441 run_test 230h "migrate .. and root"
19442
19443 test_230i() {
19444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19446         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19447                 skip "Need MDS version at least 2.11.52"
19448
19449         mkdir -p $DIR/$tdir/migrate_dir
19450
19451         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19452                 error "migration fails with a tailing slash"
19453
19454         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19455                 error "migration fails with two tailing slashes"
19456 }
19457 run_test 230i "lfs migrate -m tolerates trailing slashes"
19458
19459 test_230j() {
19460         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19461         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19462                 skip "Need MDS version at least 2.11.52"
19463
19464         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19465         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19466                 error "create $tfile failed"
19467         cat /etc/passwd > $DIR/$tdir/$tfile
19468
19469         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19470
19471         cmp /etc/passwd $DIR/$tdir/$tfile ||
19472                 error "DoM file mismatch after migration"
19473 }
19474 run_test 230j "DoM file data not changed after dir migration"
19475
19476 test_230k() {
19477         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19478         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19479                 skip "Need MDS version at least 2.11.56"
19480
19481         local total=20
19482         local files_on_starting_mdt=0
19483
19484         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19485         $LFS getdirstripe $DIR/$tdir
19486         for i in $(seq $total); do
19487                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19488                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19489                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19490         done
19491
19492         echo "$files_on_starting_mdt files on MDT0"
19493
19494         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19495         $LFS getdirstripe $DIR/$tdir
19496
19497         files_on_starting_mdt=0
19498         for i in $(seq $total); do
19499                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19500                         error "file $tfile.$i mismatch after migration"
19501                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19502                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19503         done
19504
19505         echo "$files_on_starting_mdt files on MDT1 after migration"
19506         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19507
19508         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19509         $LFS getdirstripe $DIR/$tdir
19510
19511         files_on_starting_mdt=0
19512         for i in $(seq $total); do
19513                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19514                         error "file $tfile.$i mismatch after 2nd migration"
19515                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19516                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19517         done
19518
19519         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19520         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19521
19522         true
19523 }
19524 run_test 230k "file data not changed after dir migration"
19525
19526 test_230l() {
19527         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19528         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19529                 skip "Need MDS version at least 2.11.56"
19530
19531         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19532         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19533                 error "create files under remote dir failed $i"
19534         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19535 }
19536 run_test 230l "readdir between MDTs won't crash"
19537
19538 test_230m() {
19539         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19540         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19541                 skip "Need MDS version at least 2.11.56"
19542
19543         local MDTIDX=1
19544         local mig_dir=$DIR/$tdir/migrate_dir
19545         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19546         local shortstr="b"
19547         local val
19548
19549         echo "Creating files and dirs with xattrs"
19550         test_mkdir $DIR/$tdir
19551         test_mkdir -i0 -c1 $mig_dir
19552         mkdir $mig_dir/dir
19553         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19554                 error "cannot set xattr attr1 on dir"
19555         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19556                 error "cannot set xattr attr2 on dir"
19557         touch $mig_dir/dir/f0
19558         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19559                 error "cannot set xattr attr1 on file"
19560         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19561                 error "cannot set xattr attr2 on file"
19562         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19563         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19564         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19565         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19566         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19567         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19568         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19569         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19570         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19571
19572         echo "Migrating to MDT1"
19573         $LFS migrate -m $MDTIDX $mig_dir ||
19574                 error "fails on migrating dir to MDT1"
19575
19576         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19577         echo "Checking xattrs"
19578         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19579         [ "$val" = $longstr ] ||
19580                 error "expecting xattr1 $longstr on dir, found $val"
19581         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19582         [ "$val" = $shortstr ] ||
19583                 error "expecting xattr2 $shortstr on dir, found $val"
19584         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19585         [ "$val" = $longstr ] ||
19586                 error "expecting xattr1 $longstr on file, found $val"
19587         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19588         [ "$val" = $shortstr ] ||
19589                 error "expecting xattr2 $shortstr on file, found $val"
19590 }
19591 run_test 230m "xattrs not changed after dir migration"
19592
19593 test_230n() {
19594         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19595         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19596                 skip "Need MDS version at least 2.13.53"
19597
19598         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19599         cat /etc/hosts > $DIR/$tdir/$tfile
19600         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19601         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19602
19603         cmp /etc/hosts $DIR/$tdir/$tfile ||
19604                 error "File data mismatch after migration"
19605 }
19606 run_test 230n "Dir migration with mirrored file"
19607
19608 test_230o() {
19609         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19610         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19611                 skip "Need MDS version at least 2.13.52"
19612
19613         local mdts=$(comma_list $(mdts_nodes))
19614         local timeout=100
19615         local restripe_status
19616         local delta
19617         local i
19618
19619         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19620
19621         # in case "crush" hash type is not set
19622         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19623
19624         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19625                            mdt.*MDT0000.enable_dir_restripe)
19626         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19627         stack_trap "do_nodes $mdts $LCTL set_param \
19628                     mdt.*.enable_dir_restripe=$restripe_status"
19629
19630         mkdir $DIR/$tdir
19631         createmany -m $DIR/$tdir/f 100 ||
19632                 error "create files under remote dir failed $i"
19633         createmany -d $DIR/$tdir/d 100 ||
19634                 error "create dirs under remote dir failed $i"
19635
19636         for i in $(seq 2 $MDSCOUNT); do
19637                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19638                 $LFS setdirstripe -c $i $DIR/$tdir ||
19639                         error "split -c $i $tdir failed"
19640                 wait_update $HOSTNAME \
19641                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19642                         error "dir split not finished"
19643                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19644                         awk '/migrate/ {sum += $2} END { print sum }')
19645                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19646                 # delta is around total_files/stripe_count
19647                 (( $delta < 200 / (i - 1) + 4 )) ||
19648                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19649         done
19650 }
19651 run_test 230o "dir split"
19652
19653 test_230p() {
19654         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19655         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19656                 skip "Need MDS version at least 2.13.52"
19657
19658         local mdts=$(comma_list $(mdts_nodes))
19659         local timeout=100
19660         local restripe_status
19661         local delta
19662         local c
19663
19664         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19665
19666         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19667
19668         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19669                            mdt.*MDT0000.enable_dir_restripe)
19670         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19671         stack_trap "do_nodes $mdts $LCTL set_param \
19672                     mdt.*.enable_dir_restripe=$restripe_status"
19673
19674         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19675         createmany -m $DIR/$tdir/f 100 ||
19676                 error "create files under remote dir failed"
19677         createmany -d $DIR/$tdir/d 100 ||
19678                 error "create dirs under remote dir failed"
19679
19680         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19681                 local mdt_hash="crush"
19682
19683                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19684                 $LFS setdirstripe -c $c $DIR/$tdir ||
19685                         error "split -c $c $tdir failed"
19686                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19687                         mdt_hash="$mdt_hash,fixed"
19688                 elif [ $c -eq 1 ]; then
19689                         mdt_hash="none"
19690                 fi
19691                 wait_update $HOSTNAME \
19692                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19693                         error "dir merge not finished"
19694                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19695                         awk '/migrate/ {sum += $2} END { print sum }')
19696                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19697                 # delta is around total_files/stripe_count
19698                 (( delta < 200 / c + 4 )) ||
19699                         error "$delta files migrated >= $((200 / c + 4))"
19700         done
19701 }
19702 run_test 230p "dir merge"
19703
19704 test_230q() {
19705         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19706         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19707                 skip "Need MDS version at least 2.13.52"
19708
19709         local mdts=$(comma_list $(mdts_nodes))
19710         local saved_threshold=$(do_facet mds1 \
19711                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19712         local saved_delta=$(do_facet mds1 \
19713                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19714         local threshold=100
19715         local delta=2
19716         local total=0
19717         local stripe_count=0
19718         local stripe_index
19719         local nr_files
19720         local create
19721
19722         # test with fewer files on ZFS
19723         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19724
19725         stack_trap "do_nodes $mdts $LCTL set_param \
19726                     mdt.*.dir_split_count=$saved_threshold"
19727         stack_trap "do_nodes $mdts $LCTL set_param \
19728                     mdt.*.dir_split_delta=$saved_delta"
19729         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19730         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19731         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19732         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19733         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19734         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19735
19736         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19737         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19738
19739         create=$((threshold * 3 / 2))
19740         while [ $stripe_count -lt $MDSCOUNT ]; do
19741                 createmany -m $DIR/$tdir/f $total $create ||
19742                         error "create sub files failed"
19743                 stat $DIR/$tdir > /dev/null
19744                 total=$((total + create))
19745                 stripe_count=$((stripe_count + delta))
19746                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19747
19748                 wait_update $HOSTNAME \
19749                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19750                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19751
19752                 wait_update $HOSTNAME \
19753                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19754                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19755
19756                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19757                 echo "$nr_files/$total files on MDT$stripe_index after split"
19758                 # allow 10% margin of imbalance with crush hash
19759                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19760                         error "$nr_files files on MDT$stripe_index after split"
19761
19762                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19763                 [ $nr_files -eq $total ] ||
19764                         error "total sub files $nr_files != $total"
19765         done
19766
19767         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19768
19769         echo "fixed layout directory won't auto split"
19770         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19771         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19772                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19773         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19774                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19775 }
19776 run_test 230q "dir auto split"
19777
19778 test_230r() {
19779         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19780         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19781         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19782                 skip "Need MDS version at least 2.13.54"
19783
19784         # maximum amount of local locks:
19785         # parent striped dir - 2 locks
19786         # new stripe in parent to migrate to - 1 lock
19787         # source and target - 2 locks
19788         # Total 5 locks for regular file
19789         mkdir -p $DIR/$tdir
19790         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19791         touch $DIR/$tdir/dir1/eee
19792
19793         # create 4 hardlink for 4 more locks
19794         # Total: 9 locks > RS_MAX_LOCKS (8)
19795         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19796         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19797         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19798         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19799         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19800         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19801         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19802         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19803
19804         cancel_lru_locks mdc
19805
19806         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19807                 error "migrate dir fails"
19808
19809         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19810 }
19811 run_test 230r "migrate with too many local locks"
19812
19813 test_230s() {
19814         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19815                 skip "Need MDS version at least 2.13.57"
19816
19817         local mdts=$(comma_list $(mdts_nodes))
19818         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19819                                 mdt.*MDT0000.enable_dir_restripe)
19820
19821         stack_trap "do_nodes $mdts $LCTL set_param \
19822                     mdt.*.enable_dir_restripe=$restripe_status"
19823
19824         local st
19825         for st in 0 1; do
19826                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19827                 test_mkdir $DIR/$tdir
19828                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19829                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19830                 rmdir $DIR/$tdir
19831         done
19832 }
19833 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19834
19835 test_230t()
19836 {
19837         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19838         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19839                 skip "Need MDS version at least 2.14.50"
19840
19841         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19842         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19843         $LFS project -p 1 -s $DIR/$tdir ||
19844                 error "set $tdir project id failed"
19845         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19846                 error "set subdir project id failed"
19847         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19848 }
19849 run_test 230t "migrate directory with project ID set"
19850
19851 test_231a()
19852 {
19853         # For simplicity this test assumes that max_pages_per_rpc
19854         # is the same across all OSCs
19855         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19856         local bulk_size=$((max_pages * PAGE_SIZE))
19857         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19858                                        head -n 1)
19859
19860         mkdir -p $DIR/$tdir
19861         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19862                 error "failed to set stripe with -S ${brw_size}M option"
19863
19864         # clear the OSC stats
19865         $LCTL set_param osc.*.stats=0 &>/dev/null
19866         stop_writeback
19867
19868         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19869         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19870                 oflag=direct &>/dev/null || error "dd failed"
19871
19872         sync; sleep 1; sync # just to be safe
19873         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19874         if [ x$nrpcs != "x1" ]; then
19875                 $LCTL get_param osc.*.stats
19876                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19877         fi
19878
19879         start_writeback
19880         # Drop the OSC cache, otherwise we will read from it
19881         cancel_lru_locks osc
19882
19883         # clear the OSC stats
19884         $LCTL set_param osc.*.stats=0 &>/dev/null
19885
19886         # Client reads $bulk_size.
19887         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19888                 iflag=direct &>/dev/null || error "dd failed"
19889
19890         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19891         if [ x$nrpcs != "x1" ]; then
19892                 $LCTL get_param osc.*.stats
19893                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19894         fi
19895 }
19896 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19897
19898 test_231b() {
19899         mkdir -p $DIR/$tdir
19900         local i
19901         for i in {0..1023}; do
19902                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19903                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19904                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19905         done
19906         sync
19907 }
19908 run_test 231b "must not assert on fully utilized OST request buffer"
19909
19910 test_232a() {
19911         mkdir -p $DIR/$tdir
19912         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19913
19914         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19915         do_facet ost1 $LCTL set_param fail_loc=0x31c
19916
19917         # ignore dd failure
19918         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19919
19920         do_facet ost1 $LCTL set_param fail_loc=0
19921         umount_client $MOUNT || error "umount failed"
19922         mount_client $MOUNT || error "mount failed"
19923         stop ost1 || error "cannot stop ost1"
19924         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19925 }
19926 run_test 232a "failed lock should not block umount"
19927
19928 test_232b() {
19929         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
19930                 skip "Need MDS version at least 2.10.58"
19931
19932         mkdir -p $DIR/$tdir
19933         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19934         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
19935         sync
19936         cancel_lru_locks osc
19937
19938         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19939         do_facet ost1 $LCTL set_param fail_loc=0x31c
19940
19941         # ignore failure
19942         $LFS data_version $DIR/$tdir/$tfile || true
19943
19944         do_facet ost1 $LCTL set_param fail_loc=0
19945         umount_client $MOUNT || error "umount failed"
19946         mount_client $MOUNT || error "mount failed"
19947         stop ost1 || error "cannot stop ost1"
19948         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19949 }
19950 run_test 232b "failed data version lock should not block umount"
19951
19952 test_233a() {
19953         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
19954                 skip "Need MDS version at least 2.3.64"
19955         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19956
19957         local fid=$($LFS path2fid $MOUNT)
19958
19959         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19960                 error "cannot access $MOUNT using its FID '$fid'"
19961 }
19962 run_test 233a "checking that OBF of the FS root succeeds"
19963
19964 test_233b() {
19965         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
19966                 skip "Need MDS version at least 2.5.90"
19967         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
19968
19969         local fid=$($LFS path2fid $MOUNT/.lustre)
19970
19971         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19972                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
19973
19974         fid=$($LFS path2fid $MOUNT/.lustre/fid)
19975         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
19976                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
19977 }
19978 run_test 233b "checking that OBF of the FS .lustre succeeds"
19979
19980 test_234() {
19981         local p="$TMP/sanityN-$TESTNAME.parameters"
19982         save_lustre_params client "llite.*.xattr_cache" > $p
19983         lctl set_param llite.*.xattr_cache 1 ||
19984                 skip_env "xattr cache is not supported"
19985
19986         mkdir -p $DIR/$tdir || error "mkdir failed"
19987         touch $DIR/$tdir/$tfile || error "touch failed"
19988         # OBD_FAIL_LLITE_XATTR_ENOMEM
19989         $LCTL set_param fail_loc=0x1405
19990         getfattr -n user.attr $DIR/$tdir/$tfile &&
19991                 error "getfattr should have failed with ENOMEM"
19992         $LCTL set_param fail_loc=0x0
19993         rm -rf $DIR/$tdir
19994
19995         restore_lustre_params < $p
19996         rm -f $p
19997 }
19998 run_test 234 "xattr cache should not crash on ENOMEM"
19999
20000 test_235() {
20001         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20002                 skip "Need MDS version at least 2.4.52"
20003
20004         flock_deadlock $DIR/$tfile
20005         local RC=$?
20006         case $RC in
20007                 0)
20008                 ;;
20009                 124) error "process hangs on a deadlock"
20010                 ;;
20011                 *) error "error executing flock_deadlock $DIR/$tfile"
20012                 ;;
20013         esac
20014 }
20015 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20016
20017 #LU-2935
20018 test_236() {
20019         check_swap_layouts_support
20020
20021         local ref1=/etc/passwd
20022         local ref2=/etc/group
20023         local file1=$DIR/$tdir/f1
20024         local file2=$DIR/$tdir/f2
20025
20026         test_mkdir -c1 $DIR/$tdir
20027         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20028         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20029         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20030         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20031         local fd=$(free_fd)
20032         local cmd="exec $fd<>$file2"
20033         eval $cmd
20034         rm $file2
20035         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20036                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20037         cmd="exec $fd>&-"
20038         eval $cmd
20039         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20040
20041         #cleanup
20042         rm -rf $DIR/$tdir
20043 }
20044 run_test 236 "Layout swap on open unlinked file"
20045
20046 # LU-4659 linkea consistency
20047 test_238() {
20048         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20049                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20050                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20051                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20052
20053         touch $DIR/$tfile
20054         ln $DIR/$tfile $DIR/$tfile.lnk
20055         touch $DIR/$tfile.new
20056         mv $DIR/$tfile.new $DIR/$tfile
20057         local fid1=$($LFS path2fid $DIR/$tfile)
20058         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20059         local path1=$($LFS fid2path $FSNAME "$fid1")
20060         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20061         local path2=$($LFS fid2path $FSNAME "$fid2")
20062         [ $tfile.lnk == $path2 ] ||
20063                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20064         rm -f $DIR/$tfile*
20065 }
20066 run_test 238 "Verify linkea consistency"
20067
20068 test_239A() { # was test_239
20069         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20070                 skip "Need MDS version at least 2.5.60"
20071
20072         local list=$(comma_list $(mdts_nodes))
20073
20074         mkdir -p $DIR/$tdir
20075         createmany -o $DIR/$tdir/f- 5000
20076         unlinkmany $DIR/$tdir/f- 5000
20077         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20078                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20079         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20080                         osp.*MDT*.sync_in_flight" | calc_sum)
20081         [ "$changes" -eq 0 ] || error "$changes not synced"
20082 }
20083 run_test 239A "osp_sync test"
20084
20085 test_239a() { #LU-5297
20086         remote_mds_nodsh && skip "remote MDS with nodsh"
20087
20088         touch $DIR/$tfile
20089         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20090         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20091         chgrp $RUNAS_GID $DIR/$tfile
20092         wait_delete_completed
20093 }
20094 run_test 239a "process invalid osp sync record correctly"
20095
20096 test_239b() { #LU-5297
20097         remote_mds_nodsh && skip "remote MDS with nodsh"
20098
20099         touch $DIR/$tfile1
20100         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20101         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20102         chgrp $RUNAS_GID $DIR/$tfile1
20103         wait_delete_completed
20104         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20105         touch $DIR/$tfile2
20106         chgrp $RUNAS_GID $DIR/$tfile2
20107         wait_delete_completed
20108 }
20109 run_test 239b "process osp sync record with ENOMEM error correctly"
20110
20111 test_240() {
20112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20113         remote_mds_nodsh && skip "remote MDS with nodsh"
20114
20115         mkdir -p $DIR/$tdir
20116
20117         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20118                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20119         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20120                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20121
20122         umount_client $MOUNT || error "umount failed"
20123         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20124         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20125         mount_client $MOUNT || error "failed to mount client"
20126
20127         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20128         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20129 }
20130 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20131
20132 test_241_bio() {
20133         local count=$1
20134         local bsize=$2
20135
20136         for LOOP in $(seq $count); do
20137                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20138                 cancel_lru_locks $OSC || true
20139         done
20140 }
20141
20142 test_241_dio() {
20143         local count=$1
20144         local bsize=$2
20145
20146         for LOOP in $(seq $1); do
20147                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20148                         2>/dev/null
20149         done
20150 }
20151
20152 test_241a() { # was test_241
20153         local bsize=$PAGE_SIZE
20154
20155         (( bsize < 40960 )) && bsize=40960
20156         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20157         ls -la $DIR/$tfile
20158         cancel_lru_locks $OSC
20159         test_241_bio 1000 $bsize &
20160         PID=$!
20161         test_241_dio 1000 $bsize
20162         wait $PID
20163 }
20164 run_test 241a "bio vs dio"
20165
20166 test_241b() {
20167         local bsize=$PAGE_SIZE
20168
20169         (( bsize < 40960 )) && bsize=40960
20170         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20171         ls -la $DIR/$tfile
20172         test_241_dio 1000 $bsize &
20173         PID=$!
20174         test_241_dio 1000 $bsize
20175         wait $PID
20176 }
20177 run_test 241b "dio vs dio"
20178
20179 test_242() {
20180         remote_mds_nodsh && skip "remote MDS with nodsh"
20181
20182         mkdir_on_mdt0 $DIR/$tdir
20183         touch $DIR/$tdir/$tfile
20184
20185         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20186         do_facet mds1 lctl set_param fail_loc=0x105
20187         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20188
20189         do_facet mds1 lctl set_param fail_loc=0
20190         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20191 }
20192 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20193
20194 test_243()
20195 {
20196         test_mkdir $DIR/$tdir
20197         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20198 }
20199 run_test 243 "various group lock tests"
20200
20201 test_244a()
20202 {
20203         test_mkdir $DIR/$tdir
20204         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20205         sendfile_grouplock $DIR/$tdir/$tfile || \
20206                 error "sendfile+grouplock failed"
20207         rm -rf $DIR/$tdir
20208 }
20209 run_test 244a "sendfile with group lock tests"
20210
20211 test_244b()
20212 {
20213         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20214
20215         local threads=50
20216         local size=$((1024*1024))
20217
20218         test_mkdir $DIR/$tdir
20219         for i in $(seq 1 $threads); do
20220                 local file=$DIR/$tdir/file_$((i / 10))
20221                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20222                 local pids[$i]=$!
20223         done
20224         for i in $(seq 1 $threads); do
20225                 wait ${pids[$i]}
20226         done
20227 }
20228 run_test 244b "multi-threaded write with group lock"
20229
20230 test_245() {
20231         local flagname="multi_mod_rpcs"
20232         local connect_data_name="max_mod_rpcs"
20233         local out
20234
20235         # check if multiple modify RPCs flag is set
20236         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20237                 grep "connect_flags:")
20238         echo "$out"
20239
20240         echo "$out" | grep -qw $flagname
20241         if [ $? -ne 0 ]; then
20242                 echo "connect flag $flagname is not set"
20243                 return
20244         fi
20245
20246         # check if multiple modify RPCs data is set
20247         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20248         echo "$out"
20249
20250         echo "$out" | grep -qw $connect_data_name ||
20251                 error "import should have connect data $connect_data_name"
20252 }
20253 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20254
20255 cleanup_247() {
20256         local submount=$1
20257
20258         trap 0
20259         umount_client $submount
20260         rmdir $submount
20261 }
20262
20263 test_247a() {
20264         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20265                 grep -q subtree ||
20266                 skip_env "Fileset feature is not supported"
20267
20268         local submount=${MOUNT}_$tdir
20269
20270         mkdir $MOUNT/$tdir
20271         mkdir -p $submount || error "mkdir $submount failed"
20272         FILESET="$FILESET/$tdir" mount_client $submount ||
20273                 error "mount $submount failed"
20274         trap "cleanup_247 $submount" EXIT
20275         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20276         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20277                 error "read $MOUNT/$tdir/$tfile failed"
20278         cleanup_247 $submount
20279 }
20280 run_test 247a "mount subdir as fileset"
20281
20282 test_247b() {
20283         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20284                 skip_env "Fileset feature is not supported"
20285
20286         local submount=${MOUNT}_$tdir
20287
20288         rm -rf $MOUNT/$tdir
20289         mkdir -p $submount || error "mkdir $submount failed"
20290         SKIP_FILESET=1
20291         FILESET="$FILESET/$tdir" mount_client $submount &&
20292                 error "mount $submount should fail"
20293         rmdir $submount
20294 }
20295 run_test 247b "mount subdir that dose not exist"
20296
20297 test_247c() {
20298         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20299                 skip_env "Fileset feature is not supported"
20300
20301         local submount=${MOUNT}_$tdir
20302
20303         mkdir -p $MOUNT/$tdir/dir1
20304         mkdir -p $submount || error "mkdir $submount failed"
20305         trap "cleanup_247 $submount" EXIT
20306         FILESET="$FILESET/$tdir" mount_client $submount ||
20307                 error "mount $submount failed"
20308         local fid=$($LFS path2fid $MOUNT/)
20309         $LFS fid2path $submount $fid && error "fid2path should fail"
20310         cleanup_247 $submount
20311 }
20312 run_test 247c "running fid2path outside subdirectory root"
20313
20314 test_247d() {
20315         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20316                 skip "Fileset feature is not supported"
20317
20318         local submount=${MOUNT}_$tdir
20319
20320         mkdir -p $MOUNT/$tdir/dir1
20321         mkdir -p $submount || error "mkdir $submount failed"
20322         FILESET="$FILESET/$tdir" mount_client $submount ||
20323                 error "mount $submount failed"
20324         trap "cleanup_247 $submount" EXIT
20325
20326         local td=$submount/dir1
20327         local fid=$($LFS path2fid $td)
20328         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20329
20330         # check that we get the same pathname back
20331         local rootpath
20332         local found
20333         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20334                 echo "$rootpath $fid"
20335                 found=$($LFS fid2path $rootpath "$fid")
20336                 [ -n "found" ] || error "fid2path should succeed"
20337                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20338         done
20339         # check wrong root path format
20340         rootpath=$submount"_wrong"
20341         found=$($LFS fid2path $rootpath "$fid")
20342         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20343
20344         cleanup_247 $submount
20345 }
20346 run_test 247d "running fid2path inside subdirectory root"
20347
20348 # LU-8037
20349 test_247e() {
20350         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20351                 grep -q subtree ||
20352                 skip "Fileset feature is not supported"
20353
20354         local submount=${MOUNT}_$tdir
20355
20356         mkdir $MOUNT/$tdir
20357         mkdir -p $submount || error "mkdir $submount failed"
20358         FILESET="$FILESET/.." mount_client $submount &&
20359                 error "mount $submount should fail"
20360         rmdir $submount
20361 }
20362 run_test 247e "mount .. as fileset"
20363
20364 test_247f() {
20365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20366         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20367                 skip "Need at least version 2.13.52"
20368         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20369                 skip "Need at least version 2.14.50"
20370         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20371                 grep -q subtree ||
20372                 skip "Fileset feature is not supported"
20373
20374         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20375         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20376                 error "mkdir remote failed"
20377         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20378                 error "mkdir remote/subdir failed"
20379         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20380                 error "mkdir striped failed"
20381         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20382
20383         local submount=${MOUNT}_$tdir
20384
20385         mkdir -p $submount || error "mkdir $submount failed"
20386         stack_trap "rmdir $submount"
20387
20388         local dir
20389         local stat
20390         local fileset=$FILESET
20391         local mdts=$(comma_list $(mdts_nodes))
20392
20393         stat=$(do_facet mds1 $LCTL get_param -n \
20394                 mdt.*MDT0000.enable_remote_subdir_mount)
20395         stack_trap "do_nodes $mdts $LCTL set_param \
20396                 mdt.*.enable_remote_subdir_mount=$stat"
20397
20398         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20399         stack_trap "umount_client $submount"
20400         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20401                 error "mount remote dir $dir should fail"
20402
20403         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20404                 $tdir/striped/. ; do
20405                 FILESET="$fileset/$dir" mount_client $submount ||
20406                         error "mount $dir failed"
20407                 umount_client $submount
20408         done
20409
20410         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20411         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20412                 error "mount $tdir/remote failed"
20413 }
20414 run_test 247f "mount striped or remote directory as fileset"
20415
20416 test_247g() {
20417         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20418         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20419                 skip "Need at least version 2.14.50"
20420
20421         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20422                 error "mkdir $tdir failed"
20423         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20424
20425         local submount=${MOUNT}_$tdir
20426
20427         mkdir -p $submount || error "mkdir $submount failed"
20428         stack_trap "rmdir $submount"
20429
20430         FILESET="$fileset/$tdir" mount_client $submount ||
20431                 error "mount $dir failed"
20432         stack_trap "umount $submount"
20433
20434         local mdts=$(comma_list $(mdts_nodes))
20435
20436         local nrpcs
20437
20438         stat $submount > /dev/null
20439         cancel_lru_locks $MDC
20440         stat $submount > /dev/null
20441         stat $submount/$tfile > /dev/null
20442         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20443         stat $submount/$tfile > /dev/null
20444         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20445                 awk '/getattr/ {sum += $2} END {print sum}')
20446
20447         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20448 }
20449 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20450
20451 test_248a() {
20452         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20453         [ -z "$fast_read_sav" ] && skip "no fast read support"
20454
20455         # create a large file for fast read verification
20456         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20457
20458         # make sure the file is created correctly
20459         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20460                 { rm -f $DIR/$tfile; skip "file creation error"; }
20461
20462         echo "Test 1: verify that fast read is 4 times faster on cache read"
20463
20464         # small read with fast read enabled
20465         $LCTL set_param -n llite.*.fast_read=1
20466         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20467                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20468                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20469         # small read with fast read disabled
20470         $LCTL set_param -n llite.*.fast_read=0
20471         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20472                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20473                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20474
20475         # verify that fast read is 4 times faster for cache read
20476         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20477                 error_not_in_vm "fast read was not 4 times faster: " \
20478                            "$t_fast vs $t_slow"
20479
20480         echo "Test 2: verify the performance between big and small read"
20481         $LCTL set_param -n llite.*.fast_read=1
20482
20483         # 1k non-cache read
20484         cancel_lru_locks osc
20485         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20486                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20487                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20488
20489         # 1M non-cache read
20490         cancel_lru_locks osc
20491         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20492                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20493                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20494
20495         # verify that big IO is not 4 times faster than small IO
20496         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20497                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20498
20499         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20500         rm -f $DIR/$tfile
20501 }
20502 run_test 248a "fast read verification"
20503
20504 test_248b() {
20505         # Default short_io_bytes=16384, try both smaller and larger sizes.
20506         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20507         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20508         echo "bs=53248 count=113 normal buffered write"
20509         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20510                 error "dd of initial data file failed"
20511         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20512
20513         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20514         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20515                 error "dd with sync normal writes failed"
20516         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20517
20518         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20519         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20520                 error "dd with sync small writes failed"
20521         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20522
20523         cancel_lru_locks osc
20524
20525         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20526         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20527         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20528         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20529                 iflag=direct || error "dd with O_DIRECT small read failed"
20530         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20531         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20532                 error "compare $TMP/$tfile.1 failed"
20533
20534         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20535         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20536
20537         # just to see what the maximum tunable value is, and test parsing
20538         echo "test invalid parameter 2MB"
20539         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20540                 error "too-large short_io_bytes allowed"
20541         echo "test maximum parameter 512KB"
20542         # if we can set a larger short_io_bytes, run test regardless of version
20543         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20544                 # older clients may not allow setting it this large, that's OK
20545                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20546                         skip "Need at least client version 2.13.50"
20547                 error "medium short_io_bytes failed"
20548         fi
20549         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20550         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20551
20552         echo "test large parameter 64KB"
20553         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20554         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20555
20556         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20557         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20558                 error "dd with sync large writes failed"
20559         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20560
20561         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20562         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20563         num=$((113 * 4096 / PAGE_SIZE))
20564         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20565         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20566                 error "dd with O_DIRECT large writes failed"
20567         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20568                 error "compare $DIR/$tfile.3 failed"
20569
20570         cancel_lru_locks osc
20571
20572         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20573         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20574                 error "dd with O_DIRECT large read failed"
20575         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20576                 error "compare $TMP/$tfile.2 failed"
20577
20578         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20579         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20580                 error "dd with O_DIRECT large read failed"
20581         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20582                 error "compare $TMP/$tfile.3 failed"
20583 }
20584 run_test 248b "test short_io read and write for both small and large sizes"
20585
20586 test_249() { # LU-7890
20587         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20588                 skip "Need at least version 2.8.54"
20589
20590         rm -f $DIR/$tfile
20591         $LFS setstripe -c 1 $DIR/$tfile
20592         # Offset 2T == 4k * 512M
20593         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20594                 error "dd to 2T offset failed"
20595 }
20596 run_test 249 "Write above 2T file size"
20597
20598 test_250() {
20599         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20600          && skip "no 16TB file size limit on ZFS"
20601
20602         $LFS setstripe -c 1 $DIR/$tfile
20603         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20604         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20605         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20606         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20607                 conv=notrunc,fsync && error "append succeeded"
20608         return 0
20609 }
20610 run_test 250 "Write above 16T limit"
20611
20612 test_251() {
20613         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20614
20615         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20616         #Skip once - writing the first stripe will succeed
20617         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20618         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20619                 error "short write happened"
20620
20621         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20622         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20623                 error "short read happened"
20624
20625         rm -f $DIR/$tfile
20626 }
20627 run_test 251 "Handling short read and write correctly"
20628
20629 test_252() {
20630         remote_mds_nodsh && skip "remote MDS with nodsh"
20631         remote_ost_nodsh && skip "remote OST with nodsh"
20632         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20633                 skip_env "ldiskfs only test"
20634         fi
20635
20636         local tgt
20637         local dev
20638         local out
20639         local uuid
20640         local num
20641         local gen
20642
20643         # check lr_reader on OST0000
20644         tgt=ost1
20645         dev=$(facet_device $tgt)
20646         out=$(do_facet $tgt $LR_READER $dev)
20647         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20648         echo "$out"
20649         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20650         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20651                 error "Invalid uuid returned by $LR_READER on target $tgt"
20652         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20653
20654         # check lr_reader -c on MDT0000
20655         tgt=mds1
20656         dev=$(facet_device $tgt)
20657         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20658                 skip "$LR_READER does not support additional options"
20659         fi
20660         out=$(do_facet $tgt $LR_READER -c $dev)
20661         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20662         echo "$out"
20663         num=$(echo "$out" | grep -c "mdtlov")
20664         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20665                 error "Invalid number of mdtlov clients returned by $LR_READER"
20666         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20667
20668         # check lr_reader -cr on MDT0000
20669         out=$(do_facet $tgt $LR_READER -cr $dev)
20670         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20671         echo "$out"
20672         echo "$out" | grep -q "^reply_data:$" ||
20673                 error "$LR_READER should have returned 'reply_data' section"
20674         num=$(echo "$out" | grep -c "client_generation")
20675         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20676 }
20677 run_test 252 "check lr_reader tool"
20678
20679 test_253() {
20680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20681         remote_mds_nodsh && skip "remote MDS with nodsh"
20682         remote_mgs_nodsh && skip "remote MGS with nodsh"
20683
20684         local ostidx=0
20685         local rc=0
20686         local ost_name=$(ostname_from_index $ostidx)
20687
20688         # on the mdt's osc
20689         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20690         do_facet $SINGLEMDS $LCTL get_param -n \
20691                 osp.$mdtosc_proc1.reserved_mb_high ||
20692                 skip  "remote MDS does not support reserved_mb_high"
20693
20694         rm -rf $DIR/$tdir
20695         wait_mds_ost_sync
20696         wait_delete_completed
20697         mkdir $DIR/$tdir
20698
20699         pool_add $TESTNAME || error "Pool creation failed"
20700         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20701
20702         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20703                 error "Setstripe failed"
20704
20705         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20706
20707         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20708                     grep "watermarks")
20709         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20710
20711         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20712                         osp.$mdtosc_proc1.prealloc_status)
20713         echo "prealloc_status $oa_status"
20714
20715         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20716                 error "File creation should fail"
20717
20718         #object allocation was stopped, but we still able to append files
20719         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20720                 oflag=append || error "Append failed"
20721
20722         rm -f $DIR/$tdir/$tfile.0
20723
20724         # For this test, we want to delete the files we created to go out of
20725         # space but leave the watermark, so we remain nearly out of space
20726         ost_watermarks_enospc_delete_files $tfile $ostidx
20727
20728         wait_delete_completed
20729
20730         sleep_maxage
20731
20732         for i in $(seq 10 12); do
20733                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20734                         2>/dev/null || error "File creation failed after rm"
20735         done
20736
20737         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20738                         osp.$mdtosc_proc1.prealloc_status)
20739         echo "prealloc_status $oa_status"
20740
20741         if (( oa_status != 0 )); then
20742                 error "Object allocation still disable after rm"
20743         fi
20744 }
20745 run_test 253 "Check object allocation limit"
20746
20747 test_254() {
20748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20749         remote_mds_nodsh && skip "remote MDS with nodsh"
20750         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20751                 skip "MDS does not support changelog_size"
20752
20753         local cl_user
20754         local MDT0=$(facet_svc $SINGLEMDS)
20755
20756         changelog_register || error "changelog_register failed"
20757
20758         changelog_clear 0 || error "changelog_clear failed"
20759
20760         local size1=$(do_facet $SINGLEMDS \
20761                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20762         echo "Changelog size $size1"
20763
20764         rm -rf $DIR/$tdir
20765         $LFS mkdir -i 0 $DIR/$tdir
20766         # change something
20767         mkdir -p $DIR/$tdir/pics/2008/zachy
20768         touch $DIR/$tdir/pics/2008/zachy/timestamp
20769         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20770         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20771         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20772         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20773         rm $DIR/$tdir/pics/desktop.jpg
20774
20775         local size2=$(do_facet $SINGLEMDS \
20776                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20777         echo "Changelog size after work $size2"
20778
20779         (( $size2 > $size1 )) ||
20780                 error "new Changelog size=$size2 less than old size=$size1"
20781 }
20782 run_test 254 "Check changelog size"
20783
20784 ladvise_no_type()
20785 {
20786         local type=$1
20787         local file=$2
20788
20789         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20790                 awk -F: '{print $2}' | grep $type > /dev/null
20791         if [ $? -ne 0 ]; then
20792                 return 0
20793         fi
20794         return 1
20795 }
20796
20797 ladvise_no_ioctl()
20798 {
20799         local file=$1
20800
20801         lfs ladvise -a willread $file > /dev/null 2>&1
20802         if [ $? -eq 0 ]; then
20803                 return 1
20804         fi
20805
20806         lfs ladvise -a willread $file 2>&1 |
20807                 grep "Inappropriate ioctl for device" > /dev/null
20808         if [ $? -eq 0 ]; then
20809                 return 0
20810         fi
20811         return 1
20812 }
20813
20814 percent() {
20815         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20816 }
20817
20818 # run a random read IO workload
20819 # usage: random_read_iops <filename> <filesize> <iosize>
20820 random_read_iops() {
20821         local file=$1
20822         local fsize=$2
20823         local iosize=${3:-4096}
20824
20825         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20826                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20827 }
20828
20829 drop_file_oss_cache() {
20830         local file="$1"
20831         local nodes="$2"
20832
20833         $LFS ladvise -a dontneed $file 2>/dev/null ||
20834                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20835 }
20836
20837 ladvise_willread_performance()
20838 {
20839         local repeat=10
20840         local average_origin=0
20841         local average_cache=0
20842         local average_ladvise=0
20843
20844         for ((i = 1; i <= $repeat; i++)); do
20845                 echo "Iter $i/$repeat: reading without willread hint"
20846                 cancel_lru_locks osc
20847                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20848                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20849                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20850                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20851
20852                 cancel_lru_locks osc
20853                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20854                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20855                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20856
20857                 cancel_lru_locks osc
20858                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20859                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20860                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20861                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20862                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20863         done
20864         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20865         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20866         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20867
20868         speedup_cache=$(percent $average_cache $average_origin)
20869         speedup_ladvise=$(percent $average_ladvise $average_origin)
20870
20871         echo "Average uncached read: $average_origin"
20872         echo "Average speedup with OSS cached read: " \
20873                 "$average_cache = +$speedup_cache%"
20874         echo "Average speedup with ladvise willread: " \
20875                 "$average_ladvise = +$speedup_ladvise%"
20876
20877         local lowest_speedup=20
20878         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20879                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20880                         "got $average_cache%. Skipping ladvise willread check."
20881                 return 0
20882         fi
20883
20884         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20885         # it is still good to run until then to exercise 'ladvise willread'
20886         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20887                 [ "$ost1_FSTYPE" = "zfs" ] &&
20888                 echo "osd-zfs does not support dontneed or drop_caches" &&
20889                 return 0
20890
20891         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20892         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20893                 error_not_in_vm "Speedup with willread is less than " \
20894                         "$lowest_speedup%, got $average_ladvise%"
20895 }
20896
20897 test_255a() {
20898         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20899                 skip "lustre < 2.8.54 does not support ladvise "
20900         remote_ost_nodsh && skip "remote OST with nodsh"
20901
20902         stack_trap "rm -f $DIR/$tfile"
20903         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20904
20905         ladvise_no_type willread $DIR/$tfile &&
20906                 skip "willread ladvise is not supported"
20907
20908         ladvise_no_ioctl $DIR/$tfile &&
20909                 skip "ladvise ioctl is not supported"
20910
20911         local size_mb=100
20912         local size=$((size_mb * 1048576))
20913         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20914                 error "dd to $DIR/$tfile failed"
20915
20916         lfs ladvise -a willread $DIR/$tfile ||
20917                 error "Ladvise failed with no range argument"
20918
20919         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20920                 error "Ladvise failed with no -l or -e argument"
20921
20922         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20923                 error "Ladvise failed with only -e argument"
20924
20925         lfs ladvise -a willread -l 1 $DIR/$tfile ||
20926                 error "Ladvise failed with only -l argument"
20927
20928         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
20929                 error "End offset should not be smaller than start offset"
20930
20931         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
20932                 error "End offset should not be equal to start offset"
20933
20934         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
20935                 error "Ladvise failed with overflowing -s argument"
20936
20937         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
20938                 error "Ladvise failed with overflowing -e argument"
20939
20940         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
20941                 error "Ladvise failed with overflowing -l argument"
20942
20943         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
20944                 error "Ladvise succeeded with conflicting -l and -e arguments"
20945
20946         echo "Synchronous ladvise should wait"
20947         local delay=4
20948 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
20949         do_nodes $(comma_list $(osts_nodes)) \
20950                 $LCTL set_param fail_val=$delay fail_loc=0x237
20951
20952         local start_ts=$SECONDS
20953         lfs ladvise -a willread $DIR/$tfile ||
20954                 error "Ladvise failed with no range argument"
20955         local end_ts=$SECONDS
20956         local inteval_ts=$((end_ts - start_ts))
20957
20958         if [ $inteval_ts -lt $(($delay - 1)) ]; then
20959                 error "Synchronous advice didn't wait reply"
20960         fi
20961
20962         echo "Asynchronous ladvise shouldn't wait"
20963         local start_ts=$SECONDS
20964         lfs ladvise -a willread -b $DIR/$tfile ||
20965                 error "Ladvise failed with no range argument"
20966         local end_ts=$SECONDS
20967         local inteval_ts=$((end_ts - start_ts))
20968
20969         if [ $inteval_ts -gt $(($delay / 2)) ]; then
20970                 error "Asynchronous advice blocked"
20971         fi
20972
20973         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
20974         ladvise_willread_performance
20975 }
20976 run_test 255a "check 'lfs ladvise -a willread'"
20977
20978 facet_meminfo() {
20979         local facet=$1
20980         local info=$2
20981
20982         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
20983 }
20984
20985 test_255b() {
20986         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20987                 skip "lustre < 2.8.54 does not support ladvise "
20988         remote_ost_nodsh && skip "remote OST with nodsh"
20989
20990         stack_trap "rm -f $DIR/$tfile"
20991         lfs setstripe -c 1 -i 0 $DIR/$tfile
20992
20993         ladvise_no_type dontneed $DIR/$tfile &&
20994                 skip "dontneed ladvise is not supported"
20995
20996         ladvise_no_ioctl $DIR/$tfile &&
20997                 skip "ladvise ioctl is not supported"
20998
20999         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21000                 [ "$ost1_FSTYPE" = "zfs" ] &&
21001                 skip "zfs-osd does not support 'ladvise dontneed'"
21002
21003         local size_mb=100
21004         local size=$((size_mb * 1048576))
21005         # In order to prevent disturbance of other processes, only check 3/4
21006         # of the memory usage
21007         local kibibytes=$((size_mb * 1024 * 3 / 4))
21008
21009         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21010                 error "dd to $DIR/$tfile failed"
21011
21012         #force write to complete before dropping OST cache & checking memory
21013         sync
21014
21015         local total=$(facet_meminfo ost1 MemTotal)
21016         echo "Total memory: $total KiB"
21017
21018         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21019         local before_read=$(facet_meminfo ost1 Cached)
21020         echo "Cache used before read: $before_read KiB"
21021
21022         lfs ladvise -a willread $DIR/$tfile ||
21023                 error "Ladvise willread failed"
21024         local after_read=$(facet_meminfo ost1 Cached)
21025         echo "Cache used after read: $after_read KiB"
21026
21027         lfs ladvise -a dontneed $DIR/$tfile ||
21028                 error "Ladvise dontneed again failed"
21029         local no_read=$(facet_meminfo ost1 Cached)
21030         echo "Cache used after dontneed ladvise: $no_read KiB"
21031
21032         if [ $total -lt $((before_read + kibibytes)) ]; then
21033                 echo "Memory is too small, abort checking"
21034                 return 0
21035         fi
21036
21037         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21038                 error "Ladvise willread should use more memory" \
21039                         "than $kibibytes KiB"
21040         fi
21041
21042         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21043                 error "Ladvise dontneed should release more memory" \
21044                         "than $kibibytes KiB"
21045         fi
21046 }
21047 run_test 255b "check 'lfs ladvise -a dontneed'"
21048
21049 test_255c() {
21050         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21051                 skip "lustre < 2.10.50 does not support lockahead"
21052
21053         local ost1_imp=$(get_osc_import_name client ost1)
21054         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21055                          cut -d'.' -f2)
21056         local count
21057         local new_count
21058         local difference
21059         local i
21060         local rc
21061
21062         test_mkdir -p $DIR/$tdir
21063         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21064
21065         #test 10 returns only success/failure
21066         i=10
21067         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21068         rc=$?
21069         if [ $rc -eq 255 ]; then
21070                 error "Ladvise test${i} failed, ${rc}"
21071         fi
21072
21073         #test 11 counts lock enqueue requests, all others count new locks
21074         i=11
21075         count=$(do_facet ost1 \
21076                 $LCTL get_param -n ost.OSS.ost.stats)
21077         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21078
21079         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21080         rc=$?
21081         if [ $rc -eq 255 ]; then
21082                 error "Ladvise test${i} failed, ${rc}"
21083         fi
21084
21085         new_count=$(do_facet ost1 \
21086                 $LCTL get_param -n ost.OSS.ost.stats)
21087         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21088                    awk '{ print $2 }')
21089
21090         difference="$((new_count - count))"
21091         if [ $difference -ne $rc ]; then
21092                 error "Ladvise test${i}, bad enqueue count, returned " \
21093                       "${rc}, actual ${difference}"
21094         fi
21095
21096         for i in $(seq 12 21); do
21097                 # If we do not do this, we run the risk of having too many
21098                 # locks and starting lock cancellation while we are checking
21099                 # lock counts.
21100                 cancel_lru_locks osc
21101
21102                 count=$($LCTL get_param -n \
21103                        ldlm.namespaces.$imp_name.lock_unused_count)
21104
21105                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21106                 rc=$?
21107                 if [ $rc -eq 255 ]; then
21108                         error "Ladvise test ${i} failed, ${rc}"
21109                 fi
21110
21111                 new_count=$($LCTL get_param -n \
21112                        ldlm.namespaces.$imp_name.lock_unused_count)
21113                 difference="$((new_count - count))"
21114
21115                 # Test 15 output is divided by 100 to map down to valid return
21116                 if [ $i -eq 15 ]; then
21117                         rc="$((rc * 100))"
21118                 fi
21119
21120                 if [ $difference -ne $rc ]; then
21121                         error "Ladvise test ${i}, bad lock count, returned " \
21122                               "${rc}, actual ${difference}"
21123                 fi
21124         done
21125
21126         #test 22 returns only success/failure
21127         i=22
21128         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21129         rc=$?
21130         if [ $rc -eq 255 ]; then
21131                 error "Ladvise test${i} failed, ${rc}"
21132         fi
21133 }
21134 run_test 255c "suite of ladvise lockahead tests"
21135
21136 test_256() {
21137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21138         remote_mds_nodsh && skip "remote MDS with nodsh"
21139         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21140         changelog_users $SINGLEMDS | grep "^cl" &&
21141                 skip "active changelog user"
21142
21143         local cl_user
21144         local cat_sl
21145         local mdt_dev
21146
21147         mdt_dev=$(mdsdevname 1)
21148         echo $mdt_dev
21149
21150         changelog_register || error "changelog_register failed"
21151
21152         rm -rf $DIR/$tdir
21153         mkdir_on_mdt0 $DIR/$tdir
21154
21155         changelog_clear 0 || error "changelog_clear failed"
21156
21157         # change something
21158         touch $DIR/$tdir/{1..10}
21159
21160         # stop the MDT
21161         stop $SINGLEMDS || error "Fail to stop MDT"
21162
21163         # remount the MDT
21164
21165         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21166
21167         #after mount new plainllog is used
21168         touch $DIR/$tdir/{11..19}
21169         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21170         stack_trap "rm -f $tmpfile"
21171         cat_sl=$(do_facet $SINGLEMDS "sync; \
21172                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21173                  llog_reader $tmpfile | grep -c type=1064553b")
21174         do_facet $SINGLEMDS llog_reader $tmpfile
21175
21176         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21177
21178         changelog_clear 0 || error "changelog_clear failed"
21179
21180         cat_sl=$(do_facet $SINGLEMDS "sync; \
21181                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21182                  llog_reader $tmpfile | grep -c type=1064553b")
21183
21184         if (( cat_sl == 2 )); then
21185                 error "Empty plain llog was not deleted from changelog catalog"
21186         elif (( cat_sl != 1 )); then
21187                 error "Active plain llog shouldn't be deleted from catalog"
21188         fi
21189 }
21190 run_test 256 "Check llog delete for empty and not full state"
21191
21192 test_257() {
21193         remote_mds_nodsh && skip "remote MDS with nodsh"
21194         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21195                 skip "Need MDS version at least 2.8.55"
21196
21197         test_mkdir $DIR/$tdir
21198
21199         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21200                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21201         stat $DIR/$tdir
21202
21203 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21204         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21205         local facet=mds$((mdtidx + 1))
21206         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21207         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21208
21209         stop $facet || error "stop MDS failed"
21210         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21211                 error "start MDS fail"
21212         wait_recovery_complete $facet
21213 }
21214 run_test 257 "xattr locks are not lost"
21215
21216 # Verify we take the i_mutex when security requires it
21217 test_258a() {
21218 #define OBD_FAIL_IMUTEX_SEC 0x141c
21219         $LCTL set_param fail_loc=0x141c
21220         touch $DIR/$tfile
21221         chmod u+s $DIR/$tfile
21222         chmod a+rwx $DIR/$tfile
21223         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21224         RC=$?
21225         if [ $RC -ne 0 ]; then
21226                 error "error, failed to take i_mutex, rc=$?"
21227         fi
21228         rm -f $DIR/$tfile
21229 }
21230 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21231
21232 # Verify we do NOT take the i_mutex in the normal case
21233 test_258b() {
21234 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21235         $LCTL set_param fail_loc=0x141d
21236         touch $DIR/$tfile
21237         chmod a+rwx $DIR
21238         chmod a+rw $DIR/$tfile
21239         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21240         RC=$?
21241         if [ $RC -ne 0 ]; then
21242                 error "error, took i_mutex unnecessarily, rc=$?"
21243         fi
21244         rm -f $DIR/$tfile
21245
21246 }
21247 run_test 258b "verify i_mutex security behavior"
21248
21249 test_259() {
21250         local file=$DIR/$tfile
21251         local before
21252         local after
21253
21254         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21255
21256         stack_trap "rm -f $file" EXIT
21257
21258         wait_delete_completed
21259         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21260         echo "before: $before"
21261
21262         $LFS setstripe -i 0 -c 1 $file
21263         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21264         sync_all_data
21265         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21266         echo "after write: $after"
21267
21268 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21269         do_facet ost1 $LCTL set_param fail_loc=0x2301
21270         $TRUNCATE $file 0
21271         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21272         echo "after truncate: $after"
21273
21274         stop ost1
21275         do_facet ost1 $LCTL set_param fail_loc=0
21276         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21277         sleep 2
21278         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21279         echo "after restart: $after"
21280         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21281                 error "missing truncate?"
21282
21283         return 0
21284 }
21285 run_test 259 "crash at delayed truncate"
21286
21287 test_260() {
21288 #define OBD_FAIL_MDC_CLOSE               0x806
21289         $LCTL set_param fail_loc=0x80000806
21290         touch $DIR/$tfile
21291
21292 }
21293 run_test 260 "Check mdc_close fail"
21294
21295 ### Data-on-MDT sanity tests ###
21296 test_270a() {
21297         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21298                 skip "Need MDS version at least 2.10.55 for DoM"
21299
21300         # create DoM file
21301         local dom=$DIR/$tdir/dom_file
21302         local tmp=$DIR/$tdir/tmp_file
21303
21304         mkdir_on_mdt0 $DIR/$tdir
21305
21306         # basic checks for DoM component creation
21307         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21308                 error "Can set MDT layout to non-first entry"
21309
21310         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21311                 error "Can define multiple entries as MDT layout"
21312
21313         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21314
21315         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21316         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21317         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21318
21319         local mdtidx=$($LFS getstripe -m $dom)
21320         local mdtname=MDT$(printf %04x $mdtidx)
21321         local facet=mds$((mdtidx + 1))
21322         local space_check=1
21323
21324         # Skip free space checks with ZFS
21325         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21326
21327         # write
21328         sync
21329         local size_tmp=$((65536 * 3))
21330         local mdtfree1=$(do_facet $facet \
21331                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21332
21333         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21334         # check also direct IO along write
21335         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21336         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21337         sync
21338         cmp $tmp $dom || error "file data is different"
21339         [ $(stat -c%s $dom) == $size_tmp ] ||
21340                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21341         if [ $space_check == 1 ]; then
21342                 local mdtfree2=$(do_facet $facet \
21343                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21344
21345                 # increase in usage from by $size_tmp
21346                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21347                         error "MDT free space wrong after write: " \
21348                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21349         fi
21350
21351         # truncate
21352         local size_dom=10000
21353
21354         $TRUNCATE $dom $size_dom
21355         [ $(stat -c%s $dom) == $size_dom ] ||
21356                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21357         if [ $space_check == 1 ]; then
21358                 mdtfree1=$(do_facet $facet \
21359                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21360                 # decrease in usage from $size_tmp to new $size_dom
21361                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21362                   $(((size_tmp - size_dom) / 1024)) ] ||
21363                         error "MDT free space is wrong after truncate: " \
21364                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21365         fi
21366
21367         # append
21368         cat $tmp >> $dom
21369         sync
21370         size_dom=$((size_dom + size_tmp))
21371         [ $(stat -c%s $dom) == $size_dom ] ||
21372                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21373         if [ $space_check == 1 ]; then
21374                 mdtfree2=$(do_facet $facet \
21375                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21376                 # increase in usage by $size_tmp from previous
21377                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21378                         error "MDT free space is wrong after append: " \
21379                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21380         fi
21381
21382         # delete
21383         rm $dom
21384         if [ $space_check == 1 ]; then
21385                 mdtfree1=$(do_facet $facet \
21386                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21387                 # decrease in usage by $size_dom from previous
21388                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21389                         error "MDT free space is wrong after removal: " \
21390                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21391         fi
21392
21393         # combined striping
21394         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21395                 error "Can't create DoM + OST striping"
21396
21397         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21398         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21399         # check also direct IO along write
21400         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21401         sync
21402         cmp $tmp $dom || error "file data is different"
21403         [ $(stat -c%s $dom) == $size_tmp ] ||
21404                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21405         rm $dom $tmp
21406
21407         return 0
21408 }
21409 run_test 270a "DoM: basic functionality tests"
21410
21411 test_270b() {
21412         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21413                 skip "Need MDS version at least 2.10.55"
21414
21415         local dom=$DIR/$tdir/dom_file
21416         local max_size=1048576
21417
21418         mkdir -p $DIR/$tdir
21419         $LFS setstripe -E $max_size -L mdt $dom
21420
21421         # truncate over the limit
21422         $TRUNCATE $dom $(($max_size + 1)) &&
21423                 error "successful truncate over the maximum size"
21424         # write over the limit
21425         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21426                 error "successful write over the maximum size"
21427         # append over the limit
21428         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21429         echo "12345" >> $dom && error "successful append over the maximum size"
21430         rm $dom
21431
21432         return 0
21433 }
21434 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21435
21436 test_270c() {
21437         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21438                 skip "Need MDS version at least 2.10.55"
21439
21440         mkdir -p $DIR/$tdir
21441         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21442
21443         # check files inherit DoM EA
21444         touch $DIR/$tdir/first
21445         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21446                 error "bad pattern"
21447         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21448                 error "bad stripe count"
21449         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21450                 error "bad stripe size"
21451
21452         # check directory inherits DoM EA and uses it as default
21453         mkdir $DIR/$tdir/subdir
21454         touch $DIR/$tdir/subdir/second
21455         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21456                 error "bad pattern in sub-directory"
21457         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21458                 error "bad stripe count in sub-directory"
21459         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21460                 error "bad stripe size in sub-directory"
21461         return 0
21462 }
21463 run_test 270c "DoM: DoM EA inheritance tests"
21464
21465 test_270d() {
21466         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21467                 skip "Need MDS version at least 2.10.55"
21468
21469         mkdir -p $DIR/$tdir
21470         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21471
21472         # inherit default DoM striping
21473         mkdir $DIR/$tdir/subdir
21474         touch $DIR/$tdir/subdir/f1
21475
21476         # change default directory striping
21477         $LFS setstripe -c 1 $DIR/$tdir/subdir
21478         touch $DIR/$tdir/subdir/f2
21479         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21480                 error "wrong default striping in file 2"
21481         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21482                 error "bad pattern in file 2"
21483         return 0
21484 }
21485 run_test 270d "DoM: change striping from DoM to RAID0"
21486
21487 test_270e() {
21488         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21489                 skip "Need MDS version at least 2.10.55"
21490
21491         mkdir -p $DIR/$tdir/dom
21492         mkdir -p $DIR/$tdir/norm
21493         DOMFILES=20
21494         NORMFILES=10
21495         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21496         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21497
21498         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21499         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21500
21501         # find DoM files by layout
21502         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21503         [ $NUM -eq  $DOMFILES ] ||
21504                 error "lfs find -L: found $NUM, expected $DOMFILES"
21505         echo "Test 1: lfs find 20 DOM files by layout: OK"
21506
21507         # there should be 1 dir with default DOM striping
21508         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21509         [ $NUM -eq  1 ] ||
21510                 error "lfs find -L: found $NUM, expected 1 dir"
21511         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21512
21513         # find DoM files by stripe size
21514         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21515         [ $NUM -eq  $DOMFILES ] ||
21516                 error "lfs find -S: found $NUM, expected $DOMFILES"
21517         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21518
21519         # find files by stripe offset except DoM files
21520         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21521         [ $NUM -eq  $NORMFILES ] ||
21522                 error "lfs find -i: found $NUM, expected $NORMFILES"
21523         echo "Test 5: lfs find no DOM files by stripe index: OK"
21524         return 0
21525 }
21526 run_test 270e "DoM: lfs find with DoM files test"
21527
21528 test_270f() {
21529         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21530                 skip "Need MDS version at least 2.10.55"
21531
21532         local mdtname=${FSNAME}-MDT0000-mdtlov
21533         local dom=$DIR/$tdir/dom_file
21534         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21535                                                 lod.$mdtname.dom_stripesize)
21536         local dom_limit=131072
21537
21538         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21539         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21540                                                 lod.$mdtname.dom_stripesize)
21541         [ ${dom_limit} -eq ${dom_current} ] ||
21542                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21543
21544         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21545         $LFS setstripe -d $DIR/$tdir
21546         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21547                 error "Can't set directory default striping"
21548
21549         # exceed maximum stripe size
21550         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21551                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21552         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21553                 error "Able to create DoM component size more than LOD limit"
21554
21555         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21556         dom_current=$(do_facet mds1 $LCTL get_param -n \
21557                                                 lod.$mdtname.dom_stripesize)
21558         [ 0 -eq ${dom_current} ] ||
21559                 error "Can't set zero DoM stripe limit"
21560         rm $dom
21561
21562         # attempt to create DoM file on server with disabled DoM should
21563         # remove DoM entry from layout and be succeed
21564         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21565                 error "Can't create DoM file (DoM is disabled)"
21566         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21567                 error "File has DoM component while DoM is disabled"
21568         rm $dom
21569
21570         # attempt to create DoM file with only DoM stripe should return error
21571         $LFS setstripe -E $dom_limit -L mdt $dom &&
21572                 error "Able to create DoM-only file while DoM is disabled"
21573
21574         # too low values to be aligned with smallest stripe size 64K
21575         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21576         dom_current=$(do_facet mds1 $LCTL get_param -n \
21577                                                 lod.$mdtname.dom_stripesize)
21578         [ 30000 -eq ${dom_current} ] &&
21579                 error "Can set too small DoM stripe limit"
21580
21581         # 64K is a minimal stripe size in Lustre, expect limit of that size
21582         [ 65536 -eq ${dom_current} ] ||
21583                 error "Limit is not set to 64K but ${dom_current}"
21584
21585         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21586         dom_current=$(do_facet mds1 $LCTL get_param -n \
21587                                                 lod.$mdtname.dom_stripesize)
21588         echo $dom_current
21589         [ 2147483648 -eq ${dom_current} ] &&
21590                 error "Can set too large DoM stripe limit"
21591
21592         do_facet mds1 $LCTL set_param -n \
21593                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21594         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21595                 error "Can't create DoM component size after limit change"
21596         do_facet mds1 $LCTL set_param -n \
21597                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21598         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21599                 error "Can't create DoM file after limit decrease"
21600         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21601                 error "Can create big DoM component after limit decrease"
21602         touch ${dom}_def ||
21603                 error "Can't create file with old default layout"
21604
21605         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21606         return 0
21607 }
21608 run_test 270f "DoM: maximum DoM stripe size checks"
21609
21610 test_270g() {
21611         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21612                 skip "Need MDS version at least 2.13.52"
21613         local dom=$DIR/$tdir/$tfile
21614
21615         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21616         local lodname=${FSNAME}-MDT0000-mdtlov
21617
21618         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21619         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21620         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21621         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21622
21623         local dom_limit=1024
21624         local dom_threshold="50%"
21625
21626         $LFS setstripe -d $DIR/$tdir
21627         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21628                 error "Can't set directory default striping"
21629
21630         do_facet mds1 $LCTL set_param -n \
21631                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21632         # set 0 threshold and create DOM file to change tunable stripesize
21633         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21634         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21635                 error "Failed to create $dom file"
21636         # now tunable dom_cur_stripesize should reach maximum
21637         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21638                                         lod.${lodname}.dom_stripesize_cur_kb)
21639         [[ $dom_current == $dom_limit ]] ||
21640                 error "Current DOM stripesize is not maximum"
21641         rm $dom
21642
21643         # set threshold for further tests
21644         do_facet mds1 $LCTL set_param -n \
21645                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21646         echo "DOM threshold is $dom_threshold free space"
21647         local dom_def
21648         local dom_set
21649         # Spoof bfree to exceed threshold
21650         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21651         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21652         for spfree in 40 20 0 15 30 55; do
21653                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21654                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21655                         error "Failed to create $dom file"
21656                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21657                                         lod.${lodname}.dom_stripesize_cur_kb)
21658                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21659                 [[ $dom_def != $dom_current ]] ||
21660                         error "Default stripe size was not changed"
21661                 if [[ $spfree > 0 ]] ; then
21662                         dom_set=$($LFS getstripe -S $dom)
21663                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21664                                 error "DOM component size is still old"
21665                 else
21666                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21667                                 error "DoM component is set with no free space"
21668                 fi
21669                 rm $dom
21670                 dom_current=$dom_def
21671         done
21672 }
21673 run_test 270g "DoM: default DoM stripe size depends on free space"
21674
21675 test_270h() {
21676         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21677                 skip "Need MDS version at least 2.13.53"
21678
21679         local mdtname=${FSNAME}-MDT0000-mdtlov
21680         local dom=$DIR/$tdir/$tfile
21681         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21682
21683         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21684         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21685
21686         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21687         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21688                 error "can't create OST file"
21689         # mirrored file with DOM entry in the second mirror
21690         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21691                 error "can't create mirror with DoM component"
21692
21693         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21694
21695         # DOM component in the middle and has other enries in the same mirror,
21696         # should succeed but lost DoM component
21697         $LFS setstripe --copy=${dom}_1 $dom ||
21698                 error "Can't create file from OST|DOM mirror layout"
21699         # check new file has no DoM layout after all
21700         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21701                 error "File has DoM component while DoM is disabled"
21702 }
21703 run_test 270h "DoM: DoM stripe removal when disabled on server"
21704
21705 test_271a() {
21706         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21707                 skip "Need MDS version at least 2.10.55"
21708
21709         local dom=$DIR/$tdir/dom
21710
21711         mkdir -p $DIR/$tdir
21712
21713         $LFS setstripe -E 1024K -L mdt $dom
21714
21715         lctl set_param -n mdc.*.stats=clear
21716         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21717         cat $dom > /dev/null
21718         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21719         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21720         ls $dom
21721         rm -f $dom
21722 }
21723 run_test 271a "DoM: data is cached for read after write"
21724
21725 test_271b() {
21726         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21727                 skip "Need MDS version at least 2.10.55"
21728
21729         local dom=$DIR/$tdir/dom
21730
21731         mkdir -p $DIR/$tdir
21732
21733         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21734
21735         lctl set_param -n mdc.*.stats=clear
21736         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21737         cancel_lru_locks mdc
21738         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21739         # second stat to check size is cached on client
21740         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21741         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21742         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21743         rm -f $dom
21744 }
21745 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21746
21747 test_271ba() {
21748         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21749                 skip "Need MDS version at least 2.10.55"
21750
21751         local dom=$DIR/$tdir/dom
21752
21753         mkdir -p $DIR/$tdir
21754
21755         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21756
21757         lctl set_param -n mdc.*.stats=clear
21758         lctl set_param -n osc.*.stats=clear
21759         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21760         cancel_lru_locks mdc
21761         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21762         # second stat to check size is cached on client
21763         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21764         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21765         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21766         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21767         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21768         rm -f $dom
21769 }
21770 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21771
21772
21773 get_mdc_stats() {
21774         local mdtidx=$1
21775         local param=$2
21776         local mdt=MDT$(printf %04x $mdtidx)
21777
21778         if [ -z $param ]; then
21779                 lctl get_param -n mdc.*$mdt*.stats
21780         else
21781                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21782         fi
21783 }
21784
21785 test_271c() {
21786         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21787                 skip "Need MDS version at least 2.10.55"
21788
21789         local dom=$DIR/$tdir/dom
21790
21791         mkdir -p $DIR/$tdir
21792
21793         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21794
21795         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21796         local facet=mds$((mdtidx + 1))
21797
21798         cancel_lru_locks mdc
21799         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21800         createmany -o $dom 1000
21801         lctl set_param -n mdc.*.stats=clear
21802         smalliomany -w $dom 1000 200
21803         get_mdc_stats $mdtidx
21804         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21805         # Each file has 1 open, 1 IO enqueues, total 2000
21806         # but now we have also +1 getxattr for security.capability, total 3000
21807         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21808         unlinkmany $dom 1000
21809
21810         cancel_lru_locks mdc
21811         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21812         createmany -o $dom 1000
21813         lctl set_param -n mdc.*.stats=clear
21814         smalliomany -w $dom 1000 200
21815         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21816         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21817         # for OPEN and IO lock.
21818         [ $((enq - enq_2)) -ge 1000 ] ||
21819                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21820         unlinkmany $dom 1000
21821         return 0
21822 }
21823 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21824
21825 cleanup_271def_tests() {
21826         trap 0
21827         rm -f $1
21828 }
21829
21830 test_271d() {
21831         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21832                 skip "Need MDS version at least 2.10.57"
21833
21834         local dom=$DIR/$tdir/dom
21835         local tmp=$TMP/$tfile
21836         trap "cleanup_271def_tests $tmp" EXIT
21837
21838         mkdir -p $DIR/$tdir
21839
21840         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21841
21842         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21843
21844         cancel_lru_locks mdc
21845         dd if=/dev/urandom of=$tmp bs=1000 count=1
21846         dd if=$tmp of=$dom bs=1000 count=1
21847         cancel_lru_locks mdc
21848
21849         cat /etc/hosts >> $tmp
21850         lctl set_param -n mdc.*.stats=clear
21851
21852         # append data to the same file it should update local page
21853         echo "Append to the same page"
21854         cat /etc/hosts >> $dom
21855         local num=$(get_mdc_stats $mdtidx ost_read)
21856         local ra=$(get_mdc_stats $mdtidx req_active)
21857         local rw=$(get_mdc_stats $mdtidx req_waittime)
21858
21859         [ -z $num ] || error "$num READ RPC occured"
21860         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21861         echo "... DONE"
21862
21863         # compare content
21864         cmp $tmp $dom || error "file miscompare"
21865
21866         cancel_lru_locks mdc
21867         lctl set_param -n mdc.*.stats=clear
21868
21869         echo "Open and read file"
21870         cat $dom > /dev/null
21871         local num=$(get_mdc_stats $mdtidx ost_read)
21872         local ra=$(get_mdc_stats $mdtidx req_active)
21873         local rw=$(get_mdc_stats $mdtidx req_waittime)
21874
21875         [ -z $num ] || error "$num READ RPC occured"
21876         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21877         echo "... DONE"
21878
21879         # compare content
21880         cmp $tmp $dom || error "file miscompare"
21881
21882         return 0
21883 }
21884 run_test 271d "DoM: read on open (1K file in reply buffer)"
21885
21886 test_271f() {
21887         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21888                 skip "Need MDS version at least 2.10.57"
21889
21890         local dom=$DIR/$tdir/dom
21891         local tmp=$TMP/$tfile
21892         trap "cleanup_271def_tests $tmp" EXIT
21893
21894         mkdir -p $DIR/$tdir
21895
21896         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21897
21898         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21899
21900         cancel_lru_locks mdc
21901         dd if=/dev/urandom of=$tmp bs=265000 count=1
21902         dd if=$tmp of=$dom bs=265000 count=1
21903         cancel_lru_locks mdc
21904         cat /etc/hosts >> $tmp
21905         lctl set_param -n mdc.*.stats=clear
21906
21907         echo "Append to the same page"
21908         cat /etc/hosts >> $dom
21909         local num=$(get_mdc_stats $mdtidx ost_read)
21910         local ra=$(get_mdc_stats $mdtidx req_active)
21911         local rw=$(get_mdc_stats $mdtidx req_waittime)
21912
21913         [ -z $num ] || error "$num READ RPC occured"
21914         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21915         echo "... DONE"
21916
21917         # compare content
21918         cmp $tmp $dom || error "file miscompare"
21919
21920         cancel_lru_locks mdc
21921         lctl set_param -n mdc.*.stats=clear
21922
21923         echo "Open and read file"
21924         cat $dom > /dev/null
21925         local num=$(get_mdc_stats $mdtidx ost_read)
21926         local ra=$(get_mdc_stats $mdtidx req_active)
21927         local rw=$(get_mdc_stats $mdtidx req_waittime)
21928
21929         [ -z $num ] && num=0
21930         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
21931         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21932         echo "... DONE"
21933
21934         # compare content
21935         cmp $tmp $dom || error "file miscompare"
21936
21937         return 0
21938 }
21939 run_test 271f "DoM: read on open (200K file and read tail)"
21940
21941 test_271g() {
21942         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
21943                 skip "Skipping due to old client or server version"
21944
21945         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
21946         # to get layout
21947         $CHECKSTAT -t file $DIR1/$tfile
21948
21949         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
21950         MULTIOP_PID=$!
21951         sleep 1
21952         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
21953         $LCTL set_param fail_loc=0x80000314
21954         rm $DIR1/$tfile || error "Unlink fails"
21955         RC=$?
21956         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
21957         [ $RC -eq 0 ] || error "Failed write to stale object"
21958 }
21959 run_test 271g "Discard DoM data vs client flush race"
21960
21961 test_272a() {
21962         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21963                 skip "Need MDS version at least 2.11.50"
21964
21965         local dom=$DIR/$tdir/dom
21966         mkdir -p $DIR/$tdir
21967
21968         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
21969         dd if=/dev/urandom of=$dom bs=512K count=1 ||
21970                 error "failed to write data into $dom"
21971         local old_md5=$(md5sum $dom)
21972
21973         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
21974                 error "failed to migrate to the same DoM component"
21975
21976         local new_md5=$(md5sum $dom)
21977
21978         [ "$old_md5" == "$new_md5" ] ||
21979                 error "md5sum differ: $old_md5, $new_md5"
21980
21981         [ $($LFS getstripe -c $dom) -eq 2 ] ||
21982                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
21983 }
21984 run_test 272a "DoM migration: new layout with the same DOM component"
21985
21986 test_272b() {
21987         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
21988                 skip "Need MDS version at least 2.11.50"
21989
21990         local dom=$DIR/$tdir/dom
21991         mkdir -p $DIR/$tdir
21992         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
21993
21994         local mdtidx=$($LFS getstripe -m $dom)
21995         local mdtname=MDT$(printf %04x $mdtidx)
21996         local facet=mds$((mdtidx + 1))
21997
21998         local mdtfree1=$(do_facet $facet \
21999                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22000         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22001                 error "failed to write data into $dom"
22002         local old_md5=$(md5sum $dom)
22003         cancel_lru_locks mdc
22004         local mdtfree1=$(do_facet $facet \
22005                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22006
22007         $LFS migrate -c2 $dom ||
22008                 error "failed to migrate to the new composite layout"
22009         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22010                 error "MDT stripe was not removed"
22011
22012         cancel_lru_locks mdc
22013         local new_md5=$(md5sum $dom)
22014         [ "$old_md5" == "$new_md5" ] ||
22015                 error "$old_md5 != $new_md5"
22016
22017         # Skip free space checks with ZFS
22018         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22019                 local mdtfree2=$(do_facet $facet \
22020                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22021                 [ $mdtfree2 -gt $mdtfree1 ] ||
22022                         error "MDT space is not freed after migration"
22023         fi
22024         return 0
22025 }
22026 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22027
22028 test_272c() {
22029         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22030                 skip "Need MDS version at least 2.11.50"
22031
22032         local dom=$DIR/$tdir/$tfile
22033         mkdir -p $DIR/$tdir
22034         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22035
22036         local mdtidx=$($LFS getstripe -m $dom)
22037         local mdtname=MDT$(printf %04x $mdtidx)
22038         local facet=mds$((mdtidx + 1))
22039
22040         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22041                 error "failed to write data into $dom"
22042         local old_md5=$(md5sum $dom)
22043         cancel_lru_locks mdc
22044         local mdtfree1=$(do_facet $facet \
22045                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22046
22047         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22048                 error "failed to migrate to the new composite layout"
22049         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22050                 error "MDT stripe was not removed"
22051
22052         cancel_lru_locks mdc
22053         local new_md5=$(md5sum $dom)
22054         [ "$old_md5" == "$new_md5" ] ||
22055                 error "$old_md5 != $new_md5"
22056
22057         # Skip free space checks with ZFS
22058         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22059                 local mdtfree2=$(do_facet $facet \
22060                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22061                 [ $mdtfree2 -gt $mdtfree1 ] ||
22062                         error "MDS space is not freed after migration"
22063         fi
22064         return 0
22065 }
22066 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22067
22068 test_272d() {
22069         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22070                 skip "Need MDS version at least 2.12.55"
22071
22072         local dom=$DIR/$tdir/$tfile
22073         mkdir -p $DIR/$tdir
22074         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22075
22076         local mdtidx=$($LFS getstripe -m $dom)
22077         local mdtname=MDT$(printf %04x $mdtidx)
22078         local facet=mds$((mdtidx + 1))
22079
22080         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22081                 error "failed to write data into $dom"
22082         local old_md5=$(md5sum $dom)
22083         cancel_lru_locks mdc
22084         local mdtfree1=$(do_facet $facet \
22085                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22086
22087         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22088                 error "failed mirroring to the new composite layout"
22089         $LFS mirror resync $dom ||
22090                 error "failed mirror resync"
22091         $LFS mirror split --mirror-id 1 -d $dom ||
22092                 error "failed mirror split"
22093
22094         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22095                 error "MDT stripe was not removed"
22096
22097         cancel_lru_locks mdc
22098         local new_md5=$(md5sum $dom)
22099         [ "$old_md5" == "$new_md5" ] ||
22100                 error "$old_md5 != $new_md5"
22101
22102         # Skip free space checks with ZFS
22103         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22104                 local mdtfree2=$(do_facet $facet \
22105                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22106                 [ $mdtfree2 -gt $mdtfree1 ] ||
22107                         error "MDS space is not freed after DOM mirror deletion"
22108         fi
22109         return 0
22110 }
22111 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22112
22113 test_272e() {
22114         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22115                 skip "Need MDS version at least 2.12.55"
22116
22117         local dom=$DIR/$tdir/$tfile
22118         mkdir -p $DIR/$tdir
22119         $LFS setstripe -c 2 $dom
22120
22121         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22122                 error "failed to write data into $dom"
22123         local old_md5=$(md5sum $dom)
22124         cancel_lru_locks mdc
22125
22126         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22127                 error "failed mirroring to the DOM layout"
22128         $LFS mirror resync $dom ||
22129                 error "failed mirror resync"
22130         $LFS mirror split --mirror-id 1 -d $dom ||
22131                 error "failed mirror split"
22132
22133         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22134                 error "MDT stripe was not removed"
22135
22136         cancel_lru_locks mdc
22137         local new_md5=$(md5sum $dom)
22138         [ "$old_md5" == "$new_md5" ] ||
22139                 error "$old_md5 != $new_md5"
22140
22141         return 0
22142 }
22143 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22144
22145 test_272f() {
22146         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22147                 skip "Need MDS version at least 2.12.55"
22148
22149         local dom=$DIR/$tdir/$tfile
22150         mkdir -p $DIR/$tdir
22151         $LFS setstripe -c 2 $dom
22152
22153         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22154                 error "failed to write data into $dom"
22155         local old_md5=$(md5sum $dom)
22156         cancel_lru_locks mdc
22157
22158         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22159                 error "failed migrating to the DOM file"
22160
22161         cancel_lru_locks mdc
22162         local new_md5=$(md5sum $dom)
22163         [ "$old_md5" != "$new_md5" ] &&
22164                 error "$old_md5 != $new_md5"
22165
22166         return 0
22167 }
22168 run_test 272f "DoM migration: OST-striped file to DOM file"
22169
22170 test_273a() {
22171         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22172                 skip "Need MDS version at least 2.11.50"
22173
22174         # Layout swap cannot be done if either file has DOM component,
22175         # this will never be supported, migration should be used instead
22176
22177         local dom=$DIR/$tdir/$tfile
22178         mkdir -p $DIR/$tdir
22179
22180         $LFS setstripe -c2 ${dom}_plain
22181         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22182         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22183                 error "can swap layout with DoM component"
22184         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22185                 error "can swap layout with DoM component"
22186
22187         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22188         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22189                 error "can swap layout with DoM component"
22190         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22191                 error "can swap layout with DoM component"
22192         return 0
22193 }
22194 run_test 273a "DoM: layout swapping should fail with DOM"
22195
22196 test_273b() {
22197         mkdir -p $DIR/$tdir
22198         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22199
22200 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22201         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22202
22203         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22204 }
22205 run_test 273b "DoM: race writeback and object destroy"
22206
22207 test_275() {
22208         remote_ost_nodsh && skip "remote OST with nodsh"
22209         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22210                 skip "Need OST version >= 2.10.57"
22211
22212         local file=$DIR/$tfile
22213         local oss
22214
22215         oss=$(comma_list $(osts_nodes))
22216
22217         dd if=/dev/urandom of=$file bs=1M count=2 ||
22218                 error "failed to create a file"
22219         cancel_lru_locks osc
22220
22221         #lock 1
22222         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22223                 error "failed to read a file"
22224
22225 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22226         $LCTL set_param fail_loc=0x8000031f
22227
22228         cancel_lru_locks osc &
22229         sleep 1
22230
22231 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22232         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22233         #IO takes another lock, but matches the PENDING one
22234         #and places it to the IO RPC
22235         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22236                 error "failed to read a file with PENDING lock"
22237 }
22238 run_test 275 "Read on a canceled duplicate lock"
22239
22240 test_276() {
22241         remote_ost_nodsh && skip "remote OST with nodsh"
22242         local pid
22243
22244         do_facet ost1 "(while true; do \
22245                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22246                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22247         pid=$!
22248
22249         for LOOP in $(seq 20); do
22250                 stop ost1
22251                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22252         done
22253         kill -9 $pid
22254         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22255                 rm $TMP/sanity_276_pid"
22256 }
22257 run_test 276 "Race between mount and obd_statfs"
22258
22259 test_277() {
22260         $LCTL set_param ldlm.namespaces.*.lru_size=0
22261         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22262         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22263                         grep ^used_mb | awk '{print $2}')
22264         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22265         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22266                 oflag=direct conv=notrunc
22267         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22268                         grep ^used_mb | awk '{print $2}')
22269         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22270 }
22271 run_test 277 "Direct IO shall drop page cache"
22272
22273 test_278() {
22274         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22275         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22276         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22277                 skip "needs the same host for mdt1 mdt2" && return
22278
22279         local pid1
22280         local pid2
22281
22282 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22283         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22284         stop mds2 &
22285         pid2=$!
22286
22287         stop mds1
22288
22289         echo "Starting MDTs"
22290         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22291         wait $pid2
22292 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22293 #will return NULL
22294         do_facet mds2 $LCTL set_param fail_loc=0
22295
22296         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22297         wait_recovery_complete mds2
22298 }
22299 run_test 278 "Race starting MDS between MDTs stop/start"
22300
22301 test_280() {
22302         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22303                 skip "Need MGS version at least 2.13.52"
22304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22305         combined_mgs_mds || skip "needs combined MGS/MDT"
22306
22307         umount_client $MOUNT
22308 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22309         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22310
22311         mount_client $MOUNT &
22312         sleep 1
22313         stop mgs || error "stop mgs failed"
22314         #for a race mgs would crash
22315         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22316         # make sure we unmount client before remounting
22317         wait
22318         umount_client $MOUNT
22319         mount_client $MOUNT || error "mount client failed"
22320 }
22321 run_test 280 "Race between MGS umount and client llog processing"
22322
22323 cleanup_test_300() {
22324         trap 0
22325         umask $SAVE_UMASK
22326 }
22327 test_striped_dir() {
22328         local mdt_index=$1
22329         local stripe_count
22330         local stripe_index
22331
22332         mkdir -p $DIR/$tdir
22333
22334         SAVE_UMASK=$(umask)
22335         trap cleanup_test_300 RETURN EXIT
22336
22337         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22338                                                 $DIR/$tdir/striped_dir ||
22339                 error "set striped dir error"
22340
22341         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22342         [ "$mode" = "755" ] || error "expect 755 got $mode"
22343
22344         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22345                 error "getdirstripe failed"
22346         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22347         if [ "$stripe_count" != "2" ]; then
22348                 error "1:stripe_count is $stripe_count, expect 2"
22349         fi
22350         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22351         if [ "$stripe_count" != "2" ]; then
22352                 error "2:stripe_count is $stripe_count, expect 2"
22353         fi
22354
22355         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22356         if [ "$stripe_index" != "$mdt_index" ]; then
22357                 error "stripe_index is $stripe_index, expect $mdt_index"
22358         fi
22359
22360         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22361                 error "nlink error after create striped dir"
22362
22363         mkdir $DIR/$tdir/striped_dir/a
22364         mkdir $DIR/$tdir/striped_dir/b
22365
22366         stat $DIR/$tdir/striped_dir/a ||
22367                 error "create dir under striped dir failed"
22368         stat $DIR/$tdir/striped_dir/b ||
22369                 error "create dir under striped dir failed"
22370
22371         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22372                 error "nlink error after mkdir"
22373
22374         rmdir $DIR/$tdir/striped_dir/a
22375         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22376                 error "nlink error after rmdir"
22377
22378         rmdir $DIR/$tdir/striped_dir/b
22379         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22380                 error "nlink error after rmdir"
22381
22382         chattr +i $DIR/$tdir/striped_dir
22383         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22384                 error "immutable flags not working under striped dir!"
22385         chattr -i $DIR/$tdir/striped_dir
22386
22387         rmdir $DIR/$tdir/striped_dir ||
22388                 error "rmdir striped dir error"
22389
22390         cleanup_test_300
22391
22392         true
22393 }
22394
22395 test_300a() {
22396         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22397                 skip "skipped for lustre < 2.7.0"
22398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22400
22401         test_striped_dir 0 || error "failed on striped dir on MDT0"
22402         test_striped_dir 1 || error "failed on striped dir on MDT0"
22403 }
22404 run_test 300a "basic striped dir sanity test"
22405
22406 test_300b() {
22407         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22408                 skip "skipped for lustre < 2.7.0"
22409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22411
22412         local i
22413         local mtime1
22414         local mtime2
22415         local mtime3
22416
22417         test_mkdir $DIR/$tdir || error "mkdir fail"
22418         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22419                 error "set striped dir error"
22420         for i in {0..9}; do
22421                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22422                 sleep 1
22423                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22424                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22425                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22426                 sleep 1
22427                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22428                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22429                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22430         done
22431         true
22432 }
22433 run_test 300b "check ctime/mtime for striped dir"
22434
22435 test_300c() {
22436         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22437                 skip "skipped for lustre < 2.7.0"
22438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22439         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22440
22441         local file_count
22442
22443         mkdir_on_mdt0 $DIR/$tdir
22444         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22445                 error "set striped dir error"
22446
22447         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22448                 error "chown striped dir failed"
22449
22450         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22451                 error "create 5k files failed"
22452
22453         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22454
22455         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22456
22457         rm -rf $DIR/$tdir
22458 }
22459 run_test 300c "chown && check ls under striped directory"
22460
22461 test_300d() {
22462         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22463                 skip "skipped for lustre < 2.7.0"
22464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22466
22467         local stripe_count
22468         local file
22469
22470         mkdir -p $DIR/$tdir
22471         $LFS setstripe -c 2 $DIR/$tdir
22472
22473         #local striped directory
22474         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22475                 error "set striped dir error"
22476         #look at the directories for debug purposes
22477         ls -l $DIR/$tdir
22478         $LFS getdirstripe $DIR/$tdir
22479         ls -l $DIR/$tdir/striped_dir
22480         $LFS getdirstripe $DIR/$tdir/striped_dir
22481         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22482                 error "create 10 files failed"
22483
22484         #remote striped directory
22485         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22486                 error "set striped dir error"
22487         #look at the directories for debug purposes
22488         ls -l $DIR/$tdir
22489         $LFS getdirstripe $DIR/$tdir
22490         ls -l $DIR/$tdir/remote_striped_dir
22491         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22492         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22493                 error "create 10 files failed"
22494
22495         for file in $(find $DIR/$tdir); do
22496                 stripe_count=$($LFS getstripe -c $file)
22497                 [ $stripe_count -eq 2 ] ||
22498                         error "wrong stripe $stripe_count for $file"
22499         done
22500
22501         rm -rf $DIR/$tdir
22502 }
22503 run_test 300d "check default stripe under striped directory"
22504
22505 test_300e() {
22506         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22507                 skip "Need MDS version at least 2.7.55"
22508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22509         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22510
22511         local stripe_count
22512         local file
22513
22514         mkdir -p $DIR/$tdir
22515
22516         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22517                 error "set striped dir error"
22518
22519         touch $DIR/$tdir/striped_dir/a
22520         touch $DIR/$tdir/striped_dir/b
22521         touch $DIR/$tdir/striped_dir/c
22522
22523         mkdir $DIR/$tdir/striped_dir/dir_a
22524         mkdir $DIR/$tdir/striped_dir/dir_b
22525         mkdir $DIR/$tdir/striped_dir/dir_c
22526
22527         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22528                 error "set striped adir under striped dir error"
22529
22530         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22531                 error "set striped bdir under striped dir error"
22532
22533         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22534                 error "set striped cdir under striped dir error"
22535
22536         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22537                 error "rename dir under striped dir fails"
22538
22539         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22540                 error "rename dir under different stripes fails"
22541
22542         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22543                 error "rename file under striped dir should succeed"
22544
22545         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22546                 error "rename dir under striped dir should succeed"
22547
22548         rm -rf $DIR/$tdir
22549 }
22550 run_test 300e "check rename under striped directory"
22551
22552 test_300f() {
22553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22555         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22556                 skip "Need MDS version at least 2.7.55"
22557
22558         local stripe_count
22559         local file
22560
22561         rm -rf $DIR/$tdir
22562         mkdir -p $DIR/$tdir
22563
22564         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22565                 error "set striped dir error"
22566
22567         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22568                 error "set striped dir error"
22569
22570         touch $DIR/$tdir/striped_dir/a
22571         mkdir $DIR/$tdir/striped_dir/dir_a
22572         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22573                 error "create striped dir under striped dir fails"
22574
22575         touch $DIR/$tdir/striped_dir1/b
22576         mkdir $DIR/$tdir/striped_dir1/dir_b
22577         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22578                 error "create striped dir under striped dir fails"
22579
22580         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22581                 error "rename dir under different striped dir should fail"
22582
22583         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22584                 error "rename striped dir under diff striped dir should fail"
22585
22586         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22587                 error "rename file under diff striped dirs fails"
22588
22589         rm -rf $DIR/$tdir
22590 }
22591 run_test 300f "check rename cross striped directory"
22592
22593 test_300_check_default_striped_dir()
22594 {
22595         local dirname=$1
22596         local default_count=$2
22597         local default_index=$3
22598         local stripe_count
22599         local stripe_index
22600         local dir_stripe_index
22601         local dir
22602
22603         echo "checking $dirname $default_count $default_index"
22604         $LFS setdirstripe -D -c $default_count -i $default_index \
22605                                 -H all_char $DIR/$tdir/$dirname ||
22606                 error "set default stripe on striped dir error"
22607         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22608         [ $stripe_count -eq $default_count ] ||
22609                 error "expect $default_count get $stripe_count for $dirname"
22610
22611         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22612         [ $stripe_index -eq $default_index ] ||
22613                 error "expect $default_index get $stripe_index for $dirname"
22614
22615         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22616                                                 error "create dirs failed"
22617
22618         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22619         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22620         for dir in $(find $DIR/$tdir/$dirname/*); do
22621                 stripe_count=$($LFS getdirstripe -c $dir)
22622                 (( $stripe_count == $default_count )) ||
22623                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22624                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22625                 error "stripe count $default_count != $stripe_count for $dir"
22626
22627                 stripe_index=$($LFS getdirstripe -i $dir)
22628                 [ $default_index -eq -1 ] ||
22629                         [ $stripe_index -eq $default_index ] ||
22630                         error "$stripe_index != $default_index for $dir"
22631
22632                 #check default stripe
22633                 stripe_count=$($LFS getdirstripe -D -c $dir)
22634                 [ $stripe_count -eq $default_count ] ||
22635                 error "default count $default_count != $stripe_count for $dir"
22636
22637                 stripe_index=$($LFS getdirstripe -D -i $dir)
22638                 [ $stripe_index -eq $default_index ] ||
22639                 error "default index $default_index != $stripe_index for $dir"
22640         done
22641         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22642 }
22643
22644 test_300g() {
22645         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22646         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22647                 skip "Need MDS version at least 2.7.55"
22648
22649         local dir
22650         local stripe_count
22651         local stripe_index
22652
22653         mkdir_on_mdt0 $DIR/$tdir
22654         mkdir $DIR/$tdir/normal_dir
22655
22656         #Checking when client cache stripe index
22657         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22658         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22659                 error "create striped_dir failed"
22660
22661         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22662                 error "create dir0 fails"
22663         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22664         [ $stripe_index -eq 0 ] ||
22665                 error "dir0 expect index 0 got $stripe_index"
22666
22667         mkdir $DIR/$tdir/striped_dir/dir1 ||
22668                 error "create dir1 fails"
22669         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22670         [ $stripe_index -eq 1 ] ||
22671                 error "dir1 expect index 1 got $stripe_index"
22672
22673         #check default stripe count/stripe index
22674         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22675         test_300_check_default_striped_dir normal_dir 1 0
22676         test_300_check_default_striped_dir normal_dir -1 1
22677         test_300_check_default_striped_dir normal_dir 2 -1
22678
22679         #delete default stripe information
22680         echo "delete default stripeEA"
22681         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22682                 error "set default stripe on striped dir error"
22683
22684         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22685         for dir in $(find $DIR/$tdir/normal_dir/*); do
22686                 stripe_count=$($LFS getdirstripe -c $dir)
22687                 [ $stripe_count -eq 0 ] ||
22688                         error "expect 1 get $stripe_count for $dir"
22689         done
22690 }
22691 run_test 300g "check default striped directory for normal directory"
22692
22693 test_300h() {
22694         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22695         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22696                 skip "Need MDS version at least 2.7.55"
22697
22698         local dir
22699         local stripe_count
22700
22701         mkdir $DIR/$tdir
22702         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22703                 error "set striped dir error"
22704
22705         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22706         test_300_check_default_striped_dir striped_dir 1 0
22707         test_300_check_default_striped_dir striped_dir -1 1
22708         test_300_check_default_striped_dir striped_dir 2 -1
22709
22710         #delete default stripe information
22711         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22712                 error "set default stripe on striped dir error"
22713
22714         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22715         for dir in $(find $DIR/$tdir/striped_dir/*); do
22716                 stripe_count=$($LFS getdirstripe -c $dir)
22717                 [ $stripe_count -eq 0 ] ||
22718                         error "expect 1 get $stripe_count for $dir"
22719         done
22720 }
22721 run_test 300h "check default striped directory for striped directory"
22722
22723 test_300i() {
22724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22726         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22727                 skip "Need MDS version at least 2.7.55"
22728
22729         local stripe_count
22730         local file
22731
22732         mkdir $DIR/$tdir
22733
22734         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22735                 error "set striped dir error"
22736
22737         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22738                 error "create files under striped dir failed"
22739
22740         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22741                 error "set striped hashdir error"
22742
22743         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22744                 error "create dir0 under hash dir failed"
22745         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22746                 error "create dir1 under hash dir failed"
22747         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22748                 error "create dir2 under hash dir failed"
22749
22750         # unfortunately, we need to umount to clear dir layout cache for now
22751         # once we fully implement dir layout, we can drop this
22752         umount_client $MOUNT || error "umount failed"
22753         mount_client $MOUNT || error "mount failed"
22754
22755         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22756         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22757         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22758
22759         #set the stripe to be unknown hash type
22760         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22761         $LCTL set_param fail_loc=0x1901
22762         for ((i = 0; i < 10; i++)); do
22763                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22764                         error "stat f-$i failed"
22765                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22766         done
22767
22768         touch $DIR/$tdir/striped_dir/f0 &&
22769                 error "create under striped dir with unknown hash should fail"
22770
22771         $LCTL set_param fail_loc=0
22772
22773         umount_client $MOUNT || error "umount failed"
22774         mount_client $MOUNT || error "mount failed"
22775
22776         return 0
22777 }
22778 run_test 300i "client handle unknown hash type striped directory"
22779
22780 test_300j() {
22781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22783         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22784                 skip "Need MDS version at least 2.7.55"
22785
22786         local stripe_count
22787         local file
22788
22789         mkdir $DIR/$tdir
22790
22791         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22792         $LCTL set_param fail_loc=0x1702
22793         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22794                 error "set striped dir error"
22795
22796         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22797                 error "create files under striped dir failed"
22798
22799         $LCTL set_param fail_loc=0
22800
22801         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22802
22803         return 0
22804 }
22805 run_test 300j "test large update record"
22806
22807 test_300k() {
22808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22810         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22811                 skip "Need MDS version at least 2.7.55"
22812
22813         # this test needs a huge transaction
22814         local kb
22815         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22816              osd*.$FSNAME-MDT0000.kbytestotal")
22817         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22818
22819         local stripe_count
22820         local file
22821
22822         mkdir $DIR/$tdir
22823
22824         #define OBD_FAIL_LARGE_STRIPE   0x1703
22825         $LCTL set_param fail_loc=0x1703
22826         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22827                 error "set striped dir error"
22828         $LCTL set_param fail_loc=0
22829
22830         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22831                 error "getstripeddir fails"
22832         rm -rf $DIR/$tdir/striped_dir ||
22833                 error "unlink striped dir fails"
22834
22835         return 0
22836 }
22837 run_test 300k "test large striped directory"
22838
22839 test_300l() {
22840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22841         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22842         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22843                 skip "Need MDS version at least 2.7.55"
22844
22845         local stripe_index
22846
22847         test_mkdir -p $DIR/$tdir/striped_dir
22848         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22849                         error "chown $RUNAS_ID failed"
22850         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22851                 error "set default striped dir failed"
22852
22853         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22854         $LCTL set_param fail_loc=0x80000158
22855         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22856
22857         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22858         [ $stripe_index -eq 1 ] ||
22859                 error "expect 1 get $stripe_index for $dir"
22860 }
22861 run_test 300l "non-root user to create dir under striped dir with stale layout"
22862
22863 test_300m() {
22864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22865         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22866         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22867                 skip "Need MDS version at least 2.7.55"
22868
22869         mkdir -p $DIR/$tdir/striped_dir
22870         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22871                 error "set default stripes dir error"
22872
22873         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22874
22875         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22876         [ $stripe_count -eq 0 ] ||
22877                         error "expect 0 get $stripe_count for a"
22878
22879         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22880                 error "set default stripes dir error"
22881
22882         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22883
22884         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22885         [ $stripe_count -eq 0 ] ||
22886                         error "expect 0 get $stripe_count for b"
22887
22888         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22889                 error "set default stripes dir error"
22890
22891         mkdir $DIR/$tdir/striped_dir/c &&
22892                 error "default stripe_index is invalid, mkdir c should fails"
22893
22894         rm -rf $DIR/$tdir || error "rmdir fails"
22895 }
22896 run_test 300m "setstriped directory on single MDT FS"
22897
22898 cleanup_300n() {
22899         local list=$(comma_list $(mdts_nodes))
22900
22901         trap 0
22902         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22903 }
22904
22905 test_300n() {
22906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22908         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22909                 skip "Need MDS version at least 2.7.55"
22910         remote_mds_nodsh && skip "remote MDS with nodsh"
22911
22912         local stripe_index
22913         local list=$(comma_list $(mdts_nodes))
22914
22915         trap cleanup_300n RETURN EXIT
22916         mkdir -p $DIR/$tdir
22917         chmod 777 $DIR/$tdir
22918         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22919                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22920                 error "create striped dir succeeds with gid=0"
22921
22922         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22923         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22924                 error "create striped dir fails with gid=-1"
22925
22926         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22927         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
22928                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22929                 error "set default striped dir succeeds with gid=0"
22930
22931
22932         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22933         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
22934                 error "set default striped dir fails with gid=-1"
22935
22936
22937         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22938         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
22939                                         error "create test_dir fails"
22940         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
22941                                         error "create test_dir1 fails"
22942         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
22943                                         error "create test_dir2 fails"
22944         cleanup_300n
22945 }
22946 run_test 300n "non-root user to create dir under striped dir with default EA"
22947
22948 test_300o() {
22949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22951         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22952                 skip "Need MDS version at least 2.7.55"
22953
22954         local numfree1
22955         local numfree2
22956
22957         mkdir -p $DIR/$tdir
22958
22959         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
22960         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
22961         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
22962                 skip "not enough free inodes $numfree1 $numfree2"
22963         fi
22964
22965         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
22966         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
22967         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
22968                 skip "not enough free space $numfree1 $numfree2"
22969         fi
22970
22971         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
22972                 error "setdirstripe fails"
22973
22974         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
22975                 error "create dirs fails"
22976
22977         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
22978         ls $DIR/$tdir/striped_dir > /dev/null ||
22979                 error "ls striped dir fails"
22980         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
22981                 error "unlink big striped dir fails"
22982 }
22983 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
22984
22985 test_300p() {
22986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22988         remote_mds_nodsh && skip "remote MDS with nodsh"
22989
22990         mkdir_on_mdt0 $DIR/$tdir
22991
22992         #define OBD_FAIL_OUT_ENOSPC     0x1704
22993         do_facet mds2 lctl set_param fail_loc=0x80001704
22994         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
22995                  && error "create striped directory should fail"
22996
22997         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
22998
22999         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23000         true
23001 }
23002 run_test 300p "create striped directory without space"
23003
23004 test_300q() {
23005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23007
23008         local fd=$(free_fd)
23009         local cmd="exec $fd<$tdir"
23010         cd $DIR
23011         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23012         eval $cmd
23013         cmd="exec $fd<&-"
23014         trap "eval $cmd" EXIT
23015         cd $tdir || error "cd $tdir fails"
23016         rmdir  ../$tdir || error "rmdir $tdir fails"
23017         mkdir local_dir && error "create dir succeeds"
23018         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23019         eval $cmd
23020         return 0
23021 }
23022 run_test 300q "create remote directory under orphan directory"
23023
23024 test_300r() {
23025         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23026                 skip "Need MDS version at least 2.7.55" && return
23027         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23028
23029         mkdir $DIR/$tdir
23030
23031         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23032                 error "set striped dir error"
23033
23034         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23035                 error "getstripeddir fails"
23036
23037         local stripe_count
23038         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23039                       awk '/lmv_stripe_count:/ { print $2 }')
23040
23041         [ $MDSCOUNT -ne $stripe_count ] &&
23042                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23043
23044         rm -rf $DIR/$tdir/striped_dir ||
23045                 error "unlink striped dir fails"
23046 }
23047 run_test 300r "test -1 striped directory"
23048
23049 test_300s_helper() {
23050         local count=$1
23051
23052         local stripe_dir=$DIR/$tdir/striped_dir.$count
23053
23054         $LFS mkdir -c $count $stripe_dir ||
23055                 error "lfs mkdir -c error"
23056
23057         $LFS getdirstripe $stripe_dir ||
23058                 error "lfs getdirstripe fails"
23059
23060         local stripe_count
23061         stripe_count=$($LFS getdirstripe $stripe_dir |
23062                       awk '/lmv_stripe_count:/ { print $2 }')
23063
23064         [ $count -ne $stripe_count ] &&
23065                 error_noexit "bad stripe count $stripe_count expected $count"
23066
23067         local dupe_stripes
23068         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23069                 awk '/0x/ {count[$1] += 1}; END {
23070                         for (idx in count) {
23071                                 if (count[idx]>1) {
23072                                         print "index " idx " count " count[idx]
23073                                 }
23074                         }
23075                 }')
23076
23077         if [[ -n "$dupe_stripes" ]] ; then
23078                 lfs getdirstripe $stripe_dir
23079                 error_noexit "Dupe MDT above: $dupe_stripes "
23080         fi
23081
23082         rm -rf $stripe_dir ||
23083                 error_noexit "unlink $stripe_dir fails"
23084 }
23085
23086 test_300s() {
23087         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23088                 skip "Need MDS version at least 2.7.55" && return
23089         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23090
23091         mkdir $DIR/$tdir
23092         for count in $(seq 2 $MDSCOUNT); do
23093                 test_300s_helper $count
23094         done
23095 }
23096 run_test 300s "test lfs mkdir -c without -i"
23097
23098
23099 prepare_remote_file() {
23100         mkdir $DIR/$tdir/src_dir ||
23101                 error "create remote source failed"
23102
23103         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23104                  error "cp to remote source failed"
23105         touch $DIR/$tdir/src_dir/a
23106
23107         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23108                 error "create remote target dir failed"
23109
23110         touch $DIR/$tdir/tgt_dir/b
23111
23112         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23113                 error "rename dir cross MDT failed!"
23114
23115         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23116                 error "src_child still exists after rename"
23117
23118         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23119                 error "missing file(a) after rename"
23120
23121         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23122                 error "diff after rename"
23123 }
23124
23125 test_310a() {
23126         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23128
23129         local remote_file=$DIR/$tdir/tgt_dir/b
23130
23131         mkdir -p $DIR/$tdir
23132
23133         prepare_remote_file || error "prepare remote file failed"
23134
23135         #open-unlink file
23136         $OPENUNLINK $remote_file $remote_file ||
23137                 error "openunlink $remote_file failed"
23138         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23139 }
23140 run_test 310a "open unlink remote file"
23141
23142 test_310b() {
23143         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23145
23146         local remote_file=$DIR/$tdir/tgt_dir/b
23147
23148         mkdir -p $DIR/$tdir
23149
23150         prepare_remote_file || error "prepare remote file failed"
23151
23152         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23153         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23154         $CHECKSTAT -t file $remote_file || error "check file failed"
23155 }
23156 run_test 310b "unlink remote file with multiple links while open"
23157
23158 test_310c() {
23159         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23160         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23161
23162         local remote_file=$DIR/$tdir/tgt_dir/b
23163
23164         mkdir -p $DIR/$tdir
23165
23166         prepare_remote_file || error "prepare remote file failed"
23167
23168         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23169         multiop_bg_pause $remote_file O_uc ||
23170                         error "mulitop failed for remote file"
23171         MULTIPID=$!
23172         $MULTIOP $DIR/$tfile Ouc
23173         kill -USR1 $MULTIPID
23174         wait $MULTIPID
23175 }
23176 run_test 310c "open-unlink remote file with multiple links"
23177
23178 #LU-4825
23179 test_311() {
23180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23181         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23182         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23183                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23184         remote_mds_nodsh && skip "remote MDS with nodsh"
23185
23186         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23187         local mdts=$(comma_list $(mdts_nodes))
23188
23189         mkdir -p $DIR/$tdir
23190         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23191         createmany -o $DIR/$tdir/$tfile. 1000
23192
23193         # statfs data is not real time, let's just calculate it
23194         old_iused=$((old_iused + 1000))
23195
23196         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23197                         osp.*OST0000*MDT0000.create_count")
23198         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23199                                 osp.*OST0000*MDT0000.max_create_count")
23200         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23201
23202         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23203         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23204         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23205
23206         unlinkmany $DIR/$tdir/$tfile. 1000
23207
23208         do_nodes $mdts "$LCTL set_param -n \
23209                         osp.*OST0000*.max_create_count=$max_count"
23210         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23211                 do_nodes $mdts "$LCTL set_param -n \
23212                                 osp.*OST0000*.create_count=$count"
23213         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23214                         grep "=0" && error "create_count is zero"
23215
23216         local new_iused
23217         for i in $(seq 120); do
23218                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23219                 # system may be too busy to destroy all objs in time, use
23220                 # a somewhat small value to not fail autotest
23221                 [ $((old_iused - new_iused)) -gt 400 ] && break
23222                 sleep 1
23223         done
23224
23225         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23226         [ $((old_iused - new_iused)) -gt 400 ] ||
23227                 error "objs not destroyed after unlink"
23228 }
23229 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23230
23231 zfs_oid_to_objid()
23232 {
23233         local ost=$1
23234         local objid=$2
23235
23236         local vdevdir=$(dirname $(facet_vdevice $ost))
23237         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23238         local zfs_zapid=$(do_facet $ost $cmd |
23239                           grep -w "/O/0/d$((objid%32))" -C 5 |
23240                           awk '/Object/{getline; print $1}')
23241         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23242                           awk "/$objid = /"'{printf $3}')
23243
23244         echo $zfs_objid
23245 }
23246
23247 zfs_object_blksz() {
23248         local ost=$1
23249         local objid=$2
23250
23251         local vdevdir=$(dirname $(facet_vdevice $ost))
23252         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23253         local blksz=$(do_facet $ost $cmd $objid |
23254                       awk '/dblk/{getline; printf $4}')
23255
23256         case "${blksz: -1}" in
23257                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23258                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23259                 *) ;;
23260         esac
23261
23262         echo $blksz
23263 }
23264
23265 test_312() { # LU-4856
23266         remote_ost_nodsh && skip "remote OST with nodsh"
23267         [ "$ost1_FSTYPE" = "zfs" ] ||
23268                 skip_env "the test only applies to zfs"
23269
23270         local max_blksz=$(do_facet ost1 \
23271                           $ZFS get -p recordsize $(facet_device ost1) |
23272                           awk '!/VALUE/{print $3}')
23273
23274         # to make life a little bit easier
23275         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23276         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23277
23278         local tf=$DIR/$tdir/$tfile
23279         touch $tf
23280         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23281
23282         # Get ZFS object id
23283         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23284         # block size change by sequential overwrite
23285         local bs
23286
23287         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23288                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23289
23290                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23291                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23292         done
23293         rm -f $tf
23294
23295         # block size change by sequential append write
23296         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23297         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23298         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23299         local count
23300
23301         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23302                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23303                         oflag=sync conv=notrunc
23304
23305                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23306                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23307                         error "blksz error, actual $blksz, " \
23308                                 "expected: 2 * $count * $PAGE_SIZE"
23309         done
23310         rm -f $tf
23311
23312         # random write
23313         touch $tf
23314         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23315         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23316
23317         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23318         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23319         [ $blksz -eq $PAGE_SIZE ] ||
23320                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23321
23322         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23323         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23324         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23325
23326         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23327         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23328         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23329 }
23330 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23331
23332 test_313() {
23333         remote_ost_nodsh && skip "remote OST with nodsh"
23334
23335         local file=$DIR/$tfile
23336
23337         rm -f $file
23338         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23339
23340         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23341         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23342         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23343                 error "write should failed"
23344         do_facet ost1 "$LCTL set_param fail_loc=0"
23345         rm -f $file
23346 }
23347 run_test 313 "io should fail after last_rcvd update fail"
23348
23349 test_314() {
23350         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23351
23352         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23353         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23354         rm -f $DIR/$tfile
23355         wait_delete_completed
23356         do_facet ost1 "$LCTL set_param fail_loc=0"
23357 }
23358 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23359
23360 test_315() { # LU-618
23361         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23362
23363         local file=$DIR/$tfile
23364         rm -f $file
23365
23366         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23367                 error "multiop file write failed"
23368         $MULTIOP $file oO_RDONLY:r4063232_c &
23369         PID=$!
23370
23371         sleep 2
23372
23373         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23374         kill -USR1 $PID
23375
23376         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23377         rm -f $file
23378 }
23379 run_test 315 "read should be accounted"
23380
23381 test_316() {
23382         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23383         large_xattr_enabled || skip_env "ea_inode feature disabled"
23384
23385         rm -rf $DIR/$tdir/d
23386         mkdir -p $DIR/$tdir/d
23387         chown nobody $DIR/$tdir/d
23388         touch $DIR/$tdir/d/file
23389
23390         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23391 }
23392 run_test 316 "lfs mv"
23393
23394 test_317() {
23395         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23396                 skip "Need MDS version at least 2.11.53"
23397         if [ "$ost1_FSTYPE" == "zfs" ]; then
23398                 skip "LU-10370: no implementation for ZFS"
23399         fi
23400
23401         local trunc_sz
23402         local grant_blk_size
23403
23404         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23405                         awk '/grant_block_size:/ { print $2; exit; }')
23406         #
23407         # Create File of size 5M. Truncate it to below size's and verify
23408         # blocks count.
23409         #
23410         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23411                 error "Create file $DIR/$tfile failed"
23412         stack_trap "rm -f $DIR/$tfile" EXIT
23413
23414         for trunc_sz in 2097152 4097 4000 509 0; do
23415                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23416                         error "truncate $tfile to $trunc_sz failed"
23417                 local sz=$(stat --format=%s $DIR/$tfile)
23418                 local blk=$(stat --format=%b $DIR/$tfile)
23419                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23420                                      grant_blk_size) * 8))
23421
23422                 if [[ $blk -ne $trunc_blk ]]; then
23423                         $(which stat) $DIR/$tfile
23424                         error "Expected Block $trunc_blk got $blk for $tfile"
23425                 fi
23426
23427                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23428                         error "Expected Size $trunc_sz got $sz for $tfile"
23429         done
23430
23431         #
23432         # sparse file test
23433         # Create file with a hole and write actual two blocks. Block count
23434         # must be 16.
23435         #
23436         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23437                 conv=fsync || error "Create file : $DIR/$tfile"
23438
23439         # Calculate the final truncate size.
23440         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23441
23442         #
23443         # truncate to size $trunc_sz bytes. Strip the last block
23444         # The block count must drop to 8
23445         #
23446         $TRUNCATE $DIR/$tfile $trunc_sz ||
23447                 error "truncate $tfile to $trunc_sz failed"
23448
23449         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23450         sz=$(stat --format=%s $DIR/$tfile)
23451         blk=$(stat --format=%b $DIR/$tfile)
23452
23453         if [[ $blk -ne $trunc_bsz ]]; then
23454                 $(which stat) $DIR/$tfile
23455                 error "Expected Block $trunc_bsz got $blk for $tfile"
23456         fi
23457
23458         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23459                 error "Expected Size $trunc_sz got $sz for $tfile"
23460 }
23461 run_test 317 "Verify blocks get correctly update after truncate"
23462
23463 test_318() {
23464         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23465         local old_max_active=$($LCTL get_param -n \
23466                             ${llite_name}.max_read_ahead_async_active \
23467                             2>/dev/null)
23468
23469         $LCTL set_param llite.*.max_read_ahead_async_active=256
23470         local max_active=$($LCTL get_param -n \
23471                            ${llite_name}.max_read_ahead_async_active \
23472                            2>/dev/null)
23473         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23474
23475         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23476                 error "set max_read_ahead_async_active should succeed"
23477
23478         $LCTL set_param llite.*.max_read_ahead_async_active=512
23479         max_active=$($LCTL get_param -n \
23480                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23481         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23482
23483         # restore @max_active
23484         [ $old_max_active -ne 0 ] && $LCTL set_param \
23485                 llite.*.max_read_ahead_async_active=$old_max_active
23486
23487         local old_threshold=$($LCTL get_param -n \
23488                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23489         local max_per_file_mb=$($LCTL get_param -n \
23490                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23491
23492         local invalid=$(($max_per_file_mb + 1))
23493         $LCTL set_param \
23494                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23495                         && error "set $invalid should fail"
23496
23497         local valid=$(($invalid - 1))
23498         $LCTL set_param \
23499                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23500                         error "set $valid should succeed"
23501         local threshold=$($LCTL get_param -n \
23502                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23503         [ $threshold -eq $valid ] || error \
23504                 "expect threshold $valid got $threshold"
23505         $LCTL set_param \
23506                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23507 }
23508 run_test 318 "Verify async readahead tunables"
23509
23510 test_319() {
23511         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23512
23513         local before=$(date +%s)
23514         local evict
23515         local mdir=$DIR/$tdir
23516         local file=$mdir/xxx
23517
23518         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23519         touch $file
23520
23521 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23522         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23523         $LFS mv -m1 $file &
23524
23525         sleep 1
23526         dd if=$file of=/dev/null
23527         wait
23528         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23529           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23530
23531         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23532 }
23533 run_test 319 "lost lease lock on migrate error"
23534
23535 test_398a() { # LU-4198
23536         local ost1_imp=$(get_osc_import_name client ost1)
23537         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23538                          cut -d'.' -f2)
23539
23540         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23541         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23542
23543         # request a new lock on client
23544         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23545
23546         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23547         local lock_count=$($LCTL get_param -n \
23548                            ldlm.namespaces.$imp_name.lru_size)
23549         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23550
23551         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23552
23553         # no lock cached, should use lockless IO and not enqueue new lock
23554         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23555         lock_count=$($LCTL get_param -n \
23556                      ldlm.namespaces.$imp_name.lru_size)
23557         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23558 }
23559 run_test 398a "direct IO should cancel lock otherwise lockless"
23560
23561 test_398b() { # LU-4198
23562         which fio || skip_env "no fio installed"
23563         $LFS setstripe -c -1 $DIR/$tfile
23564
23565         local size=12
23566         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23567
23568         local njobs=4
23569         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23570         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23571                 --numjobs=$njobs --fallocate=none \
23572                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23573                 --filename=$DIR/$tfile &
23574         bg_pid=$!
23575
23576         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23577         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23578                 --numjobs=$njobs --fallocate=none \
23579                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23580                 --filename=$DIR/$tfile || true
23581         wait $bg_pid
23582
23583         rm -f $DIR/$tfile
23584 }
23585 run_test 398b "DIO and buffer IO race"
23586
23587 test_398c() { # LU-4198
23588         local ost1_imp=$(get_osc_import_name client ost1)
23589         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23590                          cut -d'.' -f2)
23591
23592         which fio || skip_env "no fio installed"
23593
23594         saved_debug=$($LCTL get_param -n debug)
23595         $LCTL set_param debug=0
23596
23597         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23598         ((size /= 1024)) # by megabytes
23599         ((size /= 2)) # write half of the OST at most
23600         [ $size -gt 40 ] && size=40 #reduce test time anyway
23601
23602         $LFS setstripe -c 1 $DIR/$tfile
23603
23604         # it seems like ldiskfs reserves more space than necessary if the
23605         # writing blocks are not mapped, so it extends the file firstly
23606         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23607         cancel_lru_locks osc
23608
23609         # clear and verify rpc_stats later
23610         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23611
23612         local njobs=4
23613         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23614         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23615                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23616                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23617                 --filename=$DIR/$tfile
23618         [ $? -eq 0 ] || error "fio write error"
23619
23620         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23621                 error "Locks were requested while doing AIO"
23622
23623         # get the percentage of 1-page I/O
23624         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23625                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23626                 awk '{print $7}')
23627         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23628
23629         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23630         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23631                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23632                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23633                 --filename=$DIR/$tfile
23634         [ $? -eq 0 ] || error "fio mixed read write error"
23635
23636         echo "AIO with large block size ${size}M"
23637         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23638                 --numjobs=1 --fallocate=none --ioengine=libaio \
23639                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23640                 --filename=$DIR/$tfile
23641         [ $? -eq 0 ] || error "fio large block size failed"
23642
23643         rm -f $DIR/$tfile
23644         $LCTL set_param debug="$saved_debug"
23645 }
23646 run_test 398c "run fio to test AIO"
23647
23648 test_398d() { #  LU-13846
23649         which aiocp || skip_env "no aiocp installed"
23650         local aio_file=$DIR/$tfile.aio
23651
23652         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23653
23654         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23655         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23656         stack_trap "rm -f $DIR/$tfile $aio_file"
23657
23658         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23659
23660         # make sure we don't crash and fail properly
23661         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23662                 error "aio not aligned with PAGE SIZE should fail"
23663
23664         rm -f $DIR/$tfile $aio_file
23665 }
23666 run_test 398d "run aiocp to verify block size > stripe size"
23667
23668 test_398e() {
23669         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23670         touch $DIR/$tfile.new
23671         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23672 }
23673 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23674
23675 test_398f() { #  LU-14687
23676         which aiocp || skip_env "no aiocp installed"
23677         local aio_file=$DIR/$tfile.aio
23678
23679         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23680
23681         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23682         stack_trap "rm -f $DIR/$tfile $aio_file"
23683
23684         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23685         $LCTL set_param fail_loc=0x1418
23686         # make sure we don't crash and fail properly
23687         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23688                 error "aio with page allocation failure succeeded"
23689         $LCTL set_param fail_loc=0
23690         diff $DIR/$tfile $aio_file
23691         [[ $? != 0 ]] || error "no diff after failed aiocp"
23692 }
23693 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23694
23695 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23696 # stripe and i/o size must be > stripe size
23697 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23698 # single RPC in flight.  This test shows async DIO submission is working by
23699 # showing multiple RPCs in flight.
23700 test_398g() { #  LU-13798
23701         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23702
23703         # We need to do some i/o first to acquire enough grant to put our RPCs
23704         # in flight; otherwise a new connection may not have enough grant
23705         # available
23706         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23707                 error "parallel dio failed"
23708         stack_trap "rm -f $DIR/$tfile"
23709
23710         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23711         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23712         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23713         stack_trap "$LCTL set_param -n $pages_per_rpc"
23714
23715         # Recreate file so it's empty
23716         rm -f $DIR/$tfile
23717         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23718         #Pause rpc completion to guarantee we see multiple rpcs in flight
23719         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23720         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23721         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23722
23723         # Clear rpc stats
23724         $LCTL set_param osc.*.rpc_stats=c
23725
23726         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23727                 error "parallel dio failed"
23728         stack_trap "rm -f $DIR/$tfile"
23729
23730         $LCTL get_param osc.*-OST0000-*.rpc_stats
23731         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23732                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23733                 grep "8:" | awk '{print $8}')
23734         # We look at the "8 rpcs in flight" field, and verify A) it is present
23735         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23736         # as expected for an 8M DIO to a file with 1M stripes.
23737         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23738
23739         # Verify turning off parallel dio works as expected
23740         # Clear rpc stats
23741         $LCTL set_param osc.*.rpc_stats=c
23742         $LCTL set_param llite.*.parallel_dio=0
23743         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23744
23745         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23746                 error "dio with parallel dio disabled failed"
23747
23748         # Ideally, we would see only one RPC in flight here, but there is an
23749         # unavoidable race between i/o completion and RPC in flight counting,
23750         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23751         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23752         # So instead we just verify it's always < 8.
23753         $LCTL get_param osc.*-OST0000-*.rpc_stats
23754         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23755                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23756                 grep '^$' -B1 | grep . | awk '{print $1}')
23757         [ $ret != "8:" ] ||
23758                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23759 }
23760 run_test 398g "verify parallel dio async RPC submission"
23761
23762 test_398h() { #  LU-13798
23763         local dio_file=$DIR/$tfile.dio
23764
23765         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23766
23767         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23768         stack_trap "rm -f $DIR/$tfile $dio_file"
23769
23770         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23771                 error "parallel dio failed"
23772         diff $DIR/$tfile $dio_file
23773         [[ $? == 0 ]] || error "file diff after aiocp"
23774 }
23775 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23776
23777 test_398i() { #  LU-13798
23778         local dio_file=$DIR/$tfile.dio
23779
23780         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23781
23782         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23783         stack_trap "rm -f $DIR/$tfile $dio_file"
23784
23785         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23786         $LCTL set_param fail_loc=0x1418
23787         # make sure we don't crash and fail properly
23788         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23789                 error "parallel dio page allocation failure succeeded"
23790         diff $DIR/$tfile $dio_file
23791         [[ $? != 0 ]] || error "no diff after failed aiocp"
23792 }
23793 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23794
23795 test_398j() { #  LU-13798
23796         # Stripe size > RPC size but less than i/o size tests split across
23797         # stripes and RPCs for individual i/o op
23798         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23799
23800         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23801         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23802         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23803         stack_trap "$LCTL set_param -n $pages_per_rpc"
23804
23805         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23806                 error "parallel dio write failed"
23807         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23808
23809         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23810                 error "parallel dio read failed"
23811         diff $DIR/$tfile $DIR/$tfile.2
23812         [[ $? == 0 ]] || error "file diff after parallel dio read"
23813 }
23814 run_test 398j "test parallel dio where stripe size > rpc_size"
23815
23816 test_398k() { #  LU-13798
23817         wait_delete_completed
23818         wait_mds_ost_sync
23819
23820         # 4 stripe file; we will cause out of space on OST0
23821         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23822
23823         # Fill OST0 (if it's not too large)
23824         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23825                    head -n1)
23826         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23827                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23828         fi
23829         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23830         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23831                 error "dd should fill OST0"
23832         stack_trap "rm -f $DIR/$tfile.1"
23833
23834         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23835         err=$?
23836
23837         ls -la $DIR/$tfile
23838         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23839                 error "file is not 0 bytes in size"
23840
23841         # dd above should not succeed, but don't error until here so we can
23842         # get debug info above
23843         [[ $err != 0 ]] ||
23844                 error "parallel dio write with enospc succeeded"
23845         stack_trap "rm -f $DIR/$tfile"
23846 }
23847 run_test 398k "test enospc on first stripe"
23848
23849 test_398l() { #  LU-13798
23850         wait_delete_completed
23851         wait_mds_ost_sync
23852
23853         # 4 stripe file; we will cause out of space on OST0
23854         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23855         # happens on the second i/o chunk we issue
23856         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23857
23858         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23859         stack_trap "rm -f $DIR/$tfile"
23860
23861         # Fill OST0 (if it's not too large)
23862         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23863                    head -n1)
23864         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23865                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23866         fi
23867         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23868         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23869                 error "dd should fill OST0"
23870         stack_trap "rm -f $DIR/$tfile.1"
23871
23872         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23873         err=$?
23874         stack_trap "rm -f $DIR/$tfile.2"
23875
23876         # Check that short write completed as expected
23877         ls -la $DIR/$tfile.2
23878         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23879                 error "file is not 1M in size"
23880
23881         # dd above should not succeed, but don't error until here so we can
23882         # get debug info above
23883         [[ $err != 0 ]] ||
23884                 error "parallel dio write with enospc succeeded"
23885
23886         # Truncate source file to same length as output file and diff them
23887         $TRUNCATE $DIR/$tfile 1048576
23888         diff $DIR/$tfile $DIR/$tfile.2
23889         [[ $? == 0 ]] || error "data incorrect after short write"
23890 }
23891 run_test 398l "test enospc on intermediate stripe/RPC"
23892
23893 test_398m() { #  LU-13798
23894         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23895
23896         # Set up failure on OST0, the first stripe:
23897         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23898         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23899         # So this fail_val specifies OST0
23900         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23901         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23902
23903         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23904                 error "parallel dio write with failure on first stripe succeeded"
23905         stack_trap "rm -f $DIR/$tfile"
23906         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23907
23908         # Place data in file for read
23909         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23910                 error "parallel dio write failed"
23911
23912         # Fail read on OST0, first stripe
23913         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23914         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
23915         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23916                 error "parallel dio read with error on first stripe succeeded"
23917         rm -f $DIR/$tfile.2
23918         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23919
23920         # Switch to testing on OST1, second stripe
23921         # Clear file contents, maintain striping
23922         echo > $DIR/$tfile
23923         # Set up failure on OST1, second stripe:
23924         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
23925         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23926
23927         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23928                 error "parallel dio write with failure on first stripe succeeded"
23929         stack_trap "rm -f $DIR/$tfile"
23930         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23931
23932         # Place data in file for read
23933         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23934                 error "parallel dio write failed"
23935
23936         # Fail read on OST1, second stripe
23937         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23938         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
23939         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23940                 error "parallel dio read with error on first stripe succeeded"
23941         rm -f $DIR/$tfile.2
23942         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
23943 }
23944 run_test 398m "test RPC failures with parallel dio"
23945
23946 # Parallel submission of DIO should not cause problems for append, but it's
23947 # important to verify.
23948 test_398n() { #  LU-13798
23949         $LFS setstripe -C 2 -S 1M $DIR/$tfile
23950
23951         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
23952                 error "dd to create source file failed"
23953         stack_trap "rm -f $DIR/$tfile"
23954
23955         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
23956                 error "parallel dio write with failure on second stripe succeeded"
23957         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
23958         diff $DIR/$tfile $DIR/$tfile.1
23959         [[ $? == 0 ]] || error "data incorrect after append"
23960
23961 }
23962 run_test 398n "test append with parallel DIO"
23963
23964 test_fake_rw() {
23965         local read_write=$1
23966         if [ "$read_write" = "write" ]; then
23967                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
23968         elif [ "$read_write" = "read" ]; then
23969                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
23970         else
23971                 error "argument error"
23972         fi
23973
23974         # turn off debug for performance testing
23975         local saved_debug=$($LCTL get_param -n debug)
23976         $LCTL set_param debug=0
23977
23978         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23979
23980         # get ost1 size - $FSNAME-OST0000
23981         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
23982         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
23983         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
23984
23985         if [ "$read_write" = "read" ]; then
23986                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
23987         fi
23988
23989         local start_time=$(date +%s.%N)
23990         $dd_cmd bs=1M count=$blocks oflag=sync ||
23991                 error "real dd $read_write error"
23992         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
23993
23994         if [ "$read_write" = "write" ]; then
23995                 rm -f $DIR/$tfile
23996         fi
23997
23998         # define OBD_FAIL_OST_FAKE_RW           0x238
23999         do_facet ost1 $LCTL set_param fail_loc=0x238
24000
24001         local start_time=$(date +%s.%N)
24002         $dd_cmd bs=1M count=$blocks oflag=sync ||
24003                 error "fake dd $read_write error"
24004         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24005
24006         if [ "$read_write" = "write" ]; then
24007                 # verify file size
24008                 cancel_lru_locks osc
24009                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24010                         error "$tfile size not $blocks MB"
24011         fi
24012         do_facet ost1 $LCTL set_param fail_loc=0
24013
24014         echo "fake $read_write $duration_fake vs. normal $read_write" \
24015                 "$duration in seconds"
24016         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24017                 error_not_in_vm "fake write is slower"
24018
24019         $LCTL set_param -n debug="$saved_debug"
24020         rm -f $DIR/$tfile
24021 }
24022 test_399a() { # LU-7655 for OST fake write
24023         remote_ost_nodsh && skip "remote OST with nodsh"
24024
24025         test_fake_rw write
24026 }
24027 run_test 399a "fake write should not be slower than normal write"
24028
24029 test_399b() { # LU-8726 for OST fake read
24030         remote_ost_nodsh && skip "remote OST with nodsh"
24031         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24032                 skip_env "ldiskfs only test"
24033         fi
24034
24035         test_fake_rw read
24036 }
24037 run_test 399b "fake read should not be slower than normal read"
24038
24039 test_400a() { # LU-1606, was conf-sanity test_74
24040         if ! which $CC > /dev/null 2>&1; then
24041                 skip_env "$CC is not installed"
24042         fi
24043
24044         local extra_flags=''
24045         local out=$TMP/$tfile
24046         local prefix=/usr/include/lustre
24047         local prog
24048
24049         # Oleg removes c files in his test rig so test if any c files exist
24050         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24051                 skip_env "Needed c test files are missing"
24052
24053         if ! [[ -d $prefix ]]; then
24054                 # Assume we're running in tree and fixup the include path.
24055                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24056                 extra_flags+=" -L$LUSTRE/utils/.lib"
24057         fi
24058
24059         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24060                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24061                         error "client api broken"
24062         done
24063         rm -f $out
24064 }
24065 run_test 400a "Lustre client api program can compile and link"
24066
24067 test_400b() { # LU-1606, LU-5011
24068         local header
24069         local out=$TMP/$tfile
24070         local prefix=/usr/include/linux/lustre
24071
24072         # We use a hard coded prefix so that this test will not fail
24073         # when run in tree. There are headers in lustre/include/lustre/
24074         # that are not packaged (like lustre_idl.h) and have more
24075         # complicated include dependencies (like config.h and lnet/types.h).
24076         # Since this test about correct packaging we just skip them when
24077         # they don't exist (see below) rather than try to fixup cppflags.
24078
24079         if ! which $CC > /dev/null 2>&1; then
24080                 skip_env "$CC is not installed"
24081         fi
24082
24083         for header in $prefix/*.h; do
24084                 if ! [[ -f "$header" ]]; then
24085                         continue
24086                 fi
24087
24088                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24089                         continue # lustre_ioctl.h is internal header
24090                 fi
24091
24092                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24093                         error "cannot compile '$header'"
24094         done
24095         rm -f $out
24096 }
24097 run_test 400b "packaged headers can be compiled"
24098
24099 test_401a() { #LU-7437
24100         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24101         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24102
24103         #count the number of parameters by "list_param -R"
24104         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24105         #count the number of parameters by listing proc files
24106         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24107         echo "proc_dirs='$proc_dirs'"
24108         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24109         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24110                       sort -u | wc -l)
24111
24112         [ $params -eq $procs ] ||
24113                 error "found $params parameters vs. $procs proc files"
24114
24115         # test the list_param -D option only returns directories
24116         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24117         #count the number of parameters by listing proc directories
24118         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24119                 sort -u | wc -l)
24120
24121         [ $params -eq $procs ] ||
24122                 error "found $params parameters vs. $procs proc files"
24123 }
24124 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24125
24126 test_401b() {
24127         # jobid_var may not allow arbitrary values, so use jobid_name
24128         # if available
24129         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24130                 local testname=jobid_name tmp='testing%p'
24131         else
24132                 local testname=jobid_var tmp=testing
24133         fi
24134
24135         local save=$($LCTL get_param -n $testname)
24136
24137         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24138                 error "no error returned when setting bad parameters"
24139
24140         local jobid_new=$($LCTL get_param -n foe $testname baz)
24141         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24142
24143         $LCTL set_param -n fog=bam $testname=$save bat=fog
24144         local jobid_old=$($LCTL get_param -n foe $testname bag)
24145         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24146 }
24147 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24148
24149 test_401c() {
24150         # jobid_var may not allow arbitrary values, so use jobid_name
24151         # if available
24152         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24153                 local testname=jobid_name
24154         else
24155                 local testname=jobid_var
24156         fi
24157
24158         local jobid_var_old=$($LCTL get_param -n $testname)
24159         local jobid_var_new
24160
24161         $LCTL set_param $testname= &&
24162                 error "no error returned for 'set_param a='"
24163
24164         jobid_var_new=$($LCTL get_param -n $testname)
24165         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24166                 error "$testname was changed by setting without value"
24167
24168         $LCTL set_param $testname &&
24169                 error "no error returned for 'set_param a'"
24170
24171         jobid_var_new=$($LCTL get_param -n $testname)
24172         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24173                 error "$testname was changed by setting without value"
24174 }
24175 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24176
24177 test_401d() {
24178         # jobid_var may not allow arbitrary values, so use jobid_name
24179         # if available
24180         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24181                 local testname=jobid_name new_value='foo=bar%p'
24182         else
24183                 local testname=jobid_var new_valuie=foo=bar
24184         fi
24185
24186         local jobid_var_old=$($LCTL get_param -n $testname)
24187         local jobid_var_new
24188
24189         $LCTL set_param $testname=$new_value ||
24190                 error "'set_param a=b' did not accept a value containing '='"
24191
24192         jobid_var_new=$($LCTL get_param -n $testname)
24193         [[ "$jobid_var_new" == "$new_value" ]] ||
24194                 error "'set_param a=b' failed on a value containing '='"
24195
24196         # Reset the $testname to test the other format
24197         $LCTL set_param $testname=$jobid_var_old
24198         jobid_var_new=$($LCTL get_param -n $testname)
24199         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24200                 error "failed to reset $testname"
24201
24202         $LCTL set_param $testname $new_value ||
24203                 error "'set_param a b' did not accept a value containing '='"
24204
24205         jobid_var_new=$($LCTL get_param -n $testname)
24206         [[ "$jobid_var_new" == "$new_value" ]] ||
24207                 error "'set_param a b' failed on a value containing '='"
24208
24209         $LCTL set_param $testname $jobid_var_old
24210         jobid_var_new=$($LCTL get_param -n $testname)
24211         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24212                 error "failed to reset $testname"
24213 }
24214 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24215
24216 test_401e() { # LU-14779
24217         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24218                 error "lctl list_param MGC* failed"
24219         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24220         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24221                 error "lctl get_param lru_size failed"
24222 }
24223 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24224
24225 test_402() {
24226         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24227         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24228                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24229         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24230                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24231                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24232         remote_mds_nodsh && skip "remote MDS with nodsh"
24233
24234         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24235 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24236         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24237         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24238                 echo "Touch failed - OK"
24239 }
24240 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24241
24242 test_403() {
24243         local file1=$DIR/$tfile.1
24244         local file2=$DIR/$tfile.2
24245         local tfile=$TMP/$tfile
24246
24247         rm -f $file1 $file2 $tfile
24248
24249         touch $file1
24250         ln $file1 $file2
24251
24252         # 30 sec OBD_TIMEOUT in ll_getattr()
24253         # right before populating st_nlink
24254         $LCTL set_param fail_loc=0x80001409
24255         stat -c %h $file1 > $tfile &
24256
24257         # create an alias, drop all locks and reclaim the dentry
24258         < $file2
24259         cancel_lru_locks mdc
24260         cancel_lru_locks osc
24261         sysctl -w vm.drop_caches=2
24262
24263         wait
24264
24265         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24266
24267         rm -f $tfile $file1 $file2
24268 }
24269 run_test 403 "i_nlink should not drop to zero due to aliasing"
24270
24271 test_404() { # LU-6601
24272         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24273                 skip "Need server version newer than 2.8.52"
24274         remote_mds_nodsh && skip "remote MDS with nodsh"
24275
24276         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24277                 awk '/osp .*-osc-MDT/ { print $4}')
24278
24279         local osp
24280         for osp in $mosps; do
24281                 echo "Deactivate: " $osp
24282                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24283                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24284                         awk -vp=$osp '$4 == p { print $2 }')
24285                 [ $stat = IN ] || {
24286                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24287                         error "deactivate error"
24288                 }
24289                 echo "Activate: " $osp
24290                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24291                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24292                         awk -vp=$osp '$4 == p { print $2 }')
24293                 [ $stat = UP ] || {
24294                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24295                         error "activate error"
24296                 }
24297         done
24298 }
24299 run_test 404 "validate manual {de}activated works properly for OSPs"
24300
24301 test_405() {
24302         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24303         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24304                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24305                         skip "Layout swap lock is not supported"
24306
24307         check_swap_layouts_support
24308         check_swap_layout_no_dom $DIR
24309
24310         test_mkdir $DIR/$tdir
24311         swap_lock_test -d $DIR/$tdir ||
24312                 error "One layout swap locked test failed"
24313 }
24314 run_test 405 "Various layout swap lock tests"
24315
24316 test_406() {
24317         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24318         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24319         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24321         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24322                 skip "Need MDS version at least 2.8.50"
24323
24324         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24325         local test_pool=$TESTNAME
24326
24327         pool_add $test_pool || error "pool_add failed"
24328         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24329                 error "pool_add_targets failed"
24330
24331         save_layout_restore_at_exit $MOUNT
24332
24333         # parent set default stripe count only, child will stripe from both
24334         # parent and fs default
24335         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24336                 error "setstripe $MOUNT failed"
24337         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24338         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24339         for i in $(seq 10); do
24340                 local f=$DIR/$tdir/$tfile.$i
24341                 touch $f || error "touch failed"
24342                 local count=$($LFS getstripe -c $f)
24343                 [ $count -eq $OSTCOUNT ] ||
24344                         error "$f stripe count $count != $OSTCOUNT"
24345                 local offset=$($LFS getstripe -i $f)
24346                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24347                 local size=$($LFS getstripe -S $f)
24348                 [ $size -eq $((def_stripe_size * 2)) ] ||
24349                         error "$f stripe size $size != $((def_stripe_size * 2))"
24350                 local pool=$($LFS getstripe -p $f)
24351                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24352         done
24353
24354         # change fs default striping, delete parent default striping, now child
24355         # will stripe from new fs default striping only
24356         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24357                 error "change $MOUNT default stripe failed"
24358         $LFS setstripe -c 0 $DIR/$tdir ||
24359                 error "delete $tdir default stripe failed"
24360         for i in $(seq 11 20); do
24361                 local f=$DIR/$tdir/$tfile.$i
24362                 touch $f || error "touch $f failed"
24363                 local count=$($LFS getstripe -c $f)
24364                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24365                 local offset=$($LFS getstripe -i $f)
24366                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24367                 local size=$($LFS getstripe -S $f)
24368                 [ $size -eq $def_stripe_size ] ||
24369                         error "$f stripe size $size != $def_stripe_size"
24370                 local pool=$($LFS getstripe -p $f)
24371                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24372         done
24373
24374         unlinkmany $DIR/$tdir/$tfile. 1 20
24375
24376         local f=$DIR/$tdir/$tfile
24377         pool_remove_all_targets $test_pool $f
24378         pool_remove $test_pool $f
24379 }
24380 run_test 406 "DNE support fs default striping"
24381
24382 test_407() {
24383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24384         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24385                 skip "Need MDS version at least 2.8.55"
24386         remote_mds_nodsh && skip "remote MDS with nodsh"
24387
24388         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24389                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24390         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24391                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24392         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24393
24394         #define OBD_FAIL_DT_TXN_STOP    0x2019
24395         for idx in $(seq $MDSCOUNT); do
24396                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24397         done
24398         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24399         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24400                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24401         true
24402 }
24403 run_test 407 "transaction fail should cause operation fail"
24404
24405 test_408() {
24406         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24407
24408         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24409         lctl set_param fail_loc=0x8000040a
24410         # let ll_prepare_partial_page() fail
24411         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24412
24413         rm -f $DIR/$tfile
24414
24415         # create at least 100 unused inodes so that
24416         # shrink_icache_memory(0) should not return 0
24417         touch $DIR/$tfile-{0..100}
24418         rm -f $DIR/$tfile-{0..100}
24419         sync
24420
24421         echo 2 > /proc/sys/vm/drop_caches
24422 }
24423 run_test 408 "drop_caches should not hang due to page leaks"
24424
24425 test_409()
24426 {
24427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24428
24429         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24430         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24431         touch $DIR/$tdir/guard || error "(2) Fail to create"
24432
24433         local PREFIX=$(str_repeat 'A' 128)
24434         echo "Create 1K hard links start at $(date)"
24435         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24436                 error "(3) Fail to hard link"
24437
24438         echo "Links count should be right although linkEA overflow"
24439         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24440         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24441         [ $linkcount -eq 1001 ] ||
24442                 error "(5) Unexpected hard links count: $linkcount"
24443
24444         echo "List all links start at $(date)"
24445         ls -l $DIR/$tdir/foo > /dev/null ||
24446                 error "(6) Fail to list $DIR/$tdir/foo"
24447
24448         echo "Unlink hard links start at $(date)"
24449         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24450                 error "(7) Fail to unlink"
24451         echo "Unlink hard links finished at $(date)"
24452 }
24453 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24454
24455 test_410()
24456 {
24457         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24458                 skip "Need client version at least 2.9.59"
24459         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24460                 skip "Need MODULES build"
24461
24462         # Create a file, and stat it from the kernel
24463         local testfile=$DIR/$tfile
24464         touch $testfile
24465
24466         local run_id=$RANDOM
24467         local my_ino=$(stat --format "%i" $testfile)
24468
24469         # Try to insert the module. This will always fail as the
24470         # module is designed to not be inserted.
24471         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24472             &> /dev/null
24473
24474         # Anything but success is a test failure
24475         dmesg | grep -q \
24476             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24477             error "no inode match"
24478 }
24479 run_test 410 "Test inode number returned from kernel thread"
24480
24481 cleanup_test411_cgroup() {
24482         trap 0
24483         rmdir "$1"
24484 }
24485
24486 test_411() {
24487         local cg_basedir=/sys/fs/cgroup/memory
24488         # LU-9966
24489         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24490                 skip "no setup for cgroup"
24491
24492         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24493                 error "test file creation failed"
24494         cancel_lru_locks osc
24495
24496         # Create a very small memory cgroup to force a slab allocation error
24497         local cgdir=$cg_basedir/osc_slab_alloc
24498         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24499         trap "cleanup_test411_cgroup $cgdir" EXIT
24500         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24501         echo 1M > $cgdir/memory.limit_in_bytes
24502
24503         # Should not LBUG, just be killed by oom-killer
24504         # dd will return 0 even allocation failure in some environment.
24505         # So don't check return value
24506         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24507         cleanup_test411_cgroup $cgdir
24508
24509         return 0
24510 }
24511 run_test 411 "Slab allocation error with cgroup does not LBUG"
24512
24513 test_412() {
24514         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24515         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24516                 skip "Need server version at least 2.10.55"
24517         fi
24518
24519         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24520                 error "mkdir failed"
24521         $LFS getdirstripe $DIR/$tdir
24522         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24523         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24524                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24525         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24526         [ $stripe_count -eq 2 ] ||
24527                 error "expect 2 get $stripe_count"
24528 }
24529 run_test 412 "mkdir on specific MDTs"
24530
24531 generate_uneven_mdts() {
24532         local threshold=$1
24533         local ffree
24534         local bavail
24535         local max
24536         local min
24537         local max_index
24538         local min_index
24539         local tmp
24540         local i
24541
24542         echo
24543         echo "Check for uneven MDTs: "
24544
24545         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24546         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24547         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24548
24549         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24550         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24551         max_index=0
24552         min_index=0
24553         for ((i = 1; i < ${#ffree[@]}; i++)); do
24554                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24555                 if [ $tmp -gt $max ]; then
24556                         max=$tmp
24557                         max_index=$i
24558                 fi
24559                 if [ $tmp -lt $min ]; then
24560                         min=$tmp
24561                         min_index=$i
24562                 fi
24563         done
24564
24565         # Check if we need to generate uneven MDTs
24566         local diff=$(((max - min) * 100 / min))
24567         local testdir=$DIR/$tdir-fillmdt
24568
24569         mkdir -p $testdir
24570
24571         i=0
24572         while (( diff < threshold )); do
24573                 # generate uneven MDTs, create till $threshold% diff
24574                 echo -n "weight diff=$diff% must be > $threshold% ..."
24575                 echo "Fill MDT$min_index with 100 files: loop $i"
24576                 testdir=$DIR/$tdir-fillmdt/$i
24577                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24578                         error "mkdir $testdir failed"
24579                 $LFS setstripe -E 1M -L mdt $testdir ||
24580                         error "setstripe $testdir failed"
24581                 for F in f.{0..99}; do
24582                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24583                                 /dev/null 2>&1 || error "dd $F failed"
24584                 done
24585
24586                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24587                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24588                 max=$(((${ffree[max_index]} >> 8) * \
24589                         (${bavail[max_index]} * bsize >> 16)))
24590                 min=$(((${ffree[min_index]} >> 8) * \
24591                         (${bavail[min_index]} * bsize >> 16)))
24592                 diff=$(((max - min) * 100 / min))
24593                 i=$((i + 1))
24594         done
24595
24596         echo "MDT filesfree available: ${ffree[@]}"
24597         echo "MDT blocks available: ${bavail[@]}"
24598         echo "weight diff=$diff%"
24599 }
24600
24601 test_qos_mkdir() {
24602         local mkdir_cmd=$1
24603         local stripe_count=$2
24604         local mdts=$(comma_list $(mdts_nodes))
24605
24606         local testdir
24607         local lmv_qos_prio_free
24608         local lmv_qos_threshold_rr
24609         local lmv_qos_maxage
24610         local lod_qos_prio_free
24611         local lod_qos_threshold_rr
24612         local lod_qos_maxage
24613         local count
24614         local i
24615
24616         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24617         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24618         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24619                 head -n1)
24620         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24621         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24622         stack_trap "$LCTL set_param \
24623                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24624         stack_trap "$LCTL set_param \
24625                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24626         stack_trap "$LCTL set_param \
24627                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24628
24629         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24630                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24631         lod_qos_prio_free=${lod_qos_prio_free%%%}
24632         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24633                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24634         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24635         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24636                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24637         stack_trap "do_nodes $mdts $LCTL set_param \
24638                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24639         stack_trap "do_nodes $mdts $LCTL set_param \
24640                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24641         stack_trap "do_nodes $mdts $LCTL set_param \
24642                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24643
24644         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24645         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24646
24647         testdir=$DIR/$tdir-s$stripe_count/rr
24648
24649         local stripe_index=$($LFS getstripe -m $testdir)
24650         local test_mkdir_rr=true
24651
24652         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24653         getfattr -d -m dmv -e hex $testdir | grep dmv
24654         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24655                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24656                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24657                         test_mkdir_rr=false
24658         fi
24659
24660         echo
24661         $test_mkdir_rr &&
24662                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24663                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24664
24665         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24666         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24667                 eval $mkdir_cmd $testdir/subdir$i ||
24668                         error "$mkdir_cmd subdir$i failed"
24669         done
24670
24671         for (( i = 0; i < $MDSCOUNT; i++ )); do
24672                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24673                 echo "$count directories created on MDT$i"
24674                 if $test_mkdir_rr; then
24675                         (( $count == 100 )) ||
24676                                 error "subdirs are not evenly distributed"
24677                 elif (( $i == $stripe_index )); then
24678                         (( $count == 100 * MDSCOUNT )) ||
24679                                 error "$count subdirs created on MDT$i"
24680                 else
24681                         (( $count == 0 )) ||
24682                                 error "$count subdirs created on MDT$i"
24683                 fi
24684
24685                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24686                         count=$($LFS getdirstripe $testdir/* |
24687                                 grep -c -P "^\s+$i\t")
24688                         echo "$count stripes created on MDT$i"
24689                         # deviation should < 5% of average
24690                         (( $count >= 95 * stripe_count &&
24691                            $count <= 105 * stripe_count)) ||
24692                                 error "stripes are not evenly distributed"
24693                 fi
24694         done
24695
24696         echo
24697         echo "Check for uneven MDTs: "
24698
24699         local ffree
24700         local bavail
24701         local max
24702         local min
24703         local max_index
24704         local min_index
24705         local tmp
24706
24707         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24708         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24709         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24710
24711         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24712         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24713         max_index=0
24714         min_index=0
24715         for ((i = 1; i < ${#ffree[@]}; i++)); do
24716                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24717                 if [ $tmp -gt $max ]; then
24718                         max=$tmp
24719                         max_index=$i
24720                 fi
24721                 if [ $tmp -lt $min ]; then
24722                         min=$tmp
24723                         min_index=$i
24724                 fi
24725         done
24726
24727         (( ${ffree[min_index]} > 0 )) ||
24728                 skip "no free files in MDT$min_index"
24729         (( ${ffree[min_index]} < 100000000 )) ||
24730                 skip "too many free files in MDT$min_index"
24731
24732         echo "MDT filesfree available: ${ffree[@]}"
24733         echo "MDT blocks available: ${bavail[@]}"
24734         echo "weight diff=$(((max - min) * 100 / min))%"
24735         echo
24736         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24737
24738         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24739         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24740         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24741         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24742         # decrease statfs age, so that it can be updated in time
24743         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24744         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24745
24746         sleep 1
24747
24748         testdir=$DIR/$tdir-s$stripe_count/qos
24749         local num=200
24750
24751         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24752         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24753                 eval $mkdir_cmd $testdir/subdir$i ||
24754                         error "$mkdir_cmd subdir$i failed"
24755         done
24756
24757         for (( i = 0; i < $MDSCOUNT; i++ )); do
24758                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24759                 echo "$count directories created on MDT$i"
24760
24761                 if [ $stripe_count -gt 1 ]; then
24762                         count=$($LFS getdirstripe $testdir/* |
24763                                 grep -c -P "^\s+$i\t")
24764                         echo "$count stripes created on MDT$i"
24765                 fi
24766         done
24767
24768         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24769         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24770
24771         # D-value should > 10% of averge
24772         (( max - min >= num / 10 )) ||
24773                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24774
24775         # 5% for stripes
24776         if (( stripe_count > 1 )); then
24777                 max=$($LFS getdirstripe $testdir/* |
24778                       grep -c -P "^\s+$max_index\t")
24779                 min=$($LFS getdirstripe $testdir/* |
24780                         grep -c -P "^\s+$min_index\t")
24781                 (( max - min >= num * stripe_count / 20 )) ||
24782                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24783         fi
24784 }
24785
24786 most_full_mdt() {
24787         local ffree
24788         local bavail
24789         local bsize
24790         local min
24791         local min_index
24792         local tmp
24793
24794         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24795         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24796         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24797
24798         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24799         min_index=0
24800         for ((i = 1; i < ${#ffree[@]}; i++)); do
24801                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24802                 (( tmp < min )) && min=$tmp && min_index=$i
24803         done
24804
24805         echo -n $min_index
24806 }
24807
24808 test_413a() {
24809         [ $MDSCOUNT -lt 2 ] &&
24810                 skip "We need at least 2 MDTs for this test"
24811
24812         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24813                 skip "Need server version at least 2.12.52"
24814
24815         local stripe_count
24816
24817         generate_uneven_mdts 100
24818         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24819                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24820                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24821                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
24822                         error "mkdir failed"
24823                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
24824         done
24825 }
24826 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24827
24828 test_413b() {
24829         [ $MDSCOUNT -lt 2 ] &&
24830                 skip "We need at least 2 MDTs for this test"
24831
24832         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24833                 skip "Need server version at least 2.12.52"
24834
24835         local testdir
24836         local stripe_count
24837
24838         generate_uneven_mdts 100
24839         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24840                 testdir=$DIR/$tdir-s$stripe_count
24841                 mkdir $testdir || error "mkdir $testdir failed"
24842                 mkdir $testdir/rr || error "mkdir rr failed"
24843                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
24844                         error "mkdir qos failed"
24845                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24846                         $testdir/rr || error "setdirstripe rr failed"
24847                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24848                         error "setdirstripe failed"
24849                 test_qos_mkdir "mkdir" $stripe_count
24850         done
24851 }
24852 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24853
24854 test_413c() {
24855         (( $MDSCOUNT >= 2 )) ||
24856                 skip "We need at least 2 MDTs for this test"
24857
24858         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
24859                 skip "Need server version at least 2.14.51"
24860
24861         local testdir
24862         local inherit
24863         local inherit_rr
24864
24865         testdir=$DIR/${tdir}-s1
24866         mkdir $testdir || error "mkdir $testdir failed"
24867         mkdir $testdir/rr || error "mkdir rr failed"
24868         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
24869         # default max_inherit is -1, default max_inherit_rr is 0
24870         $LFS setdirstripe -D -c 1 $testdir/rr ||
24871                 error "setdirstripe rr failed"
24872         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24873                 error "setdirstripe qos failed"
24874         test_qos_mkdir "mkdir" 1
24875
24876         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24877         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24878         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24879         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24880         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
24881
24882         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24883         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24884         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24885         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24886         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
24887         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24888         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
24889                 error "level2 shouldn't have default LMV" || true
24890 }
24891 run_test 413c "mkdir with default LMV max inherit rr"
24892
24893 test_413z() {
24894         local pids=""
24895         local subdir
24896         local pid
24897
24898         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
24899                 unlinkmany $subdir/f. 100 &
24900                 pids="$pids $!"
24901         done
24902
24903         for pid in $pids; do
24904                 wait $pid
24905         done
24906 }
24907 run_test 413z "413 test cleanup"
24908
24909 test_414() {
24910 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
24911         $LCTL set_param fail_loc=0x80000521
24912         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
24913         rm -f $DIR/$tfile
24914 }
24915 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
24916
24917 test_415() {
24918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24919         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24920                 skip "Need server version at least 2.11.52"
24921
24922         # LU-11102
24923         local total
24924         local setattr_pid
24925         local start_time
24926         local end_time
24927         local duration
24928
24929         total=500
24930         # this test may be slow on ZFS
24931         [ "$mds1_FSTYPE" == "zfs" ] && total=100
24932
24933         # though this test is designed for striped directory, let's test normal
24934         # directory too since lock is always saved as CoS lock.
24935         test_mkdir $DIR/$tdir || error "mkdir $tdir"
24936         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
24937
24938         (
24939                 while true; do
24940                         touch $DIR/$tdir
24941                 done
24942         ) &
24943         setattr_pid=$!
24944
24945         start_time=$(date +%s)
24946         for i in $(seq $total); do
24947                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
24948                         > /dev/null
24949         done
24950         end_time=$(date +%s)
24951         duration=$((end_time - start_time))
24952
24953         kill -9 $setattr_pid
24954
24955         echo "rename $total files took $duration sec"
24956         [ $duration -lt 100 ] || error "rename took $duration sec"
24957 }
24958 run_test 415 "lock revoke is not missing"
24959
24960 test_416() {
24961         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24962                 skip "Need server version at least 2.11.55"
24963
24964         # define OBD_FAIL_OSD_TXN_START    0x19a
24965         do_facet mds1 lctl set_param fail_loc=0x19a
24966
24967         lfs mkdir -c $MDSCOUNT $DIR/$tdir
24968
24969         true
24970 }
24971 run_test 416 "transaction start failure won't cause system hung"
24972
24973 cleanup_417() {
24974         trap 0
24975         do_nodes $(comma_list $(mdts_nodes)) \
24976                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
24977         do_nodes $(comma_list $(mdts_nodes)) \
24978                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
24979         do_nodes $(comma_list $(mdts_nodes)) \
24980                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
24981 }
24982
24983 test_417() {
24984         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24985         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
24986                 skip "Need MDS version at least 2.11.56"
24987
24988         trap cleanup_417 RETURN EXIT
24989
24990         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
24991         do_nodes $(comma_list $(mdts_nodes)) \
24992                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
24993         $LFS migrate -m 0 $DIR/$tdir.1 &&
24994                 error "migrate dir $tdir.1 should fail"
24995
24996         do_nodes $(comma_list $(mdts_nodes)) \
24997                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
24998         $LFS mkdir -i 1 $DIR/$tdir.2 &&
24999                 error "create remote dir $tdir.2 should fail"
25000
25001         do_nodes $(comma_list $(mdts_nodes)) \
25002                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25003         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25004                 error "create striped dir $tdir.3 should fail"
25005         true
25006 }
25007 run_test 417 "disable remote dir, striped dir and dir migration"
25008
25009 # Checks that the outputs of df [-i] and lfs df [-i] match
25010 #
25011 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25012 check_lfs_df() {
25013         local dir=$2
25014         local inodes
25015         local df_out
25016         local lfs_df_out
25017         local count
25018         local passed=false
25019
25020         # blocks or inodes
25021         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25022
25023         for count in {1..100}; do
25024                 cancel_lru_locks
25025                 sync; sleep 0.2
25026
25027                 # read the lines of interest
25028                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25029                         error "df $inodes $dir | tail -n +2 failed"
25030                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25031                         error "lfs df $inodes $dir | grep summary: failed"
25032
25033                 # skip first substrings of each output as they are different
25034                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25035                 # compare the two outputs
25036                 passed=true
25037                 for i in {1..5}; do
25038                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25039                 done
25040                 $passed && break
25041         done
25042
25043         if ! $passed; then
25044                 df -P $inodes $dir
25045                 echo
25046                 lfs df $inodes $dir
25047                 error "df and lfs df $1 output mismatch: "      \
25048                       "df ${inodes}: ${df_out[*]}, "            \
25049                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25050         fi
25051 }
25052
25053 test_418() {
25054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25055
25056         local dir=$DIR/$tdir
25057         local numfiles=$((RANDOM % 4096 + 2))
25058         local numblocks=$((RANDOM % 256 + 1))
25059
25060         wait_delete_completed
25061         test_mkdir $dir
25062
25063         # check block output
25064         check_lfs_df blocks $dir
25065         # check inode output
25066         check_lfs_df inodes $dir
25067
25068         # create a single file and retest
25069         echo "Creating a single file and testing"
25070         createmany -o $dir/$tfile- 1 &>/dev/null ||
25071                 error "creating 1 file in $dir failed"
25072         check_lfs_df blocks $dir
25073         check_lfs_df inodes $dir
25074
25075         # create a random number of files
25076         echo "Creating $((numfiles - 1)) files and testing"
25077         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25078                 error "creating $((numfiles - 1)) files in $dir failed"
25079
25080         # write a random number of blocks to the first test file
25081         echo "Writing $numblocks 4K blocks and testing"
25082         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25083                 count=$numblocks &>/dev/null ||
25084                 error "dd to $dir/${tfile}-0 failed"
25085
25086         # retest
25087         check_lfs_df blocks $dir
25088         check_lfs_df inodes $dir
25089
25090         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25091                 error "unlinking $numfiles files in $dir failed"
25092 }
25093 run_test 418 "df and lfs df outputs match"
25094
25095 test_419()
25096 {
25097         local dir=$DIR/$tdir
25098
25099         mkdir -p $dir
25100         touch $dir/file
25101
25102         cancel_lru_locks mdc
25103
25104         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25105         $LCTL set_param fail_loc=0x1410
25106         cat $dir/file
25107         $LCTL set_param fail_loc=0
25108         rm -rf $dir
25109 }
25110 run_test 419 "Verify open file by name doesn't crash kernel"
25111
25112 test_420()
25113 {
25114         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25115                 skip "Need MDS version at least 2.12.53"
25116
25117         local SAVE_UMASK=$(umask)
25118         local dir=$DIR/$tdir
25119         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25120
25121         mkdir -p $dir
25122         umask 0000
25123         mkdir -m03777 $dir/testdir
25124         ls -dn $dir/testdir
25125         # Need to remove trailing '.' when SELinux is enabled
25126         local dirperms=$(ls -dn $dir/testdir |
25127                          awk '{ sub(/\.$/, "", $1); print $1}')
25128         [ $dirperms == "drwxrwsrwt" ] ||
25129                 error "incorrect perms on $dir/testdir"
25130
25131         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25132                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25133         ls -n $dir/testdir/testfile
25134         local fileperms=$(ls -n $dir/testdir/testfile |
25135                           awk '{ sub(/\.$/, "", $1); print $1}')
25136         [ $fileperms == "-rwxr-xr-x" ] ||
25137                 error "incorrect perms on $dir/testdir/testfile"
25138
25139         umask $SAVE_UMASK
25140 }
25141 run_test 420 "clear SGID bit on non-directories for non-members"
25142
25143 test_421a() {
25144         local cnt
25145         local fid1
25146         local fid2
25147
25148         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25149                 skip "Need MDS version at least 2.12.54"
25150
25151         test_mkdir $DIR/$tdir
25152         createmany -o $DIR/$tdir/f 3
25153         cnt=$(ls -1 $DIR/$tdir | wc -l)
25154         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25155
25156         fid1=$(lfs path2fid $DIR/$tdir/f1)
25157         fid2=$(lfs path2fid $DIR/$tdir/f2)
25158         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25159
25160         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25161         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25162
25163         cnt=$(ls -1 $DIR/$tdir | wc -l)
25164         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25165
25166         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25167         createmany -o $DIR/$tdir/f 3
25168         cnt=$(ls -1 $DIR/$tdir | wc -l)
25169         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25170
25171         fid1=$(lfs path2fid $DIR/$tdir/f1)
25172         fid2=$(lfs path2fid $DIR/$tdir/f2)
25173         echo "remove using fsname $FSNAME"
25174         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25175
25176         cnt=$(ls -1 $DIR/$tdir | wc -l)
25177         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25178 }
25179 run_test 421a "simple rm by fid"
25180
25181 test_421b() {
25182         local cnt
25183         local FID1
25184         local FID2
25185
25186         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25187                 skip "Need MDS version at least 2.12.54"
25188
25189         test_mkdir $DIR/$tdir
25190         createmany -o $DIR/$tdir/f 3
25191         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25192         MULTIPID=$!
25193
25194         FID1=$(lfs path2fid $DIR/$tdir/f1)
25195         FID2=$(lfs path2fid $DIR/$tdir/f2)
25196         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25197
25198         kill -USR1 $MULTIPID
25199         wait
25200
25201         cnt=$(ls $DIR/$tdir | wc -l)
25202         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25203 }
25204 run_test 421b "rm by fid on open file"
25205
25206 test_421c() {
25207         local cnt
25208         local FIDS
25209
25210         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25211                 skip "Need MDS version at least 2.12.54"
25212
25213         test_mkdir $DIR/$tdir
25214         createmany -o $DIR/$tdir/f 3
25215         touch $DIR/$tdir/$tfile
25216         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25217         cnt=$(ls -1 $DIR/$tdir | wc -l)
25218         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25219
25220         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25221         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25222
25223         cnt=$(ls $DIR/$tdir | wc -l)
25224         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25225 }
25226 run_test 421c "rm by fid against hardlinked files"
25227
25228 test_421d() {
25229         local cnt
25230         local FIDS
25231
25232         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25233                 skip "Need MDS version at least 2.12.54"
25234
25235         test_mkdir $DIR/$tdir
25236         createmany -o $DIR/$tdir/f 4097
25237         cnt=$(ls -1 $DIR/$tdir | wc -l)
25238         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25239
25240         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25241         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25242
25243         cnt=$(ls $DIR/$tdir | wc -l)
25244         rm -rf $DIR/$tdir
25245         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25246 }
25247 run_test 421d "rmfid en masse"
25248
25249 test_421e() {
25250         local cnt
25251         local FID
25252
25253         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25254         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25255                 skip "Need MDS version at least 2.12.54"
25256
25257         mkdir -p $DIR/$tdir
25258         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25259         createmany -o $DIR/$tdir/striped_dir/f 512
25260         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25261         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25262
25263         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25264                 sed "s/[/][^:]*://g")
25265         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25266
25267         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25268         rm -rf $DIR/$tdir
25269         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25270 }
25271 run_test 421e "rmfid in DNE"
25272
25273 test_421f() {
25274         local cnt
25275         local FID
25276
25277         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25278                 skip "Need MDS version at least 2.12.54"
25279
25280         test_mkdir $DIR/$tdir
25281         touch $DIR/$tdir/f
25282         cnt=$(ls -1 $DIR/$tdir | wc -l)
25283         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25284
25285         FID=$(lfs path2fid $DIR/$tdir/f)
25286         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25287         # rmfid should fail
25288         cnt=$(ls -1 $DIR/$tdir | wc -l)
25289         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25290
25291         chmod a+rw $DIR/$tdir
25292         ls -la $DIR/$tdir
25293         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25294         # rmfid should fail
25295         cnt=$(ls -1 $DIR/$tdir | wc -l)
25296         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25297
25298         rm -f $DIR/$tdir/f
25299         $RUNAS touch $DIR/$tdir/f
25300         FID=$(lfs path2fid $DIR/$tdir/f)
25301         echo "rmfid as root"
25302         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25303         cnt=$(ls -1 $DIR/$tdir | wc -l)
25304         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25305
25306         rm -f $DIR/$tdir/f
25307         $RUNAS touch $DIR/$tdir/f
25308         cnt=$(ls -1 $DIR/$tdir | wc -l)
25309         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25310         FID=$(lfs path2fid $DIR/$tdir/f)
25311         # rmfid w/o user_fid2path mount option should fail
25312         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25313         cnt=$(ls -1 $DIR/$tdir | wc -l)
25314         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25315
25316         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25317         stack_trap "rmdir $tmpdir"
25318         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25319                 error "failed to mount client'"
25320         stack_trap "umount_client $tmpdir"
25321
25322         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25323         # rmfid should succeed
25324         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25325         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25326
25327         # rmfid shouldn't allow to remove files due to dir's permission
25328         chmod a+rwx $tmpdir/$tdir
25329         touch $tmpdir/$tdir/f
25330         ls -la $tmpdir/$tdir
25331         FID=$(lfs path2fid $tmpdir/$tdir/f)
25332         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25333         return 0
25334 }
25335 run_test 421f "rmfid checks permissions"
25336
25337 test_421g() {
25338         local cnt
25339         local FIDS
25340
25341         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25342         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25343                 skip "Need MDS version at least 2.12.54"
25344
25345         mkdir -p $DIR/$tdir
25346         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25347         createmany -o $DIR/$tdir/striped_dir/f 512
25348         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25349         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25350
25351         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25352                 sed "s/[/][^:]*://g")
25353
25354         rm -f $DIR/$tdir/striped_dir/f1*
25355         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25356         removed=$((512 - cnt))
25357
25358         # few files have been just removed, so we expect
25359         # rmfid to fail on their fids
25360         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25361         [ $removed != $errors ] && error "$errors != $removed"
25362
25363         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25364         rm -rf $DIR/$tdir
25365         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25366 }
25367 run_test 421g "rmfid to return errors properly"
25368
25369 test_422() {
25370         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25371         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25372         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25373         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25374         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25375
25376         local amc=$(at_max_get client)
25377         local amo=$(at_max_get mds1)
25378         local timeout=`lctl get_param -n timeout`
25379
25380         at_max_set 0 client
25381         at_max_set 0 mds1
25382
25383 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25384         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25385                         fail_val=$(((2*timeout + 10)*1000))
25386         touch $DIR/$tdir/d3/file &
25387         sleep 2
25388 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25389         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25390                         fail_val=$((2*timeout + 5))
25391         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25392         local pid=$!
25393         sleep 1
25394         kill -9 $pid
25395         sleep $((2 * timeout))
25396         echo kill $pid
25397         kill -9 $pid
25398         lctl mark touch
25399         touch $DIR/$tdir/d2/file3
25400         touch $DIR/$tdir/d2/file4
25401         touch $DIR/$tdir/d2/file5
25402
25403         wait
25404         at_max_set $amc client
25405         at_max_set $amo mds1
25406
25407         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25408         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25409                 error "Watchdog is always throttled"
25410 }
25411 run_test 422 "kill a process with RPC in progress"
25412
25413 stat_test() {
25414     df -h $MOUNT &
25415     df -h $MOUNT &
25416     df -h $MOUNT &
25417     df -h $MOUNT &
25418     df -h $MOUNT &
25419     df -h $MOUNT &
25420 }
25421
25422 test_423() {
25423     local _stats
25424     # ensure statfs cache is expired
25425     sleep 2;
25426
25427     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25428     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25429
25430     return 0
25431 }
25432 run_test 423 "statfs should return a right data"
25433
25434 test_424() {
25435 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25436         $LCTL set_param fail_loc=0x80000522
25437         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25438         rm -f $DIR/$tfile
25439 }
25440 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25441
25442 test_425() {
25443         test_mkdir -c -1 $DIR/$tdir
25444         $LFS setstripe -c -1 $DIR/$tdir
25445
25446         lru_resize_disable "" 100
25447         stack_trap "lru_resize_enable" EXIT
25448
25449         sleep 5
25450
25451         for i in $(seq $((MDSCOUNT * 125))); do
25452                 local t=$DIR/$tdir/$tfile_$i
25453
25454                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25455                         error_noexit "Create file $t"
25456         done
25457         stack_trap "rm -rf $DIR/$tdir" EXIT
25458
25459         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25460                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25461                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25462
25463                 [ $lock_count -le $lru_size ] ||
25464                         error "osc lock count $lock_count > lru size $lru_size"
25465         done
25466
25467         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25468                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25469                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25470
25471                 [ $lock_count -le $lru_size ] ||
25472                         error "mdc lock count $lock_count > lru size $lru_size"
25473         done
25474 }
25475 run_test 425 "lock count should not exceed lru size"
25476
25477 test_426() {
25478         splice-test -r $DIR/$tfile
25479         splice-test -rd $DIR/$tfile
25480         splice-test $DIR/$tfile
25481         splice-test -d $DIR/$tfile
25482 }
25483 run_test 426 "splice test on Lustre"
25484
25485 test_427() {
25486         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25487         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25488                 skip "Need MDS version at least 2.12.4"
25489         local log
25490
25491         mkdir $DIR/$tdir
25492         mkdir $DIR/$tdir/1
25493         mkdir $DIR/$tdir/2
25494         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25495         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25496
25497         $LFS getdirstripe $DIR/$tdir/1/dir
25498
25499         #first setfattr for creating updatelog
25500         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25501
25502 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25503         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25504         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25505         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25506
25507         sleep 2
25508         fail mds2
25509         wait_recovery_complete mds2 $((2*TIMEOUT))
25510
25511         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25512         echo $log | grep "get update log failed" &&
25513                 error "update log corruption is detected" || true
25514 }
25515 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25516
25517 test_428() {
25518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25519         local cache_limit=$CACHE_MAX
25520
25521         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25522         $LCTL set_param -n llite.*.max_cached_mb=64
25523
25524         mkdir $DIR/$tdir
25525         $LFS setstripe -c 1 $DIR/$tdir
25526         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25527         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25528         #test write
25529         for f in $(seq 4); do
25530                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25531         done
25532         wait
25533
25534         cancel_lru_locks osc
25535         # Test read
25536         for f in $(seq 4); do
25537                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25538         done
25539         wait
25540 }
25541 run_test 428 "large block size IO should not hang"
25542
25543 test_429() { # LU-7915 / LU-10948
25544         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25545         local testfile=$DIR/$tfile
25546         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25547         local new_flag=1
25548         local first_rpc
25549         local second_rpc
25550         local third_rpc
25551
25552         $LCTL get_param $ll_opencache_threshold_count ||
25553                 skip "client does not have opencache parameter"
25554
25555         set_opencache $new_flag
25556         stack_trap "restore_opencache"
25557         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25558                 error "enable opencache failed"
25559         touch $testfile
25560         # drop MDC DLM locks
25561         cancel_lru_locks mdc
25562         # clear MDC RPC stats counters
25563         $LCTL set_param $mdc_rpcstats=clear
25564
25565         # According to the current implementation, we need to run 3 times
25566         # open & close file to verify if opencache is enabled correctly.
25567         # 1st, RPCs are sent for lookup/open and open handle is released on
25568         #      close finally.
25569         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25570         #      so open handle won't be released thereafter.
25571         # 3rd, No RPC is sent out.
25572         $MULTIOP $testfile oc || error "multiop failed"
25573         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25574         echo "1st: $first_rpc RPCs in flight"
25575
25576         $MULTIOP $testfile oc || error "multiop failed"
25577         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25578         echo "2nd: $second_rpc RPCs in flight"
25579
25580         $MULTIOP $testfile oc || error "multiop failed"
25581         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25582         echo "3rd: $third_rpc RPCs in flight"
25583
25584         #verify no MDC RPC is sent
25585         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25586 }
25587 run_test 429 "verify if opencache flag on client side does work"
25588
25589 lseek_test_430() {
25590         local offset
25591         local file=$1
25592
25593         # data at [200K, 400K)
25594         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25595                 error "256K->512K dd fails"
25596         # data at [2M, 3M)
25597         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25598                 error "2M->3M dd fails"
25599         # data at [4M, 5M)
25600         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25601                 error "4M->5M dd fails"
25602         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25603         # start at first component hole #1
25604         printf "Seeking hole from 1000 ... "
25605         offset=$(lseek_test -l 1000 $file)
25606         echo $offset
25607         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25608         printf "Seeking data from 1000 ... "
25609         offset=$(lseek_test -d 1000 $file)
25610         echo $offset
25611         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25612
25613         # start at first component data block
25614         printf "Seeking hole from 300000 ... "
25615         offset=$(lseek_test -l 300000 $file)
25616         echo $offset
25617         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25618         printf "Seeking data from 300000 ... "
25619         offset=$(lseek_test -d 300000 $file)
25620         echo $offset
25621         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25622
25623         # start at the first component but beyond end of object size
25624         printf "Seeking hole from 1000000 ... "
25625         offset=$(lseek_test -l 1000000 $file)
25626         echo $offset
25627         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25628         printf "Seeking data from 1000000 ... "
25629         offset=$(lseek_test -d 1000000 $file)
25630         echo $offset
25631         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25632
25633         # start at second component stripe 2 (empty file)
25634         printf "Seeking hole from 1500000 ... "
25635         offset=$(lseek_test -l 1500000 $file)
25636         echo $offset
25637         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25638         printf "Seeking data from 1500000 ... "
25639         offset=$(lseek_test -d 1500000 $file)
25640         echo $offset
25641         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25642
25643         # start at second component stripe 1 (all data)
25644         printf "Seeking hole from 3000000 ... "
25645         offset=$(lseek_test -l 3000000 $file)
25646         echo $offset
25647         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25648         printf "Seeking data from 3000000 ... "
25649         offset=$(lseek_test -d 3000000 $file)
25650         echo $offset
25651         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25652
25653         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25654                 error "2nd dd fails"
25655         echo "Add data block at 640K...1280K"
25656
25657         # start at before new data block, in hole
25658         printf "Seeking hole from 600000 ... "
25659         offset=$(lseek_test -l 600000 $file)
25660         echo $offset
25661         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25662         printf "Seeking data from 600000 ... "
25663         offset=$(lseek_test -d 600000 $file)
25664         echo $offset
25665         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25666
25667         # start at the first component new data block
25668         printf "Seeking hole from 1000000 ... "
25669         offset=$(lseek_test -l 1000000 $file)
25670         echo $offset
25671         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25672         printf "Seeking data from 1000000 ... "
25673         offset=$(lseek_test -d 1000000 $file)
25674         echo $offset
25675         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25676
25677         # start at second component stripe 2, new data
25678         printf "Seeking hole from 1200000 ... "
25679         offset=$(lseek_test -l 1200000 $file)
25680         echo $offset
25681         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25682         printf "Seeking data from 1200000 ... "
25683         offset=$(lseek_test -d 1200000 $file)
25684         echo $offset
25685         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25686
25687         # start beyond file end
25688         printf "Using offset > filesize ... "
25689         lseek_test -l 4000000 $file && error "lseek should fail"
25690         printf "Using offset > filesize ... "
25691         lseek_test -d 4000000 $file && error "lseek should fail"
25692
25693         printf "Done\n\n"
25694 }
25695
25696 test_430a() {
25697         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25698                 skip "MDT does not support SEEK_HOLE"
25699
25700         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25701                 skip "OST does not support SEEK_HOLE"
25702
25703         local file=$DIR/$tdir/$tfile
25704
25705         mkdir -p $DIR/$tdir
25706
25707         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25708         # OST stripe #1 will have continuous data at [1M, 3M)
25709         # OST stripe #2 is empty
25710         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25711         lseek_test_430 $file
25712         rm $file
25713         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25714         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25715         lseek_test_430 $file
25716         rm $file
25717         $LFS setstripe -c2 -S 512K $file
25718         echo "Two stripes, stripe size 512K"
25719         lseek_test_430 $file
25720         rm $file
25721         # FLR with stale mirror
25722         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25723                        -N -c2 -S 1M $file
25724         echo "Mirrored file:"
25725         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25726         echo "Plain 2 stripes 1M"
25727         lseek_test_430 $file
25728         rm $file
25729 }
25730 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25731
25732 test_430b() {
25733         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25734                 skip "OST does not support SEEK_HOLE"
25735
25736         local offset
25737         local file=$DIR/$tdir/$tfile
25738
25739         mkdir -p $DIR/$tdir
25740         # Empty layout lseek should fail
25741         $MCREATE $file
25742         # seek from 0
25743         printf "Seeking hole from 0 ... "
25744         lseek_test -l 0 $file && error "lseek should fail"
25745         printf "Seeking data from 0 ... "
25746         lseek_test -d 0 $file && error "lseek should fail"
25747         rm $file
25748
25749         # 1M-hole file
25750         $LFS setstripe -E 1M -c2 -E eof $file
25751         $TRUNCATE $file 1048576
25752         printf "Seeking hole from 1000000 ... "
25753         offset=$(lseek_test -l 1000000 $file)
25754         echo $offset
25755         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25756         printf "Seeking data from 1000000 ... "
25757         lseek_test -d 1000000 $file && error "lseek should fail"
25758         rm $file
25759
25760         # full component followed by non-inited one
25761         $LFS setstripe -E 1M -c2 -E eof $file
25762         dd if=/dev/urandom of=$file bs=1M count=1
25763         printf "Seeking hole from 1000000 ... "
25764         offset=$(lseek_test -l 1000000 $file)
25765         echo $offset
25766         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25767         printf "Seeking hole from 1048576 ... "
25768         lseek_test -l 1048576 $file && error "lseek should fail"
25769         # init second component and truncate back
25770         echo "123" >> $file
25771         $TRUNCATE $file 1048576
25772         printf "Seeking hole from 1000000 ... "
25773         offset=$(lseek_test -l 1000000 $file)
25774         echo $offset
25775         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25776         printf "Seeking hole from 1048576 ... "
25777         lseek_test -l 1048576 $file && error "lseek should fail"
25778         # boundary checks for big values
25779         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25780         offset=$(lseek_test -d 0 $file.10g)
25781         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25782         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25783         offset=$(lseek_test -d 0 $file.100g)
25784         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25785         return 0
25786 }
25787 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25788
25789 test_430c() {
25790         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25791                 skip "OST does not support SEEK_HOLE"
25792
25793         local file=$DIR/$tdir/$tfile
25794         local start
25795
25796         mkdir -p $DIR/$tdir
25797         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25798
25799         # cp version 8.33+ prefers lseek over fiemap
25800         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25801                 start=$SECONDS
25802                 time cp $file /dev/null
25803                 (( SECONDS - start < 5 )) ||
25804                         error "cp: too long runtime $((SECONDS - start))"
25805
25806         fi
25807         # tar version 1.29+ supports SEEK_HOLE/DATA
25808         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25809                 start=$SECONDS
25810                 time tar cS $file - | cat > /dev/null
25811                 (( SECONDS - start < 5 )) ||
25812                         error "tar: too long runtime $((SECONDS - start))"
25813         fi
25814 }
25815 run_test 430c "lseek: external tools check"
25816
25817 test_431() { # LU-14187
25818         local file=$DIR/$tdir/$tfile
25819
25820         mkdir -p $DIR/$tdir
25821         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25822         dd if=/dev/urandom of=$file bs=4k count=1
25823         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25824         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25825         #define OBD_FAIL_OST_RESTART_IO 0x251
25826         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25827         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25828         cp $file $file.0
25829         cancel_lru_locks
25830         sync_all_data
25831         echo 3 > /proc/sys/vm/drop_caches
25832         diff  $file $file.0 || error "data diff"
25833 }
25834 run_test 431 "Restart transaction for IO"
25835
25836 cleanup_test_432() {
25837         do_facet mgs $LCTL nodemap_activate 0
25838         wait_nm_sync active
25839 }
25840
25841 test_432() {
25842         local tmpdir=$TMP/dir432
25843
25844         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
25845                 skip "Need MDS version at least 2.14.52"
25846
25847         stack_trap cleanup_test_432 EXIT
25848         mkdir $DIR/$tdir
25849         mkdir $tmpdir
25850
25851         do_facet mgs $LCTL nodemap_activate 1
25852         wait_nm_sync active
25853         do_facet mgs $LCTL nodemap_modify --name default \
25854                 --property admin --value 1
25855         do_facet mgs $LCTL nodemap_modify --name default \
25856                 --property trusted --value 1
25857         cancel_lru_locks mdc
25858         wait_nm_sync default admin_nodemap
25859         wait_nm_sync default trusted_nodemap
25860
25861         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
25862                grep -ci "Operation not permitted") -ne 0 ]; then
25863                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
25864         fi
25865 }
25866 run_test 432 "mv dir from outside Lustre"
25867
25868 prep_801() {
25869         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25870         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25871                 skip "Need server version at least 2.9.55"
25872
25873         start_full_debug_logging
25874 }
25875
25876 post_801() {
25877         stop_full_debug_logging
25878 }
25879
25880 barrier_stat() {
25881         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25882                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25883                            awk '/The barrier for/ { print $7 }')
25884                 echo $st
25885         else
25886                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25887                 echo \'$st\'
25888         fi
25889 }
25890
25891 barrier_expired() {
25892         local expired
25893
25894         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25895                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25896                           awk '/will be expired/ { print $7 }')
25897         else
25898                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
25899         fi
25900
25901         echo $expired
25902 }
25903
25904 test_801a() {
25905         prep_801
25906
25907         echo "Start barrier_freeze at: $(date)"
25908         #define OBD_FAIL_BARRIER_DELAY          0x2202
25909         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25910         # Do not reduce barrier time - See LU-11873
25911         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
25912
25913         sleep 2
25914         local b_status=$(barrier_stat)
25915         echo "Got barrier status at: $(date)"
25916         [ "$b_status" = "'freezing_p1'" ] ||
25917                 error "(1) unexpected barrier status $b_status"
25918
25919         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25920         wait
25921         b_status=$(barrier_stat)
25922         [ "$b_status" = "'frozen'" ] ||
25923                 error "(2) unexpected barrier status $b_status"
25924
25925         local expired=$(barrier_expired)
25926         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
25927         sleep $((expired + 3))
25928
25929         b_status=$(barrier_stat)
25930         [ "$b_status" = "'expired'" ] ||
25931                 error "(3) unexpected barrier status $b_status"
25932
25933         # Do not reduce barrier time - See LU-11873
25934         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
25935                 error "(4) fail to freeze barrier"
25936
25937         b_status=$(barrier_stat)
25938         [ "$b_status" = "'frozen'" ] ||
25939                 error "(5) unexpected barrier status $b_status"
25940
25941         echo "Start barrier_thaw at: $(date)"
25942         #define OBD_FAIL_BARRIER_DELAY          0x2202
25943         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
25944         do_facet mgs $LCTL barrier_thaw $FSNAME &
25945
25946         sleep 2
25947         b_status=$(barrier_stat)
25948         echo "Got barrier status at: $(date)"
25949         [ "$b_status" = "'thawing'" ] ||
25950                 error "(6) unexpected barrier status $b_status"
25951
25952         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
25953         wait
25954         b_status=$(barrier_stat)
25955         [ "$b_status" = "'thawed'" ] ||
25956                 error "(7) unexpected barrier status $b_status"
25957
25958         #define OBD_FAIL_BARRIER_FAILURE        0x2203
25959         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
25960         do_facet mgs $LCTL barrier_freeze $FSNAME
25961
25962         b_status=$(barrier_stat)
25963         [ "$b_status" = "'failed'" ] ||
25964                 error "(8) unexpected barrier status $b_status"
25965
25966         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
25967         do_facet mgs $LCTL barrier_thaw $FSNAME
25968
25969         post_801
25970 }
25971 run_test 801a "write barrier user interfaces and stat machine"
25972
25973 test_801b() {
25974         prep_801
25975
25976         mkdir $DIR/$tdir || error "(1) fail to mkdir"
25977         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
25978         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
25979         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
25980         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
25981
25982         cancel_lru_locks mdc
25983
25984         # 180 seconds should be long enough
25985         do_facet mgs $LCTL barrier_freeze $FSNAME 180
25986
25987         local b_status=$(barrier_stat)
25988         [ "$b_status" = "'frozen'" ] ||
25989                 error "(6) unexpected barrier status $b_status"
25990
25991         mkdir $DIR/$tdir/d0/d10 &
25992         mkdir_pid=$!
25993
25994         touch $DIR/$tdir/d1/f13 &
25995         touch_pid=$!
25996
25997         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
25998         ln_pid=$!
25999
26000         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26001         mv_pid=$!
26002
26003         rm -f $DIR/$tdir/d4/f12 &
26004         rm_pid=$!
26005
26006         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26007
26008         # To guarantee taht the 'stat' is not blocked
26009         b_status=$(barrier_stat)
26010         [ "$b_status" = "'frozen'" ] ||
26011                 error "(8) unexpected barrier status $b_status"
26012
26013         # let above commands to run at background
26014         sleep 5
26015
26016         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26017         ps -p $touch_pid || error "(10) touch should be blocked"
26018         ps -p $ln_pid || error "(11) link should be blocked"
26019         ps -p $mv_pid || error "(12) rename should be blocked"
26020         ps -p $rm_pid || error "(13) unlink should be blocked"
26021
26022         b_status=$(barrier_stat)
26023         [ "$b_status" = "'frozen'" ] ||
26024                 error "(14) unexpected barrier status $b_status"
26025
26026         do_facet mgs $LCTL barrier_thaw $FSNAME
26027         b_status=$(barrier_stat)
26028         [ "$b_status" = "'thawed'" ] ||
26029                 error "(15) unexpected barrier status $b_status"
26030
26031         wait $mkdir_pid || error "(16) mkdir should succeed"
26032         wait $touch_pid || error "(17) touch should succeed"
26033         wait $ln_pid || error "(18) link should succeed"
26034         wait $mv_pid || error "(19) rename should succeed"
26035         wait $rm_pid || error "(20) unlink should succeed"
26036
26037         post_801
26038 }
26039 run_test 801b "modification will be blocked by write barrier"
26040
26041 test_801c() {
26042         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26043
26044         prep_801
26045
26046         stop mds2 || error "(1) Fail to stop mds2"
26047
26048         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26049
26050         local b_status=$(barrier_stat)
26051         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26052                 do_facet mgs $LCTL barrier_thaw $FSNAME
26053                 error "(2) unexpected barrier status $b_status"
26054         }
26055
26056         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26057                 error "(3) Fail to rescan barrier bitmap"
26058
26059         # Do not reduce barrier time - See LU-11873
26060         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26061
26062         b_status=$(barrier_stat)
26063         [ "$b_status" = "'frozen'" ] ||
26064                 error "(4) unexpected barrier status $b_status"
26065
26066         do_facet mgs $LCTL barrier_thaw $FSNAME
26067         b_status=$(barrier_stat)
26068         [ "$b_status" = "'thawed'" ] ||
26069                 error "(5) unexpected barrier status $b_status"
26070
26071         local devname=$(mdsdevname 2)
26072
26073         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26074
26075         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26076                 error "(7) Fail to rescan barrier bitmap"
26077
26078         post_801
26079 }
26080 run_test 801c "rescan barrier bitmap"
26081
26082 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26083 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26084 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26085 saved_MOUNT_OPTS=$MOUNT_OPTS
26086
26087 cleanup_802a() {
26088         trap 0
26089
26090         stopall
26091         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26092         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26093         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26094         MOUNT_OPTS=$saved_MOUNT_OPTS
26095         setupall
26096 }
26097
26098 test_802a() {
26099         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26100         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26101         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26102                 skip "Need server version at least 2.9.55"
26103
26104         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26105
26106         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26107
26108         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26109                 error "(2) Fail to copy"
26110
26111         trap cleanup_802a EXIT
26112
26113         # sync by force before remount as readonly
26114         sync; sync_all_data; sleep 3; sync_all_data
26115
26116         stopall
26117
26118         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26119         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26120         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26121
26122         echo "Mount the server as read only"
26123         setupall server_only || error "(3) Fail to start servers"
26124
26125         echo "Mount client without ro should fail"
26126         mount_client $MOUNT &&
26127                 error "(4) Mount client without 'ro' should fail"
26128
26129         echo "Mount client with ro should succeed"
26130         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26131         mount_client $MOUNT ||
26132                 error "(5) Mount client with 'ro' should succeed"
26133
26134         echo "Modify should be refused"
26135         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26136
26137         echo "Read should be allowed"
26138         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26139                 error "(7) Read should succeed under ro mode"
26140
26141         cleanup_802a
26142 }
26143 run_test 802a "simulate readonly device"
26144
26145 test_802b() {
26146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26147         remote_mds_nodsh && skip "remote MDS with nodsh"
26148
26149         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26150                 skip "readonly option not available"
26151
26152         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26153
26154         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26155                 error "(2) Fail to copy"
26156
26157         # write back all cached data before setting MDT to readonly
26158         cancel_lru_locks
26159         sync_all_data
26160
26161         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26162         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26163
26164         echo "Modify should be refused"
26165         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26166
26167         echo "Read should be allowed"
26168         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26169                 error "(7) Read should succeed under ro mode"
26170
26171         # disable readonly
26172         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26173 }
26174 run_test 802b "be able to set MDTs to readonly"
26175
26176 test_803a() {
26177         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26178         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26179                 skip "MDS needs to be newer than 2.10.54"
26180
26181         mkdir_on_mdt0 $DIR/$tdir
26182         # Create some objects on all MDTs to trigger related logs objects
26183         for idx in $(seq $MDSCOUNT); do
26184                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26185                         $DIR/$tdir/dir${idx} ||
26186                         error "Fail to create $DIR/$tdir/dir${idx}"
26187         done
26188
26189         sync; sleep 3
26190         wait_delete_completed # ensure old test cleanups are finished
26191         echo "before create:"
26192         $LFS df -i $MOUNT
26193         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26194
26195         for i in {1..10}; do
26196                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26197                         error "Fail to create $DIR/$tdir/foo$i"
26198         done
26199
26200         sync; sleep 3
26201         echo "after create:"
26202         $LFS df -i $MOUNT
26203         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26204
26205         # allow for an llog to be cleaned up during the test
26206         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26207                 error "before ($before_used) + 10 > after ($after_used)"
26208
26209         for i in {1..10}; do
26210                 rm -rf $DIR/$tdir/foo$i ||
26211                         error "Fail to remove $DIR/$tdir/foo$i"
26212         done
26213
26214         sleep 3 # avoid MDT return cached statfs
26215         wait_delete_completed
26216         echo "after unlink:"
26217         $LFS df -i $MOUNT
26218         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26219
26220         # allow for an llog to be created during the test
26221         [ $after_used -le $((before_used + 1)) ] ||
26222                 error "after ($after_used) > before ($before_used) + 1"
26223 }
26224 run_test 803a "verify agent object for remote object"
26225
26226 test_803b() {
26227         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26228         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26229                 skip "MDS needs to be newer than 2.13.56"
26230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26231
26232         for i in $(seq 0 $((MDSCOUNT - 1))); do
26233                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26234         done
26235
26236         local before=0
26237         local after=0
26238
26239         local tmp
26240
26241         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26242         for i in $(seq 0 $((MDSCOUNT - 1))); do
26243                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26244                         awk '/getattr/ { print $2 }')
26245                 before=$((before + tmp))
26246         done
26247         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26248         for i in $(seq 0 $((MDSCOUNT - 1))); do
26249                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26250                         awk '/getattr/ { print $2 }')
26251                 after=$((after + tmp))
26252         done
26253
26254         [ $before -eq $after ] || error "getattr count $before != $after"
26255 }
26256 run_test 803b "remote object can getattr from cache"
26257
26258 test_804() {
26259         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26260         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26261                 skip "MDS needs to be newer than 2.10.54"
26262         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26263
26264         mkdir -p $DIR/$tdir
26265         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26266                 error "Fail to create $DIR/$tdir/dir0"
26267
26268         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26269         local dev=$(mdsdevname 2)
26270
26271         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26272                 grep ${fid} || error "NOT found agent entry for dir0"
26273
26274         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26275                 error "Fail to create $DIR/$tdir/dir1"
26276
26277         touch $DIR/$tdir/dir1/foo0 ||
26278                 error "Fail to create $DIR/$tdir/dir1/foo0"
26279         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26280         local rc=0
26281
26282         for idx in $(seq $MDSCOUNT); do
26283                 dev=$(mdsdevname $idx)
26284                 do_facet mds${idx} \
26285                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26286                         grep ${fid} && rc=$idx
26287         done
26288
26289         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26290                 error "Fail to rename foo0 to foo1"
26291         if [ $rc -eq 0 ]; then
26292                 for idx in $(seq $MDSCOUNT); do
26293                         dev=$(mdsdevname $idx)
26294                         do_facet mds${idx} \
26295                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26296                         grep ${fid} && rc=$idx
26297                 done
26298         fi
26299
26300         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26301                 error "Fail to rename foo1 to foo2"
26302         if [ $rc -eq 0 ]; then
26303                 for idx in $(seq $MDSCOUNT); do
26304                         dev=$(mdsdevname $idx)
26305                         do_facet mds${idx} \
26306                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26307                         grep ${fid} && rc=$idx
26308                 done
26309         fi
26310
26311         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26312
26313         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26314                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26315         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26316                 error "Fail to rename foo2 to foo0"
26317         unlink $DIR/$tdir/dir1/foo0 ||
26318                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26319         rm -rf $DIR/$tdir/dir0 ||
26320                 error "Fail to rm $DIR/$tdir/dir0"
26321
26322         for idx in $(seq $MDSCOUNT); do
26323                 dev=$(mdsdevname $idx)
26324                 rc=0
26325
26326                 stop mds${idx}
26327                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26328                         rc=$?
26329                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26330                         error "mount mds$idx failed"
26331                 df $MOUNT > /dev/null 2>&1
26332
26333                 # e2fsck should not return error
26334                 [ $rc -eq 0 ] ||
26335                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26336         done
26337 }
26338 run_test 804 "verify agent entry for remote entry"
26339
26340 cleanup_805() {
26341         do_facet $SINGLEMDS zfs set quota=$old $fsset
26342         unlinkmany $DIR/$tdir/f- 1000000
26343         trap 0
26344 }
26345
26346 test_805() {
26347         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26348         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26349         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26350                 skip "netfree not implemented before 0.7"
26351         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26352                 skip "Need MDS version at least 2.10.57"
26353
26354         local fsset
26355         local freekb
26356         local usedkb
26357         local old
26358         local quota
26359         local pref="osd-zfs.$FSNAME-MDT0000."
26360
26361         # limit available space on MDS dataset to meet nospace issue
26362         # quickly. then ZFS 0.7.2 can use reserved space if asked
26363         # properly (using netfree flag in osd_declare_destroy()
26364         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26365         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26366                 gawk '{print $3}')
26367         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26368         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26369         let "usedkb=usedkb-freekb"
26370         let "freekb=freekb/2"
26371         if let "freekb > 5000"; then
26372                 let "freekb=5000"
26373         fi
26374         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26375         trap cleanup_805 EXIT
26376         mkdir_on_mdt0 $DIR/$tdir
26377         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26378                 error "Can't set PFL layout"
26379         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26380         rm -rf $DIR/$tdir || error "not able to remove"
26381         do_facet $SINGLEMDS zfs set quota=$old $fsset
26382         trap 0
26383 }
26384 run_test 805 "ZFS can remove from full fs"
26385
26386 # Size-on-MDS test
26387 check_lsom_data()
26388 {
26389         local file=$1
26390         local expect=$(stat -c %s $file)
26391
26392         check_lsom_size $1 $expect
26393
26394         local blocks=$($LFS getsom -b $file)
26395         expect=$(stat -c %b $file)
26396         [[ $blocks == $expect ]] ||
26397                 error "$file expected blocks: $expect, got: $blocks"
26398 }
26399
26400 check_lsom_size()
26401 {
26402         local size
26403         local expect=$2
26404
26405         cancel_lru_locks mdc
26406
26407         size=$($LFS getsom -s $1)
26408         [[ $size == $expect ]] ||
26409                 error "$file expected size: $expect, got: $size"
26410 }
26411
26412 test_806() {
26413         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26414                 skip "Need MDS version at least 2.11.52"
26415
26416         local bs=1048576
26417
26418         touch $DIR/$tfile || error "touch $tfile failed"
26419
26420         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26421         save_lustre_params client "llite.*.xattr_cache" > $save
26422         lctl set_param llite.*.xattr_cache=0
26423         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26424
26425         # single-threaded write
26426         echo "Test SOM for single-threaded write"
26427         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26428                 error "write $tfile failed"
26429         check_lsom_size $DIR/$tfile $bs
26430
26431         local num=32
26432         local size=$(($num * $bs))
26433         local offset=0
26434         local i
26435
26436         echo "Test SOM for single client multi-threaded($num) write"
26437         $TRUNCATE $DIR/$tfile 0
26438         for ((i = 0; i < $num; i++)); do
26439                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26440                 local pids[$i]=$!
26441                 offset=$((offset + $bs))
26442         done
26443         for (( i=0; i < $num; i++ )); do
26444                 wait ${pids[$i]}
26445         done
26446         check_lsom_size $DIR/$tfile $size
26447
26448         $TRUNCATE $DIR/$tfile 0
26449         for ((i = 0; i < $num; i++)); do
26450                 offset=$((offset - $bs))
26451                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26452                 local pids[$i]=$!
26453         done
26454         for (( i=0; i < $num; i++ )); do
26455                 wait ${pids[$i]}
26456         done
26457         check_lsom_size $DIR/$tfile $size
26458
26459         # multi-client writes
26460         num=$(get_node_count ${CLIENTS//,/ })
26461         size=$(($num * $bs))
26462         offset=0
26463         i=0
26464
26465         echo "Test SOM for multi-client ($num) writes"
26466         $TRUNCATE $DIR/$tfile 0
26467         for client in ${CLIENTS//,/ }; do
26468                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26469                 local pids[$i]=$!
26470                 i=$((i + 1))
26471                 offset=$((offset + $bs))
26472         done
26473         for (( i=0; i < $num; i++ )); do
26474                 wait ${pids[$i]}
26475         done
26476         check_lsom_size $DIR/$tfile $offset
26477
26478         i=0
26479         $TRUNCATE $DIR/$tfile 0
26480         for client in ${CLIENTS//,/ }; do
26481                 offset=$((offset - $bs))
26482                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26483                 local pids[$i]=$!
26484                 i=$((i + 1))
26485         done
26486         for (( i=0; i < $num; i++ )); do
26487                 wait ${pids[$i]}
26488         done
26489         check_lsom_size $DIR/$tfile $size
26490
26491         # verify truncate
26492         echo "Test SOM for truncate"
26493         $TRUNCATE $DIR/$tfile 1048576
26494         check_lsom_size $DIR/$tfile 1048576
26495         $TRUNCATE $DIR/$tfile 1234
26496         check_lsom_size $DIR/$tfile 1234
26497
26498         # verify SOM blocks count
26499         echo "Verify SOM block count"
26500         $TRUNCATE $DIR/$tfile 0
26501         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26502                 error "failed to write file $tfile"
26503         check_lsom_data $DIR/$tfile
26504 }
26505 run_test 806 "Verify Lazy Size on MDS"
26506
26507 test_807() {
26508         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26509         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26510                 skip "Need MDS version at least 2.11.52"
26511
26512         # Registration step
26513         changelog_register || error "changelog_register failed"
26514         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26515         changelog_users $SINGLEMDS | grep -q $cl_user ||
26516                 error "User $cl_user not found in changelog_users"
26517
26518         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26519         save_lustre_params client "llite.*.xattr_cache" > $save
26520         lctl set_param llite.*.xattr_cache=0
26521         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26522
26523         rm -rf $DIR/$tdir || error "rm $tdir failed"
26524         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26525         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26526         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26527         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26528                 error "truncate $tdir/trunc failed"
26529
26530         local bs=1048576
26531         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26532                 error "write $tfile failed"
26533
26534         # multi-client wirtes
26535         local num=$(get_node_count ${CLIENTS//,/ })
26536         local offset=0
26537         local i=0
26538
26539         echo "Test SOM for multi-client ($num) writes"
26540         touch $DIR/$tfile || error "touch $tfile failed"
26541         $TRUNCATE $DIR/$tfile 0
26542         for client in ${CLIENTS//,/ }; do
26543                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26544                 local pids[$i]=$!
26545                 i=$((i + 1))
26546                 offset=$((offset + $bs))
26547         done
26548         for (( i=0; i < $num; i++ )); do
26549                 wait ${pids[$i]}
26550         done
26551
26552         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26553         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26554         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26555         check_lsom_data $DIR/$tdir/trunc
26556         check_lsom_data $DIR/$tdir/single_dd
26557         check_lsom_data $DIR/$tfile
26558
26559         rm -rf $DIR/$tdir
26560         # Deregistration step
26561         changelog_deregister || error "changelog_deregister failed"
26562 }
26563 run_test 807 "verify LSOM syncing tool"
26564
26565 check_som_nologged()
26566 {
26567         local lines=$($LFS changelog $FSNAME-MDT0000 |
26568                 grep 'x=trusted.som' | wc -l)
26569         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26570 }
26571
26572 test_808() {
26573         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26574                 skip "Need MDS version at least 2.11.55"
26575
26576         # Registration step
26577         changelog_register || error "changelog_register failed"
26578
26579         touch $DIR/$tfile || error "touch $tfile failed"
26580         check_som_nologged
26581
26582         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26583                 error "write $tfile failed"
26584         check_som_nologged
26585
26586         $TRUNCATE $DIR/$tfile 1234
26587         check_som_nologged
26588
26589         $TRUNCATE $DIR/$tfile 1048576
26590         check_som_nologged
26591
26592         # Deregistration step
26593         changelog_deregister || error "changelog_deregister failed"
26594 }
26595 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26596
26597 check_som_nodata()
26598 {
26599         $LFS getsom $1
26600         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26601 }
26602
26603 test_809() {
26604         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26605                 skip "Need MDS version at least 2.11.56"
26606
26607         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26608                 error "failed to create DoM-only file $DIR/$tfile"
26609         touch $DIR/$tfile || error "touch $tfile failed"
26610         check_som_nodata $DIR/$tfile
26611
26612         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26613                 error "write $tfile failed"
26614         check_som_nodata $DIR/$tfile
26615
26616         $TRUNCATE $DIR/$tfile 1234
26617         check_som_nodata $DIR/$tfile
26618
26619         $TRUNCATE $DIR/$tfile 4097
26620         check_som_nodata $DIR/$file
26621 }
26622 run_test 809 "Verify no SOM xattr store for DoM-only files"
26623
26624 test_810() {
26625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26626         $GSS && skip_env "could not run with gss"
26627         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26628                 skip "OST < 2.12.58 doesn't align checksum"
26629
26630         set_checksums 1
26631         stack_trap "set_checksums $ORIG_CSUM" EXIT
26632         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26633
26634         local csum
26635         local before
26636         local after
26637         for csum in $CKSUM_TYPES; do
26638                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26639                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26640                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26641                         eval set -- $i
26642                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26643                         before=$(md5sum $DIR/$tfile)
26644                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26645                         after=$(md5sum $DIR/$tfile)
26646                         [ "$before" == "$after" ] ||
26647                                 error "$csum: $before != $after bs=$1 seek=$2"
26648                 done
26649         done
26650 }
26651 run_test 810 "partial page writes on ZFS (LU-11663)"
26652
26653 test_812a() {
26654         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26655                 skip "OST < 2.12.51 doesn't support this fail_loc"
26656
26657         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26658         # ensure ost1 is connected
26659         stat $DIR/$tfile >/dev/null || error "can't stat"
26660         wait_osc_import_state client ost1 FULL
26661         # no locks, no reqs to let the connection idle
26662         cancel_lru_locks osc
26663
26664         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26665 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26666         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26667         wait_osc_import_state client ost1 CONNECTING
26668         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26669
26670         stat $DIR/$tfile >/dev/null || error "can't stat file"
26671 }
26672 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26673
26674 test_812b() { # LU-12378
26675         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26676                 skip "OST < 2.12.51 doesn't support this fail_loc"
26677
26678         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26679         # ensure ost1 is connected
26680         stat $DIR/$tfile >/dev/null || error "can't stat"
26681         wait_osc_import_state client ost1 FULL
26682         # no locks, no reqs to let the connection idle
26683         cancel_lru_locks osc
26684
26685         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26686 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26687         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26688         wait_osc_import_state client ost1 CONNECTING
26689         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26690
26691         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26692         wait_osc_import_state client ost1 IDLE
26693 }
26694 run_test 812b "do not drop no resend request for idle connect"
26695
26696 test_812c() {
26697         local old
26698
26699         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26700
26701         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26702         $LFS getstripe $DIR/$tfile
26703         $LCTL set_param osc.*.idle_timeout=10
26704         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26705         # ensure ost1 is connected
26706         stat $DIR/$tfile >/dev/null || error "can't stat"
26707         wait_osc_import_state client ost1 FULL
26708         # no locks, no reqs to let the connection idle
26709         cancel_lru_locks osc
26710
26711 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26712         $LCTL set_param fail_loc=0x80000533
26713         sleep 15
26714         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26715 }
26716 run_test 812c "idle import vs lock enqueue race"
26717
26718 test_813() {
26719         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26720         [ -z "$file_heat_sav" ] && skip "no file heat support"
26721
26722         local readsample
26723         local writesample
26724         local readbyte
26725         local writebyte
26726         local readsample1
26727         local writesample1
26728         local readbyte1
26729         local writebyte1
26730
26731         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26732         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26733
26734         $LCTL set_param -n llite.*.file_heat=1
26735         echo "Turn on file heat"
26736         echo "Period second: $period_second, Decay percentage: $decay_pct"
26737
26738         echo "QQQQ" > $DIR/$tfile
26739         echo "QQQQ" > $DIR/$tfile
26740         echo "QQQQ" > $DIR/$tfile
26741         cat $DIR/$tfile > /dev/null
26742         cat $DIR/$tfile > /dev/null
26743         cat $DIR/$tfile > /dev/null
26744         cat $DIR/$tfile > /dev/null
26745
26746         local out=$($LFS heat_get $DIR/$tfile)
26747
26748         $LFS heat_get $DIR/$tfile
26749         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26750         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26751         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26752         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26753
26754         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26755         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26756         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26757         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26758
26759         sleep $((period_second + 3))
26760         echo "Sleep $((period_second + 3)) seconds..."
26761         # The recursion formula to calculate the heat of the file f is as
26762         # follow:
26763         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26764         # Where Hi is the heat value in the period between time points i*I and
26765         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26766         # to the weight of Ci.
26767         out=$($LFS heat_get $DIR/$tfile)
26768         $LFS heat_get $DIR/$tfile
26769         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26770         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26771         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26772         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26773
26774         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26775                 error "read sample ($readsample) is wrong"
26776         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26777                 error "write sample ($writesample) is wrong"
26778         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26779                 error "read bytes ($readbyte) is wrong"
26780         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26781                 error "write bytes ($writebyte) is wrong"
26782
26783         echo "QQQQ" > $DIR/$tfile
26784         echo "QQQQ" > $DIR/$tfile
26785         echo "QQQQ" > $DIR/$tfile
26786         cat $DIR/$tfile > /dev/null
26787         cat $DIR/$tfile > /dev/null
26788         cat $DIR/$tfile > /dev/null
26789         cat $DIR/$tfile > /dev/null
26790
26791         sleep $((period_second + 3))
26792         echo "Sleep $((period_second + 3)) seconds..."
26793
26794         out=$($LFS heat_get $DIR/$tfile)
26795         $LFS heat_get $DIR/$tfile
26796         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26797         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26798         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26799         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26800
26801         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26802                 4 * $decay_pct) / 100") -eq 1 ] ||
26803                 error "read sample ($readsample1) is wrong"
26804         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26805                 3 * $decay_pct) / 100") -eq 1 ] ||
26806                 error "write sample ($writesample1) is wrong"
26807         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26808                 20 * $decay_pct) / 100") -eq 1 ] ||
26809                 error "read bytes ($readbyte1) is wrong"
26810         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26811                 15 * $decay_pct) / 100") -eq 1 ] ||
26812                 error "write bytes ($writebyte1) is wrong"
26813
26814         echo "Turn off file heat for the file $DIR/$tfile"
26815         $LFS heat_set -o $DIR/$tfile
26816
26817         echo "QQQQ" > $DIR/$tfile
26818         echo "QQQQ" > $DIR/$tfile
26819         echo "QQQQ" > $DIR/$tfile
26820         cat $DIR/$tfile > /dev/null
26821         cat $DIR/$tfile > /dev/null
26822         cat $DIR/$tfile > /dev/null
26823         cat $DIR/$tfile > /dev/null
26824
26825         out=$($LFS heat_get $DIR/$tfile)
26826         $LFS heat_get $DIR/$tfile
26827         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26828         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26829         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26830         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26831
26832         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26833         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26834         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26835         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26836
26837         echo "Trun on file heat for the file $DIR/$tfile"
26838         $LFS heat_set -O $DIR/$tfile
26839
26840         echo "QQQQ" > $DIR/$tfile
26841         echo "QQQQ" > $DIR/$tfile
26842         echo "QQQQ" > $DIR/$tfile
26843         cat $DIR/$tfile > /dev/null
26844         cat $DIR/$tfile > /dev/null
26845         cat $DIR/$tfile > /dev/null
26846         cat $DIR/$tfile > /dev/null
26847
26848         out=$($LFS heat_get $DIR/$tfile)
26849         $LFS heat_get $DIR/$tfile
26850         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26851         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26852         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26853         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26854
26855         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26856         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26857         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26858         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26859
26860         $LFS heat_set -c $DIR/$tfile
26861         $LCTL set_param -n llite.*.file_heat=0
26862         echo "Turn off file heat support for the Lustre filesystem"
26863
26864         echo "QQQQ" > $DIR/$tfile
26865         echo "QQQQ" > $DIR/$tfile
26866         echo "QQQQ" > $DIR/$tfile
26867         cat $DIR/$tfile > /dev/null
26868         cat $DIR/$tfile > /dev/null
26869         cat $DIR/$tfile > /dev/null
26870         cat $DIR/$tfile > /dev/null
26871
26872         out=$($LFS heat_get $DIR/$tfile)
26873         $LFS heat_get $DIR/$tfile
26874         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26875         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26876         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26877         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26878
26879         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26880         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26881         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26882         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26883
26884         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26885         rm -f $DIR/$tfile
26886 }
26887 run_test 813 "File heat verfication"
26888
26889 test_814()
26890 {
26891         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26892         echo -n y >> $DIR/$tfile
26893         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26894         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26895 }
26896 run_test 814 "sparse cp works as expected (LU-12361)"
26897
26898 test_815()
26899 {
26900         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
26901         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
26902 }
26903 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
26904
26905 test_816() {
26906         local ost1_imp=$(get_osc_import_name client ost1)
26907         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26908                          cut -d'.' -f2)
26909
26910         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26911         # ensure ost1 is connected
26912
26913         stat $DIR/$tfile >/dev/null || error "can't stat"
26914         wait_osc_import_state client ost1 FULL
26915         # no locks, no reqs to let the connection idle
26916         cancel_lru_locks osc
26917         lru_resize_disable osc
26918         local before
26919         local now
26920         before=$($LCTL get_param -n \
26921                  ldlm.namespaces.$imp_name.lru_size)
26922
26923         wait_osc_import_state client ost1 IDLE
26924         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
26925         now=$($LCTL get_param -n \
26926               ldlm.namespaces.$imp_name.lru_size)
26927         [ $before == $now ] || error "lru_size changed $before != $now"
26928 }
26929 run_test 816 "do not reset lru_resize on idle reconnect"
26930
26931 cleanup_817() {
26932         umount $tmpdir
26933         exportfs -u localhost:$DIR/nfsexp
26934         rm -rf $DIR/nfsexp
26935 }
26936
26937 test_817() {
26938         systemctl restart nfs-server.service || skip "failed to restart nfsd"
26939
26940         mkdir -p $DIR/nfsexp
26941         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
26942                 error "failed to export nfs"
26943
26944         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
26945         stack_trap cleanup_817 EXIT
26946
26947         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
26948                 error "failed to mount nfs to $tmpdir"
26949
26950         cp /bin/true $tmpdir
26951         $DIR/nfsexp/true || error "failed to execute 'true' command"
26952 }
26953 run_test 817 "nfsd won't cache write lock for exec file"
26954
26955 test_818() {
26956         mkdir $DIR/$tdir
26957         $LFS setstripe -c1 -i0 $DIR/$tfile
26958         $LFS setstripe -c1 -i1 $DIR/$tfile
26959         stop $SINGLEMDS
26960         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
26961         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
26962         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
26963                 error "start $SINGLEMDS failed"
26964         rm -rf $DIR/$tdir
26965 }
26966 run_test 818 "unlink with failed llog"
26967
26968 test_819a() {
26969         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26970         cancel_lru_locks osc
26971         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26972         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26973         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
26974         rm -f $TDIR/$tfile
26975 }
26976 run_test 819a "too big niobuf in read"
26977
26978 test_819b() {
26979         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
26980         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
26981         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26982         cancel_lru_locks osc
26983         sleep 1
26984         rm -f $TDIR/$tfile
26985 }
26986 run_test 819b "too big niobuf in write"
26987
26988
26989 function test_820_start_ost() {
26990         sleep 5
26991
26992         for num in $(seq $OSTCOUNT); do
26993                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
26994         done
26995 }
26996
26997 test_820() {
26998         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26999
27000         mkdir $DIR/$tdir
27001         umount_client $MOUNT || error "umount failed"
27002         for num in $(seq $OSTCOUNT); do
27003                 stop ost$num
27004         done
27005
27006         # mount client with no active OSTs
27007         # so that the client can't initialize max LOV EA size
27008         # from OSC notifications
27009         mount_client $MOUNT || error "mount failed"
27010         # delay OST starting to keep this 0 max EA size for a while
27011         test_820_start_ost &
27012
27013         # create a directory on MDS2
27014         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27015                 error "Failed to create directory"
27016         # open intent should update default EA size
27017         # see mdc_update_max_ea_from_body()
27018         # notice this is the very first RPC to MDS2
27019         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27020         ret=$?
27021         echo $out
27022         # With SSK, this situation can lead to -EPERM being returned.
27023         # In that case, simply retry.
27024         if [ $ret -ne 0 ] && $SHARED_KEY; then
27025                 if echo "$out" | grep -q "not permitted"; then
27026                         cp /etc/services $DIR/$tdir/mds2
27027                         ret=$?
27028                 fi
27029         fi
27030         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27031 }
27032 run_test 820 "update max EA from open intent"
27033
27034 test_822() {
27035         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27036
27037         save_lustre_params mds1 \
27038                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27039         do_facet $SINGLEMDS "$LCTL set_param -n \
27040                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27041         do_facet $SINGLEMDS "$LCTL set_param -n \
27042                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27043
27044         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27045         local maxage=$(do_facet mds1 $LCTL get_param -n \
27046                        osp.$FSNAME-OST0000*MDT0000.maxage)
27047         sleep $((maxage + 1))
27048
27049         #define OBD_FAIL_NET_ERROR_RPC          0x532
27050         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27051
27052         stack_trap "restore_lustre_params < $p; rm $p"
27053
27054         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27055                       osp.$FSNAME-OST0000*MDT0000.create_count")
27056         for i in $(seq 1 $count); do
27057                 touch $DIR/$tfile.${i} || error "touch failed"
27058         done
27059 }
27060 run_test 822 "test precreate failure"
27061
27062 #
27063 # tests that do cleanup/setup should be run at the end
27064 #
27065
27066 test_900() {
27067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27068         local ls
27069
27070         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27071         $LCTL set_param fail_loc=0x903
27072
27073         cancel_lru_locks MGC
27074
27075         FAIL_ON_ERROR=true cleanup
27076         FAIL_ON_ERROR=true setup
27077 }
27078 run_test 900 "umount should not race with any mgc requeue thread"
27079
27080 # LUS-6253/LU-11185
27081 test_901() {
27082         local oldc
27083         local newc
27084         local olds
27085         local news
27086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27087
27088         # some get_param have a bug to handle dot in param name
27089         cancel_lru_locks MGC
27090         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27091         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27092         umount_client $MOUNT || error "umount failed"
27093         mount_client $MOUNT || error "mount failed"
27094         cancel_lru_locks MGC
27095         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27096         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27097
27098         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27099         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27100
27101         return 0
27102 }
27103 run_test 901 "don't leak a mgc lock on client umount"
27104
27105 # LU-13377
27106 test_902() {
27107         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27108                 skip "client does not have LU-13377 fix"
27109         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27110         $LCTL set_param fail_loc=0x1415
27111         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27112         cancel_lru_locks osc
27113         rm -f $DIR/$tfile
27114 }
27115 run_test 902 "test short write doesn't hang lustre"
27116
27117 complete $SECONDS
27118 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27119 check_and_cleanup_lustre
27120 if [ "$I_MOUNTED" != "yes" ]; then
27121         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27122 fi
27123 exit_status