Whamcloud - gitweb
LU-14924 osd-ldiskfs: fix T10PI verify/generate_fn
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_0e() { # LU-13417
257         (( $MDSCOUNT > 1 )) ||
258                 skip "We need at least 2 MDTs for this test"
259
260         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
261                 skip "Need server version at least 2.14.51"
262
263         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
264         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
265
266         [ $default_lmv_count -eq 1 ] ||
267                 error "$MOUNT default stripe count $default_lmv_count"
268
269         [ $default_lmv_index -eq -1 ] ||
270                 error "$MOUNT default stripe index $default_lmv_index"
271
272         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
273         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
274
275         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
276         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
277
278         [ $mdt_index1 -eq $mdt_index2 ] &&
279                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
280
281         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
282 }
283 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718         local devname=$(mdsdevname $mds_index)
719
720         echo "stop and checking mds${mds_index}:"
721         # e2fsck should not return error
722         stop mds${mds_index}
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 local devname=$(mdsdevname $mdt_index)
743                 # e2fsck should not return error
744                 stop mds${mdt_index}
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170 test_24t() {
1171         test_mkdir $DIR/R16a
1172         test_mkdir $DIR/R16a/b
1173         test_mkdir $DIR/R16a/b/c
1174         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1175         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1176         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1177 }
1178 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1179
1180 test_24u() { # bug12192
1181         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1182         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1183 }
1184 run_test 24u "create stripe file"
1185
1186 simple_cleanup_common() {
1187         local rc=0
1188         trap 0
1189         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1190
1191         local start=$SECONDS
1192         rm -rf $DIR/$tdir
1193         rc=$?
1194         wait_delete_completed
1195         echo "cleanup time $((SECONDS - start))"
1196         return $rc
1197 }
1198
1199 max_pages_per_rpc() {
1200         local mdtname="$(printf "MDT%04x" ${1:-0})"
1201         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1202 }
1203
1204 test_24v() {
1205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1206
1207         local nrfiles=${COUNT:-100000}
1208         local fname="$DIR/$tdir/$tfile"
1209
1210         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1211         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1212
1213         test_mkdir "$(dirname $fname)"
1214         # assume MDT0000 has the fewest inodes
1215         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1216         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1217         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1218
1219         trap simple_cleanup_common EXIT
1220
1221         createmany -m "$fname" $nrfiles
1222
1223         cancel_lru_locks mdc
1224         lctl set_param mdc.*.stats clear
1225
1226         # was previously test_24D: LU-6101
1227         # readdir() returns correct number of entries after cursor reload
1228         local num_ls=$(ls $DIR/$tdir | wc -l)
1229         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1230         local num_all=$(ls -a $DIR/$tdir | wc -l)
1231         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1232                 [ $num_all -ne $((nrfiles + 2)) ]; then
1233                         error "Expected $nrfiles files, got $num_ls " \
1234                                 "($num_uniq unique $num_all .&..)"
1235         fi
1236         # LU-5 large readdir
1237         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1238         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1239         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1240         # take into account of overhead in lu_dirpage header and end mark in
1241         # each page, plus one in rpc_num calculation.
1242         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1243         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1244         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1245         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1246         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1247         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1248         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1249         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1250                 error "large readdir doesn't take effect: " \
1251                       "$mds_readpage should be about $rpc_max"
1252
1253         simple_cleanup_common
1254 }
1255 run_test 24v "list large directory (test hash collision, b=17560)"
1256
1257 test_24w() { # bug21506
1258         SZ1=234852
1259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1260         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1261         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1262         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1263         [[ "$SZ1" -eq "$SZ2" ]] ||
1264                 error "Error reading at the end of the file $tfile"
1265 }
1266 run_test 24w "Reading a file larger than 4Gb"
1267
1268 test_24x() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1272                 skip "Need MDS version at least 2.7.56"
1273
1274         local MDTIDX=1
1275         local remote_dir=$DIR/$tdir/remote_dir
1276
1277         test_mkdir $DIR/$tdir
1278         $LFS mkdir -i $MDTIDX $remote_dir ||
1279                 error "create remote directory failed"
1280
1281         test_mkdir $DIR/$tdir/src_dir
1282         touch $DIR/$tdir/src_file
1283         test_mkdir $remote_dir/tgt_dir
1284         touch $remote_dir/tgt_file
1285
1286         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1287                 error "rename dir cross MDT failed!"
1288
1289         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1290                 error "rename file cross MDT failed!"
1291
1292         touch $DIR/$tdir/ln_file
1293         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1294                 error "ln file cross MDT failed"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24x "cross MDT rename/link"
1299
1300 test_24y() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1303
1304         local remote_dir=$DIR/$tdir/remote_dir
1305         local mdtidx=1
1306
1307         test_mkdir $DIR/$tdir
1308         $LFS mkdir -i $mdtidx $remote_dir ||
1309                 error "create remote directory failed"
1310
1311         test_mkdir $remote_dir/src_dir
1312         touch $remote_dir/src_file
1313         test_mkdir $remote_dir/tgt_dir
1314         touch $remote_dir/tgt_file
1315
1316         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1317                 error "rename subdir in the same remote dir failed!"
1318
1319         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1320                 error "rename files in the same remote dir failed!"
1321
1322         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1323                 error "link files in the same remote dir failed!"
1324
1325         rm -rf $DIR/$tdir || error "Can not delete directories"
1326 }
1327 run_test 24y "rename/link on the same dir should succeed"
1328
1329 test_24z() {
1330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1331         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1332                 skip "Need MDS version at least 2.12.51"
1333
1334         local index
1335
1336         for index in 0 1; do
1337                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1338                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1339         done
1340
1341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1344         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1345
1346         local mdts=$(comma_list $(mdts_nodes))
1347
1348         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1349         stack_trap "do_nodes $mdts $LCTL \
1350                 set_param mdt.*.enable_remote_rename=1" EXIT
1351
1352         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1353
1354         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1355         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1356 }
1357 run_test 24z "cross-MDT rename is done as cp"
1358
1359 test_24A() { # LU-3182
1360         local NFILES=5000
1361
1362         rm -rf $DIR/$tdir
1363         test_mkdir $DIR/$tdir
1364         trap simple_cleanup_common EXIT
1365         createmany -m $DIR/$tdir/$tfile $NFILES
1366         local t=$(ls $DIR/$tdir | wc -l)
1367         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1368         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1369         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1370            [ $v -ne $((NFILES + 2)) ] ; then
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372         fi
1373
1374         simple_cleanup_common || error "Can not delete directories"
1375 }
1376 run_test 24A "readdir() returns correct number of entries."
1377
1378 test_24B() { # LU-4805
1379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1380
1381         local count
1382
1383         test_mkdir $DIR/$tdir
1384         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1385                 error "create striped dir failed"
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 2 ] || error "Expected 2, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/a
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 3 ] || error "Expected 3, got $count"
1394
1395         touch $DIR/$tdir/striped_dir/.f
1396
1397         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1398         [ $count -eq 4 ] || error "Expected 4, got $count"
1399
1400         rm -rf $DIR/$tdir || error "Can not delete directories"
1401 }
1402 run_test 24B "readdir for striped dir return correct number of entries"
1403
1404 test_24C() {
1405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1406
1407         mkdir $DIR/$tdir
1408         mkdir $DIR/$tdir/d0
1409         mkdir $DIR/$tdir/d1
1410
1411         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1412                 error "create striped dir failed"
1413
1414         cd $DIR/$tdir/d0/striped_dir
1415
1416         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1417         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1418         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d0_ino" = "$parent_ino" ] ||
1421                 error ".. wrong, expect $d0_ino, get $parent_ino"
1422
1423         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1424                 error "mv striped dir failed"
1425
1426         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1427
1428         [ "$d1_ino" = "$parent_ino" ] ||
1429                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1430 }
1431 run_test 24C "check .. in striped dir"
1432
1433 test_24E() {
1434         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1436
1437         mkdir -p $DIR/$tdir
1438         mkdir $DIR/$tdir/src_dir
1439         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1440                 error "create remote source failed"
1441
1442         touch $DIR/$tdir/src_dir/src_child/a
1443
1444         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1445                 error "create remote target dir failed"
1446
1447         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "create remote target child failed"
1449
1450         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1451                 error "rename dir cross MDT failed!"
1452
1453         find $DIR/$tdir
1454
1455         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1456                 error "src_child still exists after rename"
1457
1458         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1459                 error "missing file(a) after rename"
1460
1461         rm -rf $DIR/$tdir || error "Can not delete directories"
1462 }
1463 run_test 24E "cross MDT rename/link"
1464
1465 test_24F () {
1466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1467
1468         local repeats=1000
1469         [ "$SLOW" = "no" ] && repeats=100
1470
1471         mkdir -p $DIR/$tdir
1472
1473         echo "$repeats repeats"
1474         for ((i = 0; i < repeats; i++)); do
1475                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1476                 touch $DIR/$tdir/test/a || error "touch fails"
1477                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1478                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1479         done
1480
1481         true
1482 }
1483 run_test 24F "hash order vs readdir (LU-11330)"
1484
1485 test_24G () {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487
1488         local ino1
1489         local ino2
1490
1491         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1492         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1493         touch $DIR/$tdir-0/f1 || error "touch f1"
1494         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1495         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1496         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1497         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1498         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1499 }
1500 run_test 24G "migrate symlink in rename"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27d() {
1724         test_mkdir $DIR/$tdir
1725         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1726                 error "setstripe failed"
1727         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1729 }
1730 run_test 27d "create file with default settings"
1731
1732 test_27e() {
1733         # LU-5839 adds check for existed layout before setting it
1734         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1735                 skip "Need MDS version at least 2.7.56"
1736
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741 }
1742 run_test 27e "setstripe existing file (should return error)"
1743
1744 test_27f() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1747                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1749                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1751         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1752 }
1753 run_test 27f "setstripe with bad stripe size (should return error)"
1754
1755 test_27g() {
1756         test_mkdir $DIR/$tdir
1757         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1758         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1759                 error "$DIR/$tdir/$tfile has object"
1760 }
1761 run_test 27g "$LFS getstripe with no objects"
1762
1763 test_27ga() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1767         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1768         local rc=$?
1769         (( rc == 2 )) || error "getstripe did not return ENOENT"
1770 }
1771 run_test 27ga "$LFS getstripe with missing file (should return error)"
1772
1773 test_27i() {
1774         test_mkdir $DIR/$tdir
1775         touch $DIR/$tdir/$tfile || error "touch failed"
1776         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1777                 error "missing objects"
1778 }
1779 run_test 27i "$LFS getstripe with some objects"
1780
1781 test_27j() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1784                 error "setstripe failed" || true
1785 }
1786 run_test 27j "setstripe with bad stripe offset (should return error)"
1787
1788 test_27k() { # bug 2844
1789         test_mkdir $DIR/$tdir
1790         local file=$DIR/$tdir/$tfile
1791         local ll_max_blksize=$((4 * 1024 * 1024))
1792         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1793         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1795         dd if=/dev/zero of=$file bs=4k count=1
1796         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1797         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1798 }
1799 run_test 27k "limit i_blksize for broken user apps"
1800
1801 test_27l() {
1802         mcreate $DIR/$tfile || error "creating file"
1803         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1804                 error "setstripe should have failed" || true
1805 }
1806 run_test 27l "check setstripe permissions (should return error)"
1807
1808 test_27m() {
1809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1810
1811         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1812                 skip_env "multiple clients -- skipping"
1813
1814         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1815                    head -n1)
1816         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1817                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1818         fi
1819         trap simple_cleanup_common EXIT
1820         test_mkdir $DIR/$tdir
1821         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1822         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1823                 error "dd should fill OST0"
1824         i=2
1825         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1826                 i=$((i + 1))
1827                 [ $i -gt 256 ] && break
1828         done
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it"
1834         i=$((i + 1))
1835         touch $DIR/$tdir/$tfile.$i
1836         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1837             awk '{print $1}'| grep -w "0") ] &&
1838                 error "OST0 was full but new created file still use it"
1839         simple_cleanup_common
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 __exhaust_precreations() {
1864         local OSTIDX=$1
1865         local FAILLOC=$2
1866         local FAILIDX=${3:-$OSTIDX}
1867         local ofacet=ost$((OSTIDX + 1))
1868
1869         mkdir_on_mdt0 $DIR/$tdir
1870         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1871         local mfacet=mds$((mdtidx + 1))
1872         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1873
1874         local OST=$(ostname_from_index $OSTIDX)
1875
1876         # on the mdt's osc
1877         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1878         local last_id=$(do_facet $mfacet lctl get_param -n \
1879                         osp.$mdtosc_proc1.prealloc_last_id)
1880         local next_id=$(do_facet $mfacet lctl get_param -n \
1881                         osp.$mdtosc_proc1.prealloc_next_id)
1882
1883         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1884         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1885
1886         test_mkdir -p $DIR/$tdir/${OST}
1887         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1888 #define OBD_FAIL_OST_ENOSPC              0x215
1889         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1890         echo "Creating to objid $last_id on ost $OST..."
1891         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1892         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1893         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1894 }
1895
1896 exhaust_precreations() {
1897         __exhaust_precreations $1 $2 $3
1898         sleep_maxage
1899 }
1900
1901 exhaust_all_precreations() {
1902         local i
1903         for (( i=0; i < OSTCOUNT; i++ )) ; do
1904                 __exhaust_precreations $i $1 -1
1905         done
1906         sleep_maxage
1907 }
1908
1909 test_27n() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917         exhaust_precreations 0 0x80000215
1918         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1919         touch $DIR/$tdir/$tfile || error "touch failed"
1920         $LFS getstripe $DIR/$tdir/$tfile
1921         reset_enospc
1922 }
1923 run_test 27n "create file with some full OSTs"
1924
1925 test_27o() {
1926         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1927         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1928         remote_mds_nodsh && skip "remote MDS with nodsh"
1929         remote_ost_nodsh && skip "remote OST with nodsh"
1930
1931         reset_enospc
1932         rm -f $DIR/$tdir/$tfile
1933         exhaust_all_precreations 0x215
1934
1935         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1936
1937         reset_enospc
1938         rm -rf $DIR/$tdir/*
1939 }
1940 run_test 27o "create file with all full OSTs (should error)"
1941
1942 function create_and_checktime() {
1943         local fname=$1
1944         local loops=$2
1945         local i
1946
1947         for ((i=0; i < $loops; i++)); do
1948                 local start=$SECONDS
1949                 multiop $fname-$i Oc
1950                 ((SECONDS-start < TIMEOUT)) ||
1951                         error "creation took " $((SECONDS-$start)) && return 1
1952         done
1953 }
1954
1955 test_27oo() {
1956         local mdts=$(comma_list $(mdts_nodes))
1957
1958         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1959                 skip "Need MDS version at least 2.13.57"
1960
1961         local f0=$DIR/${tfile}-0
1962         local f1=$DIR/${tfile}-1
1963
1964         wait_delete_completed
1965
1966         # refill precreated objects
1967         $LFS setstripe -i0 -c1 $f0
1968
1969         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1970         # force QoS allocation policy
1971         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1972         stack_trap "do_nodes $mdts $LCTL set_param \
1973                 lov.*.qos_threshold_rr=$saved" EXIT
1974         sleep_maxage
1975
1976         # one OST is unavailable, but still have few objects preallocated
1977         stop ost1
1978         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1979                 rm -rf $f1 $DIR/$tdir*" EXIT
1980
1981         for ((i=0; i < 7; i++)); do
1982                 mkdir $DIR/$tdir$i || error "can't create dir"
1983                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1984                         error "can't set striping"
1985         done
1986         for ((i=0; i < 7; i++)); do
1987                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1988         done
1989         wait
1990 }
1991 run_test 27oo "don't let few threads to reserve too many objects"
1992
1993 test_27p() {
1994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1996         remote_mds_nodsh && skip "remote MDS with nodsh"
1997         remote_ost_nodsh && skip "remote OST with nodsh"
1998
1999         reset_enospc
2000         rm -f $DIR/$tdir/$tfile
2001         test_mkdir $DIR/$tdir
2002
2003         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2004         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2005         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2006
2007         exhaust_precreations 0 0x80000215
2008         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2009         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2010         $LFS getstripe $DIR/$tdir/$tfile
2011
2012         reset_enospc
2013 }
2014 run_test 27p "append to a truncated file with some full OSTs"
2015
2016 test_27q() {
2017         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2019         remote_mds_nodsh && skip "remote MDS with nodsh"
2020         remote_ost_nodsh && skip "remote OST with nodsh"
2021
2022         reset_enospc
2023         rm -f $DIR/$tdir/$tfile
2024
2025         mkdir_on_mdt0 $DIR/$tdir
2026         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2027         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2028                 error "truncate $DIR/$tdir/$tfile failed"
2029         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2030
2031         exhaust_all_precreations 0x215
2032
2033         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2034         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2035
2036         reset_enospc
2037 }
2038 run_test 27q "append to truncated file with all OSTs full (should error)"
2039
2040 test_27r() {
2041         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2043         remote_mds_nodsh && skip "remote MDS with nodsh"
2044         remote_ost_nodsh && skip "remote OST with nodsh"
2045
2046         reset_enospc
2047         rm -f $DIR/$tdir/$tfile
2048         exhaust_precreations 0 0x80000215
2049
2050         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2051
2052         reset_enospc
2053 }
2054 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2055
2056 test_27s() { # bug 10725
2057         test_mkdir $DIR/$tdir
2058         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2059         local stripe_count=0
2060         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2061         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2062                 error "stripe width >= 2^32 succeeded" || true
2063
2064 }
2065 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2066
2067 test_27t() { # bug 10864
2068         WDIR=$(pwd)
2069         WLFS=$(which lfs)
2070         cd $DIR
2071         touch $tfile
2072         $WLFS getstripe $tfile
2073         cd $WDIR
2074 }
2075 run_test 27t "check that utils parse path correctly"
2076
2077 test_27u() { # bug 4900
2078         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2079         remote_mds_nodsh && skip "remote MDS with nodsh"
2080
2081         local index
2082         local list=$(comma_list $(mdts_nodes))
2083
2084 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2085         do_nodes $list $LCTL set_param fail_loc=0x139
2086         test_mkdir -p $DIR/$tdir
2087         trap simple_cleanup_common EXIT
2088         createmany -o $DIR/$tdir/t- 1000
2089         do_nodes $list $LCTL set_param fail_loc=0
2090
2091         TLOG=$TMP/$tfile.getstripe
2092         $LFS getstripe $DIR/$tdir > $TLOG
2093         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2094         unlinkmany $DIR/$tdir/t- 1000
2095         trap 0
2096         [[ $OBJS -gt 0 ]] &&
2097                 error "$OBJS objects created on OST-0. See $TLOG" ||
2098                 rm -f $TLOG
2099 }
2100 run_test 27u "skip object creation on OSC w/o objects"
2101
2102 test_27v() { # bug 4900
2103         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2105         remote_mds_nodsh && skip "remote MDS with nodsh"
2106         remote_ost_nodsh && skip "remote OST with nodsh"
2107
2108         exhaust_all_precreations 0x215
2109         reset_enospc
2110
2111         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2112
2113         touch $DIR/$tdir/$tfile
2114         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2115         # all except ost1
2116         for (( i=1; i < OSTCOUNT; i++ )); do
2117                 do_facet ost$i lctl set_param fail_loc=0x705
2118         done
2119         local START=`date +%s`
2120         createmany -o $DIR/$tdir/$tfile 32
2121
2122         local FINISH=`date +%s`
2123         local TIMEOUT=`lctl get_param -n timeout`
2124         local PROCESS=$((FINISH - START))
2125         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2126                error "$FINISH - $START >= $TIMEOUT / 2"
2127         sleep $((TIMEOUT / 2 - PROCESS))
2128         reset_enospc
2129 }
2130 run_test 27v "skip object creation on slow OST"
2131
2132 test_27w() { # bug 10997
2133         test_mkdir $DIR/$tdir
2134         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2135         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2136                 error "stripe size $size != 65536" || true
2137         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2138                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2139 }
2140 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2141
2142 test_27wa() {
2143         [[ $OSTCOUNT -lt 2 ]] &&
2144                 skip_env "skipping multiple stripe count/offset test"
2145
2146         test_mkdir $DIR/$tdir
2147         for i in $(seq 1 $OSTCOUNT); do
2148                 offset=$((i - 1))
2149                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2150                         error "setstripe -c $i -i $offset failed"
2151                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2152                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2153                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2154                 [ $index -ne $offset ] &&
2155                         error "stripe offset $index != $offset" || true
2156         done
2157 }
2158 run_test 27wa "check $LFS setstripe -c -i options"
2159
2160 test_27x() {
2161         remote_ost_nodsh && skip "remote OST with nodsh"
2162         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2164
2165         OFFSET=$(($OSTCOUNT - 1))
2166         OSTIDX=0
2167         local OST=$(ostname_from_index $OSTIDX)
2168
2169         test_mkdir $DIR/$tdir
2170         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2171         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2172         sleep_maxage
2173         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2174         for i in $(seq 0 $OFFSET); do
2175                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2176                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2177                 error "OST0 was degraded but new created file still use it"
2178         done
2179         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2180 }
2181 run_test 27x "create files while OST0 is degraded"
2182
2183 test_27y() {
2184         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2185         remote_mds_nodsh && skip "remote MDS with nodsh"
2186         remote_ost_nodsh && skip "remote OST with nodsh"
2187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2188
2189         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2190         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2191                 osp.$mdtosc.prealloc_last_id)
2192         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2193                 osp.$mdtosc.prealloc_next_id)
2194         local fcount=$((last_id - next_id))
2195         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2196         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2197
2198         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2199                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2200         local OST_DEACTIVE_IDX=-1
2201         local OSC
2202         local OSTIDX
2203         local OST
2204
2205         for OSC in $MDS_OSCS; do
2206                 OST=$(osc_to_ost $OSC)
2207                 OSTIDX=$(index_from_ostuuid $OST)
2208                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2209                         OST_DEACTIVE_IDX=$OSTIDX
2210                 fi
2211                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2212                         echo $OSC "is Deactivated:"
2213                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2214                 fi
2215         done
2216
2217         OSTIDX=$(index_from_ostuuid $OST)
2218         test_mkdir $DIR/$tdir
2219         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2220
2221         for OSC in $MDS_OSCS; do
2222                 OST=$(osc_to_ost $OSC)
2223                 OSTIDX=$(index_from_ostuuid $OST)
2224                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2225                         echo $OST "is degraded:"
2226                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2227                                                 obdfilter.$OST.degraded=1
2228                 fi
2229         done
2230
2231         sleep_maxage
2232         createmany -o $DIR/$tdir/$tfile $fcount
2233
2234         for OSC in $MDS_OSCS; do
2235                 OST=$(osc_to_ost $OSC)
2236                 OSTIDX=$(index_from_ostuuid $OST)
2237                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2238                         echo $OST "is recovered from degraded:"
2239                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2240                                                 obdfilter.$OST.degraded=0
2241                 else
2242                         do_facet $SINGLEMDS lctl --device %$OSC activate
2243                 fi
2244         done
2245
2246         # all osp devices get activated, hence -1 stripe count restored
2247         local stripe_count=0
2248
2249         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2250         # devices get activated.
2251         sleep_maxage
2252         $LFS setstripe -c -1 $DIR/$tfile
2253         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2254         rm -f $DIR/$tfile
2255         [ $stripe_count -ne $OSTCOUNT ] &&
2256                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2257         return 0
2258 }
2259 run_test 27y "create files while OST0 is degraded and the rest inactive"
2260
2261 check_seq_oid()
2262 {
2263         log "check file $1"
2264
2265         lmm_count=$($LFS getstripe -c $1)
2266         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2267         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2268
2269         local old_ifs="$IFS"
2270         IFS=$'[:]'
2271         fid=($($LFS path2fid $1))
2272         IFS="$old_ifs"
2273
2274         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2275         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2276
2277         # compare lmm_seq and lu_fid->f_seq
2278         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2279         # compare lmm_object_id and lu_fid->oid
2280         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2281
2282         # check the trusted.fid attribute of the OST objects of the file
2283         local have_obdidx=false
2284         local stripe_nr=0
2285         $LFS getstripe $1 | while read obdidx oid hex seq; do
2286                 # skip lines up to and including "obdidx"
2287                 [ -z "$obdidx" ] && break
2288                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2289                 $have_obdidx || continue
2290
2291                 local ost=$((obdidx + 1))
2292                 local dev=$(ostdevname $ost)
2293                 local oid_hex
2294
2295                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2296
2297                 seq=$(echo $seq | sed -e "s/^0x//g")
2298                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2299                         oid_hex=$(echo $oid)
2300                 else
2301                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2302                 fi
2303                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2304
2305                 local ff=""
2306                 #
2307                 # Don't unmount/remount the OSTs if we don't need to do that.
2308                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2309                 # update too, until that use mount/ll_decode_filter_fid/mount.
2310                 # Re-enable when debugfs will understand new filter_fid.
2311                 #
2312                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2313                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2314                                 $dev 2>/dev/null" | grep "parent=")
2315                 fi
2316                 if [ -z "$ff" ]; then
2317                         stop ost$ost
2318                         mount_fstype ost$ost
2319                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2320                                 $(facet_mntpt ost$ost)/$obj_file)
2321                         unmount_fstype ost$ost
2322                         start ost$ost $dev $OST_MOUNT_OPTS
2323                         clients_up
2324                 fi
2325
2326                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2327
2328                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2329
2330                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2331                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2332                 #
2333                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2334                 #       stripe_size=1048576 component_id=1 component_start=0 \
2335                 #       component_end=33554432
2336                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2337                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2338                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2339                 local ff_pstripe
2340                 if grep -q 'stripe=' <<<$ff; then
2341                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2342                 else
2343                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2344                         # into f_ver in this case.  See comment on ff_parent.
2345                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2346                 fi
2347
2348                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2349                 [ $ff_pseq = $lmm_seq ] ||
2350                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2351                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2352                 [ $ff_poid = $lmm_oid ] ||
2353                         error "FF parent OID $ff_poid != $lmm_oid"
2354                 (($ff_pstripe == $stripe_nr)) ||
2355                         error "FF stripe $ff_pstripe != $stripe_nr"
2356
2357                 stripe_nr=$((stripe_nr + 1))
2358                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2359                         continue
2360                 if grep -q 'stripe_count=' <<<$ff; then
2361                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2362                                             -e 's/ .*//' <<<$ff)
2363                         [ $lmm_count = $ff_scnt ] ||
2364                                 error "FF stripe count $lmm_count != $ff_scnt"
2365                 fi
2366         done
2367 }
2368
2369 test_27z() {
2370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2371         remote_ost_nodsh && skip "remote OST with nodsh"
2372
2373         test_mkdir $DIR/$tdir
2374         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2375                 { error "setstripe -c -1 failed"; return 1; }
2376         # We need to send a write to every object to get parent FID info set.
2377         # This _should_ also work for setattr, but does not currently.
2378         # touch $DIR/$tdir/$tfile-1 ||
2379         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2380                 { error "dd $tfile-1 failed"; return 2; }
2381         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2382                 { error "setstripe -c -1 failed"; return 3; }
2383         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2384                 { error "dd $tfile-2 failed"; return 4; }
2385
2386         # make sure write RPCs have been sent to OSTs
2387         sync; sleep 5; sync
2388
2389         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2390         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2391 }
2392 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2393
2394 test_27A() { # b=19102
2395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2396
2397         save_layout_restore_at_exit $MOUNT
2398         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2399         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2400                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2401         local default_size=$($LFS getstripe -S $MOUNT)
2402         local default_offset=$($LFS getstripe -i $MOUNT)
2403         local dsize=$(do_facet $SINGLEMDS \
2404                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2405         [ $default_size -eq $dsize ] ||
2406                 error "stripe size $default_size != $dsize"
2407         [ $default_offset -eq -1 ] ||
2408                 error "stripe offset $default_offset != -1"
2409 }
2410 run_test 27A "check filesystem-wide default LOV EA values"
2411
2412 test_27B() { # LU-2523
2413         test_mkdir $DIR/$tdir
2414         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2415         touch $DIR/$tdir/f0
2416         # open f1 with O_LOV_DELAY_CREATE
2417         # rename f0 onto f1
2418         # call setstripe ioctl on open file descriptor for f1
2419         # close
2420         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2421                 $DIR/$tdir/f0
2422
2423         rm -f $DIR/$tdir/f1
2424         # open f1 with O_LOV_DELAY_CREATE
2425         # unlink f1
2426         # call setstripe ioctl on open file descriptor for f1
2427         # close
2428         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2429
2430         # Allow multiop to fail in imitation of NFS's busted semantics.
2431         true
2432 }
2433 run_test 27B "call setstripe on open unlinked file/rename victim"
2434
2435 # 27C family tests full striping and overstriping
2436 test_27Ca() { #LU-2871
2437         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2438
2439         declare -a ost_idx
2440         local index
2441         local found
2442         local i
2443         local j
2444
2445         test_mkdir $DIR/$tdir
2446         cd $DIR/$tdir
2447         for i in $(seq 0 $((OSTCOUNT - 1))); do
2448                 # set stripe across all OSTs starting from OST$i
2449                 $LFS setstripe -i $i -c -1 $tfile$i
2450                 # get striping information
2451                 ost_idx=($($LFS getstripe $tfile$i |
2452                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2453                 echo ${ost_idx[@]}
2454
2455                 # check the layout
2456                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2457                         error "${#ost_idx[@]} != $OSTCOUNT"
2458
2459                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2460                         found=0
2461                         for j in $(echo ${ost_idx[@]}); do
2462                                 if [ $index -eq $j ]; then
2463                                         found=1
2464                                         break
2465                                 fi
2466                         done
2467                         [ $found = 1 ] ||
2468                                 error "Can not find $index in ${ost_idx[@]}"
2469                 done
2470         done
2471 }
2472 run_test 27Ca "check full striping across all OSTs"
2473
2474 test_27Cb() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2478                 skip_env "too many osts, skipping"
2479
2480         test_mkdir -p $DIR/$tdir
2481         local setcount=$(($OSTCOUNT * 2))
2482         [ $setcount -lt 160 ] || large_xattr_enabled ||
2483                 skip_env "ea_inode feature disabled"
2484
2485         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2486                 error "setstripe failed"
2487
2488         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2489         [ $count -eq $setcount ] ||
2490                 error "stripe count $count, should be $setcount"
2491
2492         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2493                 error "overstriped should be set in pattern"
2494
2495         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2496                 error "dd failed"
2497 }
2498 run_test 27Cb "more stripes than OSTs with -C"
2499
2500 test_27Cc() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2504
2505         test_mkdir -p $DIR/$tdir
2506         local setcount=$(($OSTCOUNT - 1))
2507
2508         [ $setcount -lt 160 ] || large_xattr_enabled ||
2509                 skip_env "ea_inode feature disabled"
2510
2511         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2512                 error "setstripe failed"
2513
2514         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2515         [ $count -eq $setcount ] ||
2516                 error "stripe count $count, should be $setcount"
2517
2518         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2519                 error "overstriped should not be set in pattern"
2520
2521         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2522                 error "dd failed"
2523 }
2524 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2525
2526 test_27Cd() {
2527         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2528                 skip "server does not support overstriping"
2529         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2530         large_xattr_enabled || skip_env "ea_inode feature disabled"
2531
2532         test_mkdir -p $DIR/$tdir
2533         local setcount=$LOV_MAX_STRIPE_COUNT
2534
2535         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2536                 error "setstripe failed"
2537
2538         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2539         [ $count -eq $setcount ] ||
2540                 error "stripe count $count, should be $setcount"
2541
2542         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2543                 error "overstriped should be set in pattern"
2544
2545         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2546                 error "dd failed"
2547
2548         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2549 }
2550 run_test 27Cd "test maximum stripe count"
2551
2552 test_27Ce() {
2553         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2554                 skip "server does not support overstriping"
2555         test_mkdir -p $DIR/$tdir
2556
2557         pool_add $TESTNAME || error "Pool creation failed"
2558         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2559
2560         local setcount=8
2561
2562         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2563                 error "setstripe failed"
2564
2565         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2566         [ $count -eq $setcount ] ||
2567                 error "stripe count $count, should be $setcount"
2568
2569         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2570                 error "overstriped should be set in pattern"
2571
2572         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2573                 error "dd failed"
2574
2575         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2576 }
2577 run_test 27Ce "test pool with overstriping"
2578
2579 test_27Cf() {
2580         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2581                 skip "server does not support overstriping"
2582         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2583                 skip_env "too many osts, skipping"
2584
2585         test_mkdir -p $DIR/$tdir
2586
2587         local setcount=$(($OSTCOUNT * 2))
2588         [ $setcount -lt 160 ] || large_xattr_enabled ||
2589                 skip_env "ea_inode feature disabled"
2590
2591         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2592                 error "setstripe failed"
2593
2594         echo 1 > $DIR/$tdir/$tfile
2595
2596         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2597         [ $count -eq $setcount ] ||
2598                 error "stripe count $count, should be $setcount"
2599
2600         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2601                 error "overstriped should be set in pattern"
2602
2603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2604                 error "dd failed"
2605
2606         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2607 }
2608 run_test 27Cf "test default inheritance with overstriping"
2609
2610 test_27D() {
2611         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2612         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2613         remote_mds_nodsh && skip "remote MDS with nodsh"
2614
2615         local POOL=${POOL:-testpool}
2616         local first_ost=0
2617         local last_ost=$(($OSTCOUNT - 1))
2618         local ost_step=1
2619         local ost_list=$(seq $first_ost $ost_step $last_ost)
2620         local ost_range="$first_ost $last_ost $ost_step"
2621
2622         test_mkdir $DIR/$tdir
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2625
2626         local skip27D
2627         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2628                 skip27D+="-s 29"
2629         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2630                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2631                         skip27D+=" -s 30,31"
2632         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2633           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2634                 skip27D+=" -s 32,33"
2635         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2636                 skip27D+=" -s 34"
2637         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2638                 error "llapi_layout_test failed"
2639
2640         destroy_test_pools || error "destroy test pools failed"
2641 }
2642 run_test 27D "validate llapi_layout API"
2643
2644 # Verify that default_easize is increased from its initial value after
2645 # accessing a widely striped file.
2646 test_27E() {
2647         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2648         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2649                 skip "client does not have LU-3338 fix"
2650
2651         # 72 bytes is the minimum space required to store striping
2652         # information for a file striped across one OST:
2653         # (sizeof(struct lov_user_md_v3) +
2654         #  sizeof(struct lov_user_ost_data_v1))
2655         local min_easize=72
2656         $LCTL set_param -n llite.*.default_easize $min_easize ||
2657                 error "lctl set_param failed"
2658         local easize=$($LCTL get_param -n llite.*.default_easize)
2659
2660         [ $easize -eq $min_easize ] ||
2661                 error "failed to set default_easize"
2662
2663         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2664                 error "setstripe failed"
2665         # In order to ensure stat() call actually talks to MDS we need to
2666         # do something drastic to this file to shake off all lock, e.g.
2667         # rename it (kills lookup lock forcing cache cleaning)
2668         mv $DIR/$tfile $DIR/${tfile}-1
2669         ls -l $DIR/${tfile}-1
2670         rm $DIR/${tfile}-1
2671
2672         easize=$($LCTL get_param -n llite.*.default_easize)
2673
2674         [ $easize -gt $min_easize ] ||
2675                 error "default_easize not updated"
2676 }
2677 run_test 27E "check that default extended attribute size properly increases"
2678
2679 test_27F() { # LU-5346/LU-7975
2680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2681         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2682         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2683                 skip "Need MDS version at least 2.8.51"
2684         remote_ost_nodsh && skip "remote OST with nodsh"
2685
2686         test_mkdir $DIR/$tdir
2687         rm -f $DIR/$tdir/f0
2688         $LFS setstripe -c 2 $DIR/$tdir
2689
2690         # stop all OSTs to reproduce situation for LU-7975 ticket
2691         for num in $(seq $OSTCOUNT); do
2692                 stop ost$num
2693         done
2694
2695         # open/create f0 with O_LOV_DELAY_CREATE
2696         # truncate f0 to a non-0 size
2697         # close
2698         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2699
2700         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2701         # open/write it again to force delayed layout creation
2702         cat /etc/hosts > $DIR/$tdir/f0 &
2703         catpid=$!
2704
2705         # restart OSTs
2706         for num in $(seq $OSTCOUNT); do
2707                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2708                         error "ost$num failed to start"
2709         done
2710
2711         wait $catpid || error "cat failed"
2712
2713         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2714         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2715                 error "wrong stripecount"
2716
2717 }
2718 run_test 27F "Client resend delayed layout creation with non-zero size"
2719
2720 test_27G() { #LU-10629
2721         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2722                 skip "Need MDS version at least 2.11.51"
2723         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2724         remote_mds_nodsh && skip "remote MDS with nodsh"
2725         local POOL=${POOL:-testpool}
2726         local ostrange="0 0 1"
2727
2728         test_mkdir $DIR/$tdir
2729         touch $DIR/$tdir/$tfile.nopool
2730         pool_add $POOL || error "pool_add failed"
2731         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2732         $LFS setstripe -p $POOL $DIR/$tdir
2733
2734         local pool=$($LFS getstripe -p $DIR/$tdir)
2735
2736         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2737         touch $DIR/$tdir/$tfile.default
2738         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2739         $LFS find $DIR/$tdir -type f --pool $POOL
2740         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2741         [[ "$found" == "2" ]] ||
2742                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2743
2744         $LFS setstripe -d $DIR/$tdir
2745
2746         pool=$($LFS getstripe -p -d $DIR/$tdir)
2747
2748         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2749 }
2750 run_test 27G "Clear OST pool from stripe"
2751
2752 test_27H() {
2753         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2754                 skip "Need MDS version newer than 2.11.54"
2755         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2756         test_mkdir $DIR/$tdir
2757         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2758         touch $DIR/$tdir/$tfile
2759         $LFS getstripe -c $DIR/$tdir/$tfile
2760         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2761                 error "two-stripe file doesn't have two stripes"
2762
2763         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2764         $LFS getstripe -y $DIR/$tdir/$tfile
2765         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2766              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2767                 error "expected l_ost_idx: [02]$ not matched"
2768
2769         # make sure ost list has been cleared
2770         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2771         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2772                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2773         touch $DIR/$tdir/f3
2774         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2775 }
2776 run_test 27H "Set specific OSTs stripe"
2777
2778 test_27I() {
2779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2780         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2781         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2782                 skip "Need MDS version newer than 2.12.52"
2783         local pool=$TESTNAME
2784         local ostrange="1 1 1"
2785
2786         save_layout_restore_at_exit $MOUNT
2787         $LFS setstripe -c 2 -i 0 $MOUNT
2788         pool_add $pool || error "pool_add failed"
2789         pool_add_targets $pool $ostrange ||
2790                 error "pool_add_targets failed"
2791         test_mkdir $DIR/$tdir
2792         $LFS setstripe -p $pool $DIR/$tdir
2793         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2794         $LFS getstripe $DIR/$tdir/$tfile
2795 }
2796 run_test 27I "check that root dir striping does not break parent dir one"
2797
2798 test_27J() {
2799         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2800                 skip "Need MDS version newer than 2.12.51"
2801
2802         test_mkdir $DIR/$tdir
2803         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2804         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2805
2806         # create foreign file (raw way)
2807         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2808                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2809
2810         ! $LFS setstripe --foreign --flags foo \
2811                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2812                         error "creating $tfile with '--flags foo' should fail"
2813
2814         ! $LFS setstripe --foreign --flags 0xffffffff \
2815                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2816                         error "creating $tfile w/ 0xffffffff flags should fail"
2817
2818         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2819                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2820
2821         # verify foreign file (raw way)
2822         parse_foreign_file -f $DIR/$tdir/$tfile |
2823                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2824                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2825         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2826                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2827         parse_foreign_file -f $DIR/$tdir/$tfile |
2828                 grep "lov_foreign_size: 73" ||
2829                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2830         parse_foreign_file -f $DIR/$tdir/$tfile |
2831                 grep "lov_foreign_type: 1" ||
2832                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2833         parse_foreign_file -f $DIR/$tdir/$tfile |
2834                 grep "lov_foreign_flags: 0x0000DA08" ||
2835                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2836         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2837                 grep "lov_foreign_value: 0x" |
2838                 sed -e 's/lov_foreign_value: 0x//')
2839         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2840         [[ $lov = ${lov2// /} ]] ||
2841                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2842
2843         # create foreign file (lfs + API)
2844         $LFS setstripe --foreign=none --flags 0xda08 \
2845                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2846                 error "$DIR/$tdir/${tfile}2: create failed"
2847
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2849                 grep "lfm_magic:.*0x0BD70BD0" ||
2850                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2851         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2852         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2853                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2854         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2855                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2856         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2857                 grep "lfm_flags:.*0x0000DA08" ||
2858                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2859         $LFS getstripe $DIR/$tdir/${tfile}2 |
2860                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2861                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2862
2863         # modify striping should fail
2864         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2865                 error "$DIR/$tdir/$tfile: setstripe should fail"
2866         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2867                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2868
2869         # R/W should fail
2870         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2871         cat $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: read should fail"
2873         cat /etc/passwd > $DIR/$tdir/$tfile &&
2874                 error "$DIR/$tdir/$tfile: write should fail"
2875         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2876                 error "$DIR/$tdir/${tfile}2: write should fail"
2877
2878         # chmod should work
2879         chmod 222 $DIR/$tdir/$tfile ||
2880                 error "$DIR/$tdir/$tfile: chmod failed"
2881         chmod 222 $DIR/$tdir/${tfile}2 ||
2882                 error "$DIR/$tdir/${tfile}2: chmod failed"
2883
2884         # chown should work
2885         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2886                 error "$DIR/$tdir/$tfile: chown failed"
2887         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2888                 error "$DIR/$tdir/${tfile}2: chown failed"
2889
2890         # rename should work
2891         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2892                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2893         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2894                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2895
2896         #remove foreign file
2897         rm $DIR/$tdir/${tfile}.new ||
2898                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2899         rm $DIR/$tdir/${tfile}2.new ||
2900                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2901 }
2902 run_test 27J "basic ops on file with foreign LOV"
2903
2904 test_27K() {
2905         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2906                 skip "Need MDS version newer than 2.12.49"
2907
2908         test_mkdir $DIR/$tdir
2909         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2910         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2911
2912         # create foreign dir (raw way)
2913         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2914                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2915
2916         ! $LFS setdirstripe --foreign --flags foo \
2917                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2918                         error "creating $tdir with '--flags foo' should fail"
2919
2920         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2921                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2922                         error "creating $tdir w/ 0xffffffff flags should fail"
2923
2924         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2925                 error "create_foreign_dir FAILED"
2926
2927         # verify foreign dir (raw way)
2928         parse_foreign_dir -d $DIR/$tdir/$tdir |
2929                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2930                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2931         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2932                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2933         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2934                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2935         parse_foreign_dir -d $DIR/$tdir/$tdir |
2936                 grep "lmv_foreign_flags: 55813$" ||
2937                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2938         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2939                 grep "lmv_foreign_value: 0x" |
2940                 sed 's/lmv_foreign_value: 0x//')
2941         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2942                 sed 's/ //g')
2943         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2944
2945         # create foreign dir (lfs + API)
2946         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2947                 $DIR/$tdir/${tdir}2 ||
2948                 error "$DIR/$tdir/${tdir}2: create failed"
2949
2950         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2951                 grep "lfm_magic:.*0x0CD50CD0" ||
2952                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2953         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2954         # - sizeof(lfm_type) - sizeof(lfm_flags)
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2956                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2958                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2959         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2960                 grep "lfm_flags:.*0x0000DA05" ||
2961                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2962         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2963                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2964                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2965
2966         # file create in dir should fail
2967         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2968         touch $DIR/$tdir/${tdir}2/$tfile &&
2969                 "$DIR/${tdir}2: file create should fail"
2970
2971         # chmod should work
2972         chmod 777 $DIR/$tdir/$tdir ||
2973                 error "$DIR/$tdir: chmod failed"
2974         chmod 777 $DIR/$tdir/${tdir}2 ||
2975                 error "$DIR/${tdir}2: chmod failed"
2976
2977         # chown should work
2978         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2979                 error "$DIR/$tdir: chown failed"
2980         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2981                 error "$DIR/${tdir}2: chown failed"
2982
2983         # rename should work
2984         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2985                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2986         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2987                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2988
2989         #remove foreign dir
2990         rmdir $DIR/$tdir/${tdir}.new ||
2991                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2992         rmdir $DIR/$tdir/${tdir}2.new ||
2993                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2994 }
2995 run_test 27K "basic ops on dir with foreign LMV"
2996
2997 test_27L() {
2998         remote_mds_nodsh && skip "remote MDS with nodsh"
2999
3000         local POOL=${POOL:-$TESTNAME}
3001
3002         pool_add $POOL || error "pool_add failed"
3003
3004         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3005                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3006                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3007 }
3008 run_test 27L "lfs pool_list gives correct pool name"
3009
3010 test_27M() {
3011         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3012                 skip "Need MDS version >= than 2.12.57"
3013         remote_mds_nodsh && skip "remote MDS with nodsh"
3014         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3015
3016         test_mkdir $DIR/$tdir
3017
3018         # Set default striping on directory
3019         local setcount=4
3020         local stripe_opt
3021
3022         # if we run against a 2.12 server which lacks overstring support
3023         # then the connect_flag will not report overstriping, even if client
3024         # is 2.14+
3025         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3026                 stripe_opt="-C $setcount"
3027         elif (( $OSTCOUNT >= $setcount )); then
3028                 stripe_opt="-c $setcount"
3029         else
3030                 skip "server does not support overstriping"
3031         fi
3032         $LFS setstripe $stripe_opt $DIR/$tdir
3033
3034         echo 1 > $DIR/$tdir/${tfile}.1
3035         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3036         [ $count -eq $setcount ] ||
3037                 error "(1) stripe count $count, should be $setcount"
3038
3039         # Capture existing append_stripe_count setting for restore
3040         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3041         local mdts=$(comma_list $(mdts_nodes))
3042         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
3043
3044         local appendcount=$orig_count
3045         echo 1 >> $DIR/$tdir/${tfile}.2_append
3046         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3047         [ $count -eq $appendcount ] ||
3048                 error "(2)stripe count $count, should be $appendcount for append"
3049
3050         # Disable O_APPEND striping, verify it works
3051         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3052
3053         # Should now get the default striping, which is 4
3054         setcount=4
3055         echo 1 >> $DIR/$tdir/${tfile}.3_append
3056         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3057         [ $count -eq $setcount ] ||
3058                 error "(3) stripe count $count, should be $setcount"
3059
3060         # Try changing the stripe count for append files
3061         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3062
3063         # Append striping is now 2 (directory default is still 4)
3064         appendcount=2
3065         echo 1 >> $DIR/$tdir/${tfile}.4_append
3066         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3067         [ $count -eq $appendcount ] ||
3068                 error "(4) stripe count $count, should be $appendcount for append"
3069
3070         # Test append stripe count of -1
3071         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3072         appendcount=$OSTCOUNT
3073         echo 1 >> $DIR/$tdir/${tfile}.5
3074         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3075         [ $count -eq $appendcount ] ||
3076                 error "(5) stripe count $count, should be $appendcount for append"
3077
3078         # Set append striping back to default of 1
3079         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3080
3081         # Try a new default striping, PFL + DOM
3082         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3083
3084         # Create normal DOM file, DOM returns stripe count == 0
3085         setcount=0
3086         touch $DIR/$tdir/${tfile}.6
3087         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3088         [ $count -eq $setcount ] ||
3089                 error "(6) stripe count $count, should be $setcount"
3090
3091         # Show
3092         appendcount=1
3093         echo 1 >> $DIR/$tdir/${tfile}.7_append
3094         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3095         [ $count -eq $appendcount ] ||
3096                 error "(7) stripe count $count, should be $appendcount for append"
3097
3098         # Clean up DOM layout
3099         $LFS setstripe -d $DIR/$tdir
3100
3101         save_layout_restore_at_exit $MOUNT
3102         # Now test that append striping works when layout is from root
3103         $LFS setstripe -c 2 $MOUNT
3104         # Make a special directory for this
3105         mkdir $DIR/${tdir}/${tdir}.2
3106
3107         # Verify for normal file
3108         setcount=2
3109         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3110         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3111         [ $count -eq $setcount ] ||
3112                 error "(8) stripe count $count, should be $setcount"
3113
3114         appendcount=1
3115         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3116         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3117         [ $count -eq $appendcount ] ||
3118                 error "(9) stripe count $count, should be $appendcount for append"
3119
3120         # Now test O_APPEND striping with pools
3121         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3122         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3123
3124         # Create the pool
3125         pool_add $TESTNAME || error "pool creation failed"
3126         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3127
3128         echo 1 >> $DIR/$tdir/${tfile}.10_append
3129
3130         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3131         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3132
3133         # Check that count is still correct
3134         appendcount=1
3135         echo 1 >> $DIR/$tdir/${tfile}.11_append
3136         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3137         [ $count -eq $appendcount ] ||
3138                 error "(11) stripe count $count, should be $appendcount for append"
3139
3140         # Disable O_APPEND stripe count, verify pool works separately
3141         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3142
3143         echo 1 >> $DIR/$tdir/${tfile}.12_append
3144
3145         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3146         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3147
3148         # Remove pool setting, verify it's not applied
3149         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3150
3151         echo 1 >> $DIR/$tdir/${tfile}.13_append
3152
3153         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3154         [ "$pool" = "" ] || error "(13) pool found: $pool"
3155 }
3156 run_test 27M "test O_APPEND striping"
3157
3158 test_27N() {
3159         combined_mgs_mds && skip "needs separate MGS/MDT"
3160
3161         pool_add $TESTNAME || error "pool_add failed"
3162         do_facet mgs "$LCTL pool_list $FSNAME" |
3163                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3164                 error "lctl pool_list on MGS failed"
3165 }
3166 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3167
3168 clean_foreign_symlink() {
3169         trap 0
3170         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3171         for i in $DIR/$tdir/* ; do
3172                 $LFS unlink_foreign $i || true
3173         done
3174 }
3175
3176 test_27O() {
3177         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3178                 skip "Need MDS version newer than 2.12.51"
3179
3180         test_mkdir $DIR/$tdir
3181         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3182         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3183
3184         trap clean_foreign_symlink EXIT
3185
3186         # enable foreign_symlink behaviour
3187         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3188
3189         # foreign symlink LOV format is a partial path by default
3190
3191         # create foreign file (lfs + API)
3192         $LFS setstripe --foreign=symlink --flags 0xda05 \
3193                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3194                 error "$DIR/$tdir/${tfile}: create failed"
3195
3196         $LFS getstripe -v $DIR/$tdir/${tfile} |
3197                 grep "lfm_magic:.*0x0BD70BD0" ||
3198                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3199         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3200                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3201         $LFS getstripe -v $DIR/$tdir/${tfile} |
3202                 grep "lfm_flags:.*0x0000DA05" ||
3203                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3204         $LFS getstripe $DIR/$tdir/${tfile} |
3205                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3206                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3207
3208         # modify striping should fail
3209         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3210                 error "$DIR/$tdir/$tfile: setstripe should fail"
3211
3212         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3213         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3214         cat /etc/passwd > $DIR/$tdir/$tfile &&
3215                 error "$DIR/$tdir/$tfile: write should fail"
3216
3217         # rename should succeed
3218         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3219                 error "$DIR/$tdir/$tfile: rename has failed"
3220
3221         #remove foreign_symlink file should fail
3222         rm $DIR/$tdir/${tfile}.new &&
3223                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3224
3225         #test fake symlink
3226         mkdir /tmp/${uuid1} ||
3227                 error "/tmp/${uuid1}: mkdir has failed"
3228         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3229                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3231         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3232                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3233         #read should succeed now
3234         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3235                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3236         #write should succeed now
3237         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3238                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3239         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3240                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3241         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3242                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3243
3244         #check that getstripe still works
3245         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3246                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3247
3248         # chmod should still succeed
3249         chmod 644 $DIR/$tdir/${tfile}.new ||
3250                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3251
3252         # chown should still succeed
3253         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3254                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3255
3256         # rename should still succeed
3257         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3258                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3259
3260         #remove foreign_symlink file should still fail
3261         rm $DIR/$tdir/${tfile} &&
3262                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3263
3264         #use special ioctl() to unlink foreign_symlink file
3265         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3266                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3267
3268 }
3269 run_test 27O "basic ops on foreign file of symlink type"
3270
3271 test_27P() {
3272         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3273                 skip "Need MDS version newer than 2.12.49"
3274
3275         test_mkdir $DIR/$tdir
3276         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3277         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3278
3279         trap clean_foreign_symlink EXIT
3280
3281         # enable foreign_symlink behaviour
3282         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3283
3284         # foreign symlink LMV format is a partial path by default
3285
3286         # create foreign dir (lfs + API)
3287         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3288                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3289                 error "$DIR/$tdir/${tdir}: create failed"
3290
3291         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3292                 grep "lfm_magic:.*0x0CD50CD0" ||
3293                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3294         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3295                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3296         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3297                 grep "lfm_flags:.*0x0000DA05" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3299         $LFS getdirstripe $DIR/$tdir/${tdir} |
3300                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3302
3303         # file create in dir should fail
3304         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3305         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3306
3307         # rename should succeed
3308         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3309                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3310
3311         #remove foreign_symlink dir should fail
3312         rmdir $DIR/$tdir/${tdir}.new &&
3313                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3314
3315         #test fake symlink
3316         mkdir -p /tmp/${uuid1}/${uuid2} ||
3317                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3318         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3319                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3320         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3321         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3322                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3323         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3324                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3325
3326         #check that getstripe fails now that foreign_symlink enabled
3327         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3328                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3329
3330         # file create in dir should work now
3331         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3332                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3333         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3334                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3335         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3336                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3337
3338         # chmod should still succeed
3339         chmod 755 $DIR/$tdir/${tdir}.new ||
3340                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3341
3342         # chown should still succeed
3343         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3344                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3345
3346         # rename should still succeed
3347         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3348                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3349
3350         #remove foreign_symlink dir should still fail
3351         rmdir $DIR/$tdir/${tdir} &&
3352                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3353
3354         #use special ioctl() to unlink foreign_symlink file
3355         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3356                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3357
3358         #created file should still exist
3359         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3360                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3361         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3362                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3363 }
3364 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3365
3366 test_27Q() {
3367         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3368         stack_trap "rm -f $TMP/$tfile*"
3369
3370         test_mkdir $DIR/$tdir-1
3371         test_mkdir $DIR/$tdir-2
3372
3373         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3374         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3375
3376         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3377         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3378
3379         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3380         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3381
3382         # Create some bad symlinks and ensure that we don't loop
3383         # forever or something. These should return ELOOP (40) and
3384         # ENOENT (2) but I don't want to test for that because there's
3385         # always some weirdo architecture that needs to ruin
3386         # everything by defining these error numbers differently.
3387
3388         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3389         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3390
3391         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3392         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3393
3394         return 0
3395 }
3396 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3397
3398 # createtest also checks that device nodes are created and
3399 # then visible correctly (#2091)
3400 test_28() { # bug 2091
3401         test_mkdir $DIR/d28
3402         $CREATETEST $DIR/d28/ct || error "createtest failed"
3403 }
3404 run_test 28 "create/mknod/mkdir with bad file types ============"
3405
3406 test_29() {
3407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3408
3409         sync; sleep 1; sync # flush out any dirty pages from previous tests
3410         cancel_lru_locks
3411         test_mkdir $DIR/d29
3412         touch $DIR/d29/foo
3413         log 'first d29'
3414         ls -l $DIR/d29
3415
3416         declare -i LOCKCOUNTORIG=0
3417         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3418                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3419         done
3420         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3421
3422         declare -i LOCKUNUSEDCOUNTORIG=0
3423         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3424                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3425         done
3426
3427         log 'second d29'
3428         ls -l $DIR/d29
3429         log 'done'
3430
3431         declare -i LOCKCOUNTCURRENT=0
3432         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3433                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3434         done
3435
3436         declare -i LOCKUNUSEDCOUNTCURRENT=0
3437         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3438                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3439         done
3440
3441         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3442                 $LCTL set_param -n ldlm.dump_namespaces ""
3443                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3444                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3445                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3446                 return 2
3447         fi
3448         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3449                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3450                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3451                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3452                 return 3
3453         fi
3454 }
3455 run_test 29 "IT_GETATTR regression  ============================"
3456
3457 test_30a() { # was test_30
3458         cp $(which ls) $DIR || cp /bin/ls $DIR
3459         $DIR/ls / || error "Can't execute binary from lustre"
3460         rm $DIR/ls
3461 }
3462 run_test 30a "execute binary from Lustre (execve) =============="
3463
3464 test_30b() {
3465         cp `which ls` $DIR || cp /bin/ls $DIR
3466         chmod go+rx $DIR/ls
3467         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3468         rm $DIR/ls
3469 }
3470 run_test 30b "execute binary from Lustre as non-root ==========="
3471
3472 test_30c() { # b=22376
3473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3474
3475         cp $(which ls) $DIR || cp /bin/ls $DIR
3476         chmod a-rw $DIR/ls
3477         cancel_lru_locks mdc
3478         cancel_lru_locks osc
3479         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3480         rm -f $DIR/ls
3481 }
3482 run_test 30c "execute binary from Lustre without read perms ===="
3483
3484 test_30d() {
3485         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3486
3487         for i in {1..10}; do
3488                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3489                 local PID=$!
3490                 sleep 1
3491                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3492                 wait $PID || error "executing dd from Lustre failed"
3493                 rm -f $DIR/$tfile
3494         done
3495
3496         rm -f $DIR/dd
3497 }
3498 run_test 30d "execute binary from Lustre while clear locks"
3499
3500 test_31a() {
3501         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3502         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3503 }
3504 run_test 31a "open-unlink file =================================="
3505
3506 test_31b() {
3507         touch $DIR/f31 || error "touch $DIR/f31 failed"
3508         ln $DIR/f31 $DIR/f31b || error "ln failed"
3509         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3510         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3511 }
3512 run_test 31b "unlink file with multiple links while open ======="
3513
3514 test_31c() {
3515         touch $DIR/f31 || error "touch $DIR/f31 failed"
3516         ln $DIR/f31 $DIR/f31c || error "ln failed"
3517         multiop_bg_pause $DIR/f31 O_uc ||
3518                 error "multiop_bg_pause for $DIR/f31 failed"
3519         MULTIPID=$!
3520         $MULTIOP $DIR/f31c Ouc
3521         kill -USR1 $MULTIPID
3522         wait $MULTIPID
3523 }
3524 run_test 31c "open-unlink file with multiple links ============="
3525
3526 test_31d() {
3527         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3528         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3529 }
3530 run_test 31d "remove of open directory ========================="
3531
3532 test_31e() { # bug 2904
3533         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3534 }
3535 run_test 31e "remove of open non-empty directory ==============="
3536
3537 test_31f() { # bug 4554
3538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3539
3540         set -vx
3541         test_mkdir $DIR/d31f
3542         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3543         cp /etc/hosts $DIR/d31f
3544         ls -l $DIR/d31f
3545         $LFS getstripe $DIR/d31f/hosts
3546         multiop_bg_pause $DIR/d31f D_c || return 1
3547         MULTIPID=$!
3548
3549         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3550         test_mkdir $DIR/d31f
3551         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3552         cp /etc/hosts $DIR/d31f
3553         ls -l $DIR/d31f
3554         $LFS getstripe $DIR/d31f/hosts
3555         multiop_bg_pause $DIR/d31f D_c || return 1
3556         MULTIPID2=$!
3557
3558         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3559         wait $MULTIPID || error "first opendir $MULTIPID failed"
3560
3561         sleep 6
3562
3563         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3564         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3565         set +vx
3566 }
3567 run_test 31f "remove of open directory with open-unlink file ==="
3568
3569 test_31g() {
3570         echo "-- cross directory link --"
3571         test_mkdir -c1 $DIR/${tdir}ga
3572         test_mkdir -c1 $DIR/${tdir}gb
3573         touch $DIR/${tdir}ga/f
3574         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3575         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3576         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3577         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3578         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3579 }
3580 run_test 31g "cross directory link==============="
3581
3582 test_31h() {
3583         echo "-- cross directory link --"
3584         test_mkdir -c1 $DIR/${tdir}
3585         test_mkdir -c1 $DIR/${tdir}/dir
3586         touch $DIR/${tdir}/f
3587         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3588         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3589         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3590         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3591         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3592 }
3593 run_test 31h "cross directory link under child==============="
3594
3595 test_31i() {
3596         echo "-- cross directory link --"
3597         test_mkdir -c1 $DIR/$tdir
3598         test_mkdir -c1 $DIR/$tdir/dir
3599         touch $DIR/$tdir/dir/f
3600         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3601         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3602         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3603         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3604         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3605 }
3606 run_test 31i "cross directory link under parent==============="
3607
3608 test_31j() {
3609         test_mkdir -c1 -p $DIR/$tdir
3610         test_mkdir -c1 -p $DIR/$tdir/dir1
3611         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3612         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3613         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3614         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3615         return 0
3616 }
3617 run_test 31j "link for directory==============="
3618
3619 test_31k() {
3620         test_mkdir -c1 -p $DIR/$tdir
3621         touch $DIR/$tdir/s
3622         touch $DIR/$tdir/exist
3623         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3624         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3625         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3626         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3627         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3628         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3629         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3630         return 0
3631 }
3632 run_test 31k "link to file: the same, non-existing, dir==============="
3633
3634 test_31m() {
3635         mkdir $DIR/d31m
3636         touch $DIR/d31m/s
3637         mkdir $DIR/d31m2
3638         touch $DIR/d31m2/exist
3639         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3640         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3641         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3642         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3643         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3644         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3645         return 0
3646 }
3647 run_test 31m "link to file: the same, non-existing, dir==============="
3648
3649 test_31n() {
3650         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3651         nlink=$(stat --format=%h $DIR/$tfile)
3652         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3653         local fd=$(free_fd)
3654         local cmd="exec $fd<$DIR/$tfile"
3655         eval $cmd
3656         cmd="exec $fd<&-"
3657         trap "eval $cmd" EXIT
3658         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3659         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3660         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3661         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3662         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3663         eval $cmd
3664 }
3665 run_test 31n "check link count of unlinked file"
3666
3667 link_one() {
3668         local tempfile=$(mktemp $1_XXXXXX)
3669         mlink $tempfile $1 2> /dev/null &&
3670                 echo "$BASHPID: link $tempfile to $1 succeeded"
3671         munlink $tempfile
3672 }
3673
3674 test_31o() { # LU-2901
3675         test_mkdir $DIR/$tdir
3676         for LOOP in $(seq 100); do
3677                 rm -f $DIR/$tdir/$tfile*
3678                 for THREAD in $(seq 8); do
3679                         link_one $DIR/$tdir/$tfile.$LOOP &
3680                 done
3681                 wait
3682                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3683                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3684                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3685                         break || true
3686         done
3687 }
3688 run_test 31o "duplicate hard links with same filename"
3689
3690 test_31p() {
3691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3692
3693         test_mkdir $DIR/$tdir
3694         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3695         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3696
3697         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3698                 error "open unlink test1 failed"
3699         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3700                 error "open unlink test2 failed"
3701
3702         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3703                 error "test1 still exists"
3704         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3705                 error "test2 still exists"
3706 }
3707 run_test 31p "remove of open striped directory"
3708
3709 test_31q() {
3710         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3711
3712         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3713         index=$($LFS getdirstripe -i $DIR/$tdir)
3714         [ $index -eq 3 ] || error "first stripe index $index != 3"
3715         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3716         [ $index -eq 1 ] || error "second stripe index $index != 1"
3717
3718         # when "-c <stripe_count>" is set, the number of MDTs specified after
3719         # "-i" should equal to the stripe count
3720         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3721 }
3722 run_test 31q "create striped directory on specific MDTs"
3723
3724 cleanup_test32_mount() {
3725         local rc=0
3726         trap 0
3727         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3728         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3729         losetup -d $loopdev || true
3730         rm -rf $DIR/$tdir
3731         return $rc
3732 }
3733
3734 test_32a() {
3735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3736
3737         echo "== more mountpoints and symlinks ================="
3738         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3739         trap cleanup_test32_mount EXIT
3740         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3741         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3742                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3743         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3744                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3745         cleanup_test32_mount
3746 }
3747 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3748
3749 test_32b() {
3750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3751
3752         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3753         trap cleanup_test32_mount EXIT
3754         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3755         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3756                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3757         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3758                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3759         cleanup_test32_mount
3760 }
3761 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3762
3763 test_32c() {
3764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3765
3766         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3767         trap cleanup_test32_mount EXIT
3768         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3769         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3770                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3771         test_mkdir -p $DIR/$tdir/d2/test_dir
3772         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3773                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3774         cleanup_test32_mount
3775 }
3776 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3777
3778 test_32d() {
3779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3780
3781         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3782         trap cleanup_test32_mount EXIT
3783         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3784         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3785                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3786         test_mkdir -p $DIR/$tdir/d2/test_dir
3787         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3788                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3789         cleanup_test32_mount
3790 }
3791 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3792
3793 test_32e() {
3794         rm -fr $DIR/$tdir
3795         test_mkdir -p $DIR/$tdir/tmp
3796         local tmp_dir=$DIR/$tdir/tmp
3797         ln -s $DIR/$tdir $tmp_dir/symlink11
3798         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3799         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3800         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3801 }
3802 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3803
3804 test_32f() {
3805         rm -fr $DIR/$tdir
3806         test_mkdir -p $DIR/$tdir/tmp
3807         local tmp_dir=$DIR/$tdir/tmp
3808         ln -s $DIR/$tdir $tmp_dir/symlink11
3809         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3810         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3811         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3812 }
3813 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3814
3815 test_32g() {
3816         local tmp_dir=$DIR/$tdir/tmp
3817         test_mkdir -p $tmp_dir
3818         test_mkdir $DIR/${tdir}2
3819         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3820         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3821         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3822         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3823         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3824         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3825 }
3826 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3827
3828 test_32h() {
3829         rm -fr $DIR/$tdir $DIR/${tdir}2
3830         tmp_dir=$DIR/$tdir/tmp
3831         test_mkdir -p $tmp_dir
3832         test_mkdir $DIR/${tdir}2
3833         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3834         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3835         ls $tmp_dir/symlink12 || error "listing symlink12"
3836         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3837 }
3838 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3839
3840 test_32i() {
3841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3842
3843         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3844         trap cleanup_test32_mount EXIT
3845         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3846         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3847                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3848         touch $DIR/$tdir/test_file
3849         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3850                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3851         cleanup_test32_mount
3852 }
3853 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3854
3855 test_32j() {
3856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3857
3858         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3859         trap cleanup_test32_mount EXIT
3860         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3861         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3862                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3863         touch $DIR/$tdir/test_file
3864         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3865                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3866         cleanup_test32_mount
3867 }
3868 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3869
3870 test_32k() {
3871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3872
3873         rm -fr $DIR/$tdir
3874         trap cleanup_test32_mount EXIT
3875         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3876         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3877                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3878         test_mkdir -p $DIR/$tdir/d2
3879         touch $DIR/$tdir/d2/test_file || error "touch failed"
3880         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3881                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3882         cleanup_test32_mount
3883 }
3884 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3885
3886 test_32l() {
3887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3888
3889         rm -fr $DIR/$tdir
3890         trap cleanup_test32_mount EXIT
3891         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3892         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3893                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3894         test_mkdir -p $DIR/$tdir/d2
3895         touch $DIR/$tdir/d2/test_file || error "touch failed"
3896         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3897                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3898         cleanup_test32_mount
3899 }
3900 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3901
3902 test_32m() {
3903         rm -fr $DIR/d32m
3904         test_mkdir -p $DIR/d32m/tmp
3905         TMP_DIR=$DIR/d32m/tmp
3906         ln -s $DIR $TMP_DIR/symlink11
3907         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3908         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3909                 error "symlink11 not a link"
3910         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3911                 error "symlink01 not a link"
3912 }
3913 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3914
3915 test_32n() {
3916         rm -fr $DIR/d32n
3917         test_mkdir -p $DIR/d32n/tmp
3918         TMP_DIR=$DIR/d32n/tmp
3919         ln -s $DIR $TMP_DIR/symlink11
3920         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3921         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3922         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3923 }
3924 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3925
3926 test_32o() {
3927         touch $DIR/$tfile
3928         test_mkdir -p $DIR/d32o/tmp
3929         TMP_DIR=$DIR/d32o/tmp
3930         ln -s $DIR/$tfile $TMP_DIR/symlink12
3931         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3932         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3933                 error "symlink12 not a link"
3934         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3935         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3936                 error "$DIR/d32o/tmp/symlink12 not file type"
3937         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3938                 error "$DIR/d32o/symlink02 not file type"
3939 }
3940 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3941
3942 test_32p() {
3943         log 32p_1
3944         rm -fr $DIR/d32p
3945         log 32p_2
3946         rm -f $DIR/$tfile
3947         log 32p_3
3948         touch $DIR/$tfile
3949         log 32p_4
3950         test_mkdir -p $DIR/d32p/tmp
3951         log 32p_5
3952         TMP_DIR=$DIR/d32p/tmp
3953         log 32p_6
3954         ln -s $DIR/$tfile $TMP_DIR/symlink12
3955         log 32p_7
3956         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3957         log 32p_8
3958         cat $DIR/d32p/tmp/symlink12 ||
3959                 error "Can't open $DIR/d32p/tmp/symlink12"
3960         log 32p_9
3961         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3962         log 32p_10
3963 }
3964 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3965
3966 test_32q() {
3967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3968
3969         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3970         trap cleanup_test32_mount EXIT
3971         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3972         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3973         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3974                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3975         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3976         cleanup_test32_mount
3977 }
3978 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3979
3980 test_32r() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982
3983         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3984         trap cleanup_test32_mount EXIT
3985         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3986         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3987         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3988                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3989         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3990         cleanup_test32_mount
3991 }
3992 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3993
3994 test_33aa() {
3995         rm -f $DIR/$tfile
3996         touch $DIR/$tfile
3997         chmod 444 $DIR/$tfile
3998         chown $RUNAS_ID $DIR/$tfile
3999         log 33_1
4000         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4001         log 33_2
4002 }
4003 run_test 33aa "write file with mode 444 (should return error)"
4004
4005 test_33a() {
4006         rm -fr $DIR/$tdir
4007         test_mkdir $DIR/$tdir
4008         chown $RUNAS_ID $DIR/$tdir
4009         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4010                 error "$RUNAS create $tdir/$tfile failed"
4011         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4012                 error "open RDWR" || true
4013 }
4014 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4015
4016 test_33b() {
4017         rm -fr $DIR/$tdir
4018         test_mkdir $DIR/$tdir
4019         chown $RUNAS_ID $DIR/$tdir
4020         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4021 }
4022 run_test 33b "test open file with malformed flags (No panic)"
4023
4024 test_33c() {
4025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4026         remote_ost_nodsh && skip "remote OST with nodsh"
4027
4028         local ostnum
4029         local ostname
4030         local write_bytes
4031         local all_zeros
4032
4033         all_zeros=true
4034         test_mkdir $DIR/$tdir
4035         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4036
4037         sync
4038         for ostnum in $(seq $OSTCOUNT); do
4039                 # test-framework's OST numbering is one-based, while Lustre's
4040                 # is zero-based
4041                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4042                 # check if at least some write_bytes stats are counted
4043                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4044                               obdfilter.$ostname.stats |
4045                               awk '/^write_bytes/ {print $7}' )
4046                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4047                 if (( ${write_bytes:-0} > 0 )); then
4048                         all_zeros=false
4049                         break
4050                 fi
4051         done
4052
4053         $all_zeros || return 0
4054
4055         # Write four bytes
4056         echo foo > $DIR/$tdir/bar
4057         # Really write them
4058         sync
4059
4060         # Total up write_bytes after writing.  We'd better find non-zeros.
4061         for ostnum in $(seq $OSTCOUNT); do
4062                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4063                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4064                               obdfilter/$ostname/stats |
4065                               awk '/^write_bytes/ {print $7}' )
4066                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4067                 if (( ${write_bytes:-0} > 0 )); then
4068                         all_zeros=false
4069                         break
4070                 fi
4071         done
4072
4073         if $all_zeros; then
4074                 for ostnum in $(seq $OSTCOUNT); do
4075                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4076                         echo "Check write_bytes is in obdfilter.*.stats:"
4077                         do_facet ost$ostnum lctl get_param -n \
4078                                 obdfilter.$ostname.stats
4079                 done
4080                 error "OST not keeping write_bytes stats (b=22312)"
4081         fi
4082 }
4083 run_test 33c "test write_bytes stats"
4084
4085 test_33d() {
4086         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4088
4089         local MDTIDX=1
4090         local remote_dir=$DIR/$tdir/remote_dir
4091
4092         test_mkdir $DIR/$tdir
4093         $LFS mkdir -i $MDTIDX $remote_dir ||
4094                 error "create remote directory failed"
4095
4096         touch $remote_dir/$tfile
4097         chmod 444 $remote_dir/$tfile
4098         chown $RUNAS_ID $remote_dir/$tfile
4099
4100         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4101
4102         chown $RUNAS_ID $remote_dir
4103         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4104                                         error "create" || true
4105         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4106                                     error "open RDWR" || true
4107         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4108 }
4109 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4110
4111 test_33e() {
4112         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4113
4114         mkdir $DIR/$tdir
4115
4116         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4117         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4118         mkdir $DIR/$tdir/local_dir
4119
4120         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4121         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4122         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4123
4124         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4125                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4126
4127         rmdir $DIR/$tdir/* || error "rmdir failed"
4128
4129         umask 777
4130         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4131         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4132         mkdir $DIR/$tdir/local_dir
4133
4134         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4135         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4136         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4137
4138         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4139                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4140
4141         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4142
4143         umask 000
4144         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4145         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4146         mkdir $DIR/$tdir/local_dir
4147
4148         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4149         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4150         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4151
4152         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4153                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4154 }
4155 run_test 33e "mkdir and striped directory should have same mode"
4156
4157 cleanup_33f() {
4158         trap 0
4159         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4160 }
4161
4162 test_33f() {
4163         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4164         remote_mds_nodsh && skip "remote MDS with nodsh"
4165
4166         mkdir $DIR/$tdir
4167         chmod go+rwx $DIR/$tdir
4168         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4169         trap cleanup_33f EXIT
4170
4171         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4172                 error "cannot create striped directory"
4173
4174         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4175                 error "cannot create files in striped directory"
4176
4177         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4178                 error "cannot remove files in striped directory"
4179
4180         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4181                 error "cannot remove striped directory"
4182
4183         cleanup_33f
4184 }
4185 run_test 33f "nonroot user can create, access, and remove a striped directory"
4186
4187 test_33g() {
4188         mkdir -p $DIR/$tdir/dir2
4189
4190         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4191         echo $err
4192         [[ $err =~ "exists" ]] || error "Not exists error"
4193 }
4194 run_test 33g "nonroot user create already existing root created file"
4195
4196 test_33h() {
4197         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4198         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4199                 skip "Need MDS version at least 2.13.50"
4200
4201         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4202                 error "mkdir $tdir failed"
4203         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4204
4205         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4206         local index2
4207
4208         for fname in $DIR/$tdir/$tfile.bak \
4209                      $DIR/$tdir/$tfile.SAV \
4210                      $DIR/$tdir/$tfile.orig \
4211                      $DIR/$tdir/$tfile~; do
4212                 touch $fname  || error "touch $fname failed"
4213                 index2=$($LFS getstripe -m $fname)
4214                 [ $index -eq $index2 ] ||
4215                         error "$fname MDT index mismatch $index != $index2"
4216         done
4217
4218         local failed=0
4219         for i in {1..250}; do
4220                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4221                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4222                         touch $fname  || error "touch $fname failed"
4223                         index2=$($LFS getstripe -m $fname)
4224                         if [[ $index != $index2 ]]; then
4225                                 failed=$((failed + 1))
4226                                 echo "$fname MDT index mismatch $index != $index2"
4227                         fi
4228                 done
4229         done
4230         echo "$failed MDT index mismatches"
4231         (( failed < 20 )) || error "MDT index mismatch $failed times"
4232
4233 }
4234 run_test 33h "temp file is located on the same MDT as target"
4235
4236 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4237 test_34a() {
4238         rm -f $DIR/f34
4239         $MCREATE $DIR/f34 || error "mcreate failed"
4240         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4241                 error "getstripe failed"
4242         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
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 34a "truncate file that has not been opened ==========="
4249
4250 test_34b() {
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_RDONLY $DIR/f34
4255         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4256                 error "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 34b "O_RDONLY opening file doesn't create objects ====="
4261
4262 test_34c() {
4263         [ ! -f $DIR/f34 ] && test_34a
4264         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4265                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4266         $OPENFILE -f O_RDWR $DIR/f34
4267         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4268                 error "$LFS getstripe failed"
4269         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4270                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4271 }
4272 run_test 34c "O_RDWR opening file-with-size works =============="
4273
4274 test_34d() {
4275         [ ! -f $DIR/f34 ] && test_34a
4276         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4277                 error "dd failed"
4278         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4279                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4280         rm $DIR/f34
4281 }
4282 run_test 34d "write to sparse file ============================="
4283
4284 test_34e() {
4285         rm -f $DIR/f34e
4286         $MCREATE $DIR/f34e || error "mcreate failed"
4287         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4288         $CHECKSTAT -s 1000 $DIR/f34e ||
4289                 error "Size of $DIR/f34e not equal to 1000 bytes"
4290         $OPENFILE -f O_RDWR $DIR/f34e
4291         $CHECKSTAT -s 1000 $DIR/f34e ||
4292                 error "Size of $DIR/f34e not equal to 1000 bytes"
4293 }
4294 run_test 34e "create objects, some with size and some without =="
4295
4296 test_34f() { # bug 6242, 6243
4297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4298
4299         SIZE34F=48000
4300         rm -f $DIR/f34f
4301         $MCREATE $DIR/f34f || error "mcreate failed"
4302         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4303         dd if=$DIR/f34f of=$TMP/f34f
4304         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4305         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4306         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4307         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4308         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4309 }
4310 run_test 34f "read from a file with no objects until EOF ======="
4311
4312 test_34g() {
4313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4314
4315         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4316                 error "dd failed"
4317         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4318         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4319                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4320         cancel_lru_locks osc
4321         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4322                 error "wrong size after lock cancel"
4323
4324         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4325         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4326                 error "expanding truncate failed"
4327         cancel_lru_locks osc
4328         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4329                 error "wrong expanded size after lock cancel"
4330 }
4331 run_test 34g "truncate long file ==============================="
4332
4333 test_34h() {
4334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4335
4336         local gid=10
4337         local sz=1000
4338
4339         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4340         sync # Flush the cache so that multiop below does not block on cache
4341              # flush when getting the group lock
4342         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4343         MULTIPID=$!
4344
4345         # Since just timed wait is not good enough, let's do a sync write
4346         # that way we are sure enough time for a roundtrip + processing
4347         # passed + 2 seconds of extra margin.
4348         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4349         rm $DIR/${tfile}-1
4350         sleep 2
4351
4352         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4353                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4354                 kill -9 $MULTIPID
4355         fi
4356         wait $MULTIPID
4357         local nsz=`stat -c %s $DIR/$tfile`
4358         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4359 }
4360 run_test 34h "ftruncate file under grouplock should not block"
4361
4362 test_35a() {
4363         cp /bin/sh $DIR/f35a
4364         chmod 444 $DIR/f35a
4365         chown $RUNAS_ID $DIR/f35a
4366         $RUNAS $DIR/f35a && error || true
4367         rm $DIR/f35a
4368 }
4369 run_test 35a "exec file with mode 444 (should return and not leak)"
4370
4371 test_36a() {
4372         rm -f $DIR/f36
4373         utime $DIR/f36 || error "utime failed for MDS"
4374 }
4375 run_test 36a "MDS utime check (mknod, utime)"
4376
4377 test_36b() {
4378         echo "" > $DIR/f36
4379         utime $DIR/f36 || error "utime failed for OST"
4380 }
4381 run_test 36b "OST utime check (open, utime)"
4382
4383 test_36c() {
4384         rm -f $DIR/d36/f36
4385         test_mkdir $DIR/d36
4386         chown $RUNAS_ID $DIR/d36
4387         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4388 }
4389 run_test 36c "non-root MDS utime check (mknod, utime)"
4390
4391 test_36d() {
4392         [ ! -d $DIR/d36 ] && test_36c
4393         echo "" > $DIR/d36/f36
4394         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4395 }
4396 run_test 36d "non-root OST utime check (open, utime)"
4397
4398 test_36e() {
4399         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4400
4401         test_mkdir $DIR/$tdir
4402         touch $DIR/$tdir/$tfile
4403         $RUNAS utime $DIR/$tdir/$tfile &&
4404                 error "utime worked, expected failure" || true
4405 }
4406 run_test 36e "utime on non-owned file (should return error)"
4407
4408 subr_36fh() {
4409         local fl="$1"
4410         local LANG_SAVE=$LANG
4411         local LC_LANG_SAVE=$LC_LANG
4412         export LANG=C LC_LANG=C # for date language
4413
4414         DATESTR="Dec 20  2000"
4415         test_mkdir $DIR/$tdir
4416         lctl set_param fail_loc=$fl
4417         date; date +%s
4418         cp /etc/hosts $DIR/$tdir/$tfile
4419         sync & # write RPC generated with "current" inode timestamp, but delayed
4420         sleep 1
4421         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4422         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4423         cancel_lru_locks $OSC
4424         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4425         date; date +%s
4426         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4427                 echo "BEFORE: $LS_BEFORE" && \
4428                 echo "AFTER : $LS_AFTER" && \
4429                 echo "WANT  : $DATESTR" && \
4430                 error "$DIR/$tdir/$tfile timestamps changed" || true
4431
4432         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4433 }
4434
4435 test_36f() {
4436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4437
4438         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4439         subr_36fh "0x80000214"
4440 }
4441 run_test 36f "utime on file racing with OST BRW write =========="
4442
4443 test_36g() {
4444         remote_ost_nodsh && skip "remote OST with nodsh"
4445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4446         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4447                 skip "Need MDS version at least 2.12.51"
4448
4449         local fmd_max_age
4450         local fmd
4451         local facet="ost1"
4452         local tgt="obdfilter"
4453
4454         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4455
4456         test_mkdir $DIR/$tdir
4457         fmd_max_age=$(do_facet $facet \
4458                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4459                 head -n 1")
4460
4461         echo "FMD max age: ${fmd_max_age}s"
4462         touch $DIR/$tdir/$tfile
4463         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4464                 gawk '{cnt=cnt+$1}  END{print cnt}')
4465         echo "FMD before: $fmd"
4466         [[ $fmd == 0 ]] &&
4467                 error "FMD wasn't create by touch"
4468         sleep $((fmd_max_age + 12))
4469         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4470                 gawk '{cnt=cnt+$1}  END{print cnt}')
4471         echo "FMD after: $fmd"
4472         [[ $fmd == 0 ]] ||
4473                 error "FMD wasn't expired by ping"
4474 }
4475 run_test 36g "FMD cache expiry ====================="
4476
4477 test_36h() {
4478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4479
4480         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4481         subr_36fh "0x80000227"
4482 }
4483 run_test 36h "utime on file racing with OST BRW write =========="
4484
4485 test_36i() {
4486         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4487
4488         test_mkdir $DIR/$tdir
4489         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4490
4491         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4492         local new_mtime=$((mtime + 200))
4493
4494         #change Modify time of striped dir
4495         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4496                         error "change mtime failed"
4497
4498         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4499
4500         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4501 }
4502 run_test 36i "change mtime on striped directory"
4503
4504 # test_37 - duplicate with tests 32q 32r
4505
4506 test_38() {
4507         local file=$DIR/$tfile
4508         touch $file
4509         openfile -f O_DIRECTORY $file
4510         local RC=$?
4511         local ENOTDIR=20
4512         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4513         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4514 }
4515 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4516
4517 test_39a() { # was test_39
4518         touch $DIR/$tfile
4519         touch $DIR/${tfile}2
4520 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4521 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4522 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4523         sleep 2
4524         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4525         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4526                 echo "mtime"
4527                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4528                 echo "atime"
4529                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4530                 echo "ctime"
4531                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4532                 error "O_TRUNC didn't change timestamps"
4533         fi
4534 }
4535 run_test 39a "mtime changed on create"
4536
4537 test_39b() {
4538         test_mkdir -c1 $DIR/$tdir
4539         cp -p /etc/passwd $DIR/$tdir/fopen
4540         cp -p /etc/passwd $DIR/$tdir/flink
4541         cp -p /etc/passwd $DIR/$tdir/funlink
4542         cp -p /etc/passwd $DIR/$tdir/frename
4543         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4544
4545         sleep 1
4546         echo "aaaaaa" >> $DIR/$tdir/fopen
4547         echo "aaaaaa" >> $DIR/$tdir/flink
4548         echo "aaaaaa" >> $DIR/$tdir/funlink
4549         echo "aaaaaa" >> $DIR/$tdir/frename
4550
4551         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4552         local link_new=`stat -c %Y $DIR/$tdir/flink`
4553         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4554         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4555
4556         cat $DIR/$tdir/fopen > /dev/null
4557         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4558         rm -f $DIR/$tdir/funlink2
4559         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4560
4561         for (( i=0; i < 2; i++ )) ; do
4562                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4563                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4564                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4565                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4566
4567                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4568                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4569                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4570                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4571
4572                 cancel_lru_locks $OSC
4573                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4574         done
4575 }
4576 run_test 39b "mtime change on open, link, unlink, rename  ======"
4577
4578 # this should be set to past
4579 TEST_39_MTIME=`date -d "1 year ago" +%s`
4580
4581 # bug 11063
4582 test_39c() {
4583         touch $DIR1/$tfile
4584         sleep 2
4585         local mtime0=`stat -c %Y $DIR1/$tfile`
4586
4587         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4588         local mtime1=`stat -c %Y $DIR1/$tfile`
4589         [ "$mtime1" = $TEST_39_MTIME ] || \
4590                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4591
4592         local d1=`date +%s`
4593         echo hello >> $DIR1/$tfile
4594         local d2=`date +%s`
4595         local mtime2=`stat -c %Y $DIR1/$tfile`
4596         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4597                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4598
4599         mv $DIR1/$tfile $DIR1/$tfile-1
4600
4601         for (( i=0; i < 2; i++ )) ; do
4602                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4603                 [ "$mtime2" = "$mtime3" ] || \
4604                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4605
4606                 cancel_lru_locks $OSC
4607                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4608         done
4609 }
4610 run_test 39c "mtime change on rename ==========================="
4611
4612 # bug 21114
4613 test_39d() {
4614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4615
4616         touch $DIR1/$tfile
4617         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4618
4619         for (( i=0; i < 2; i++ )) ; do
4620                 local mtime=`stat -c %Y $DIR1/$tfile`
4621                 [ $mtime = $TEST_39_MTIME ] || \
4622                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4623
4624                 cancel_lru_locks $OSC
4625                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4626         done
4627 }
4628 run_test 39d "create, utime, stat =============================="
4629
4630 # bug 21114
4631 test_39e() {
4632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4633
4634         touch $DIR1/$tfile
4635         local mtime1=`stat -c %Y $DIR1/$tfile`
4636
4637         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4638
4639         for (( i=0; i < 2; i++ )) ; do
4640                 local mtime2=`stat -c %Y $DIR1/$tfile`
4641                 [ $mtime2 = $TEST_39_MTIME ] || \
4642                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4643
4644                 cancel_lru_locks $OSC
4645                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4646         done
4647 }
4648 run_test 39e "create, stat, utime, stat ========================"
4649
4650 # bug 21114
4651 test_39f() {
4652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4653
4654         touch $DIR1/$tfile
4655         mtime1=`stat -c %Y $DIR1/$tfile`
4656
4657         sleep 2
4658         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4659
4660         for (( i=0; i < 2; i++ )) ; do
4661                 local mtime2=`stat -c %Y $DIR1/$tfile`
4662                 [ $mtime2 = $TEST_39_MTIME ] || \
4663                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4664
4665                 cancel_lru_locks $OSC
4666                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4667         done
4668 }
4669 run_test 39f "create, stat, sleep, utime, stat ================="
4670
4671 # bug 11063
4672 test_39g() {
4673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4674
4675         echo hello >> $DIR1/$tfile
4676         local mtime1=`stat -c %Y $DIR1/$tfile`
4677
4678         sleep 2
4679         chmod o+r $DIR1/$tfile
4680
4681         for (( i=0; i < 2; i++ )) ; do
4682                 local mtime2=`stat -c %Y $DIR1/$tfile`
4683                 [ "$mtime1" = "$mtime2" ] || \
4684                         error "lost mtime: $mtime2, should be $mtime1"
4685
4686                 cancel_lru_locks $OSC
4687                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4688         done
4689 }
4690 run_test 39g "write, chmod, stat ==============================="
4691
4692 # bug 11063
4693 test_39h() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         touch $DIR1/$tfile
4697         sleep 1
4698
4699         local d1=`date`
4700         echo hello >> $DIR1/$tfile
4701         local mtime1=`stat -c %Y $DIR1/$tfile`
4702
4703         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4704         local d2=`date`
4705         if [ "$d1" != "$d2" ]; then
4706                 echo "write and touch not within one second"
4707         else
4708                 for (( i=0; i < 2; i++ )) ; do
4709                         local mtime2=`stat -c %Y $DIR1/$tfile`
4710                         [ "$mtime2" = $TEST_39_MTIME ] || \
4711                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4712
4713                         cancel_lru_locks $OSC
4714                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4715                 done
4716         fi
4717 }
4718 run_test 39h "write, utime within one second, stat ============="
4719
4720 test_39i() {
4721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4722
4723         touch $DIR1/$tfile
4724         sleep 1
4725
4726         echo hello >> $DIR1/$tfile
4727         local mtime1=`stat -c %Y $DIR1/$tfile`
4728
4729         mv $DIR1/$tfile $DIR1/$tfile-1
4730
4731         for (( i=0; i < 2; i++ )) ; do
4732                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4733
4734                 [ "$mtime1" = "$mtime2" ] || \
4735                         error "lost mtime: $mtime2, should be $mtime1"
4736
4737                 cancel_lru_locks $OSC
4738                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4739         done
4740 }
4741 run_test 39i "write, rename, stat =============================="
4742
4743 test_39j() {
4744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4745
4746         start_full_debug_logging
4747         touch $DIR1/$tfile
4748         sleep 1
4749
4750         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4751         lctl set_param fail_loc=0x80000412
4752         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4753                 error "multiop failed"
4754         local multipid=$!
4755         local mtime1=`stat -c %Y $DIR1/$tfile`
4756
4757         mv $DIR1/$tfile $DIR1/$tfile-1
4758
4759         kill -USR1 $multipid
4760         wait $multipid || error "multiop close failed"
4761
4762         for (( i=0; i < 2; i++ )) ; do
4763                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4764                 [ "$mtime1" = "$mtime2" ] ||
4765                         error "mtime is lost on close: $mtime2, " \
4766                               "should be $mtime1"
4767
4768                 cancel_lru_locks
4769                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4770         done
4771         lctl set_param fail_loc=0
4772         stop_full_debug_logging
4773 }
4774 run_test 39j "write, rename, close, stat ======================="
4775
4776 test_39k() {
4777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4778
4779         touch $DIR1/$tfile
4780         sleep 1
4781
4782         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4783         local multipid=$!
4784         local mtime1=`stat -c %Y $DIR1/$tfile`
4785
4786         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4787
4788         kill -USR1 $multipid
4789         wait $multipid || error "multiop close failed"
4790
4791         for (( i=0; i < 2; i++ )) ; do
4792                 local mtime2=`stat -c %Y $DIR1/$tfile`
4793
4794                 [ "$mtime2" = $TEST_39_MTIME ] || \
4795                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4796
4797                 cancel_lru_locks
4798                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4799         done
4800 }
4801 run_test 39k "write, utime, close, stat ========================"
4802
4803 # this should be set to future
4804 TEST_39_ATIME=`date -d "1 year" +%s`
4805
4806 test_39l() {
4807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4808         remote_mds_nodsh && skip "remote MDS with nodsh"
4809
4810         local atime_diff=$(do_facet $SINGLEMDS \
4811                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4812         rm -rf $DIR/$tdir
4813         mkdir_on_mdt0 $DIR/$tdir
4814
4815         # test setting directory atime to future
4816         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4817         local atime=$(stat -c %X $DIR/$tdir)
4818         [ "$atime" = $TEST_39_ATIME ] ||
4819                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4820
4821         # test setting directory atime from future to now
4822         local now=$(date +%s)
4823         touch -a -d @$now $DIR/$tdir
4824
4825         atime=$(stat -c %X $DIR/$tdir)
4826         [ "$atime" -eq "$now"  ] ||
4827                 error "atime is not updated from future: $atime, $now"
4828
4829         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4830         sleep 3
4831
4832         # test setting directory atime when now > dir atime + atime_diff
4833         local d1=$(date +%s)
4834         ls $DIR/$tdir
4835         local d2=$(date +%s)
4836         cancel_lru_locks mdc
4837         atime=$(stat -c %X $DIR/$tdir)
4838         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4839                 error "atime is not updated  : $atime, should be $d2"
4840
4841         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4842         sleep 3
4843
4844         # test not setting directory atime when now < dir atime + atime_diff
4845         ls $DIR/$tdir
4846         cancel_lru_locks mdc
4847         atime=$(stat -c %X $DIR/$tdir)
4848         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4849                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4850
4851         do_facet $SINGLEMDS \
4852                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4853 }
4854 run_test 39l "directory atime update ==========================="
4855
4856 test_39m() {
4857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4858
4859         touch $DIR1/$tfile
4860         sleep 2
4861         local far_past_mtime=$(date -d "May 29 1953" +%s)
4862         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4863
4864         touch -m -d @$far_past_mtime $DIR1/$tfile
4865         touch -a -d @$far_past_atime $DIR1/$tfile
4866
4867         for (( i=0; i < 2; i++ )) ; do
4868                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4869                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4870                         error "atime or mtime set incorrectly"
4871
4872                 cancel_lru_locks $OSC
4873                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4874         done
4875 }
4876 run_test 39m "test atime and mtime before 1970"
4877
4878 test_39n() { # LU-3832
4879         remote_mds_nodsh && skip "remote MDS with nodsh"
4880
4881         local atime_diff=$(do_facet $SINGLEMDS \
4882                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4883         local atime0
4884         local atime1
4885         local atime2
4886
4887         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4888
4889         rm -rf $DIR/$tfile
4890         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4891         atime0=$(stat -c %X $DIR/$tfile)
4892
4893         sleep 5
4894         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4895         atime1=$(stat -c %X $DIR/$tfile)
4896
4897         sleep 5
4898         cancel_lru_locks mdc
4899         cancel_lru_locks osc
4900         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4901         atime2=$(stat -c %X $DIR/$tfile)
4902
4903         do_facet $SINGLEMDS \
4904                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4905
4906         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4907         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4908 }
4909 run_test 39n "check that O_NOATIME is honored"
4910
4911 test_39o() {
4912         TESTDIR=$DIR/$tdir/$tfile
4913         [ -e $TESTDIR ] && rm -rf $TESTDIR
4914         mkdir -p $TESTDIR
4915         cd $TESTDIR
4916         links1=2
4917         ls
4918         mkdir a b
4919         ls
4920         links2=$(stat -c %h .)
4921         [ $(($links1 + 2)) != $links2 ] &&
4922                 error "wrong links count $(($links1 + 2)) != $links2"
4923         rmdir b
4924         links3=$(stat -c %h .)
4925         [ $(($links1 + 1)) != $links3 ] &&
4926                 error "wrong links count $links1 != $links3"
4927         return 0
4928 }
4929 run_test 39o "directory cached attributes updated after create"
4930
4931 test_39p() {
4932         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4933
4934         local MDTIDX=1
4935         TESTDIR=$DIR/$tdir/$tdir
4936         [ -e $TESTDIR ] && rm -rf $TESTDIR
4937         test_mkdir -p $TESTDIR
4938         cd $TESTDIR
4939         links1=2
4940         ls
4941         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4942         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4943         ls
4944         links2=$(stat -c %h .)
4945         [ $(($links1 + 2)) != $links2 ] &&
4946                 error "wrong links count $(($links1 + 2)) != $links2"
4947         rmdir remote_dir2
4948         links3=$(stat -c %h .)
4949         [ $(($links1 + 1)) != $links3 ] &&
4950                 error "wrong links count $links1 != $links3"
4951         return 0
4952 }
4953 run_test 39p "remote directory cached attributes updated after create ========"
4954
4955 test_39r() {
4956         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4957                 skip "no atime update on old OST"
4958         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4959                 skip_env "ldiskfs only test"
4960         fi
4961
4962         local saved_adiff
4963         saved_adiff=$(do_facet ost1 \
4964                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4965         stack_trap "do_facet ost1 \
4966                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4967
4968         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4969
4970         $LFS setstripe -i 0 $DIR/$tfile
4971         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4972                 error "can't write initial file"
4973         cancel_lru_locks osc
4974
4975         # exceed atime_diff and access file
4976         sleep 6
4977         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4978                 error "can't udpate atime"
4979
4980         local atime_cli=$(stat -c %X $DIR/$tfile)
4981         echo "client atime: $atime_cli"
4982         # allow atime update to be written to device
4983         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4984         sleep 5
4985
4986         local ostdev=$(ostdevname 1)
4987         local fid=($(lfs getstripe -y $DIR/$tfile |
4988                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4989         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4990         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4991
4992         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4993         local atime_ost=$(do_facet ost1 "$cmd" |&
4994                           awk -F'[: ]' '/atime:/ { print $4 }')
4995         (( atime_cli == atime_ost )) ||
4996                 error "atime on client $atime_cli != ost $atime_ost"
4997 }
4998 run_test 39r "lazy atime update on OST"
4999
5000 test_39q() { # LU-8041
5001         local testdir=$DIR/$tdir
5002         mkdir -p $testdir
5003         multiop_bg_pause $testdir D_c || error "multiop failed"
5004         local multipid=$!
5005         cancel_lru_locks mdc
5006         kill -USR1 $multipid
5007         local atime=$(stat -c %X $testdir)
5008         [ "$atime" -ne 0 ] || error "atime is zero"
5009 }
5010 run_test 39q "close won't zero out atime"
5011
5012 test_40() {
5013         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5014         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5015                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5016         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5017                 error "$tfile is not 4096 bytes in size"
5018 }
5019 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5020
5021 test_41() {
5022         # bug 1553
5023         small_write $DIR/f41 18
5024 }
5025 run_test 41 "test small file write + fstat ====================="
5026
5027 count_ost_writes() {
5028         lctl get_param -n ${OSC}.*.stats |
5029                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5030                         END { printf("%0.0f", writes) }'
5031 }
5032
5033 # decent default
5034 WRITEBACK_SAVE=500
5035 DIRTY_RATIO_SAVE=40
5036 MAX_DIRTY_RATIO=50
5037 BG_DIRTY_RATIO_SAVE=10
5038 MAX_BG_DIRTY_RATIO=25
5039
5040 start_writeback() {
5041         trap 0
5042         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5043         # dirty_ratio, dirty_background_ratio
5044         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5045                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5046                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5047                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5048         else
5049                 # if file not here, we are a 2.4 kernel
5050                 kill -CONT `pidof kupdated`
5051         fi
5052 }
5053
5054 stop_writeback() {
5055         # setup the trap first, so someone cannot exit the test at the
5056         # exact wrong time and mess up a machine
5057         trap start_writeback EXIT
5058         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5059         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5060                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5061                 sysctl -w vm.dirty_writeback_centisecs=0
5062                 sysctl -w vm.dirty_writeback_centisecs=0
5063                 # save and increase /proc/sys/vm/dirty_ratio
5064                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5065                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5066                 # save and increase /proc/sys/vm/dirty_background_ratio
5067                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5068                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5069         else
5070                 # if file not here, we are a 2.4 kernel
5071                 kill -STOP `pidof kupdated`
5072         fi
5073 }
5074
5075 # ensure that all stripes have some grant before we test client-side cache
5076 setup_test42() {
5077         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5078                 dd if=/dev/zero of=$i bs=4k count=1
5079                 rm $i
5080         done
5081 }
5082
5083 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5084 # file truncation, and file removal.
5085 test_42a() {
5086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5087
5088         setup_test42
5089         cancel_lru_locks $OSC
5090         stop_writeback
5091         sync; sleep 1; sync # just to be safe
5092         BEFOREWRITES=`count_ost_writes`
5093         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5094         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5095         AFTERWRITES=`count_ost_writes`
5096         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5097                 error "$BEFOREWRITES < $AFTERWRITES"
5098         start_writeback
5099 }
5100 run_test 42a "ensure that we don't flush on close"
5101
5102 test_42b() {
5103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5104
5105         setup_test42
5106         cancel_lru_locks $OSC
5107         stop_writeback
5108         sync
5109         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5110         BEFOREWRITES=$(count_ost_writes)
5111         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5112         AFTERWRITES=$(count_ost_writes)
5113         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5114                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5115         fi
5116         BEFOREWRITES=$(count_ost_writes)
5117         sync || error "sync: $?"
5118         AFTERWRITES=$(count_ost_writes)
5119         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5120                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5121         fi
5122         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5123         start_writeback
5124         return 0
5125 }
5126 run_test 42b "test destroy of file with cached dirty data ======"
5127
5128 # if these tests just want to test the effect of truncation,
5129 # they have to be very careful.  consider:
5130 # - the first open gets a {0,EOF}PR lock
5131 # - the first write conflicts and gets a {0, count-1}PW
5132 # - the rest of the writes are under {count,EOF}PW
5133 # - the open for truncate tries to match a {0,EOF}PR
5134 #   for the filesize and cancels the PWs.
5135 # any number of fixes (don't get {0,EOF} on open, match
5136 # composite locks, do smarter file size management) fix
5137 # this, but for now we want these tests to verify that
5138 # the cancellation with truncate intent works, so we
5139 # start the file with a full-file pw lock to match against
5140 # until the truncate.
5141 trunc_test() {
5142         test=$1
5143         file=$DIR/$test
5144         offset=$2
5145         cancel_lru_locks $OSC
5146         stop_writeback
5147         # prime the file with 0,EOF PW to match
5148         touch $file
5149         $TRUNCATE $file 0
5150         sync; sync
5151         # now the real test..
5152         dd if=/dev/zero of=$file bs=1024 count=100
5153         BEFOREWRITES=`count_ost_writes`
5154         $TRUNCATE $file $offset
5155         cancel_lru_locks $OSC
5156         AFTERWRITES=`count_ost_writes`
5157         start_writeback
5158 }
5159
5160 test_42c() {
5161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5162
5163         trunc_test 42c 1024
5164         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5165                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5166         rm $file
5167 }
5168 run_test 42c "test partial truncate of file with cached dirty data"
5169
5170 test_42d() {
5171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5172
5173         trunc_test 42d 0
5174         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5175                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5176         rm $file
5177 }
5178 run_test 42d "test complete truncate of file with cached dirty data"
5179
5180 test_42e() { # bug22074
5181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5182
5183         local TDIR=$DIR/${tdir}e
5184         local pages=16 # hardcoded 16 pages, don't change it.
5185         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5186         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5187         local max_dirty_mb
5188         local warmup_files
5189
5190         test_mkdir $DIR/${tdir}e
5191         $LFS setstripe -c 1 $TDIR
5192         createmany -o $TDIR/f $files
5193
5194         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5195
5196         # we assume that with $OSTCOUNT files, at least one of them will
5197         # be allocated on OST0.
5198         warmup_files=$((OSTCOUNT * max_dirty_mb))
5199         createmany -o $TDIR/w $warmup_files
5200
5201         # write a large amount of data into one file and sync, to get good
5202         # avail_grant number from OST.
5203         for ((i=0; i<$warmup_files; i++)); do
5204                 idx=$($LFS getstripe -i $TDIR/w$i)
5205                 [ $idx -ne 0 ] && continue
5206                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5207                 break
5208         done
5209         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5210         sync
5211         $LCTL get_param $proc_osc0/cur_dirty_bytes
5212         $LCTL get_param $proc_osc0/cur_grant_bytes
5213
5214         # create as much dirty pages as we can while not to trigger the actual
5215         # RPCs directly. but depends on the env, VFS may trigger flush during this
5216         # period, hopefully we are good.
5217         for ((i=0; i<$warmup_files; i++)); do
5218                 idx=$($LFS getstripe -i $TDIR/w$i)
5219                 [ $idx -ne 0 ] && continue
5220                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5221         done
5222         $LCTL get_param $proc_osc0/cur_dirty_bytes
5223         $LCTL get_param $proc_osc0/cur_grant_bytes
5224
5225         # perform the real test
5226         $LCTL set_param $proc_osc0/rpc_stats 0
5227         for ((;i<$files; i++)); do
5228                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5229                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5230         done
5231         sync
5232         $LCTL get_param $proc_osc0/rpc_stats
5233
5234         local percent=0
5235         local have_ppr=false
5236         $LCTL get_param $proc_osc0/rpc_stats |
5237                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5238                         # skip lines until we are at the RPC histogram data
5239                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5240                         $have_ppr || continue
5241
5242                         # we only want the percent stat for < 16 pages
5243                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5244
5245                         percent=$((percent + WPCT))
5246                         if [[ $percent -gt 15 ]]; then
5247                                 error "less than 16-pages write RPCs" \
5248                                       "$percent% > 15%"
5249                                 break
5250                         fi
5251                 done
5252         rm -rf $TDIR
5253 }
5254 run_test 42e "verify sub-RPC writes are not done synchronously"
5255
5256 test_43A() { # was test_43
5257         test_mkdir $DIR/$tdir
5258         cp -p /bin/ls $DIR/$tdir/$tfile
5259         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5260         pid=$!
5261         # give multiop a chance to open
5262         sleep 1
5263
5264         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5265         kill -USR1 $pid
5266         # Wait for multiop to exit
5267         wait $pid
5268 }
5269 run_test 43A "execution of file opened for write should return -ETXTBSY"
5270
5271 test_43a() {
5272         test_mkdir $DIR/$tdir
5273         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5274         $DIR/$tdir/sleep 60 &
5275         SLEEP_PID=$!
5276         # Make sure exec of $tdir/sleep wins race with truncate
5277         sleep 1
5278         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5279         kill $SLEEP_PID
5280 }
5281 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5282
5283 test_43b() {
5284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5285
5286         test_mkdir $DIR/$tdir
5287         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5288         $DIR/$tdir/sleep 60 &
5289         SLEEP_PID=$!
5290         # Make sure exec of $tdir/sleep wins race with truncate
5291         sleep 1
5292         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5293         kill $SLEEP_PID
5294 }
5295 run_test 43b "truncate of file being executed should return -ETXTBSY"
5296
5297 test_43c() {
5298         local testdir="$DIR/$tdir"
5299         test_mkdir $testdir
5300         cp $SHELL $testdir/
5301         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5302                 ( cd $testdir && md5sum -c )
5303 }
5304 run_test 43c "md5sum of copy into lustre"
5305
5306 test_44A() { # was test_44
5307         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5308
5309         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5310         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5311 }
5312 run_test 44A "zero length read from a sparse stripe"
5313
5314 test_44a() {
5315         local nstripe=$($LFS getstripe -c -d $DIR)
5316         [ -z "$nstripe" ] && skip "can't get stripe info"
5317         [[ $nstripe -gt $OSTCOUNT ]] &&
5318                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5319
5320         local stride=$($LFS getstripe -S -d $DIR)
5321         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5322                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5323         fi
5324
5325         OFFSETS="0 $((stride/2)) $((stride-1))"
5326         for offset in $OFFSETS; do
5327                 for i in $(seq 0 $((nstripe-1))); do
5328                         local GLOBALOFFSETS=""
5329                         # size in Bytes
5330                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5331                         local myfn=$DIR/d44a-$size
5332                         echo "--------writing $myfn at $size"
5333                         ll_sparseness_write $myfn $size ||
5334                                 error "ll_sparseness_write"
5335                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5336                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5337                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5338
5339                         for j in $(seq 0 $((nstripe-1))); do
5340                                 # size in Bytes
5341                                 size=$((((j + $nstripe )*$stride + $offset)))
5342                                 ll_sparseness_write $myfn $size ||
5343                                         error "ll_sparseness_write"
5344                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5345                         done
5346                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5347                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5348                         rm -f $myfn
5349                 done
5350         done
5351 }
5352 run_test 44a "test sparse pwrite ==============================="
5353
5354 dirty_osc_total() {
5355         tot=0
5356         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5357                 tot=$(($tot + $d))
5358         done
5359         echo $tot
5360 }
5361 do_dirty_record() {
5362         before=`dirty_osc_total`
5363         echo executing "\"$*\""
5364         eval $*
5365         after=`dirty_osc_total`
5366         echo before $before, after $after
5367 }
5368 test_45() {
5369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5370
5371         f="$DIR/f45"
5372         # Obtain grants from OST if it supports it
5373         echo blah > ${f}_grant
5374         stop_writeback
5375         sync
5376         do_dirty_record "echo blah > $f"
5377         [[ $before -eq $after ]] && error "write wasn't cached"
5378         do_dirty_record "> $f"
5379         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5380         do_dirty_record "echo blah > $f"
5381         [[ $before -eq $after ]] && error "write wasn't cached"
5382         do_dirty_record "sync"
5383         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5384         do_dirty_record "echo blah > $f"
5385         [[ $before -eq $after ]] && error "write wasn't cached"
5386         do_dirty_record "cancel_lru_locks osc"
5387         [[ $before -gt $after ]] ||
5388                 error "lock cancellation didn't lower dirty count"
5389         start_writeback
5390 }
5391 run_test 45 "osc io page accounting ============================"
5392
5393 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5394 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5395 # objects offset and an assert hit when an rpc was built with 1023's mapped
5396 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5397 test_46() {
5398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5399
5400         f="$DIR/f46"
5401         stop_writeback
5402         sync
5403         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5404         sync
5405         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5406         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5407         sync
5408         start_writeback
5409 }
5410 run_test 46 "dirtying a previously written page ================"
5411
5412 # test_47 is removed "Device nodes check" is moved to test_28
5413
5414 test_48a() { # bug 2399
5415         [ "$mds1_FSTYPE" = "zfs" ] &&
5416         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5417                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5418
5419         test_mkdir $DIR/$tdir
5420         cd $DIR/$tdir
5421         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5422         test_mkdir $DIR/$tdir
5423         touch foo || error "'touch foo' failed after recreating cwd"
5424         test_mkdir bar
5425         touch .foo || error "'touch .foo' failed after recreating cwd"
5426         test_mkdir .bar
5427         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5428         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5429         cd . || error "'cd .' failed after recreating cwd"
5430         mkdir . && error "'mkdir .' worked after recreating cwd"
5431         rmdir . && error "'rmdir .' worked after recreating cwd"
5432         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5433         cd .. || error "'cd ..' failed after recreating cwd"
5434 }
5435 run_test 48a "Access renamed working dir (should return errors)="
5436
5437 test_48b() { # bug 2399
5438         rm -rf $DIR/$tdir
5439         test_mkdir $DIR/$tdir
5440         cd $DIR/$tdir
5441         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5442         touch foo && error "'touch foo' worked after removing cwd"
5443         mkdir foo && error "'mkdir foo' worked after removing cwd"
5444         touch .foo && error "'touch .foo' worked after removing cwd"
5445         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5446         ls . > /dev/null && error "'ls .' worked after removing cwd"
5447         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5448         mkdir . && error "'mkdir .' worked after removing cwd"
5449         rmdir . && error "'rmdir .' worked after removing cwd"
5450         ln -s . foo && error "'ln -s .' worked after removing cwd"
5451         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5452 }
5453 run_test 48b "Access removed working dir (should return errors)="
5454
5455 test_48c() { # bug 2350
5456         #lctl set_param debug=-1
5457         #set -vx
5458         rm -rf $DIR/$tdir
5459         test_mkdir -p $DIR/$tdir/dir
5460         cd $DIR/$tdir/dir
5461         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5462         $TRACE touch foo && error "touch foo worked after removing cwd"
5463         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5464         touch .foo && error "touch .foo worked after removing cwd"
5465         mkdir .foo && error "mkdir .foo worked after removing cwd"
5466         $TRACE ls . && error "'ls .' worked after removing cwd"
5467         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5468         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5469         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5470         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5471         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5472 }
5473 run_test 48c "Access removed working subdir (should return errors)"
5474
5475 test_48d() { # bug 2350
5476         #lctl set_param debug=-1
5477         #set -vx
5478         rm -rf $DIR/$tdir
5479         test_mkdir -p $DIR/$tdir/dir
5480         cd $DIR/$tdir/dir
5481         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5482         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5483         $TRACE touch foo && error "'touch foo' worked after removing parent"
5484         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5485         touch .foo && error "'touch .foo' worked after removing parent"
5486         mkdir .foo && error "mkdir .foo worked after removing parent"
5487         $TRACE ls . && error "'ls .' worked after removing parent"
5488         $TRACE ls .. && error "'ls ..' worked after removing parent"
5489         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5490         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5491         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5492         true
5493 }
5494 run_test 48d "Access removed parent subdir (should return errors)"
5495
5496 test_48e() { # bug 4134
5497         #lctl set_param debug=-1
5498         #set -vx
5499         rm -rf $DIR/$tdir
5500         test_mkdir -p $DIR/$tdir/dir
5501         cd $DIR/$tdir/dir
5502         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5503         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5504         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5505         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5506         # On a buggy kernel addition of "touch foo" after cd .. will
5507         # produce kernel oops in lookup_hash_it
5508         touch ../foo && error "'cd ..' worked after recreate parent"
5509         cd $DIR
5510         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5511 }
5512 run_test 48e "Access to recreated parent subdir (should return errors)"
5513
5514 test_48f() {
5515         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5516                 skip "need MDS >= 2.13.55"
5517         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5518         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5519                 skip "needs different host for mdt1 mdt2"
5520         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5521
5522         $LFS mkdir -i0 $DIR/$tdir
5523         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5524
5525         for d in sub1 sub2 sub3; do
5526                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5527                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5528                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5529         done
5530
5531         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5532 }
5533 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5534
5535 test_49() { # LU-1030
5536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5537         remote_ost_nodsh && skip "remote OST with nodsh"
5538
5539         # get ost1 size - $FSNAME-OST0000
5540         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5541                 awk '{ print $4 }')
5542         # write 800M at maximum
5543         [[ $ost1_size -lt 2 ]] && ost1_size=2
5544         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5545
5546         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5547         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5548         local dd_pid=$!
5549
5550         # change max_pages_per_rpc while writing the file
5551         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5552         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5553         # loop until dd process exits
5554         while ps ax -opid | grep -wq $dd_pid; do
5555                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5556                 sleep $((RANDOM % 5 + 1))
5557         done
5558         # restore original max_pages_per_rpc
5559         $LCTL set_param $osc1_mppc=$orig_mppc
5560         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5561 }
5562 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5563
5564 test_50() {
5565         # bug 1485
5566         test_mkdir $DIR/$tdir
5567         cd $DIR/$tdir
5568         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5569 }
5570 run_test 50 "special situations: /proc symlinks  ==============="
5571
5572 test_51a() {    # was test_51
5573         # bug 1516 - create an empty entry right after ".." then split dir
5574         test_mkdir -c1 $DIR/$tdir
5575         touch $DIR/$tdir/foo
5576         $MCREATE $DIR/$tdir/bar
5577         rm $DIR/$tdir/foo
5578         createmany -m $DIR/$tdir/longfile 201
5579         FNUM=202
5580         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5581                 $MCREATE $DIR/$tdir/longfile$FNUM
5582                 FNUM=$(($FNUM + 1))
5583                 echo -n "+"
5584         done
5585         echo
5586         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5587 }
5588 run_test 51a "special situations: split htree with empty entry =="
5589
5590 cleanup_print_lfs_df () {
5591         trap 0
5592         $LFS df
5593         $LFS df -i
5594 }
5595
5596 test_51b() {
5597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5598
5599         local dir=$DIR/$tdir
5600         local nrdirs=$((65536 + 100))
5601
5602         # cleanup the directory
5603         rm -fr $dir
5604
5605         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5606
5607         $LFS df
5608         $LFS df -i
5609         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5610         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5611         [[ $numfree -lt $nrdirs ]] &&
5612                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5613
5614         # need to check free space for the directories as well
5615         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5616         numfree=$(( blkfree / $(fs_inode_ksize) ))
5617         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5618
5619         trap cleanup_print_lfs_df EXIT
5620
5621         # create files
5622         createmany -d $dir/d $nrdirs || {
5623                 unlinkmany $dir/d $nrdirs
5624                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5625         }
5626
5627         # really created :
5628         nrdirs=$(ls -U $dir | wc -l)
5629
5630         # unlink all but 100 subdirectories, then check it still works
5631         local left=100
5632         local delete=$((nrdirs - left))
5633
5634         $LFS df
5635         $LFS df -i
5636
5637         # for ldiskfs the nlink count should be 1, but this is OSD specific
5638         # and so this is listed for informational purposes only
5639         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5640         unlinkmany -d $dir/d $delete ||
5641                 error "unlink of first $delete subdirs failed"
5642
5643         echo "nlink between: $(stat -c %h $dir)"
5644         local found=$(ls -U $dir | wc -l)
5645         [ $found -ne $left ] &&
5646                 error "can't find subdirs: found only $found, expected $left"
5647
5648         unlinkmany -d $dir/d $delete $left ||
5649                 error "unlink of second $left subdirs failed"
5650         # regardless of whether the backing filesystem tracks nlink accurately
5651         # or not, the nlink count shouldn't be more than "." and ".." here
5652         local after=$(stat -c %h $dir)
5653         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5654                 echo "nlink after: $after"
5655
5656         cleanup_print_lfs_df
5657 }
5658 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5659
5660 test_51d() {
5661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5662         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5663
5664         test_mkdir $DIR/$tdir
5665         createmany -o $DIR/$tdir/t- 1000
5666         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5667         for N in $(seq 0 $((OSTCOUNT - 1))); do
5668                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5669                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5670                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5671                         '($1 == '$N') { objs += 1 } \
5672                         END { printf("%0.0f", objs) }')
5673                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5674         done
5675         unlinkmany $DIR/$tdir/t- 1000
5676
5677         NLAST=0
5678         for N in $(seq 1 $((OSTCOUNT - 1))); do
5679                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5680                         error "OST $N has less objects vs OST $NLAST" \
5681                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5682                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5683                         error "OST $N has less objects vs OST $NLAST" \
5684                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5685
5686                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5687                         error "OST $N has less #0 objects vs OST $NLAST" \
5688                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5689                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5690                         error "OST $N has less #0 objects vs OST $NLAST" \
5691                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5692                 NLAST=$N
5693         done
5694         rm -f $TMP/$tfile
5695 }
5696 run_test 51d "check object distribution"
5697
5698 test_51e() {
5699         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5700                 skip_env "ldiskfs only test"
5701         fi
5702
5703         test_mkdir -c1 $DIR/$tdir
5704         test_mkdir -c1 $DIR/$tdir/d0
5705
5706         touch $DIR/$tdir/d0/foo
5707         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5708                 error "file exceed 65000 nlink limit!"
5709         unlinkmany $DIR/$tdir/d0/f- 65001
5710         return 0
5711 }
5712 run_test 51e "check file nlink limit"
5713
5714 test_51f() {
5715         test_mkdir $DIR/$tdir
5716
5717         local max=100000
5718         local ulimit_old=$(ulimit -n)
5719         local spare=20 # number of spare fd's for scripts/libraries, etc.
5720         local mdt=$($LFS getstripe -m $DIR/$tdir)
5721         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5722
5723         echo "MDT$mdt numfree=$numfree, max=$max"
5724         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5725         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5726                 while ! ulimit -n $((numfree + spare)); do
5727                         numfree=$((numfree * 3 / 4))
5728                 done
5729                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5730         else
5731                 echo "left ulimit at $ulimit_old"
5732         fi
5733
5734         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5735                 unlinkmany $DIR/$tdir/f $numfree
5736                 error "create+open $numfree files in $DIR/$tdir failed"
5737         }
5738         ulimit -n $ulimit_old
5739
5740         # if createmany exits at 120s there will be fewer than $numfree files
5741         unlinkmany $DIR/$tdir/f $numfree || true
5742 }
5743 run_test 51f "check many open files limit"
5744
5745 test_52a() {
5746         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5747         test_mkdir $DIR/$tdir
5748         touch $DIR/$tdir/foo
5749         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5750         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5751         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5752         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5753         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5754                                         error "link worked"
5755         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5756         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5757         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5758                                                      error "lsattr"
5759         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5760         cp -r $DIR/$tdir $TMP/
5761         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5762 }
5763 run_test 52a "append-only flag test (should return errors)"
5764
5765 test_52b() {
5766         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5767         test_mkdir $DIR/$tdir
5768         touch $DIR/$tdir/foo
5769         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5770         cat test > $DIR/$tdir/foo && error "cat test worked"
5771         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5772         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5773         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5774                                         error "link worked"
5775         echo foo >> $DIR/$tdir/foo && error "echo worked"
5776         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5777         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5778         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5779         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5780                                                         error "lsattr"
5781         chattr -i $DIR/$tdir/foo || error "chattr failed"
5782
5783         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5784 }
5785 run_test 52b "immutable flag test (should return errors) ======="
5786
5787 test_53() {
5788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5789         remote_mds_nodsh && skip "remote MDS with nodsh"
5790         remote_ost_nodsh && skip "remote OST with nodsh"
5791
5792         local param
5793         local param_seq
5794         local ostname
5795         local mds_last
5796         local mds_last_seq
5797         local ost_last
5798         local ost_last_seq
5799         local ost_last_id
5800         local ostnum
5801         local node
5802         local found=false
5803         local support_last_seq=true
5804
5805         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5806                 support_last_seq=false
5807
5808         # only test MDT0000
5809         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5810         local value
5811         for value in $(do_facet $SINGLEMDS \
5812                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5813                 param=$(echo ${value[0]} | cut -d "=" -f1)
5814                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5815
5816                 if $support_last_seq; then
5817                         param_seq=$(echo $param |
5818                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5819                         mds_last_seq=$(do_facet $SINGLEMDS \
5820                                        $LCTL get_param -n $param_seq)
5821                 fi
5822                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5823
5824                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5825                 node=$(facet_active_host ost$((ostnum+1)))
5826                 param="obdfilter.$ostname.last_id"
5827                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5828                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5829                         ost_last_id=$ost_last
5830
5831                         if $support_last_seq; then
5832                                 ost_last_id=$(echo $ost_last |
5833                                               awk -F':' '{print $2}' |
5834                                               sed -e "s/^0x//g")
5835                                 ost_last_seq=$(echo $ost_last |
5836                                                awk -F':' '{print $1}')
5837                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5838                         fi
5839
5840                         if [[ $ost_last_id != $mds_last ]]; then
5841                                 error "$ost_last_id != $mds_last"
5842                         else
5843                                 found=true
5844                                 break
5845                         fi
5846                 done
5847         done
5848         $found || error "can not match last_seq/last_id for $mdtosc"
5849         return 0
5850 }
5851 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5852
5853 test_54a() {
5854         perl -MSocket -e ';' || skip "no Socket perl module installed"
5855
5856         $SOCKETSERVER $DIR/socket ||
5857                 error "$SOCKETSERVER $DIR/socket failed: $?"
5858         $SOCKETCLIENT $DIR/socket ||
5859                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5860         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5861 }
5862 run_test 54a "unix domain socket test =========================="
5863
5864 test_54b() {
5865         f="$DIR/f54b"
5866         mknod $f c 1 3
5867         chmod 0666 $f
5868         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5869 }
5870 run_test 54b "char device works in lustre ======================"
5871
5872 find_loop_dev() {
5873         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5874         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5875         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5876
5877         for i in $(seq 3 7); do
5878                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5879                 LOOPDEV=$LOOPBASE$i
5880                 LOOPNUM=$i
5881                 break
5882         done
5883 }
5884
5885 cleanup_54c() {
5886         local rc=0
5887         loopdev="$DIR/loop54c"
5888
5889         trap 0
5890         $UMOUNT $DIR/$tdir || rc=$?
5891         losetup -d $loopdev || true
5892         losetup -d $LOOPDEV || true
5893         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5894         return $rc
5895 }
5896
5897 test_54c() {
5898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5899
5900         loopdev="$DIR/loop54c"
5901
5902         find_loop_dev
5903         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5904         trap cleanup_54c EXIT
5905         mknod $loopdev b 7 $LOOPNUM
5906         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5907         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5908         losetup $loopdev $DIR/$tfile ||
5909                 error "can't set up $loopdev for $DIR/$tfile"
5910         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5911         test_mkdir $DIR/$tdir
5912         mount -t ext2 $loopdev $DIR/$tdir ||
5913                 error "error mounting $loopdev on $DIR/$tdir"
5914         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5915                 error "dd write"
5916         df $DIR/$tdir
5917         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5918                 error "dd read"
5919         cleanup_54c
5920 }
5921 run_test 54c "block device works in lustre ====================="
5922
5923 test_54d() {
5924         f="$DIR/f54d"
5925         string="aaaaaa"
5926         mknod $f p
5927         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5928 }
5929 run_test 54d "fifo device works in lustre ======================"
5930
5931 test_54e() {
5932         f="$DIR/f54e"
5933         string="aaaaaa"
5934         cp -aL /dev/console $f
5935         echo $string > $f || error "echo $string to $f failed"
5936 }
5937 run_test 54e "console/tty device works in lustre ======================"
5938
5939 test_56a() {
5940         local numfiles=3
5941         local numdirs=2
5942         local dir=$DIR/$tdir
5943
5944         rm -rf $dir
5945         test_mkdir -p $dir/dir
5946         for i in $(seq $numfiles); do
5947                 touch $dir/file$i
5948                 touch $dir/dir/file$i
5949         done
5950
5951         local numcomp=$($LFS getstripe --component-count $dir)
5952
5953         [[ $numcomp == 0 ]] && numcomp=1
5954
5955         # test lfs getstripe with --recursive
5956         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5957
5958         [[ $filenum -eq $((numfiles * 2)) ]] ||
5959                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5960         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5961         [[ $filenum -eq $numfiles ]] ||
5962                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5963         echo "$LFS getstripe showed obdidx or l_ost_idx"
5964
5965         # test lfs getstripe with file instead of dir
5966         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5967         [[ $filenum -eq 1 ]] ||
5968                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5969         echo "$LFS getstripe file1 passed"
5970
5971         #test lfs getstripe with --verbose
5972         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5973         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5974                 error "$LFS getstripe --verbose $dir: "\
5975                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5976         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5977                 error "$LFS getstripe $dir: showed lmm_magic"
5978
5979         #test lfs getstripe with -v prints lmm_fid
5980         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5981         local countfids=$((numdirs + numfiles * numcomp))
5982         [[ $filenum -eq $countfids ]] ||
5983                 error "$LFS getstripe -v $dir: "\
5984                       "got $filenum want $countfids lmm_fid"
5985         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5986                 error "$LFS getstripe $dir: showed lmm_fid by default"
5987         echo "$LFS getstripe --verbose passed"
5988
5989         #check for FID information
5990         local fid1=$($LFS getstripe --fid $dir/file1)
5991         local fid2=$($LFS getstripe --verbose $dir/file1 |
5992                      awk '/lmm_fid: / { print $2; exit; }')
5993         local fid3=$($LFS path2fid $dir/file1)
5994
5995         [ "$fid1" != "$fid2" ] &&
5996                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5997         [ "$fid1" != "$fid3" ] &&
5998                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5999         echo "$LFS getstripe --fid passed"
6000
6001         #test lfs getstripe with --obd
6002         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6003                 error "$LFS getstripe --obd wrong_uuid: should return error"
6004
6005         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6006
6007         local ostidx=1
6008         local obduuid=$(ostuuid_from_index $ostidx)
6009         local found=$($LFS getstripe -r --obd $obduuid $dir |
6010                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6011
6012         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6013         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6014                 ((filenum--))
6015         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6016                 ((filenum--))
6017
6018         [[ $found -eq $filenum ]] ||
6019                 error "$LFS getstripe --obd: found $found expect $filenum"
6020         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6021                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6022                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6023                 error "$LFS getstripe --obd: should not show file on other obd"
6024         echo "$LFS getstripe --obd passed"
6025 }
6026 run_test 56a "check $LFS getstripe"
6027
6028 test_56b() {
6029         local dir=$DIR/$tdir
6030         local numdirs=3
6031
6032         test_mkdir $dir
6033         for i in $(seq $numdirs); do
6034                 test_mkdir $dir/dir$i
6035         done
6036
6037         # test lfs getdirstripe default mode is non-recursion, which is
6038         # different from lfs getstripe
6039         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6040
6041         [[ $dircnt -eq 1 ]] ||
6042                 error "$LFS getdirstripe: found $dircnt, not 1"
6043         dircnt=$($LFS getdirstripe --recursive $dir |
6044                 grep -c lmv_stripe_count)
6045         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6046                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6047 }
6048 run_test 56b "check $LFS getdirstripe"
6049
6050 test_56c() {
6051         remote_ost_nodsh && skip "remote OST with nodsh"
6052
6053         local ost_idx=0
6054         local ost_name=$(ostname_from_index $ost_idx)
6055         local old_status=$(ost_dev_status $ost_idx)
6056         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6057
6058         [[ -z "$old_status" ]] ||
6059                 skip_env "OST $ost_name is in $old_status status"
6060
6061         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6062         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6063                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6064         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6065                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6066                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6067         fi
6068
6069         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6070                 error "$LFS df -v showing inactive devices"
6071         sleep_maxage
6072
6073         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6074
6075         [[ "$new_status" =~ "D" ]] ||
6076                 error "$ost_name status is '$new_status', missing 'D'"
6077         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6078                 [[ "$new_status" =~ "N" ]] ||
6079                         error "$ost_name status is '$new_status', missing 'N'"
6080         fi
6081         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6082                 [[ "$new_status" =~ "f" ]] ||
6083                         error "$ost_name status is '$new_status', missing 'f'"
6084         fi
6085
6086         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6087         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6088                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6089         [[ -z "$p" ]] && restore_lustre_params < $p || true
6090         sleep_maxage
6091
6092         new_status=$(ost_dev_status $ost_idx)
6093         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6094                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6095         # can't check 'f' as devices may actually be on flash
6096 }
6097 run_test 56c "check 'lfs df' showing device status"
6098
6099 test_56d() {
6100         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6101         local osts=$($LFS df -v $MOUNT | grep -c OST)
6102
6103         $LFS df $MOUNT
6104
6105         (( mdts == MDSCOUNT )) ||
6106                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6107         (( osts == OSTCOUNT )) ||
6108                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6109 }
6110 run_test 56d "'lfs df -v' prints only configured devices"
6111
6112 NUMFILES=3
6113 NUMDIRS=3
6114 setup_56() {
6115         local local_tdir="$1"
6116         local local_numfiles="$2"
6117         local local_numdirs="$3"
6118         local dir_params="$4"
6119         local dir_stripe_params="$5"
6120
6121         if [ ! -d "$local_tdir" ] ; then
6122                 test_mkdir -p $dir_stripe_params $local_tdir
6123                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6124                 for i in $(seq $local_numfiles) ; do
6125                         touch $local_tdir/file$i
6126                 done
6127                 for i in $(seq $local_numdirs) ; do
6128                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6129                         for j in $(seq $local_numfiles) ; do
6130                                 touch $local_tdir/dir$i/file$j
6131                         done
6132                 done
6133         fi
6134 }
6135
6136 setup_56_special() {
6137         local local_tdir=$1
6138         local local_numfiles=$2
6139         local local_numdirs=$3
6140
6141         setup_56 $local_tdir $local_numfiles $local_numdirs
6142
6143         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6144                 for i in $(seq $local_numfiles) ; do
6145                         mknod $local_tdir/loop${i}b b 7 $i
6146                         mknod $local_tdir/null${i}c c 1 3
6147                         ln -s $local_tdir/file1 $local_tdir/link${i}
6148                 done
6149                 for i in $(seq $local_numdirs) ; do
6150                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6151                         mknod $local_tdir/dir$i/null${i}c c 1 3
6152                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6153                 done
6154         fi
6155 }
6156
6157 test_56g() {
6158         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6159         local expected=$(($NUMDIRS + 2))
6160
6161         setup_56 $dir $NUMFILES $NUMDIRS
6162
6163         # test lfs find with -name
6164         for i in $(seq $NUMFILES) ; do
6165                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6166
6167                 [ $nums -eq $expected ] ||
6168                         error "lfs find -name '*$i' $dir wrong: "\
6169                               "found $nums, expected $expected"
6170         done
6171 }
6172 run_test 56g "check lfs find -name"
6173
6174 test_56h() {
6175         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6176         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6177
6178         setup_56 $dir $NUMFILES $NUMDIRS
6179
6180         # test lfs find with ! -name
6181         for i in $(seq $NUMFILES) ; do
6182                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6183
6184                 [ $nums -eq $expected ] ||
6185                         error "lfs find ! -name '*$i' $dir wrong: "\
6186                               "found $nums, expected $expected"
6187         done
6188 }
6189 run_test 56h "check lfs find ! -name"
6190
6191 test_56i() {
6192         local dir=$DIR/$tdir
6193
6194         test_mkdir $dir
6195
6196         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6197         local out=$($cmd)
6198
6199         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6200 }
6201 run_test 56i "check 'lfs find -ost UUID' skips directories"
6202
6203 test_56j() {
6204         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6205
6206         setup_56_special $dir $NUMFILES $NUMDIRS
6207
6208         local expected=$((NUMDIRS + 1))
6209         local cmd="$LFS find -type d $dir"
6210         local nums=$($cmd | wc -l)
6211
6212         [ $nums -eq $expected ] ||
6213                 error "'$cmd' wrong: found $nums, expected $expected"
6214 }
6215 run_test 56j "check lfs find -type d"
6216
6217 test_56k() {
6218         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6219
6220         setup_56_special $dir $NUMFILES $NUMDIRS
6221
6222         local expected=$(((NUMDIRS + 1) * NUMFILES))
6223         local cmd="$LFS find -type f $dir"
6224         local nums=$($cmd | wc -l)
6225
6226         [ $nums -eq $expected ] ||
6227                 error "'$cmd' wrong: found $nums, expected $expected"
6228 }
6229 run_test 56k "check lfs find -type f"
6230
6231 test_56l() {
6232         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6233
6234         setup_56_special $dir $NUMFILES $NUMDIRS
6235
6236         local expected=$((NUMDIRS + NUMFILES))
6237         local cmd="$LFS find -type b $dir"
6238         local nums=$($cmd | wc -l)
6239
6240         [ $nums -eq $expected ] ||
6241                 error "'$cmd' wrong: found $nums, expected $expected"
6242 }
6243 run_test 56l "check lfs find -type b"
6244
6245 test_56m() {
6246         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6247
6248         setup_56_special $dir $NUMFILES $NUMDIRS
6249
6250         local expected=$((NUMDIRS + NUMFILES))
6251         local cmd="$LFS find -type c $dir"
6252         local nums=$($cmd | wc -l)
6253         [ $nums -eq $expected ] ||
6254                 error "'$cmd' wrong: found $nums, expected $expected"
6255 }
6256 run_test 56m "check lfs find -type c"
6257
6258 test_56n() {
6259         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6260         setup_56_special $dir $NUMFILES $NUMDIRS
6261
6262         local expected=$((NUMDIRS + NUMFILES))
6263         local cmd="$LFS find -type l $dir"
6264         local nums=$($cmd | wc -l)
6265
6266         [ $nums -eq $expected ] ||
6267                 error "'$cmd' wrong: found $nums, expected $expected"
6268 }
6269 run_test 56n "check lfs find -type l"
6270
6271 test_56o() {
6272         local dir=$DIR/$tdir
6273
6274         setup_56 $dir $NUMFILES $NUMDIRS
6275         utime $dir/file1 > /dev/null || error "utime (1)"
6276         utime $dir/file2 > /dev/null || error "utime (2)"
6277         utime $dir/dir1 > /dev/null || error "utime (3)"
6278         utime $dir/dir2 > /dev/null || error "utime (4)"
6279         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6280         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6281
6282         local expected=4
6283         local nums=$($LFS find -mtime +0 $dir | wc -l)
6284
6285         [ $nums -eq $expected ] ||
6286                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6287
6288         expected=12
6289         cmd="$LFS find -mtime 0 $dir"
6290         nums=$($cmd | wc -l)
6291         [ $nums -eq $expected ] ||
6292                 error "'$cmd' wrong: found $nums, expected $expected"
6293 }
6294 run_test 56o "check lfs find -mtime for old files"
6295
6296 test_56ob() {
6297         local dir=$DIR/$tdir
6298         local expected=1
6299         local count=0
6300
6301         # just to make sure there is something that won't be found
6302         test_mkdir $dir
6303         touch $dir/$tfile.now
6304
6305         for age in year week day hour min; do
6306                 count=$((count + 1))
6307
6308                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6309                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6310                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6311
6312                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6313                 local nums=$($cmd | wc -l)
6314                 [ $nums -eq $expected ] ||
6315                         error "'$cmd' wrong: found $nums, expected $expected"
6316
6317                 cmd="$LFS find $dir -atime $count${age:0:1}"
6318                 nums=$($cmd | wc -l)
6319                 [ $nums -eq $expected ] ||
6320                         error "'$cmd' wrong: found $nums, expected $expected"
6321         done
6322
6323         sleep 2
6324         cmd="$LFS find $dir -ctime +1s -type f"
6325         nums=$($cmd | wc -l)
6326         (( $nums == $count * 2 + 1)) ||
6327                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6328 }
6329 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6330
6331 test_newerXY_base() {
6332         local x=$1
6333         local y=$2
6334         local dir=$DIR/$tdir
6335         local ref
6336         local negref
6337
6338         if [ $y == "t" ]; then
6339                 if [ $x == "b" ]; then
6340                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6341                 else
6342                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6343                 fi
6344         else
6345                 ref=$DIR/$tfile.newer.$x$y
6346                 touch $ref || error "touch $ref failed"
6347         fi
6348
6349         echo "before = $ref"
6350         sleep 2
6351         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6352         sleep 2
6353         if [ $y == "t" ]; then
6354                 if [ $x == "b" ]; then
6355                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6356                 else
6357                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6358                 fi
6359         else
6360                 negref=$DIR/$tfile.negnewer.$x$y
6361                 touch $negref || error "touch $negref failed"
6362         fi
6363
6364         echo "after = $negref"
6365         local cmd="$LFS find $dir -newer$x$y $ref"
6366         local nums=$(eval $cmd | wc -l)
6367         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6368
6369         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6370                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6371
6372         cmd="$LFS find $dir ! -newer$x$y $negref"
6373         nums=$(eval $cmd | wc -l)
6374         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6375                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6376
6377         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6378         nums=$(eval $cmd | wc -l)
6379         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6380                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6381
6382         rm -rf $DIR/*
6383 }
6384
6385 test_56oc() {
6386         test_newerXY_base "a" "a"
6387         test_newerXY_base "a" "m"
6388         test_newerXY_base "a" "c"
6389         test_newerXY_base "m" "a"
6390         test_newerXY_base "m" "m"
6391         test_newerXY_base "m" "c"
6392         test_newerXY_base "c" "a"
6393         test_newerXY_base "c" "m"
6394         test_newerXY_base "c" "c"
6395
6396         [[ -n "$sles_version" ]] &&
6397                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6398
6399         test_newerXY_base "a" "t"
6400         test_newerXY_base "m" "t"
6401         test_newerXY_base "c" "t"
6402
6403         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6404            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6405                 ! btime_supported && echo "btime unsupported" && return 0
6406
6407         test_newerXY_base "b" "b"
6408         test_newerXY_base "b" "t"
6409 }
6410 run_test 56oc "check lfs find -newerXY work"
6411
6412 btime_supported() {
6413         local dir=$DIR/$tdir
6414         local rc
6415
6416         mkdir -p $dir
6417         touch $dir/$tfile
6418         $LFS find $dir -btime -1d -type f
6419         rc=$?
6420         rm -rf $dir
6421         return $rc
6422 }
6423
6424 test_56od() {
6425         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6426                 ! btime_supported && skip "btime unsupported on MDS"
6427
6428         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6429                 ! btime_supported && skip "btime unsupported on clients"
6430
6431         local dir=$DIR/$tdir
6432         local ref=$DIR/$tfile.ref
6433         local negref=$DIR/$tfile.negref
6434
6435         mkdir $dir || error "mkdir $dir failed"
6436         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6437         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6438         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6439         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6440         touch $ref || error "touch $ref failed"
6441         # sleep 3 seconds at least
6442         sleep 3
6443
6444         local before=$(do_facet mds1 date +%s)
6445         local skew=$(($(date +%s) - before + 1))
6446
6447         if (( skew < 0 && skew > -5 )); then
6448                 sleep $((0 - skew + 1))
6449                 skew=0
6450         fi
6451
6452         # Set the dir stripe params to limit files all on MDT0,
6453         # otherwise we need to calc the max clock skew between
6454         # the client and MDTs.
6455         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6456         sleep 2
6457         touch $negref || error "touch $negref failed"
6458
6459         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6460         local nums=$($cmd | wc -l)
6461         local expected=$(((NUMFILES + 1) * NUMDIRS))
6462
6463         [ $nums -eq $expected ] ||
6464                 error "'$cmd' wrong: found $nums, expected $expected"
6465
6466         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6467         nums=$($cmd | wc -l)
6468         expected=$((NUMFILES + 1))
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         [ $skew -lt 0 ] && return
6473
6474         local after=$(do_facet mds1 date +%s)
6475         local age=$((after - before + 1 + skew))
6476
6477         cmd="$LFS find $dir -btime -${age}s -type f"
6478         nums=$($cmd | wc -l)
6479         expected=$(((NUMFILES + 1) * NUMDIRS))
6480
6481         echo "Clock skew between client and server: $skew, age:$age"
6482         [ $nums -eq $expected ] ||
6483                 error "'$cmd' wrong: found $nums, expected $expected"
6484
6485         expected=$(($NUMDIRS + 1))
6486         cmd="$LFS find $dir -btime -${age}s -type d"
6487         nums=$($cmd | wc -l)
6488         [ $nums -eq $expected ] ||
6489                 error "'$cmd' wrong: found $nums, expected $expected"
6490         rm -f $ref $negref || error "Failed to remove $ref $negref"
6491 }
6492 run_test 56od "check lfs find -btime with units"
6493
6494 test_56p() {
6495         [ $RUNAS_ID -eq $UID ] &&
6496                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6497
6498         local dir=$DIR/$tdir
6499
6500         setup_56 $dir $NUMFILES $NUMDIRS
6501         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6502
6503         local expected=$NUMFILES
6504         local cmd="$LFS find -uid $RUNAS_ID $dir"
6505         local nums=$($cmd | wc -l)
6506
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509
6510         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6511         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6512         nums=$($cmd | wc -l)
6513         [ $nums -eq $expected ] ||
6514                 error "'$cmd' wrong: found $nums, expected $expected"
6515 }
6516 run_test 56p "check lfs find -uid and ! -uid"
6517
6518 test_56q() {
6519         [ $RUNAS_ID -eq $UID ] &&
6520                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6521
6522         local dir=$DIR/$tdir
6523
6524         setup_56 $dir $NUMFILES $NUMDIRS
6525         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6526
6527         local expected=$NUMFILES
6528         local cmd="$LFS find -gid $RUNAS_GID $dir"
6529         local nums=$($cmd | wc -l)
6530
6531         [ $nums -eq $expected ] ||
6532                 error "'$cmd' wrong: found $nums, expected $expected"
6533
6534         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6535         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6536         nums=$($cmd | wc -l)
6537         [ $nums -eq $expected ] ||
6538                 error "'$cmd' wrong: found $nums, expected $expected"
6539 }
6540 run_test 56q "check lfs find -gid and ! -gid"
6541
6542 test_56r() {
6543         local dir=$DIR/$tdir
6544
6545         setup_56 $dir $NUMFILES $NUMDIRS
6546
6547         local expected=12
6548         local cmd="$LFS find -size 0 -type f -lazy $dir"
6549         local nums=$($cmd | wc -l)
6550
6551         [ $nums -eq $expected ] ||
6552                 error "'$cmd' wrong: found $nums, expected $expected"
6553         cmd="$LFS find -size 0 -type f $dir"
6554         nums=$($cmd | wc -l)
6555         [ $nums -eq $expected ] ||
6556                 error "'$cmd' wrong: found $nums, expected $expected"
6557
6558         expected=0
6559         cmd="$LFS find ! -size 0 -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 0 -type f $dir"
6564         nums=$($cmd | wc -l)
6565         [ $nums -eq $expected ] ||
6566                 error "'$cmd' wrong: found $nums, expected $expected"
6567
6568         echo "test" > $dir/$tfile
6569         echo "test2" > $dir/$tfile.2 && sync
6570         expected=1
6571         cmd="$LFS find -size 5 -type f -lazy $dir"
6572         nums=$($cmd | wc -l)
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575         cmd="$LFS find -size 5 -type f $dir"
6576         nums=$($cmd | wc -l)
6577         [ $nums -eq $expected ] ||
6578                 error "'$cmd' wrong: found $nums, expected $expected"
6579
6580         expected=1
6581         cmd="$LFS find -size +5 -type f -lazy $dir"
6582         nums=$($cmd | wc -l)
6583         [ $nums -eq $expected ] ||
6584                 error "'$cmd' wrong: found $nums, expected $expected"
6585         cmd="$LFS find -size +5 -type f $dir"
6586         nums=$($cmd | wc -l)
6587         [ $nums -eq $expected ] ||
6588                 error "'$cmd' wrong: found $nums, expected $expected"
6589
6590         expected=2
6591         cmd="$LFS find -size +0 -type f -lazy $dir"
6592         nums=$($cmd | wc -l)
6593         [ $nums -eq $expected ] ||
6594                 error "'$cmd' wrong: found $nums, expected $expected"
6595         cmd="$LFS find -size +0 -type f $dir"
6596         nums=$($cmd | wc -l)
6597         [ $nums -eq $expected ] ||
6598                 error "'$cmd' wrong: found $nums, expected $expected"
6599
6600         expected=2
6601         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6602         nums=$($cmd | wc -l)
6603         [ $nums -eq $expected ] ||
6604                 error "'$cmd' wrong: found $nums, expected $expected"
6605         cmd="$LFS find ! -size -5 -type f $dir"
6606         nums=$($cmd | wc -l)
6607         [ $nums -eq $expected ] ||
6608                 error "'$cmd' wrong: found $nums, expected $expected"
6609
6610         expected=12
6611         cmd="$LFS find -size -5 -type f -lazy $dir"
6612         nums=$($cmd | wc -l)
6613         [ $nums -eq $expected ] ||
6614                 error "'$cmd' wrong: found $nums, expected $expected"
6615         cmd="$LFS find -size -5 -type f $dir"
6616         nums=$($cmd | wc -l)
6617         [ $nums -eq $expected ] ||
6618                 error "'$cmd' wrong: found $nums, expected $expected"
6619 }
6620 run_test 56r "check lfs find -size works"
6621
6622 test_56ra_sub() {
6623         local expected=$1
6624         local glimpses=$2
6625         local cmd="$3"
6626
6627         cancel_lru_locks $OSC
6628
6629         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6630         local nums=$($cmd | wc -l)
6631
6632         [ $nums -eq $expected ] ||
6633                 error "'$cmd' wrong: found $nums, expected $expected"
6634
6635         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6636
6637         if (( rpcs_before + glimpses != rpcs_after )); then
6638                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6639                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6640
6641                 if [[ $glimpses == 0 ]]; then
6642                         error "'$cmd' should not send glimpse RPCs to OST"
6643                 else
6644                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6645                 fi
6646         fi
6647 }
6648
6649 test_56ra() {
6650         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6651                 skip "MDS < 2.12.58 doesn't return LSOM data"
6652         local dir=$DIR/$tdir
6653         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6654
6655         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6656
6657         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6658         $LCTL set_param -n llite.*.statahead_agl=0
6659         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6660
6661         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6662         # open and close all files to ensure LSOM is updated
6663         cancel_lru_locks $OSC
6664         find $dir -type f | xargs cat > /dev/null
6665
6666         #   expect_found  glimpse_rpcs  command_to_run
6667         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6668         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6669         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6670         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6671
6672         echo "test" > $dir/$tfile
6673         echo "test2" > $dir/$tfile.2 && sync
6674         cancel_lru_locks $OSC
6675         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6676
6677         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6678         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6679         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6680         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6681
6682         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6683         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6684         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6685         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6686         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6687         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6688 }
6689 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6690
6691 test_56rb() {
6692         local dir=$DIR/$tdir
6693         local tmp=$TMP/$tfile.log
6694         local mdt_idx;
6695
6696         test_mkdir -p $dir || error "failed to mkdir $dir"
6697         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6698                 error "failed to setstripe $dir/$tfile"
6699         mdt_idx=$($LFS getdirstripe -i $dir)
6700         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6701
6702         stack_trap "rm -f $tmp" EXIT
6703         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6704         ! grep -q obd_uuid $tmp ||
6705                 error "failed to find --size +100K --ost 0 $dir"
6706         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6707         ! grep -q obd_uuid $tmp ||
6708                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6709 }
6710 run_test 56rb "check lfs find --size --ost/--mdt works"
6711
6712 test_56rc() {
6713         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6714         local dir=$DIR/$tdir
6715         local found
6716
6717         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6718         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6719         (( $MDSCOUNT > 2 )) &&
6720                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6721         mkdir $dir/$tdir-{1..10}
6722         touch $dir/$tfile-{1..10}
6723
6724         found=$($LFS find $dir --mdt-count 2 | wc -l)
6725         expect=11
6726         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6727
6728         found=$($LFS find $dir -T +1 | wc -l)
6729         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6730         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6731
6732         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6733         expect=11
6734         (( $found == $expect )) || error "found $found all_char, expect $expect"
6735
6736         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6737         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6738         (( $found == $expect )) || error "found $found all_char, expect $expect"
6739 }
6740 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6741
6742 test_56s() { # LU-611 #LU-9369
6743         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6744
6745         local dir=$DIR/$tdir
6746         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6747
6748         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6749         for i in $(seq $NUMDIRS); do
6750                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6751         done
6752
6753         local expected=$NUMDIRS
6754         local cmd="$LFS find -c $OSTCOUNT $dir"
6755         local nums=$($cmd | wc -l)
6756
6757         [ $nums -eq $expected ] || {
6758                 $LFS getstripe -R $dir
6759                 error "'$cmd' wrong: found $nums, expected $expected"
6760         }
6761
6762         expected=$((NUMDIRS + onestripe))
6763         cmd="$LFS find -stripe-count +0 -type f $dir"
6764         nums=$($cmd | wc -l)
6765         [ $nums -eq $expected ] || {
6766                 $LFS getstripe -R $dir
6767                 error "'$cmd' wrong: found $nums, expected $expected"
6768         }
6769
6770         expected=$onestripe
6771         cmd="$LFS find -stripe-count 1 -type f $dir"
6772         nums=$($cmd | wc -l)
6773         [ $nums -eq $expected ] || {
6774                 $LFS getstripe -R $dir
6775                 error "'$cmd' wrong: found $nums, expected $expected"
6776         }
6777
6778         cmd="$LFS find -stripe-count -2 -type f $dir"
6779         nums=$($cmd | wc -l)
6780         [ $nums -eq $expected ] || {
6781                 $LFS getstripe -R $dir
6782                 error "'$cmd' wrong: found $nums, expected $expected"
6783         }
6784
6785         expected=0
6786         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6787         nums=$($cmd | wc -l)
6788         [ $nums -eq $expected ] || {
6789                 $LFS getstripe -R $dir
6790                 error "'$cmd' wrong: found $nums, expected $expected"
6791         }
6792 }
6793 run_test 56s "check lfs find -stripe-count works"
6794
6795 test_56t() { # LU-611 #LU-9369
6796         local dir=$DIR/$tdir
6797
6798         setup_56 $dir 0 $NUMDIRS
6799         for i in $(seq $NUMDIRS); do
6800                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6801         done
6802
6803         local expected=$NUMDIRS
6804         local cmd="$LFS find -S 8M $dir"
6805         local nums=$($cmd | wc -l)
6806
6807         [ $nums -eq $expected ] || {
6808                 $LFS getstripe -R $dir
6809                 error "'$cmd' wrong: found $nums, expected $expected"
6810         }
6811         rm -rf $dir
6812
6813         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6814
6815         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6816
6817         expected=$(((NUMDIRS + 1) * NUMFILES))
6818         cmd="$LFS find -stripe-size 512k -type f $dir"
6819         nums=$($cmd | wc -l)
6820         [ $nums -eq $expected ] ||
6821                 error "'$cmd' wrong: found $nums, expected $expected"
6822
6823         cmd="$LFS find -stripe-size +320k -type f $dir"
6824         nums=$($cmd | wc -l)
6825         [ $nums -eq $expected ] ||
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827
6828         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6829         cmd="$LFS find -stripe-size +200k -type f $dir"
6830         nums=$($cmd | wc -l)
6831         [ $nums -eq $expected ] ||
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833
6834         cmd="$LFS find -stripe-size -640k -type f $dir"
6835         nums=$($cmd | wc -l)
6836         [ $nums -eq $expected ] ||
6837                 error "'$cmd' wrong: found $nums, expected $expected"
6838
6839         expected=4
6840         cmd="$LFS find -stripe-size 256k -type f $dir"
6841         nums=$($cmd | wc -l)
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844
6845         cmd="$LFS find -stripe-size -320k -type f $dir"
6846         nums=$($cmd | wc -l)
6847         [ $nums -eq $expected ] ||
6848                 error "'$cmd' wrong: found $nums, expected $expected"
6849
6850         expected=0
6851         cmd="$LFS find -stripe-size 1024k -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] ||
6854                 error "'$cmd' wrong: found $nums, expected $expected"
6855 }
6856 run_test 56t "check lfs find -stripe-size works"
6857
6858 test_56u() { # LU-611
6859         local dir=$DIR/$tdir
6860
6861         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6862
6863         if [[ $OSTCOUNT -gt 1 ]]; then
6864                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6865                 onestripe=4
6866         else
6867                 onestripe=0
6868         fi
6869
6870         local expected=$(((NUMDIRS + 1) * NUMFILES))
6871         local cmd="$LFS find -stripe-index 0 -type f $dir"
6872         local nums=$($cmd | wc -l)
6873
6874         [ $nums -eq $expected ] ||
6875                 error "'$cmd' wrong: found $nums, expected $expected"
6876
6877         expected=$onestripe
6878         cmd="$LFS find -stripe-index 1 -type f $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882
6883         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         expected=0
6889         # This should produce an error and not return any files
6890         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6891         nums=$($cmd 2>/dev/null | wc -l)
6892         [ $nums -eq $expected ] ||
6893                 error "'$cmd' wrong: found $nums, expected $expected"
6894
6895         if [[ $OSTCOUNT -gt 1 ]]; then
6896                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6897                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6898                 nums=$($cmd | wc -l)
6899                 [ $nums -eq $expected ] ||
6900                         error "'$cmd' wrong: found $nums, expected $expected"
6901         fi
6902 }
6903 run_test 56u "check lfs find -stripe-index works"
6904
6905 test_56v() {
6906         local mdt_idx=0
6907         local dir=$DIR/$tdir
6908
6909         setup_56 $dir $NUMFILES $NUMDIRS
6910
6911         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6912         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6913
6914         for file in $($LFS find -m $UUID $dir); do
6915                 file_midx=$($LFS getstripe -m $file)
6916                 [ $file_midx -eq $mdt_idx ] ||
6917                         error "lfs find -m $UUID != getstripe -m $file_midx"
6918         done
6919 }
6920 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6921
6922 test_56w() {
6923         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6925
6926         local dir=$DIR/$tdir
6927
6928         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6929
6930         local stripe_size=$($LFS getstripe -S -d $dir) ||
6931                 error "$LFS getstripe -S -d $dir failed"
6932         stripe_size=${stripe_size%% *}
6933
6934         local file_size=$((stripe_size * OSTCOUNT))
6935         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6936         local required_space=$((file_num * file_size))
6937         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6938                            head -n1)
6939         [[ $free_space -le $((required_space / 1024)) ]] &&
6940                 skip_env "need $required_space, have $free_space kbytes"
6941
6942         local dd_bs=65536
6943         local dd_count=$((file_size / dd_bs))
6944
6945         # write data into the files
6946         local i
6947         local j
6948         local file
6949
6950         for i in $(seq $NUMFILES); do
6951                 file=$dir/file$i
6952                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6953                         error "write data into $file failed"
6954         done
6955         for i in $(seq $NUMDIRS); do
6956                 for j in $(seq $NUMFILES); do
6957                         file=$dir/dir$i/file$j
6958                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6959                                 error "write data into $file failed"
6960                 done
6961         done
6962
6963         # $LFS_MIGRATE will fail if hard link migration is unsupported
6964         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6965                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6966                         error "creating links to $dir/dir1/file1 failed"
6967         fi
6968
6969         local expected=-1
6970
6971         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6972
6973         # lfs_migrate file
6974         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6975
6976         echo "$cmd"
6977         eval $cmd || error "$cmd failed"
6978
6979         check_stripe_count $dir/file1 $expected
6980
6981         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6982         then
6983                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6984                 # OST 1 if it is on OST 0. This file is small enough to
6985                 # be on only one stripe.
6986                 file=$dir/migr_1_ost
6987                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6988                         error "write data into $file failed"
6989                 local obdidx=$($LFS getstripe -i $file)
6990                 local oldmd5=$(md5sum $file)
6991                 local newobdidx=0
6992
6993                 [[ $obdidx -eq 0 ]] && newobdidx=1
6994                 cmd="$LFS migrate -i $newobdidx $file"
6995                 echo $cmd
6996                 eval $cmd || error "$cmd failed"
6997
6998                 local realobdix=$($LFS getstripe -i $file)
6999                 local newmd5=$(md5sum $file)
7000
7001                 [[ $newobdidx -ne $realobdix ]] &&
7002                         error "new OST is different (was=$obdidx, "\
7003                               "wanted=$newobdidx, got=$realobdix)"
7004                 [[ "$oldmd5" != "$newmd5" ]] &&
7005                         error "md5sum differ: $oldmd5, $newmd5"
7006         fi
7007
7008         # lfs_migrate dir
7009         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7010         echo "$cmd"
7011         eval $cmd || error "$cmd failed"
7012
7013         for j in $(seq $NUMFILES); do
7014                 check_stripe_count $dir/dir1/file$j $expected
7015         done
7016
7017         # lfs_migrate works with lfs find
7018         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7019              $LFS_MIGRATE -y -c $expected"
7020         echo "$cmd"
7021         eval $cmd || error "$cmd failed"
7022
7023         for i in $(seq 2 $NUMFILES); do
7024                 check_stripe_count $dir/file$i $expected
7025         done
7026         for i in $(seq 2 $NUMDIRS); do
7027                 for j in $(seq $NUMFILES); do
7028                 check_stripe_count $dir/dir$i/file$j $expected
7029                 done
7030         done
7031 }
7032 run_test 56w "check lfs_migrate -c stripe_count works"
7033
7034 test_56wb() {
7035         local file1=$DIR/$tdir/file1
7036         local create_pool=false
7037         local initial_pool=$($LFS getstripe -p $DIR)
7038         local pool_list=()
7039         local pool=""
7040
7041         echo -n "Creating test dir..."
7042         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7043         echo "done."
7044
7045         echo -n "Creating test file..."
7046         touch $file1 || error "cannot create file"
7047         echo "done."
7048
7049         echo -n "Detecting existing pools..."
7050         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7051
7052         if [ ${#pool_list[@]} -gt 0 ]; then
7053                 echo "${pool_list[@]}"
7054                 for thispool in "${pool_list[@]}"; do
7055                         if [[ -z "$initial_pool" ||
7056                               "$initial_pool" != "$thispool" ]]; then
7057                                 pool="$thispool"
7058                                 echo "Using existing pool '$pool'"
7059                                 break
7060                         fi
7061                 done
7062         else
7063                 echo "none detected."
7064         fi
7065         if [ -z "$pool" ]; then
7066                 pool=${POOL:-testpool}
7067                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7068                 echo -n "Creating pool '$pool'..."
7069                 create_pool=true
7070                 pool_add $pool &> /dev/null ||
7071                         error "pool_add failed"
7072                 echo "done."
7073
7074                 echo -n "Adding target to pool..."
7075                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7076                         error "pool_add_targets failed"
7077                 echo "done."
7078         fi
7079
7080         echo -n "Setting pool using -p option..."
7081         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7082                 error "migrate failed rc = $?"
7083         echo "done."
7084
7085         echo -n "Verifying test file is in pool after migrating..."
7086         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7087                 error "file was not migrated to pool $pool"
7088         echo "done."
7089
7090         echo -n "Removing test file from pool '$pool'..."
7091         # "lfs migrate $file" won't remove the file from the pool
7092         # until some striping information is changed.
7093         $LFS migrate -c 1 $file1 &> /dev/null ||
7094                 error "cannot remove from pool"
7095         [ "$($LFS getstripe -p $file1)" ] &&
7096                 error "pool still set"
7097         echo "done."
7098
7099         echo -n "Setting pool using --pool option..."
7100         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7101                 error "migrate failed rc = $?"
7102         echo "done."
7103
7104         # Clean up
7105         rm -f $file1
7106         if $create_pool; then
7107                 destroy_test_pools 2> /dev/null ||
7108                         error "destroy test pools failed"
7109         fi
7110 }
7111 run_test 56wb "check lfs_migrate pool support"
7112
7113 test_56wc() {
7114         local file1="$DIR/$tdir/file1"
7115         local parent_ssize
7116         local parent_scount
7117         local cur_ssize
7118         local cur_scount
7119         local orig_ssize
7120
7121         echo -n "Creating test dir..."
7122         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7123         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7124                 error "cannot set stripe by '-S 1M -c 1'"
7125         echo "done"
7126
7127         echo -n "Setting initial stripe for test file..."
7128         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7129                 error "cannot set stripe"
7130         cur_ssize=$($LFS getstripe -S "$file1")
7131         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7132         echo "done."
7133
7134         # File currently set to -S 512K -c 1
7135
7136         # Ensure -c and -S options are rejected when -R is set
7137         echo -n "Verifying incompatible options are detected..."
7138         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7139                 error "incompatible -c and -R options not detected"
7140         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7141                 error "incompatible -S and -R options not detected"
7142         echo "done."
7143
7144         # Ensure unrecognized options are passed through to 'lfs migrate'
7145         echo -n "Verifying -S option is passed through to lfs migrate..."
7146         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7147                 error "migration failed"
7148         cur_ssize=$($LFS getstripe -S "$file1")
7149         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7150         echo "done."
7151
7152         # File currently set to -S 1M -c 1
7153
7154         # Ensure long options are supported
7155         echo -n "Verifying long options supported..."
7156         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7157                 error "long option without argument not supported"
7158         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7159                 error "long option with argument not supported"
7160         cur_ssize=$($LFS getstripe -S "$file1")
7161         [ $cur_ssize -eq 524288 ] ||
7162                 error "migrate --stripe-size $cur_ssize != 524288"
7163         echo "done."
7164
7165         # File currently set to -S 512K -c 1
7166
7167         if [ "$OSTCOUNT" -gt 1 ]; then
7168                 echo -n "Verifying explicit stripe count can be set..."
7169                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7170                         error "migrate failed"
7171                 cur_scount=$($LFS getstripe -c "$file1")
7172                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7173                 echo "done."
7174         fi
7175
7176         # File currently set to -S 512K -c 1 or -S 512K -c 2
7177
7178         # Ensure parent striping is used if -R is set, and no stripe
7179         # count or size is specified
7180         echo -n "Setting stripe for parent directory..."
7181         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7182                 error "cannot set stripe '-S 2M -c 1'"
7183         echo "done."
7184
7185         echo -n "Verifying restripe option uses parent stripe settings..."
7186         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7187         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7188         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7189                 error "migrate failed"
7190         cur_ssize=$($LFS getstripe -S "$file1")
7191         [ $cur_ssize -eq $parent_ssize ] ||
7192                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7193         cur_scount=$($LFS getstripe -c "$file1")
7194         [ $cur_scount -eq $parent_scount ] ||
7195                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7196         echo "done."
7197
7198         # File currently set to -S 1M -c 1
7199
7200         # Ensure striping is preserved if -R is not set, and no stripe
7201         # count or size is specified
7202         echo -n "Verifying striping size preserved when not specified..."
7203         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7204         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7205                 error "cannot set stripe on parent directory"
7206         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7207                 error "migrate failed"
7208         cur_ssize=$($LFS getstripe -S "$file1")
7209         [ $cur_ssize -eq $orig_ssize ] ||
7210                 error "migrate by default $cur_ssize != $orig_ssize"
7211         echo "done."
7212
7213         # Ensure file name properly detected when final option has no argument
7214         echo -n "Verifying file name properly detected..."
7215         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7216                 error "file name interpreted as option argument"
7217         echo "done."
7218
7219         # Clean up
7220         rm -f "$file1"
7221 }
7222 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7223
7224 test_56wd() {
7225         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7226
7227         local file1=$DIR/$tdir/file1
7228
7229         echo -n "Creating test dir..."
7230         test_mkdir $DIR/$tdir || error "cannot create dir"
7231         echo "done."
7232
7233         echo -n "Creating test file..."
7234         touch $file1
7235         echo "done."
7236
7237         # Ensure 'lfs migrate' will fail by using a non-existent option,
7238         # and make sure rsync is not called to recover
7239         echo -n "Make sure --no-rsync option works..."
7240         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7241                 grep -q 'refusing to fall back to rsync' ||
7242                 error "rsync was called with --no-rsync set"
7243         echo "done."
7244
7245         # Ensure rsync is called without trying 'lfs migrate' first
7246         echo -n "Make sure --rsync option works..."
7247         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7248                 grep -q 'falling back to rsync' &&
7249                 error "lfs migrate was called with --rsync set"
7250         echo "done."
7251
7252         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7253         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7254                 grep -q 'at the same time' ||
7255                 error "--rsync and --no-rsync accepted concurrently"
7256         echo "done."
7257
7258         # Clean up
7259         rm -f $file1
7260 }
7261 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7262
7263 test_56we() {
7264         local td=$DIR/$tdir
7265         local tf=$td/$tfile
7266
7267         test_mkdir $td || error "cannot create $td"
7268         touch $tf || error "cannot touch $tf"
7269
7270         echo -n "Make sure --non-direct|-D works..."
7271         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7272                 grep -q "lfs migrate --non-direct" ||
7273                 error "--non-direct option cannot work correctly"
7274         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7275                 grep -q "lfs migrate -D" ||
7276                 error "-D option cannot work correctly"
7277         echo "done."
7278 }
7279 run_test 56we "check lfs_migrate --non-direct|-D support"
7280
7281 test_56x() {
7282         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7283         check_swap_layouts_support
7284
7285         local dir=$DIR/$tdir
7286         local ref1=/etc/passwd
7287         local file1=$dir/file1
7288
7289         test_mkdir $dir || error "creating dir $dir"
7290         $LFS setstripe -c 2 $file1
7291         cp $ref1 $file1
7292         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7293         stripe=$($LFS getstripe -c $file1)
7294         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7295         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7296
7297         # clean up
7298         rm -f $file1
7299 }
7300 run_test 56x "lfs migration support"
7301
7302 test_56xa() {
7303         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7304         check_swap_layouts_support
7305
7306         local dir=$DIR/$tdir/$testnum
7307
7308         test_mkdir -p $dir
7309
7310         local ref1=/etc/passwd
7311         local file1=$dir/file1
7312
7313         $LFS setstripe -c 2 $file1
7314         cp $ref1 $file1
7315         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7316
7317         local stripe=$($LFS getstripe -c $file1)
7318
7319         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7320         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7321
7322         # clean up
7323         rm -f $file1
7324 }
7325 run_test 56xa "lfs migration --block support"
7326
7327 check_migrate_links() {
7328         local dir="$1"
7329         local file1="$dir/file1"
7330         local begin="$2"
7331         local count="$3"
7332         local runas="$4"
7333         local total_count=$(($begin + $count - 1))
7334         local symlink_count=10
7335         local uniq_count=10
7336
7337         if [ ! -f "$file1" ]; then
7338                 echo -n "creating initial file..."
7339                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7340                         error "cannot setstripe initial file"
7341                 echo "done"
7342
7343                 echo -n "creating symlinks..."
7344                 for s in $(seq 1 $symlink_count); do
7345                         ln -s "$file1" "$dir/slink$s" ||
7346                                 error "cannot create symlinks"
7347                 done
7348                 echo "done"
7349
7350                 echo -n "creating nonlinked files..."
7351                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7352                         error "cannot create nonlinked files"
7353                 echo "done"
7354         fi
7355
7356         # create hard links
7357         if [ ! -f "$dir/file$total_count" ]; then
7358                 echo -n "creating hard links $begin:$total_count..."
7359                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7360                         /dev/null || error "cannot create hard links"
7361                 echo "done"
7362         fi
7363
7364         echo -n "checking number of hard links listed in xattrs..."
7365         local fid=$($LFS getstripe -F "$file1")
7366         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7367
7368         echo "${#paths[*]}"
7369         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7370                         skip "hard link list has unexpected size, skipping test"
7371         fi
7372         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7373                         error "link names should exceed xattrs size"
7374         fi
7375
7376         echo -n "migrating files..."
7377         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7378         local rc=$?
7379         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7380         echo "done"
7381
7382         # make sure all links have been properly migrated
7383         echo -n "verifying files..."
7384         fid=$($LFS getstripe -F "$file1") ||
7385                 error "cannot get fid for file $file1"
7386         for i in $(seq 2 $total_count); do
7387                 local fid2=$($LFS getstripe -F $dir/file$i)
7388
7389                 [ "$fid2" == "$fid" ] ||
7390                         error "migrated hard link has mismatched FID"
7391         done
7392
7393         # make sure hard links were properly detected, and migration was
7394         # performed only once for the entire link set; nonlinked files should
7395         # also be migrated
7396         local actual=$(grep -c 'done' <<< "$migrate_out")
7397         local expected=$(($uniq_count + 1))
7398
7399         [ "$actual" -eq  "$expected" ] ||
7400                 error "hard links individually migrated ($actual != $expected)"
7401
7402         # make sure the correct number of hard links are present
7403         local hardlinks=$(stat -c '%h' "$file1")
7404
7405         [ $hardlinks -eq $total_count ] ||
7406                 error "num hard links $hardlinks != $total_count"
7407         echo "done"
7408
7409         return 0
7410 }
7411
7412 test_56xb() {
7413         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7414                 skip "Need MDS version at least 2.10.55"
7415
7416         local dir="$DIR/$tdir"
7417
7418         test_mkdir "$dir" || error "cannot create dir $dir"
7419
7420         echo "testing lfs migrate mode when all links fit within xattrs"
7421         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7422
7423         echo "testing rsync mode when all links fit within xattrs"
7424         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7425
7426         echo "testing lfs migrate mode when all links do not fit within xattrs"
7427         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7428
7429         echo "testing rsync mode when all links do not fit within xattrs"
7430         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7431
7432         chown -R $RUNAS_ID $dir
7433         echo "testing non-root lfs migrate mode when not all links are in xattr"
7434         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7435
7436         # clean up
7437         rm -rf $dir
7438 }
7439 run_test 56xb "lfs migration hard link support"
7440
7441 test_56xc() {
7442         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7443
7444         local dir="$DIR/$tdir"
7445
7446         test_mkdir "$dir" || error "cannot create dir $dir"
7447
7448         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7449         echo -n "Setting initial stripe for 20MB test file..."
7450         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7451                 error "cannot setstripe 20MB file"
7452         echo "done"
7453         echo -n "Sizing 20MB test file..."
7454         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7455         echo "done"
7456         echo -n "Verifying small file autostripe count is 1..."
7457         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7458                 error "cannot migrate 20MB file"
7459         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7460                 error "cannot get stripe for $dir/20mb"
7461         [ $stripe_count -eq 1 ] ||
7462                 error "unexpected stripe count $stripe_count for 20MB file"
7463         rm -f "$dir/20mb"
7464         echo "done"
7465
7466         # Test 2: File is small enough to fit within the available space on
7467         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7468         # have at least an additional 1KB for each desired stripe for test 3
7469         echo -n "Setting stripe for 1GB test file..."
7470         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7471         echo "done"
7472         echo -n "Sizing 1GB test file..."
7473         # File size is 1GB + 3KB
7474         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7475         echo "done"
7476
7477         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7478         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7479         if (( avail > 524288 * OSTCOUNT )); then
7480                 echo -n "Migrating 1GB file..."
7481                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7482                         error "cannot migrate 1GB file"
7483                 echo "done"
7484                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7485                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7486                         error "cannot getstripe for 1GB file"
7487                 [ $stripe_count -eq 2 ] ||
7488                         error "unexpected stripe count $stripe_count != 2"
7489                 echo "done"
7490         fi
7491
7492         # Test 3: File is too large to fit within the available space on
7493         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7494         if [ $OSTCOUNT -ge 3 ]; then
7495                 # The required available space is calculated as
7496                 # file size (1GB + 3KB) / OST count (3).
7497                 local kb_per_ost=349526
7498
7499                 echo -n "Migrating 1GB file with limit..."
7500                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7501                         error "cannot migrate 1GB file with limit"
7502                 echo "done"
7503
7504                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7505                 echo -n "Verifying 1GB autostripe count with limited space..."
7506                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7507                         error "unexpected stripe count $stripe_count (min 3)"
7508                 echo "done"
7509         fi
7510
7511         # clean up
7512         rm -rf $dir
7513 }
7514 run_test 56xc "lfs migration autostripe"
7515
7516 test_56xd() {
7517         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7518
7519         local dir=$DIR/$tdir
7520         local f_mgrt=$dir/$tfile.mgrt
7521         local f_yaml=$dir/$tfile.yaml
7522         local f_copy=$dir/$tfile.copy
7523         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7524         local layout_copy="-c 2 -S 2M -i 1"
7525         local yamlfile=$dir/yamlfile
7526         local layout_before;
7527         local layout_after;
7528
7529         test_mkdir "$dir" || error "cannot create dir $dir"
7530         $LFS setstripe $layout_yaml $f_yaml ||
7531                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7532         $LFS getstripe --yaml $f_yaml > $yamlfile
7533         $LFS setstripe $layout_copy $f_copy ||
7534                 error "cannot setstripe $f_copy with layout $layout_copy"
7535         touch $f_mgrt
7536         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7537
7538         # 1. test option --yaml
7539         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7540                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7541         layout_before=$(get_layout_param $f_yaml)
7542         layout_after=$(get_layout_param $f_mgrt)
7543         [ "$layout_after" == "$layout_before" ] ||
7544                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7545
7546         # 2. test option --copy
7547         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7548                 error "cannot migrate $f_mgrt with --copy $f_copy"
7549         layout_before=$(get_layout_param $f_copy)
7550         layout_after=$(get_layout_param $f_mgrt)
7551         [ "$layout_after" == "$layout_before" ] ||
7552                 error "lfs_migrate --copy: $layout_after != $layout_before"
7553 }
7554 run_test 56xd "check lfs_migrate --yaml and --copy support"
7555
7556 test_56xe() {
7557         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7558
7559         local dir=$DIR/$tdir
7560         local f_comp=$dir/$tfile
7561         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7562         local layout_before=""
7563         local layout_after=""
7564
7565         test_mkdir "$dir" || error "cannot create dir $dir"
7566         $LFS setstripe $layout $f_comp ||
7567                 error "cannot setstripe $f_comp with layout $layout"
7568         layout_before=$(get_layout_param $f_comp)
7569         dd if=/dev/zero of=$f_comp bs=1M count=4
7570
7571         # 1. migrate a comp layout file by lfs_migrate
7572         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7573         layout_after=$(get_layout_param $f_comp)
7574         [ "$layout_before" == "$layout_after" ] ||
7575                 error "lfs_migrate: $layout_before != $layout_after"
7576
7577         # 2. migrate a comp layout file by lfs migrate
7578         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7579         layout_after=$(get_layout_param $f_comp)
7580         [ "$layout_before" == "$layout_after" ] ||
7581                 error "lfs migrate: $layout_before != $layout_after"
7582 }
7583 run_test 56xe "migrate a composite layout file"
7584
7585 test_56xf() {
7586         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7587
7588         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7589                 skip "Need server version at least 2.13.53"
7590
7591         local dir=$DIR/$tdir
7592         local f_comp=$dir/$tfile
7593         local layout="-E 1M -c1 -E -1 -c2"
7594         local fid_before=""
7595         local fid_after=""
7596
7597         test_mkdir "$dir" || error "cannot create dir $dir"
7598         $LFS setstripe $layout $f_comp ||
7599                 error "cannot setstripe $f_comp with layout $layout"
7600         fid_before=$($LFS getstripe --fid $f_comp)
7601         dd if=/dev/zero of=$f_comp bs=1M count=4
7602
7603         # 1. migrate a comp layout file to a comp layout
7604         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7605         fid_after=$($LFS getstripe --fid $f_comp)
7606         [ "$fid_before" == "$fid_after" ] ||
7607                 error "comp-to-comp migrate: $fid_before != $fid_after"
7608
7609         # 2. migrate a comp layout file to a plain layout
7610         $LFS migrate -c2 $f_comp ||
7611                 error "cannot migrate $f_comp by lfs migrate"
7612         fid_after=$($LFS getstripe --fid $f_comp)
7613         [ "$fid_before" == "$fid_after" ] ||
7614                 error "comp-to-plain migrate: $fid_before != $fid_after"
7615
7616         # 3. migrate a plain layout file to a comp layout
7617         $LFS migrate $layout $f_comp ||
7618                 error "cannot migrate $f_comp by lfs migrate"
7619         fid_after=$($LFS getstripe --fid $f_comp)
7620         [ "$fid_before" == "$fid_after" ] ||
7621                 error "plain-to-comp migrate: $fid_before != $fid_after"
7622 }
7623 run_test 56xf "FID is not lost during migration of a composite layout file"
7624
7625 test_56y() {
7626         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7627                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7628
7629         local res=""
7630         local dir=$DIR/$tdir
7631         local f1=$dir/file1
7632         local f2=$dir/file2
7633
7634         test_mkdir -p $dir || error "creating dir $dir"
7635         touch $f1 || error "creating std file $f1"
7636         $MULTIOP $f2 H2c || error "creating released file $f2"
7637
7638         # a directory can be raid0, so ask only for files
7639         res=$($LFS find $dir -L raid0 -type f | wc -l)
7640         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7641
7642         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7643         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7644
7645         # only files can be released, so no need to force file search
7646         res=$($LFS find $dir -L released)
7647         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7648
7649         res=$($LFS find $dir -type f \! -L released)
7650         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7651 }
7652 run_test 56y "lfs find -L raid0|released"
7653
7654 test_56z() { # LU-4824
7655         # This checks to make sure 'lfs find' continues after errors
7656         # There are two classes of errors that should be caught:
7657         # - If multiple paths are provided, all should be searched even if one
7658         #   errors out
7659         # - If errors are encountered during the search, it should not terminate
7660         #   early
7661         local dir=$DIR/$tdir
7662         local i
7663
7664         test_mkdir $dir
7665         for i in d{0..9}; do
7666                 test_mkdir $dir/$i
7667                 touch $dir/$i/$tfile
7668         done
7669         $LFS find $DIR/non_existent_dir $dir &&
7670                 error "$LFS find did not return an error"
7671         # Make a directory unsearchable. This should NOT be the last entry in
7672         # directory order.  Arbitrarily pick the 6th entry
7673         chmod 700 $($LFS find $dir -type d | sed '6!d')
7674
7675         $RUNAS $LFS find $DIR/non_existent $dir
7676         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7677
7678         # The user should be able to see 10 directories and 9 files
7679         (( count == 19 )) ||
7680                 error "$LFS find found $count != 19 entries after error"
7681 }
7682 run_test 56z "lfs find should continue after an error"
7683
7684 test_56aa() { # LU-5937
7685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7686
7687         local dir=$DIR/$tdir
7688
7689         mkdir $dir
7690         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7691
7692         createmany -o $dir/striped_dir/${tfile}- 1024
7693         local dirs=$($LFS find --size +8k $dir/)
7694
7695         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7696 }
7697 run_test 56aa "lfs find --size under striped dir"
7698
7699 test_56ab() { # LU-10705
7700         test_mkdir $DIR/$tdir
7701         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7702         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7703         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7704         # Flush writes to ensure valid blocks.  Need to be more thorough for
7705         # ZFS, since blocks are not allocated/returned to client immediately.
7706         sync_all_data
7707         wait_zfs_commit ost1 2
7708         cancel_lru_locks osc
7709         ls -ls $DIR/$tdir
7710
7711         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7712
7713         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7714
7715         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7716         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7717
7718         rm -f $DIR/$tdir/$tfile.[123]
7719 }
7720 run_test 56ab "lfs find --blocks"
7721
7722 # LU-11188
7723 test_56aca() {
7724         local dir="$DIR/$tdir"
7725         local perms=(001 002 003 004 005 006 007
7726                      010 020 030 040 050 060 070
7727                      100 200 300 400 500 600 700
7728                      111 222 333 444 555 666 777)
7729         local perm_minus=(8 8 4 8 4 4 2
7730                           8 8 4 8 4 4 2
7731                           8 8 4 8 4 4 2
7732                           4 4 2 4 2 2 1)
7733         local perm_slash=(8  8 12  8 12 12 14
7734                           8  8 12  8 12 12 14
7735                           8  8 12  8 12 12 14
7736                          16 16 24 16 24 24 28)
7737
7738         test_mkdir "$dir"
7739         for perm in ${perms[*]}; do
7740                 touch "$dir/$tfile.$perm"
7741                 chmod $perm "$dir/$tfile.$perm"
7742         done
7743
7744         for ((i = 0; i < ${#perms[*]}; i++)); do
7745                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7746                 (( $num == 1 )) ||
7747                         error "lfs find -perm ${perms[i]}:"\
7748                               "$num != 1"
7749
7750                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7751                 (( $num == ${perm_minus[i]} )) ||
7752                         error "lfs find -perm -${perms[i]}:"\
7753                               "$num != ${perm_minus[i]}"
7754
7755                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7756                 (( $num == ${perm_slash[i]} )) ||
7757                         error "lfs find -perm /${perms[i]}:"\
7758                               "$num != ${perm_slash[i]}"
7759         done
7760 }
7761 run_test 56aca "check lfs find -perm with octal representation"
7762
7763 test_56acb() {
7764         local dir=$DIR/$tdir
7765         # p is the permission of write and execute for user, group and other
7766         # without the umask. It is used to test +wx.
7767         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7768         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7769         local symbolic=(+t  a+t u+t g+t o+t
7770                         g+s u+s o+s +s o+sr
7771                         o=r,ug+o,u+w
7772                         u+ g+ o+ a+ ugo+
7773                         u- g- o- a- ugo-
7774                         u= g= o= a= ugo=
7775                         o=r,ug+o,u+w u=r,a+u,u+w
7776                         g=r,ugo=g,u+w u+x,+X +X
7777                         u+x,u+X u+X u+x,g+X o+r,+X
7778                         u+x,go+X +wx +rwx)
7779
7780         test_mkdir $dir
7781         for perm in ${perms[*]}; do
7782                 touch "$dir/$tfile.$perm"
7783                 chmod $perm "$dir/$tfile.$perm"
7784         done
7785
7786         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7787                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7788
7789                 (( $num == 1 )) ||
7790                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7791         done
7792 }
7793 run_test 56acb "check lfs find -perm with symbolic representation"
7794
7795 test_56acc() {
7796         local dir=$DIR/$tdir
7797         local tests="17777 787 789 abcd
7798                 ug=uu ug=a ug=gu uo=ou urw
7799                 u+xg+x a=r,u+x,"
7800
7801         test_mkdir $dir
7802         for err in $tests; do
7803                 if $LFS find $dir -perm $err 2>/dev/null; then
7804                         error "lfs find -perm $err: parsing should have failed"
7805                 fi
7806         done
7807 }
7808 run_test 56acc "check parsing error for lfs find -perm"
7809
7810 test_56ba() {
7811         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7812                 skip "Need MDS version at least 2.10.50"
7813
7814         # Create composite files with one component
7815         local dir=$DIR/$tdir
7816
7817         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7818         # Create composite files with three components
7819         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7820         # Create non-composite files
7821         createmany -o $dir/${tfile}- 10
7822
7823         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7824
7825         [[ $nfiles == 10 ]] ||
7826                 error "lfs find -E 1M found $nfiles != 10 files"
7827
7828         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7829         [[ $nfiles == 25 ]] ||
7830                 error "lfs find ! -E 1M found $nfiles != 25 files"
7831
7832         # All files have a component that starts at 0
7833         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7834         [[ $nfiles == 35 ]] ||
7835                 error "lfs find --component-start 0 - $nfiles != 35 files"
7836
7837         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7838         [[ $nfiles == 15 ]] ||
7839                 error "lfs find --component-start 2M - $nfiles != 15 files"
7840
7841         # All files created here have a componenet that does not starts at 2M
7842         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7843         [[ $nfiles == 35 ]] ||
7844                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7845
7846         # Find files with a specified number of components
7847         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7848         [[ $nfiles == 15 ]] ||
7849                 error "lfs find --component-count 3 - $nfiles != 15 files"
7850
7851         # Remember non-composite files have a component count of zero
7852         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7853         [[ $nfiles == 10 ]] ||
7854                 error "lfs find --component-count 0 - $nfiles != 10 files"
7855
7856         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7857         [[ $nfiles == 20 ]] ||
7858                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7859
7860         # All files have a flag called "init"
7861         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7862         [[ $nfiles == 35 ]] ||
7863                 error "lfs find --component-flags init - $nfiles != 35 files"
7864
7865         # Multi-component files will have a component not initialized
7866         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7867         [[ $nfiles == 15 ]] ||
7868                 error "lfs find !--component-flags init - $nfiles != 15 files"
7869
7870         rm -rf $dir
7871
7872 }
7873 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7874
7875 test_56ca() {
7876         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7877                 skip "Need MDS version at least 2.10.57"
7878
7879         local td=$DIR/$tdir
7880         local tf=$td/$tfile
7881         local dir
7882         local nfiles
7883         local cmd
7884         local i
7885         local j
7886
7887         # create mirrored directories and mirrored files
7888         mkdir $td || error "mkdir $td failed"
7889         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7890         createmany -o $tf- 10 || error "create $tf- failed"
7891
7892         for i in $(seq 2); do
7893                 dir=$td/dir$i
7894                 mkdir $dir || error "mkdir $dir failed"
7895                 $LFS mirror create -N$((3 + i)) $dir ||
7896                         error "create mirrored dir $dir failed"
7897                 createmany -o $dir/$tfile- 10 ||
7898                         error "create $dir/$tfile- failed"
7899         done
7900
7901         # change the states of some mirrored files
7902         echo foo > $tf-6
7903         for i in $(seq 2); do
7904                 dir=$td/dir$i
7905                 for j in $(seq 4 9); do
7906                         echo foo > $dir/$tfile-$j
7907                 done
7908         done
7909
7910         # find mirrored files with specific mirror count
7911         cmd="$LFS find --mirror-count 3 --type f $td"
7912         nfiles=$($cmd | wc -l)
7913         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7914
7915         cmd="$LFS find ! --mirror-count 3 --type f $td"
7916         nfiles=$($cmd | wc -l)
7917         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7918
7919         cmd="$LFS find --mirror-count +2 --type f $td"
7920         nfiles=$($cmd | wc -l)
7921         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7922
7923         cmd="$LFS find --mirror-count -6 --type f $td"
7924         nfiles=$($cmd | wc -l)
7925         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7926
7927         # find mirrored files with specific file state
7928         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7929         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7930
7931         cmd="$LFS find --mirror-state=ro --type f $td"
7932         nfiles=$($cmd | wc -l)
7933         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7934
7935         cmd="$LFS find ! --mirror-state=ro --type f $td"
7936         nfiles=$($cmd | wc -l)
7937         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7938
7939         cmd="$LFS find --mirror-state=wp --type f $td"
7940         nfiles=$($cmd | wc -l)
7941         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7942
7943         cmd="$LFS find ! --mirror-state=sp --type f $td"
7944         nfiles=$($cmd | wc -l)
7945         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7946 }
7947 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7948
7949 test_56da() { # LU-14179
7950         local path=$DIR/$tdir
7951
7952         test_mkdir $path
7953         cd $path
7954
7955         local longdir=$(str_repeat 'a' 255)
7956
7957         for i in {1..15}; do
7958                 path=$path/$longdir
7959                 test_mkdir $longdir
7960                 cd $longdir
7961         done
7962
7963         local len=${#path}
7964         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
7965
7966         test_mkdir $lastdir
7967         cd $lastdir
7968         # PATH_MAX-1
7969         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
7970
7971         # NAME_MAX
7972         touch $(str_repeat 'f' 255)
7973
7974         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
7975                 error "lfs find reported an error"
7976
7977         rm -rf $DIR/$tdir
7978 }
7979 run_test 56da "test lfs find with long paths"
7980
7981 test_57a() {
7982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7983         # note test will not do anything if MDS is not local
7984         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7985                 skip_env "ldiskfs only test"
7986         fi
7987         remote_mds_nodsh && skip "remote MDS with nodsh"
7988
7989         local MNTDEV="osd*.*MDT*.mntdev"
7990         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7991         [ -z "$DEV" ] && error "can't access $MNTDEV"
7992         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7993                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7994                         error "can't access $DEV"
7995                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7996                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7997                 rm $TMP/t57a.dump
7998         done
7999 }
8000 run_test 57a "verify MDS filesystem created with large inodes =="
8001
8002 test_57b() {
8003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8004         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8005                 skip_env "ldiskfs only test"
8006         fi
8007         remote_mds_nodsh && skip "remote MDS with nodsh"
8008
8009         local dir=$DIR/$tdir
8010         local filecount=100
8011         local file1=$dir/f1
8012         local fileN=$dir/f$filecount
8013
8014         rm -rf $dir || error "removing $dir"
8015         test_mkdir -c1 $dir
8016         local mdtidx=$($LFS getstripe -m $dir)
8017         local mdtname=MDT$(printf %04x $mdtidx)
8018         local facet=mds$((mdtidx + 1))
8019
8020         echo "mcreating $filecount files"
8021         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8022
8023         # verify that files do not have EAs yet
8024         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8025                 error "$file1 has an EA"
8026         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8027                 error "$fileN has an EA"
8028
8029         sync
8030         sleep 1
8031         df $dir  #make sure we get new statfs data
8032         local mdsfree=$(do_facet $facet \
8033                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8034         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8035         local file
8036
8037         echo "opening files to create objects/EAs"
8038         for file in $(seq -f $dir/f%g 1 $filecount); do
8039                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8040                         error "opening $file"
8041         done
8042
8043         # verify that files have EAs now
8044         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8045         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8046
8047         sleep 1  #make sure we get new statfs data
8048         df $dir
8049         local mdsfree2=$(do_facet $facet \
8050                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8051         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8052
8053         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8054                 if [ "$mdsfree" != "$mdsfree2" ]; then
8055                         error "MDC before $mdcfree != after $mdcfree2"
8056                 else
8057                         echo "MDC before $mdcfree != after $mdcfree2"
8058                         echo "unable to confirm if MDS has large inodes"
8059                 fi
8060         fi
8061         rm -rf $dir
8062 }
8063 run_test 57b "default LOV EAs are stored inside large inodes ==="
8064
8065 test_58() {
8066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8067         [ -z "$(which wiretest 2>/dev/null)" ] &&
8068                         skip_env "could not find wiretest"
8069
8070         wiretest
8071 }
8072 run_test 58 "verify cross-platform wire constants =============="
8073
8074 test_59() {
8075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8076
8077         echo "touch 130 files"
8078         createmany -o $DIR/f59- 130
8079         echo "rm 130 files"
8080         unlinkmany $DIR/f59- 130
8081         sync
8082         # wait for commitment of removal
8083         wait_delete_completed
8084 }
8085 run_test 59 "verify cancellation of llog records async ========="
8086
8087 TEST60_HEAD="test_60 run $RANDOM"
8088 test_60a() {
8089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8090         remote_mgs_nodsh && skip "remote MGS with nodsh"
8091         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8092                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8093                         skip_env "missing subtest run-llog.sh"
8094
8095         log "$TEST60_HEAD - from kernel mode"
8096         do_facet mgs "$LCTL dk > /dev/null"
8097         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8098         do_facet mgs $LCTL dk > $TMP/$tfile
8099
8100         # LU-6388: test llog_reader
8101         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8102         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8103         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8104                         skip_env "missing llog_reader"
8105         local fstype=$(facet_fstype mgs)
8106         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8107                 skip_env "Only for ldiskfs or zfs type mgs"
8108
8109         local mntpt=$(facet_mntpt mgs)
8110         local mgsdev=$(mgsdevname 1)
8111         local fid_list
8112         local fid
8113         local rec_list
8114         local rec
8115         local rec_type
8116         local obj_file
8117         local path
8118         local seq
8119         local oid
8120         local pass=true
8121
8122         #get fid and record list
8123         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8124                 tail -n 4))
8125         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8126                 tail -n 4))
8127         #remount mgs as ldiskfs or zfs type
8128         stop mgs || error "stop mgs failed"
8129         mount_fstype mgs || error "remount mgs failed"
8130         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8131                 fid=${fid_list[i]}
8132                 rec=${rec_list[i]}
8133                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8134                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8135                 oid=$((16#$oid))
8136
8137                 case $fstype in
8138                         ldiskfs )
8139                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8140                         zfs )
8141                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8142                 esac
8143                 echo "obj_file is $obj_file"
8144                 do_facet mgs $llog_reader $obj_file
8145
8146                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8147                         awk '{ print $3 }' | sed -e "s/^type=//g")
8148                 if [ $rec_type != $rec ]; then
8149                         echo "FAILED test_60a wrong record type $rec_type," \
8150                               "should be $rec"
8151                         pass=false
8152                         break
8153                 fi
8154
8155                 #check obj path if record type is LLOG_LOGID_MAGIC
8156                 if [ "$rec" == "1064553b" ]; then
8157                         path=$(do_facet mgs $llog_reader $obj_file |
8158                                 grep "path=" | awk '{ print $NF }' |
8159                                 sed -e "s/^path=//g")
8160                         if [ $obj_file != $mntpt/$path ]; then
8161                                 echo "FAILED test_60a wrong obj path" \
8162                                       "$montpt/$path, should be $obj_file"
8163                                 pass=false
8164                                 break
8165                         fi
8166                 fi
8167         done
8168         rm -f $TMP/$tfile
8169         #restart mgs before "error", otherwise it will block the next test
8170         stop mgs || error "stop mgs failed"
8171         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8172         $pass || error "test failed, see FAILED test_60a messages for specifics"
8173 }
8174 run_test 60a "llog_test run from kernel module and test llog_reader"
8175
8176 test_60b() { # bug 6411
8177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8178
8179         dmesg > $DIR/$tfile
8180         LLOG_COUNT=$(do_facet mgs dmesg |
8181                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8182                           /llog_[a-z]*.c:[0-9]/ {
8183                                 if (marker)
8184                                         from_marker++
8185                                 from_begin++
8186                           }
8187                           END {
8188                                 if (marker)
8189                                         print from_marker
8190                                 else
8191                                         print from_begin
8192                           }")
8193
8194         [[ $LLOG_COUNT -gt 120 ]] &&
8195                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8196 }
8197 run_test 60b "limit repeated messages from CERROR/CWARN"
8198
8199 test_60c() {
8200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8201
8202         echo "create 5000 files"
8203         createmany -o $DIR/f60c- 5000
8204 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8205         lctl set_param fail_loc=0x80000137
8206         unlinkmany $DIR/f60c- 5000
8207         lctl set_param fail_loc=0
8208 }
8209 run_test 60c "unlink file when mds full"
8210
8211 test_60d() {
8212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8213
8214         SAVEPRINTK=$(lctl get_param -n printk)
8215         # verify "lctl mark" is even working"
8216         MESSAGE="test message ID $RANDOM $$"
8217         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8218         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8219
8220         lctl set_param printk=0 || error "set lnet.printk failed"
8221         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8222         MESSAGE="new test message ID $RANDOM $$"
8223         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8224         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8225         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8226
8227         lctl set_param -n printk="$SAVEPRINTK"
8228 }
8229 run_test 60d "test printk console message masking"
8230
8231 test_60e() {
8232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8233         remote_mds_nodsh && skip "remote MDS with nodsh"
8234
8235         touch $DIR/$tfile
8236 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8237         do_facet mds1 lctl set_param fail_loc=0x15b
8238         rm $DIR/$tfile
8239 }
8240 run_test 60e "no space while new llog is being created"
8241
8242 test_60f() {
8243         local old_path=$($LCTL get_param -n debug_path)
8244
8245         stack_trap "$LCTL set_param debug_path=$old_path"
8246         stack_trap "rm -f $TMP/$tfile*"
8247         rm -f $TMP/$tfile* 2> /dev/null
8248         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8249         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8250         test_mkdir $DIR/$tdir
8251         # retry in case the open is cached and not released
8252         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8253                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8254                 sleep 0.1
8255         done
8256         ls $TMP/$tfile*
8257         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8258 }
8259 run_test 60f "change debug_path works"
8260
8261 test_60g() {
8262         local pid
8263         local i
8264
8265         test_mkdir -c $MDSCOUNT $DIR/$tdir
8266
8267         (
8268                 local index=0
8269                 while true; do
8270                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8271                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8272                                 2>/dev/null
8273                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8274                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8275                         index=$((index + 1))
8276                 done
8277         ) &
8278
8279         pid=$!
8280
8281         for i in {0..100}; do
8282                 # define OBD_FAIL_OSD_TXN_START    0x19a
8283                 local index=$((i % MDSCOUNT + 1))
8284
8285                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8286                         > /dev/null
8287                 sleep 0.01
8288         done
8289
8290         kill -9 $pid
8291
8292         for i in $(seq $MDSCOUNT); do
8293                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8294         done
8295
8296         mkdir $DIR/$tdir/new || error "mkdir failed"
8297         rmdir $DIR/$tdir/new || error "rmdir failed"
8298
8299         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8300                 -t namespace
8301         for i in $(seq $MDSCOUNT); do
8302                 wait_update_facet mds$i "$LCTL get_param -n \
8303                         mdd.$(facet_svc mds$i).lfsck_namespace |
8304                         awk '/^status/ { print \\\$2 }'" "completed"
8305         done
8306
8307         ls -R $DIR/$tdir || error "ls failed"
8308         rm -rf $DIR/$tdir || error "rmdir failed"
8309 }
8310 run_test 60g "transaction abort won't cause MDT hung"
8311
8312 test_60h() {
8313         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8314                 skip "Need MDS version at least 2.12.52"
8315         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8316
8317         local f
8318
8319         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8320         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8321         for fail_loc in 0x80000188 0x80000189; do
8322                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8323                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8324                         error "mkdir $dir-$fail_loc failed"
8325                 for i in {0..10}; do
8326                         # create may fail on missing stripe
8327                         echo $i > $DIR/$tdir-$fail_loc/$i
8328                 done
8329                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8330                         error "getdirstripe $tdir-$fail_loc failed"
8331                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8332                         error "migrate $tdir-$fail_loc failed"
8333                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8334                         error "getdirstripe $tdir-$fail_loc failed"
8335                 pushd $DIR/$tdir-$fail_loc
8336                 for f in *; do
8337                         echo $f | cmp $f - || error "$f data mismatch"
8338                 done
8339                 popd
8340                 rm -rf $DIR/$tdir-$fail_loc
8341         done
8342 }
8343 run_test 60h "striped directory with missing stripes can be accessed"
8344
8345 function t60i_load() {
8346         mkdir $DIR/$tdir
8347         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8348         $LCTL set_param fail_loc=0x131c fail_val=1
8349         for ((i=0; i<5000; i++)); do
8350                 touch $DIR/$tdir/f$i
8351         done
8352 }
8353
8354 test_60i() {
8355         changelog_register || error "changelog_register failed"
8356         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8357         changelog_users $SINGLEMDS | grep -q $cl_user ||
8358                 error "User $cl_user not found in changelog_users"
8359         changelog_chmask "ALL"
8360         t60i_load &
8361         local PID=$!
8362         for((i=0; i<100; i++)); do
8363                 changelog_dump >/dev/null ||
8364                         error "can't read changelog"
8365         done
8366         kill $PID
8367         wait $PID
8368         changelog_deregister || error "changelog_deregister failed"
8369         $LCTL set_param fail_loc=0
8370 }
8371 run_test 60i "llog: new record vs reader race"
8372
8373 test_61a() {
8374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8375
8376         f="$DIR/f61"
8377         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8378         cancel_lru_locks osc
8379         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8380         sync
8381 }
8382 run_test 61a "mmap() writes don't make sync hang ================"
8383
8384 test_61b() {
8385         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8386 }
8387 run_test 61b "mmap() of unstriped file is successful"
8388
8389 # bug 2330 - insufficient obd_match error checking causes LBUG
8390 test_62() {
8391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8392
8393         f="$DIR/f62"
8394         echo foo > $f
8395         cancel_lru_locks osc
8396         lctl set_param fail_loc=0x405
8397         cat $f && error "cat succeeded, expect -EIO"
8398         lctl set_param fail_loc=0
8399 }
8400 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8401 # match every page all of the time.
8402 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8403
8404 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8405 # Though this test is irrelevant anymore, it helped to reveal some
8406 # other grant bugs (LU-4482), let's keep it.
8407 test_63a() {   # was test_63
8408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8409
8410         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8411
8412         for i in `seq 10` ; do
8413                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8414                 sleep 5
8415                 kill $!
8416                 sleep 1
8417         done
8418
8419         rm -f $DIR/f63 || true
8420 }
8421 run_test 63a "Verify oig_wait interruption does not crash ======="
8422
8423 # bug 2248 - async write errors didn't return to application on sync
8424 # bug 3677 - async write errors left page locked
8425 test_63b() {
8426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8427
8428         debugsave
8429         lctl set_param debug=-1
8430
8431         # ensure we have a grant to do async writes
8432         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8433         rm $DIR/$tfile
8434
8435         sync    # sync lest earlier test intercept the fail_loc
8436
8437         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8438         lctl set_param fail_loc=0x80000406
8439         $MULTIOP $DIR/$tfile Owy && \
8440                 error "sync didn't return ENOMEM"
8441         sync; sleep 2; sync     # do a real sync this time to flush page
8442         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8443                 error "locked page left in cache after async error" || true
8444         debugrestore
8445 }
8446 run_test 63b "async write errors should be returned to fsync ==="
8447
8448 test_64a () {
8449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8450
8451         lfs df $DIR
8452         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8453 }
8454 run_test 64a "verify filter grant calculations (in kernel) ====="
8455
8456 test_64b () {
8457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8458
8459         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8460 }
8461 run_test 64b "check out-of-space detection on client"
8462
8463 test_64c() {
8464         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8465 }
8466 run_test 64c "verify grant shrink"
8467
8468 import_param() {
8469         local tgt=$1
8470         local param=$2
8471
8472         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8473 }
8474
8475 # this does exactly what osc_request.c:osc_announce_cached() does in
8476 # order to calculate max amount of grants to ask from server
8477 want_grant() {
8478         local tgt=$1
8479
8480         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8481         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8482
8483         ((rpc_in_flight++));
8484         nrpages=$((nrpages * rpc_in_flight))
8485
8486         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8487
8488         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8489
8490         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8491         local undirty=$((nrpages * PAGE_SIZE))
8492
8493         local max_extent_pages
8494         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8495         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8496         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8497         local grant_extent_tax
8498         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8499
8500         undirty=$((undirty + nrextents * grant_extent_tax))
8501
8502         echo $undirty
8503 }
8504
8505 # this is size of unit for grant allocation. It should be equal to
8506 # what tgt_grant.c:tgt_grant_chunk() calculates
8507 grant_chunk() {
8508         local tgt=$1
8509         local max_brw_size
8510         local grant_extent_tax
8511
8512         max_brw_size=$(import_param $tgt max_brw_size)
8513
8514         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8515
8516         echo $(((max_brw_size + grant_extent_tax) * 2))
8517 }
8518
8519 test_64d() {
8520         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8521                 skip "OST < 2.10.55 doesn't limit grants enough"
8522
8523         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8524
8525         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8526                 skip "no grant_param connect flag"
8527
8528         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8529
8530         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8531         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8532
8533
8534         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8535         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8536
8537         $LFS setstripe $DIR/$tfile -i 0 -c 1
8538         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8539         ddpid=$!
8540
8541         while kill -0 $ddpid; do
8542                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8543
8544                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8545                         kill $ddpid
8546                         error "cur_grant $cur_grant > $max_cur_granted"
8547                 fi
8548
8549                 sleep 1
8550         done
8551 }
8552 run_test 64d "check grant limit exceed"
8553
8554 check_grants() {
8555         local tgt=$1
8556         local expected=$2
8557         local msg=$3
8558         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8559
8560         ((cur_grants == expected)) ||
8561                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8562 }
8563
8564 round_up_p2() {
8565         echo $((($1 + $2 - 1) & ~($2 - 1)))
8566 }
8567
8568 test_64e() {
8569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8570         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8571                 skip "Need OSS version at least 2.11.56"
8572
8573         # Remount client to reset grant
8574         remount_client $MOUNT || error "failed to remount client"
8575         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8576
8577         local init_grants=$(import_param $osc_tgt initial_grant)
8578
8579         check_grants $osc_tgt $init_grants "init grants"
8580
8581         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8582         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8583         local gbs=$(import_param $osc_tgt grant_block_size)
8584
8585         # write random number of bytes from max_brw_size / 4 to max_brw_size
8586         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8587         # align for direct io
8588         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8589         # round to grant consumption unit
8590         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8591
8592         local grants=$((wb_round_up + extent_tax))
8593
8594         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8595
8596         # define OBD_FAIL_TGT_NO_GRANT 0x725
8597         # make the server not grant more back
8598         do_facet ost1 $LCTL set_param fail_loc=0x725
8599         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8600
8601         do_facet ost1 $LCTL set_param fail_loc=0
8602
8603         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8604
8605         rm -f $DIR/$tfile || error "rm failed"
8606
8607         # Remount client to reset grant
8608         remount_client $MOUNT || error "failed to remount client"
8609         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8610
8611         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8612
8613         # define OBD_FAIL_TGT_NO_GRANT 0x725
8614         # make the server not grant more back
8615         do_facet ost1 $LCTL set_param fail_loc=0x725
8616         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8617         do_facet ost1 $LCTL set_param fail_loc=0
8618
8619         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8620 }
8621 run_test 64e "check grant consumption (no grant allocation)"
8622
8623 test_64f() {
8624         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8625
8626         # Remount client to reset grant
8627         remount_client $MOUNT || error "failed to remount client"
8628         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8629
8630         local init_grants=$(import_param $osc_tgt initial_grant)
8631         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8632         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8633         local gbs=$(import_param $osc_tgt grant_block_size)
8634         local chunk=$(grant_chunk $osc_tgt)
8635
8636         # write random number of bytes from max_brw_size / 4 to max_brw_size
8637         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8638         # align for direct io
8639         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8640         # round to grant consumption unit
8641         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8642
8643         local grants=$((wb_round_up + extent_tax))
8644
8645         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8646         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8647                 error "error writing to $DIR/$tfile"
8648
8649         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8650                 "direct io with grant allocation"
8651
8652         rm -f $DIR/$tfile || error "rm failed"
8653
8654         # Remount client to reset grant
8655         remount_client $MOUNT || error "failed to remount client"
8656         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8657
8658         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8659
8660         local cmd="oO_WRONLY:w${write_bytes}_yc"
8661
8662         $MULTIOP $DIR/$tfile $cmd &
8663         MULTIPID=$!
8664         sleep 1
8665
8666         check_grants $osc_tgt $((init_grants - grants)) \
8667                 "buffered io, not write rpc"
8668
8669         kill -USR1 $MULTIPID
8670         wait
8671
8672         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8673                 "buffered io, one RPC"
8674 }
8675 run_test 64f "check grant consumption (with grant allocation)"
8676
8677 # bug 1414 - set/get directories' stripe info
8678 test_65a() {
8679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8680
8681         test_mkdir $DIR/$tdir
8682         touch $DIR/$tdir/f1
8683         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8684 }
8685 run_test 65a "directory with no stripe info"
8686
8687 test_65b() {
8688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8689
8690         test_mkdir $DIR/$tdir
8691         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8692
8693         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8694                                                 error "setstripe"
8695         touch $DIR/$tdir/f2
8696         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8697 }
8698 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8699
8700 test_65c() {
8701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8702         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8703
8704         test_mkdir $DIR/$tdir
8705         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8706
8707         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8708                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8709         touch $DIR/$tdir/f3
8710         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8711 }
8712 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8713
8714 test_65d() {
8715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8716
8717         test_mkdir $DIR/$tdir
8718         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8719         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8720
8721         if [[ $STRIPECOUNT -le 0 ]]; then
8722                 sc=1
8723         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8724                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8725                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8726         else
8727                 sc=$(($STRIPECOUNT - 1))
8728         fi
8729         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8730         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8731         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8732                 error "lverify failed"
8733 }
8734 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8735
8736 test_65e() {
8737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8738
8739         test_mkdir $DIR/$tdir
8740
8741         $LFS setstripe $DIR/$tdir || error "setstripe"
8742         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8743                                         error "no stripe info failed"
8744         touch $DIR/$tdir/f6
8745         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8746 }
8747 run_test 65e "directory setstripe defaults"
8748
8749 test_65f() {
8750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8751
8752         test_mkdir $DIR/${tdir}f
8753         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8754                 error "setstripe succeeded" || true
8755 }
8756 run_test 65f "dir setstripe permission (should return error) ==="
8757
8758 test_65g() {
8759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8760
8761         test_mkdir $DIR/$tdir
8762         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8763
8764         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8765                 error "setstripe -S failed"
8766         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8767         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8768                 error "delete default stripe failed"
8769 }
8770 run_test 65g "directory setstripe -d"
8771
8772 test_65h() {
8773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8774
8775         test_mkdir $DIR/$tdir
8776         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8777
8778         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8779                 error "setstripe -S failed"
8780         test_mkdir $DIR/$tdir/dd1
8781         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8782                 error "stripe info inherit failed"
8783 }
8784 run_test 65h "directory stripe info inherit ===================="
8785
8786 test_65i() {
8787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8788
8789         save_layout_restore_at_exit $MOUNT
8790
8791         # bug6367: set non-default striping on root directory
8792         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8793
8794         # bug12836: getstripe on -1 default directory striping
8795         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8796
8797         # bug12836: getstripe -v on -1 default directory striping
8798         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8799
8800         # bug12836: new find on -1 default directory striping
8801         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8802 }
8803 run_test 65i "various tests to set root directory striping"
8804
8805 test_65j() { # bug6367
8806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8807
8808         sync; sleep 1
8809
8810         # if we aren't already remounting for each test, do so for this test
8811         if [ "$I_MOUNTED" = "yes" ]; then
8812                 cleanup || error "failed to unmount"
8813                 setup
8814         fi
8815
8816         save_layout_restore_at_exit $MOUNT
8817
8818         $LFS setstripe -d $MOUNT || error "setstripe failed"
8819 }
8820 run_test 65j "set default striping on root directory (bug 6367)="
8821
8822 cleanup_65k() {
8823         rm -rf $DIR/$tdir
8824         wait_delete_completed
8825         do_facet $SINGLEMDS "lctl set_param -n \
8826                 osp.$ost*MDT0000.max_create_count=$max_count"
8827         do_facet $SINGLEMDS "lctl set_param -n \
8828                 osp.$ost*MDT0000.create_count=$count"
8829         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8830         echo $INACTIVE_OSC "is Activate"
8831
8832         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8833 }
8834
8835 test_65k() { # bug11679
8836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8837         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8838         remote_mds_nodsh && skip "remote MDS with nodsh"
8839
8840         local disable_precreate=true
8841         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8842                 disable_precreate=false
8843
8844         echo "Check OST status: "
8845         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8846                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8847
8848         for OSC in $MDS_OSCS; do
8849                 echo $OSC "is active"
8850                 do_facet $SINGLEMDS lctl --device %$OSC activate
8851         done
8852
8853         for INACTIVE_OSC in $MDS_OSCS; do
8854                 local ost=$(osc_to_ost $INACTIVE_OSC)
8855                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8856                                lov.*md*.target_obd |
8857                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8858
8859                 mkdir -p $DIR/$tdir
8860                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8861                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8862
8863                 echo "Deactivate: " $INACTIVE_OSC
8864                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8865
8866                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8867                               osp.$ost*MDT0000.create_count")
8868                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8869                                   osp.$ost*MDT0000.max_create_count")
8870                 $disable_precreate &&
8871                         do_facet $SINGLEMDS "lctl set_param -n \
8872                                 osp.$ost*MDT0000.max_create_count=0"
8873
8874                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8875                         [ -f $DIR/$tdir/$idx ] && continue
8876                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8877                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8878                                 { cleanup_65k;
8879                                   error "setstripe $idx should succeed"; }
8880                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8881                 done
8882                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8883                 rmdir $DIR/$tdir
8884
8885                 do_facet $SINGLEMDS "lctl set_param -n \
8886                         osp.$ost*MDT0000.max_create_count=$max_count"
8887                 do_facet $SINGLEMDS "lctl set_param -n \
8888                         osp.$ost*MDT0000.create_count=$count"
8889                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8890                 echo $INACTIVE_OSC "is Activate"
8891
8892                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8893         done
8894 }
8895 run_test 65k "validate manual striping works properly with deactivated OSCs"
8896
8897 test_65l() { # bug 12836
8898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8899
8900         test_mkdir -p $DIR/$tdir/test_dir
8901         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8902         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8903 }
8904 run_test 65l "lfs find on -1 stripe dir ========================"
8905
8906 test_65m() {
8907         local layout=$(save_layout $MOUNT)
8908         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8909                 restore_layout $MOUNT $layout
8910                 error "setstripe should fail by non-root users"
8911         }
8912         true
8913 }
8914 run_test 65m "normal user can't set filesystem default stripe"
8915
8916 test_65n() {
8917         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8918         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8919                 skip "Need MDS version at least 2.12.50"
8920         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8921
8922         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8923         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8924         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8925
8926         save_layout_restore_at_exit $MOUNT
8927
8928         # new subdirectory under root directory should not inherit
8929         # the default layout from root
8930         local dir1=$MOUNT/$tdir-1
8931         mkdir $dir1 || error "mkdir $dir1 failed"
8932         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8933                 error "$dir1 shouldn't have LOV EA"
8934
8935         # delete the default layout on root directory
8936         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8937
8938         local dir2=$MOUNT/$tdir-2
8939         mkdir $dir2 || error "mkdir $dir2 failed"
8940         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8941                 error "$dir2 shouldn't have LOV EA"
8942
8943         # set a new striping pattern on root directory
8944         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8945         local new_def_stripe_size=$((def_stripe_size * 2))
8946         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8947                 error "set stripe size on $MOUNT failed"
8948
8949         # new file created in $dir2 should inherit the new stripe size from
8950         # the filesystem default
8951         local file2=$dir2/$tfile-2
8952         touch $file2 || error "touch $file2 failed"
8953
8954         local file2_stripe_size=$($LFS getstripe -S $file2)
8955         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8956         {
8957                 echo "file2_stripe_size: '$file2_stripe_size'"
8958                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8959                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8960         }
8961
8962         local dir3=$MOUNT/$tdir-3
8963         mkdir $dir3 || error "mkdir $dir3 failed"
8964         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8965         # the root layout, which is the actual default layout that will be used
8966         # when new files are created in $dir3.
8967         local dir3_layout=$(get_layout_param $dir3)
8968         local root_dir_layout=$(get_layout_param $MOUNT)
8969         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8970         {
8971                 echo "dir3_layout: '$dir3_layout'"
8972                 echo "root_dir_layout: '$root_dir_layout'"
8973                 error "$dir3 should show the default layout from $MOUNT"
8974         }
8975
8976         # set OST pool on root directory
8977         local pool=$TESTNAME
8978         pool_add $pool || error "add $pool failed"
8979         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8980                 error "add targets to $pool failed"
8981
8982         $LFS setstripe -p $pool $MOUNT ||
8983                 error "set OST pool on $MOUNT failed"
8984
8985         # new file created in $dir3 should inherit the pool from
8986         # the filesystem default
8987         local file3=$dir3/$tfile-3
8988         touch $file3 || error "touch $file3 failed"
8989
8990         local file3_pool=$($LFS getstripe -p $file3)
8991         [[ "$file3_pool" = "$pool" ]] ||
8992                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8993
8994         local dir4=$MOUNT/$tdir-4
8995         mkdir $dir4 || error "mkdir $dir4 failed"
8996         local dir4_layout=$(get_layout_param $dir4)
8997         root_dir_layout=$(get_layout_param $MOUNT)
8998         echo "$LFS getstripe -d $dir4"
8999         $LFS getstripe -d $dir4
9000         echo "$LFS getstripe -d $MOUNT"
9001         $LFS getstripe -d $MOUNT
9002         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9003         {
9004                 echo "dir4_layout: '$dir4_layout'"
9005                 echo "root_dir_layout: '$root_dir_layout'"
9006                 error "$dir4 should show the default layout from $MOUNT"
9007         }
9008
9009         # new file created in $dir4 should inherit the pool from
9010         # the filesystem default
9011         local file4=$dir4/$tfile-4
9012         touch $file4 || error "touch $file4 failed"
9013
9014         local file4_pool=$($LFS getstripe -p $file4)
9015         [[ "$file4_pool" = "$pool" ]] ||
9016                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9017
9018         # new subdirectory under non-root directory should inherit
9019         # the default layout from its parent directory
9020         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9021                 error "set directory layout on $dir4 failed"
9022
9023         local dir5=$dir4/$tdir-5
9024         mkdir $dir5 || error "mkdir $dir5 failed"
9025
9026         dir4_layout=$(get_layout_param $dir4)
9027         local dir5_layout=$(get_layout_param $dir5)
9028         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9029         {
9030                 echo "dir4_layout: '$dir4_layout'"
9031                 echo "dir5_layout: '$dir5_layout'"
9032                 error "$dir5 should inherit the default layout from $dir4"
9033         }
9034
9035         # though subdir under ROOT doesn't inherit default layout, but
9036         # its sub dir/file should be created with default layout.
9037         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9038         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9039                 skip "Need MDS version at least 2.12.59"
9040
9041         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9042         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9043         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9044
9045         if [ $default_lmv_hash == "none" ]; then
9046                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9047         else
9048                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9049                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9050         fi
9051
9052         $LFS setdirstripe -D -c 2 $MOUNT ||
9053                 error "setdirstripe -D -c 2 failed"
9054         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9055         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9056         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9057 }
9058 run_test 65n "don't inherit default layout from root for new subdirectories"
9059
9060 # bug 2543 - update blocks count on client
9061 test_66() {
9062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9063
9064         COUNT=${COUNT:-8}
9065         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9066         sync; sync_all_data; sync; sync_all_data
9067         cancel_lru_locks osc
9068         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9069         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9070 }
9071 run_test 66 "update inode blocks count on client ==============="
9072
9073 meminfo() {
9074         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9075 }
9076
9077 swap_used() {
9078         swapon -s | awk '($1 == "'$1'") { print $4 }'
9079 }
9080
9081 # bug5265, obdfilter oa2dentry return -ENOENT
9082 # #define OBD_FAIL_SRV_ENOENT 0x217
9083 test_69() {
9084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9085         remote_ost_nodsh && skip "remote OST with nodsh"
9086
9087         f="$DIR/$tfile"
9088         $LFS setstripe -c 1 -i 0 $f
9089
9090         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9091
9092         do_facet ost1 lctl set_param fail_loc=0x217
9093         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9094         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9095
9096         do_facet ost1 lctl set_param fail_loc=0
9097         $DIRECTIO write $f 0 2 || error "write error"
9098
9099         cancel_lru_locks osc
9100         $DIRECTIO read $f 0 1 || error "read error"
9101
9102         do_facet ost1 lctl set_param fail_loc=0x217
9103         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9104
9105         do_facet ost1 lctl set_param fail_loc=0
9106         rm -f $f
9107 }
9108 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9109
9110 test_71() {
9111         test_mkdir $DIR/$tdir
9112         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9113         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9114 }
9115 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9116
9117 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9119         [ "$RUNAS_ID" = "$UID" ] &&
9120                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9121         # Check that testing environment is properly set up. Skip if not
9122         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9123                 skip_env "User $RUNAS_ID does not exist - skipping"
9124
9125         touch $DIR/$tfile
9126         chmod 777 $DIR/$tfile
9127         chmod ug+s $DIR/$tfile
9128         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9129                 error "$RUNAS dd $DIR/$tfile failed"
9130         # See if we are still setuid/sgid
9131         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9132                 error "S/gid is not dropped on write"
9133         # Now test that MDS is updated too
9134         cancel_lru_locks mdc
9135         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9136                 error "S/gid is not dropped on MDS"
9137         rm -f $DIR/$tfile
9138 }
9139 run_test 72a "Test that remove suid works properly (bug5695) ===="
9140
9141 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9142         local perm
9143
9144         [ "$RUNAS_ID" = "$UID" ] &&
9145                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9146         [ "$RUNAS_ID" -eq 0 ] &&
9147                 skip_env "RUNAS_ID = 0 -- skipping"
9148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9149         # Check that testing environment is properly set up. Skip if not
9150         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9151                 skip_env "User $RUNAS_ID does not exist - skipping"
9152
9153         touch $DIR/${tfile}-f{g,u}
9154         test_mkdir $DIR/${tfile}-dg
9155         test_mkdir $DIR/${tfile}-du
9156         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9157         chmod g+s $DIR/${tfile}-{f,d}g
9158         chmod u+s $DIR/${tfile}-{f,d}u
9159         for perm in 777 2777 4777; do
9160                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9161                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9162                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9163                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9164         done
9165         true
9166 }
9167 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9168
9169 # bug 3462 - multiple simultaneous MDC requests
9170 test_73() {
9171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9172
9173         test_mkdir $DIR/d73-1
9174         test_mkdir $DIR/d73-2
9175         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9176         pid1=$!
9177
9178         lctl set_param fail_loc=0x80000129
9179         $MULTIOP $DIR/d73-1/f73-2 Oc &
9180         sleep 1
9181         lctl set_param fail_loc=0
9182
9183         $MULTIOP $DIR/d73-2/f73-3 Oc &
9184         pid3=$!
9185
9186         kill -USR1 $pid1
9187         wait $pid1 || return 1
9188
9189         sleep 25
9190
9191         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9192         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9193         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9194
9195         rm -rf $DIR/d73-*
9196 }
9197 run_test 73 "multiple MDC requests (should not deadlock)"
9198
9199 test_74a() { # bug 6149, 6184
9200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9201
9202         touch $DIR/f74a
9203         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9204         #
9205         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9206         # will spin in a tight reconnection loop
9207         $LCTL set_param fail_loc=0x8000030e
9208         # get any lock that won't be difficult - lookup works.
9209         ls $DIR/f74a
9210         $LCTL set_param fail_loc=0
9211         rm -f $DIR/f74a
9212         true
9213 }
9214 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9215
9216 test_74b() { # bug 13310
9217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9218
9219         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9220         #
9221         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9222         # will spin in a tight reconnection loop
9223         $LCTL set_param fail_loc=0x8000030e
9224         # get a "difficult" lock
9225         touch $DIR/f74b
9226         $LCTL set_param fail_loc=0
9227         rm -f $DIR/f74b
9228         true
9229 }
9230 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9231
9232 test_74c() {
9233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9234
9235         #define OBD_FAIL_LDLM_NEW_LOCK
9236         $LCTL set_param fail_loc=0x319
9237         touch $DIR/$tfile && error "touch successful"
9238         $LCTL set_param fail_loc=0
9239         true
9240 }
9241 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9242
9243 slab_lic=/sys/kernel/slab/lustre_inode_cache
9244 num_objects() {
9245         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9246         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9247                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9248 }
9249
9250 test_76a() { # Now for b=20433, added originally in b=1443
9251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9252
9253         cancel_lru_locks osc
9254         # there may be some slab objects cached per core
9255         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9256         local before=$(num_objects)
9257         local count=$((512 * cpus))
9258         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9259         local margin=$((count / 10))
9260         if [[ -f $slab_lic/aliases ]]; then
9261                 local aliases=$(cat $slab_lic/aliases)
9262                 (( aliases > 0 )) && margin=$((margin * aliases))
9263         fi
9264
9265         echo "before slab objects: $before"
9266         for i in $(seq $count); do
9267                 touch $DIR/$tfile
9268                 rm -f $DIR/$tfile
9269         done
9270         cancel_lru_locks osc
9271         local after=$(num_objects)
9272         echo "created: $count, after slab objects: $after"
9273         # shared slab counts are not very accurate, allow significant margin
9274         # the main goal is that the cache growth is not permanently > $count
9275         while (( after > before + margin )); do
9276                 sleep 1
9277                 after=$(num_objects)
9278                 wait=$((wait + 1))
9279                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9280                 if (( wait > 60 )); then
9281                         error "inode slab grew from $before+$margin to $after"
9282                 fi
9283         done
9284 }
9285 run_test 76a "confirm clients recycle inodes properly ===="
9286
9287 test_76b() {
9288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9289         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9290
9291         local count=512
9292         local before=$(num_objects)
9293
9294         for i in $(seq $count); do
9295                 mkdir $DIR/$tdir
9296                 rmdir $DIR/$tdir
9297         done
9298
9299         local after=$(num_objects)
9300         local wait=0
9301
9302         while (( after > before )); do
9303                 sleep 1
9304                 after=$(num_objects)
9305                 wait=$((wait + 1))
9306                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9307                 if (( wait > 60 )); then
9308                         error "inode slab grew from $before to $after"
9309                 fi
9310         done
9311
9312         echo "slab objects before: $before, after: $after"
9313 }
9314 run_test 76b "confirm clients recycle directory inodes properly ===="
9315
9316 export ORIG_CSUM=""
9317 set_checksums()
9318 {
9319         # Note: in sptlrpc modes which enable its own bulk checksum, the
9320         # original crc32_le bulk checksum will be automatically disabled,
9321         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9322         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9323         # In this case set_checksums() will not be no-op, because sptlrpc
9324         # bulk checksum will be enabled all through the test.
9325
9326         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9327         lctl set_param -n osc.*.checksums $1
9328         return 0
9329 }
9330
9331 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9332                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9333 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9334                              tr -d [] | head -n1)}
9335 set_checksum_type()
9336 {
9337         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9338         rc=$?
9339         log "set checksum type to $1, rc = $rc"
9340         return $rc
9341 }
9342
9343 get_osc_checksum_type()
9344 {
9345         # arugment 1: OST name, like OST0000
9346         ost=$1
9347         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9348                         sed 's/.*\[\(.*\)\].*/\1/g')
9349         rc=$?
9350         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9351         echo $checksum_type
9352 }
9353
9354 F77_TMP=$TMP/f77-temp
9355 F77SZ=8
9356 setup_f77() {
9357         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9358                 error "error writing to $F77_TMP"
9359 }
9360
9361 test_77a() { # 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         set_checksums 1
9367         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9368         set_checksums 0
9369         rm -f $DIR/$tfile
9370 }
9371 run_test 77a "normal checksum read/write operation"
9372
9373 test_77b() { # bug 10889
9374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9375         $GSS && skip_env "could not run with gss"
9376
9377         [ ! -f $F77_TMP ] && setup_f77
9378         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9379         $LCTL set_param fail_loc=0x80000409
9380         set_checksums 1
9381
9382         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9383                 error "dd error: $?"
9384         $LCTL set_param fail_loc=0
9385
9386         for algo in $CKSUM_TYPES; do
9387                 cancel_lru_locks osc
9388                 set_checksum_type $algo
9389                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9390                 $LCTL set_param fail_loc=0x80000408
9391                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9392                 $LCTL set_param fail_loc=0
9393         done
9394         set_checksums 0
9395         set_checksum_type $ORIG_CSUM_TYPE
9396         rm -f $DIR/$tfile
9397 }
9398 run_test 77b "checksum error on client write, read"
9399
9400 cleanup_77c() {
9401         trap 0
9402         set_checksums 0
9403         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9404         $check_ost &&
9405                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9406         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9407         $check_ost && [ -n "$ost_file_prefix" ] &&
9408                 do_facet ost1 rm -f ${ost_file_prefix}\*
9409 }
9410
9411 test_77c() {
9412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9413         $GSS && skip_env "could not run with gss"
9414         remote_ost_nodsh && skip "remote OST with nodsh"
9415
9416         local bad1
9417         local osc_file_prefix
9418         local osc_file
9419         local check_ost=false
9420         local ost_file_prefix
9421         local ost_file
9422         local orig_cksum
9423         local dump_cksum
9424         local fid
9425
9426         # ensure corruption will occur on first OSS/OST
9427         $LFS setstripe -i 0 $DIR/$tfile
9428
9429         [ ! -f $F77_TMP ] && setup_f77
9430         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9431                 error "dd write error: $?"
9432         fid=$($LFS path2fid $DIR/$tfile)
9433
9434         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9435         then
9436                 check_ost=true
9437                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9438                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9439         else
9440                 echo "OSS do not support bulk pages dump upon error"
9441         fi
9442
9443         osc_file_prefix=$($LCTL get_param -n debug_path)
9444         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9445
9446         trap cleanup_77c EXIT
9447
9448         set_checksums 1
9449         # enable bulk pages dump upon error on Client
9450         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9451         # enable bulk pages dump upon error on OSS
9452         $check_ost &&
9453                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9454
9455         # flush Client cache to allow next read to reach OSS
9456         cancel_lru_locks osc
9457
9458         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9459         $LCTL set_param fail_loc=0x80000408
9460         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9461         $LCTL set_param fail_loc=0
9462
9463         rm -f $DIR/$tfile
9464
9465         # check cksum dump on Client
9466         osc_file=$(ls ${osc_file_prefix}*)
9467         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9468         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9469         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9470         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9471         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9472                      cksum)
9473         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9474         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9475                 error "dump content does not match on Client"
9476
9477         $check_ost || skip "No need to check cksum dump on OSS"
9478
9479         # check cksum dump on OSS
9480         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9481         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9482         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9483         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9484         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9485                 error "dump content does not match on OSS"
9486
9487         cleanup_77c
9488 }
9489 run_test 77c "checksum error on client read with debug"
9490
9491 test_77d() { # bug 10889
9492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9493         $GSS && skip_env "could not run with gss"
9494
9495         stack_trap "rm -f $DIR/$tfile"
9496         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9497         $LCTL set_param fail_loc=0x80000409
9498         set_checksums 1
9499         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9500                 error "direct write: rc=$?"
9501         $LCTL set_param fail_loc=0
9502         set_checksums 0
9503
9504         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9505         $LCTL set_param fail_loc=0x80000408
9506         set_checksums 1
9507         cancel_lru_locks osc
9508         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9509                 error "direct read: rc=$?"
9510         $LCTL set_param fail_loc=0
9511         set_checksums 0
9512 }
9513 run_test 77d "checksum error on OST direct write, read"
9514
9515 test_77f() { # bug 10889
9516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9517         $GSS && skip_env "could not run with gss"
9518
9519         set_checksums 1
9520         stack_trap "rm -f $DIR/$tfile"
9521         for algo in $CKSUM_TYPES; do
9522                 cancel_lru_locks osc
9523                 set_checksum_type $algo
9524                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9525                 $LCTL set_param fail_loc=0x409
9526                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9527                         error "direct write succeeded"
9528                 $LCTL set_param fail_loc=0
9529         done
9530         set_checksum_type $ORIG_CSUM_TYPE
9531         set_checksums 0
9532 }
9533 run_test 77f "repeat checksum error on write (expect error)"
9534
9535 test_77g() { # bug 10889
9536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9537         $GSS && skip_env "could not run with gss"
9538         remote_ost_nodsh && skip "remote OST with nodsh"
9539
9540         [ ! -f $F77_TMP ] && setup_f77
9541
9542         local file=$DIR/$tfile
9543         stack_trap "rm -f $file" EXIT
9544
9545         $LFS setstripe -c 1 -i 0 $file
9546         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9547         do_facet ost1 lctl set_param fail_loc=0x8000021a
9548         set_checksums 1
9549         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9550                 error "write error: rc=$?"
9551         do_facet ost1 lctl set_param fail_loc=0
9552         set_checksums 0
9553
9554         cancel_lru_locks osc
9555         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9556         do_facet ost1 lctl set_param fail_loc=0x8000021b
9557         set_checksums 1
9558         cmp $F77_TMP $file || error "file compare failed"
9559         do_facet ost1 lctl set_param fail_loc=0
9560         set_checksums 0
9561 }
9562 run_test 77g "checksum error on OST write, read"
9563
9564 test_77k() { # LU-10906
9565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9566         $GSS && skip_env "could not run with gss"
9567
9568         local cksum_param="osc.$FSNAME*.checksums"
9569         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9570         local checksum
9571         local i
9572
9573         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9574         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9575         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9576
9577         for i in 0 1; do
9578                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9579                         error "failed to set checksum=$i on MGS"
9580                 wait_update $HOSTNAME "$get_checksum" $i
9581                 #remount
9582                 echo "remount client, checksum should be $i"
9583                 remount_client $MOUNT || error "failed to remount client"
9584                 checksum=$(eval $get_checksum)
9585                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9586         done
9587         # remove persistent param to avoid races with checksum mountopt below
9588         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9589                 error "failed to delete checksum on MGS"
9590
9591         for opt in "checksum" "nochecksum"; do
9592                 #remount with mount option
9593                 echo "remount client with option $opt, checksum should be $i"
9594                 umount_client $MOUNT || error "failed to umount client"
9595                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9596                         error "failed to mount client with option '$opt'"
9597                 checksum=$(eval $get_checksum)
9598                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9599                 i=$((i - 1))
9600         done
9601
9602         remount_client $MOUNT || error "failed to remount client"
9603 }
9604 run_test 77k "enable/disable checksum correctly"
9605
9606 test_77l() {
9607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9608         $GSS && skip_env "could not run with gss"
9609
9610         set_checksums 1
9611         stack_trap "set_checksums $ORIG_CSUM" EXIT
9612         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9613
9614         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9615
9616         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9617         for algo in $CKSUM_TYPES; do
9618                 set_checksum_type $algo || error "fail to set checksum type $algo"
9619                 osc_algo=$(get_osc_checksum_type OST0000)
9620                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9621
9622                 # no locks, no reqs to let the connection idle
9623                 cancel_lru_locks osc
9624                 lru_resize_disable osc
9625                 wait_osc_import_state client ost1 IDLE
9626
9627                 # ensure ost1 is connected
9628                 stat $DIR/$tfile >/dev/null || error "can't stat"
9629                 wait_osc_import_state client ost1 FULL
9630
9631                 osc_algo=$(get_osc_checksum_type OST0000)
9632                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9633         done
9634         return 0
9635 }
9636 run_test 77l "preferred checksum type is remembered after reconnected"
9637
9638 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9639 rm -f $F77_TMP
9640 unset F77_TMP
9641
9642 test_77m() {
9643         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9644                 skip "Need at least version 2.14.52"
9645         local param=checksum_speed
9646
9647         $LCTL get_param $param || error "reading $param failed"
9648
9649         csum_speeds=$($LCTL get_param -n $param)
9650
9651         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9652                 error "known checksum types are missing"
9653 }
9654 run_test 77m "Verify checksum_speed is correctly read"
9655
9656 check_filefrag_77n() {
9657         local nr_ext=0
9658         local starts=()
9659         local ends=()
9660
9661         while read extidx a b start end rest; do
9662                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9663                         nr_ext=$(( $nr_ext + 1 ))
9664                         starts+=( ${start%..} )
9665                         ends+=( ${end%:} )
9666                 fi
9667         done < <( filefrag -sv $1 )
9668
9669         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9670         return 1
9671 }
9672
9673 test_77n() {
9674         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9675
9676         touch $DIR/$tfile
9677         $TRUNCATE $DIR/$tfile 0
9678         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9679         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9680         check_filefrag_77n $DIR/$tfile ||
9681                 skip "$tfile blocks not contiguous around hole"
9682
9683         set_checksums 1
9684         stack_trap "set_checksums $ORIG_CSUM" EXIT
9685         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9686         stack_trap "rm -f $DIR/$tfile"
9687
9688         for algo in $CKSUM_TYPES; do
9689                 if [[ "$algo" =~ ^t10 ]]; then
9690                         set_checksum_type $algo ||
9691                                 error "fail to set checksum type $algo"
9692                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9693                                 error "fail to read $tfile with $algo"
9694                 fi
9695         done
9696         rm -f $DIR/$tfile
9697         return 0
9698 }
9699 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9700
9701 cleanup_test_78() {
9702         trap 0
9703         rm -f $DIR/$tfile
9704 }
9705
9706 test_78() { # bug 10901
9707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9708         remote_ost || skip_env "local OST"
9709
9710         NSEQ=5
9711         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9712         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9713         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9714         echo "MemTotal: $MEMTOTAL"
9715
9716         # reserve 256MB of memory for the kernel and other running processes,
9717         # and then take 1/2 of the remaining memory for the read/write buffers.
9718         if [ $MEMTOTAL -gt 512 ] ;then
9719                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9720         else
9721                 # for those poor memory-starved high-end clusters...
9722                 MEMTOTAL=$((MEMTOTAL / 2))
9723         fi
9724         echo "Mem to use for directio: $MEMTOTAL"
9725
9726         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9727         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9728         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9729         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9730                 head -n1)
9731         echo "Smallest OST: $SMALLESTOST"
9732         [[ $SMALLESTOST -lt 10240 ]] &&
9733                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9734
9735         trap cleanup_test_78 EXIT
9736
9737         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9738                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9739
9740         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9741         echo "File size: $F78SIZE"
9742         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9743         for i in $(seq 1 $NSEQ); do
9744                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9745                 echo directIO rdwr round $i of $NSEQ
9746                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9747         done
9748
9749         cleanup_test_78
9750 }
9751 run_test 78 "handle large O_DIRECT writes correctly ============"
9752
9753 test_79() { # bug 12743
9754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9755
9756         wait_delete_completed
9757
9758         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9759         BKFREE=$(calc_osc_kbytes kbytesfree)
9760         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9761
9762         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9763         DFTOTAL=`echo $STRING | cut -d, -f1`
9764         DFUSED=`echo $STRING  | cut -d, -f2`
9765         DFAVAIL=`echo $STRING | cut -d, -f3`
9766         DFFREE=$(($DFTOTAL - $DFUSED))
9767
9768         ALLOWANCE=$((64 * $OSTCOUNT))
9769
9770         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9771            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9772                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9773         fi
9774         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9775            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9776                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9777         fi
9778         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9779            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9780                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9781         fi
9782 }
9783 run_test 79 "df report consistency check ======================="
9784
9785 test_80() { # bug 10718
9786         remote_ost_nodsh && skip "remote OST with nodsh"
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788
9789         # relax strong synchronous semantics for slow backends like ZFS
9790         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9791                 local soc="obdfilter.*.sync_lock_cancel"
9792                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9793
9794                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9795                 if [ -z "$save" ]; then
9796                         soc="obdfilter.*.sync_on_lock_cancel"
9797                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9798                 fi
9799
9800                 if [ "$save" != "never" ]; then
9801                         local hosts=$(comma_list $(osts_nodes))
9802
9803                         do_nodes $hosts $LCTL set_param $soc=never
9804                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9805                 fi
9806         fi
9807
9808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9809         sync; sleep 1; sync
9810         local before=$(date +%s)
9811         cancel_lru_locks osc
9812         local after=$(date +%s)
9813         local diff=$((after - before))
9814         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9815
9816         rm -f $DIR/$tfile
9817 }
9818 run_test 80 "Page eviction is equally fast at high offsets too"
9819
9820 test_81a() { # LU-456
9821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9822         remote_ost_nodsh && skip "remote OST with nodsh"
9823
9824         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9825         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9826         do_facet ost1 lctl set_param fail_loc=0x80000228
9827
9828         # write should trigger a retry and success
9829         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9830         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9831         RC=$?
9832         if [ $RC -ne 0 ] ; then
9833                 error "write should success, but failed for $RC"
9834         fi
9835 }
9836 run_test 81a "OST should retry write when get -ENOSPC ==============="
9837
9838 test_81b() { # LU-456
9839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9840         remote_ost_nodsh && skip "remote OST with nodsh"
9841
9842         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9843         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9844         do_facet ost1 lctl set_param fail_loc=0x228
9845
9846         # write should retry several times and return -ENOSPC finally
9847         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9848         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9849         RC=$?
9850         ENOSPC=28
9851         if [ $RC -ne $ENOSPC ] ; then
9852                 error "dd should fail for -ENOSPC, but succeed."
9853         fi
9854 }
9855 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9856
9857 test_99() {
9858         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9859
9860         test_mkdir $DIR/$tdir.cvsroot
9861         chown $RUNAS_ID $DIR/$tdir.cvsroot
9862
9863         cd $TMP
9864         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9865
9866         cd /etc/init.d
9867         # some versions of cvs import exit(1) when asked to import links or
9868         # files they can't read.  ignore those files.
9869         local toignore=$(find . -type l -printf '-I %f\n' -o \
9870                          ! -perm /4 -printf '-I %f\n')
9871         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9872                 $tdir.reposname vtag rtag
9873
9874         cd $DIR
9875         test_mkdir $DIR/$tdir.reposname
9876         chown $RUNAS_ID $DIR/$tdir.reposname
9877         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9878
9879         cd $DIR/$tdir.reposname
9880         $RUNAS touch foo99
9881         $RUNAS cvs add -m 'addmsg' foo99
9882         $RUNAS cvs update
9883         $RUNAS cvs commit -m 'nomsg' foo99
9884         rm -fr $DIR/$tdir.cvsroot
9885 }
9886 run_test 99 "cvs strange file/directory operations"
9887
9888 test_100() {
9889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9890         [[ "$NETTYPE" =~ tcp ]] ||
9891                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9892         remote_ost_nodsh && skip "remote OST with nodsh"
9893         remote_mds_nodsh && skip "remote MDS with nodsh"
9894         remote_servers ||
9895                 skip "useless for local single node setup"
9896
9897         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9898                 [ "$PROT" != "tcp" ] && continue
9899                 RPORT=$(echo $REMOTE | cut -d: -f2)
9900                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9901
9902                 rc=0
9903                 LPORT=`echo $LOCAL | cut -d: -f2`
9904                 if [ $LPORT -ge 1024 ]; then
9905                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9906                         netstat -tna
9907                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9908                 fi
9909         done
9910         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9911 }
9912 run_test 100 "check local port using privileged port ==========="
9913
9914 function get_named_value()
9915 {
9916     local tag=$1
9917
9918     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
9919 }
9920
9921 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9922                    awk '/^max_cached_mb/ { print $2 }')
9923
9924 cleanup_101a() {
9925         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9926         trap 0
9927 }
9928
9929 test_101a() {
9930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9931
9932         local s
9933         local discard
9934         local nreads=10000
9935         local cache_limit=32
9936
9937         $LCTL set_param -n osc.*-osc*.rpc_stats=0
9938         trap cleanup_101a EXIT
9939         $LCTL set_param -n llite.*.read_ahead_stats=0
9940         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
9941
9942         #
9943         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9944         #
9945         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9946         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9947
9948         discard=0
9949         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9950                    get_named_value 'read.but.discarded'); do
9951                         discard=$(($discard + $s))
9952         done
9953         cleanup_101a
9954
9955         $LCTL get_param osc.*-osc*.rpc_stats
9956         $LCTL get_param llite.*.read_ahead_stats
9957
9958         # Discard is generally zero, but sometimes a few random reads line up
9959         # and trigger larger readahead, which is wasted & leads to discards.
9960         if [[ $(($discard)) -gt $nreads ]]; then
9961                 error "too many ($discard) discarded pages"
9962         fi
9963         rm -f $DIR/$tfile || true
9964 }
9965 run_test 101a "check read-ahead for random reads"
9966
9967 setup_test101bc() {
9968         test_mkdir $DIR/$tdir
9969         local ssize=$1
9970         local FILE_LENGTH=$2
9971         STRIPE_OFFSET=0
9972
9973         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9974
9975         local list=$(comma_list $(osts_nodes))
9976         set_osd_param $list '' read_cache_enable 0
9977         set_osd_param $list '' writethrough_cache_enable 0
9978
9979         trap cleanup_test101bc EXIT
9980         # prepare the read-ahead file
9981         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9982
9983         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9984                                 count=$FILE_SIZE_MB 2> /dev/null
9985
9986 }
9987
9988 cleanup_test101bc() {
9989         trap 0
9990         rm -rf $DIR/$tdir
9991         rm -f $DIR/$tfile
9992
9993         local list=$(comma_list $(osts_nodes))
9994         set_osd_param $list '' read_cache_enable 1
9995         set_osd_param $list '' writethrough_cache_enable 1
9996 }
9997
9998 calc_total() {
9999         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10000 }
10001
10002 ra_check_101() {
10003         local READ_SIZE=$1
10004         local STRIPE_SIZE=$2
10005         local FILE_LENGTH=$3
10006         local RA_INC=1048576
10007         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10008         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10009                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10010         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10011                   get_named_value 'read.but.discarded' | calc_total)
10012         if [[ $DISCARD -gt $discard_limit ]]; then
10013                 $LCTL get_param llite.*.read_ahead_stats
10014                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10015         else
10016                 echo "Read-ahead success for size ${READ_SIZE}"
10017         fi
10018 }
10019
10020 test_101b() {
10021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10023
10024         local STRIPE_SIZE=1048576
10025         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10026
10027         if [ $SLOW == "yes" ]; then
10028                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10029         else
10030                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10031         fi
10032
10033         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10034
10035         # prepare the read-ahead file
10036         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10037         cancel_lru_locks osc
10038         for BIDX in 2 4 8 16 32 64 128 256
10039         do
10040                 local BSIZE=$((BIDX*4096))
10041                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10042                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10043                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10044                 $LCTL set_param -n llite.*.read_ahead_stats=0
10045                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10046                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10047                 cancel_lru_locks osc
10048                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10049         done
10050         cleanup_test101bc
10051         true
10052 }
10053 run_test 101b "check stride-io mode read-ahead ================="
10054
10055 test_101c() {
10056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10057
10058         local STRIPE_SIZE=1048576
10059         local FILE_LENGTH=$((STRIPE_SIZE*100))
10060         local nreads=10000
10061         local rsize=65536
10062         local osc_rpc_stats
10063
10064         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10065
10066         cancel_lru_locks osc
10067         $LCTL set_param osc.*.rpc_stats=0
10068         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10069         $LCTL get_param osc.*.rpc_stats
10070         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10071                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10072                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10073                 local size
10074
10075                 if [ $lines -le 20 ]; then
10076                         echo "continue debug"
10077                         continue
10078                 fi
10079                 for size in 1 2 4 8; do
10080                         local rpc=$(echo "$stats" |
10081                                     awk '($1 == "'$size':") {print $2; exit; }')
10082                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10083                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10084                 done
10085                 echo "$osc_rpc_stats check passed!"
10086         done
10087         cleanup_test101bc
10088         true
10089 }
10090 run_test 101c "check stripe_size aligned read-ahead"
10091
10092 test_101d() {
10093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10094
10095         local file=$DIR/$tfile
10096         local sz_MB=${FILESIZE_101d:-80}
10097         local ra_MB=${READAHEAD_MB:-40}
10098
10099         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10100         [ $free_MB -lt $sz_MB ] &&
10101                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10102
10103         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10104         $LFS setstripe -c -1 $file || error "setstripe failed"
10105
10106         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10107         echo Cancel LRU locks on lustre client to flush the client cache
10108         cancel_lru_locks osc
10109
10110         echo Disable read-ahead
10111         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10112         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10113         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10114         $LCTL get_param -n llite.*.max_read_ahead_mb
10115
10116         echo "Reading the test file $file with read-ahead disabled"
10117         local sz_KB=$((sz_MB * 1024 / 4))
10118         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10119         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10120         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10121                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10122
10123         echo "Cancel LRU locks on lustre client to flush the client cache"
10124         cancel_lru_locks osc
10125         echo Enable read-ahead with ${ra_MB}MB
10126         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10127
10128         echo "Reading the test file $file with read-ahead enabled"
10129         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10130                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10131
10132         echo "read-ahead disabled time read $raOFF"
10133         echo "read-ahead enabled time read $raON"
10134
10135         rm -f $file
10136         wait_delete_completed
10137
10138         # use awk for this check instead of bash because it handles decimals
10139         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10140                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10141 }
10142 run_test 101d "file read with and without read-ahead enabled"
10143
10144 test_101e() {
10145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10146
10147         local file=$DIR/$tfile
10148         local size_KB=500  #KB
10149         local count=100
10150         local bsize=1024
10151
10152         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10153         local need_KB=$((count * size_KB))
10154         [[ $free_KB -le $need_KB ]] &&
10155                 skip_env "Need free space $need_KB, have $free_KB"
10156
10157         echo "Creating $count ${size_KB}K test files"
10158         for ((i = 0; i < $count; i++)); do
10159                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10160         done
10161
10162         echo "Cancel LRU locks on lustre client to flush the client cache"
10163         cancel_lru_locks $OSC
10164
10165         echo "Reset readahead stats"
10166         $LCTL set_param -n llite.*.read_ahead_stats=0
10167
10168         for ((i = 0; i < $count; i++)); do
10169                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10170         done
10171
10172         $LCTL get_param llite.*.max_cached_mb
10173         $LCTL get_param llite.*.read_ahead_stats
10174         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10175                      get_named_value 'misses' | calc_total)
10176
10177         for ((i = 0; i < $count; i++)); do
10178                 rm -rf $file.$i 2>/dev/null
10179         done
10180
10181         #10000 means 20% reads are missing in readahead
10182         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10183 }
10184 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10185
10186 test_101f() {
10187         which iozone || skip_env "no iozone installed"
10188
10189         local old_debug=$($LCTL get_param debug)
10190         old_debug=${old_debug#*=}
10191         $LCTL set_param debug="reada mmap"
10192
10193         # create a test file
10194         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10195
10196         echo Cancel LRU locks on lustre client to flush the client cache
10197         cancel_lru_locks osc
10198
10199         echo Reset readahead stats
10200         $LCTL set_param -n llite.*.read_ahead_stats=0
10201
10202         echo mmap read the file with small block size
10203         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10204                 > /dev/null 2>&1
10205
10206         echo checking missing pages
10207         $LCTL get_param llite.*.read_ahead_stats
10208         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10209                         get_named_value 'misses' | calc_total)
10210
10211         $LCTL set_param debug="$old_debug"
10212         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10213         rm -f $DIR/$tfile
10214 }
10215 run_test 101f "check mmap read performance"
10216
10217 test_101g_brw_size_test() {
10218         local mb=$1
10219         local pages=$((mb * 1048576 / PAGE_SIZE))
10220         local file=$DIR/$tfile
10221
10222         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10223                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10224         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10225                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10226                         return 2
10227         done
10228
10229         stack_trap "rm -f $file" EXIT
10230         $LCTL set_param -n osc.*.rpc_stats=0
10231
10232         # 10 RPCs should be enough for the test
10233         local count=10
10234         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10235                 { error "dd write ${mb} MB blocks failed"; return 3; }
10236         cancel_lru_locks osc
10237         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10238                 { error "dd write ${mb} MB blocks failed"; return 4; }
10239
10240         # calculate number of full-sized read and write RPCs
10241         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10242                 sed -n '/pages per rpc/,/^$/p' |
10243                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10244                 END { print reads,writes }'))
10245         # allow one extra full-sized read RPC for async readahead
10246         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10247                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10248         [[ ${rpcs[1]} == $count ]] ||
10249                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10250 }
10251
10252 test_101g() {
10253         remote_ost_nodsh && skip "remote OST with nodsh"
10254
10255         local rpcs
10256         local osts=$(get_facets OST)
10257         local list=$(comma_list $(osts_nodes))
10258         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10259         local brw_size="obdfilter.*.brw_size"
10260
10261         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10262
10263         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10264
10265         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10266                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10267                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10268            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10269                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10270                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10271
10272                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10273                         suffix="M"
10274
10275                 if [[ $orig_mb -lt 16 ]]; then
10276                         save_lustre_params $osts "$brw_size" > $p
10277                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10278                                 error "set 16MB RPC size failed"
10279
10280                         echo "remount client to enable new RPC size"
10281                         remount_client $MOUNT || error "remount_client failed"
10282                 fi
10283
10284                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10285                 # should be able to set brw_size=12, but no rpc_stats for that
10286                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10287         fi
10288
10289         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10290
10291         if [[ $orig_mb -lt 16 ]]; then
10292                 restore_lustre_params < $p
10293                 remount_client $MOUNT || error "remount_client restore failed"
10294         fi
10295
10296         rm -f $p $DIR/$tfile
10297 }
10298 run_test 101g "Big bulk(4/16 MiB) readahead"
10299
10300 test_101h() {
10301         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10302
10303         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10304                 error "dd 70M file failed"
10305         echo Cancel LRU locks on lustre client to flush the client cache
10306         cancel_lru_locks osc
10307
10308         echo "Reset readahead stats"
10309         $LCTL set_param -n llite.*.read_ahead_stats 0
10310
10311         echo "Read 10M of data but cross 64M bundary"
10312         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10313         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10314                      get_named_value 'misses' | calc_total)
10315         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10316         rm -f $p $DIR/$tfile
10317 }
10318 run_test 101h "Readahead should cover current read window"
10319
10320 test_101i() {
10321         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10322                 error "dd 10M file failed"
10323
10324         local max_per_file_mb=$($LCTL get_param -n \
10325                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10326         cancel_lru_locks osc
10327         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10328         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10329                 error "set max_read_ahead_per_file_mb to 1 failed"
10330
10331         echo "Reset readahead stats"
10332         $LCTL set_param llite.*.read_ahead_stats=0
10333
10334         dd if=$DIR/$tfile of=/dev/null bs=2M
10335
10336         $LCTL get_param llite.*.read_ahead_stats
10337         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10338                      awk '/misses/ { print $2 }')
10339         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10340         rm -f $DIR/$tfile
10341 }
10342 run_test 101i "allow current readahead to exceed reservation"
10343
10344 test_101j() {
10345         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10346                 error "setstripe $DIR/$tfile failed"
10347         local file_size=$((1048576 * 16))
10348         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10349         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10350
10351         echo Disable read-ahead
10352         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10353
10354         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10355         for blk in $PAGE_SIZE 1048576 $file_size; do
10356                 cancel_lru_locks osc
10357                 echo "Reset readahead stats"
10358                 $LCTL set_param -n llite.*.read_ahead_stats=0
10359                 local count=$(($file_size / $blk))
10360                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10361                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10362                              get_named_value 'failed.to.fast.read' | calc_total)
10363                 $LCTL get_param -n llite.*.read_ahead_stats
10364                 [ $miss -eq $count ] || error "expected $count got $miss"
10365         done
10366
10367         rm -f $p $DIR/$tfile
10368 }
10369 run_test 101j "A complete read block should be submitted when no RA"
10370
10371 setup_test102() {
10372         test_mkdir $DIR/$tdir
10373         chown $RUNAS_ID $DIR/$tdir
10374         STRIPE_SIZE=65536
10375         STRIPE_OFFSET=1
10376         STRIPE_COUNT=$OSTCOUNT
10377         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10378
10379         trap cleanup_test102 EXIT
10380         cd $DIR
10381         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10382         cd $DIR/$tdir
10383         for num in 1 2 3 4; do
10384                 for count in $(seq 1 $STRIPE_COUNT); do
10385                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10386                                 local size=`expr $STRIPE_SIZE \* $num`
10387                                 local file=file"$num-$idx-$count"
10388                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10389                         done
10390                 done
10391         done
10392
10393         cd $DIR
10394         $1 tar cf $TMP/f102.tar $tdir --xattrs
10395 }
10396
10397 cleanup_test102() {
10398         trap 0
10399         rm -f $TMP/f102.tar
10400         rm -rf $DIR/d0.sanity/d102
10401 }
10402
10403 test_102a() {
10404         [ "$UID" != 0 ] && skip "must run as root"
10405         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10406                 skip_env "must have user_xattr"
10407
10408         [ -z "$(which setfattr 2>/dev/null)" ] &&
10409                 skip_env "could not find setfattr"
10410
10411         local testfile=$DIR/$tfile
10412
10413         touch $testfile
10414         echo "set/get xattr..."
10415         setfattr -n trusted.name1 -v value1 $testfile ||
10416                 error "setfattr -n trusted.name1=value1 $testfile failed"
10417         getfattr -n trusted.name1 $testfile 2> /dev/null |
10418           grep "trusted.name1=.value1" ||
10419                 error "$testfile missing trusted.name1=value1"
10420
10421         setfattr -n user.author1 -v author1 $testfile ||
10422                 error "setfattr -n user.author1=author1 $testfile failed"
10423         getfattr -n user.author1 $testfile 2> /dev/null |
10424           grep "user.author1=.author1" ||
10425                 error "$testfile missing trusted.author1=author1"
10426
10427         echo "listxattr..."
10428         setfattr -n trusted.name2 -v value2 $testfile ||
10429                 error "$testfile unable to set trusted.name2"
10430         setfattr -n trusted.name3 -v value3 $testfile ||
10431                 error "$testfile unable to set trusted.name3"
10432         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10433             grep "trusted.name" | wc -l) -eq 3 ] ||
10434                 error "$testfile missing 3 trusted.name xattrs"
10435
10436         setfattr -n user.author2 -v author2 $testfile ||
10437                 error "$testfile unable to set user.author2"
10438         setfattr -n user.author3 -v author3 $testfile ||
10439                 error "$testfile unable to set user.author3"
10440         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10441             grep "user.author" | wc -l) -eq 3 ] ||
10442                 error "$testfile missing 3 user.author xattrs"
10443
10444         echo "remove xattr..."
10445         setfattr -x trusted.name1 $testfile ||
10446                 error "$testfile error deleting trusted.name1"
10447         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10448                 error "$testfile did not delete trusted.name1 xattr"
10449
10450         setfattr -x user.author1 $testfile ||
10451                 error "$testfile error deleting user.author1"
10452         echo "set lustre special xattr ..."
10453         $LFS setstripe -c1 $testfile
10454         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10455                 awk -F "=" '/trusted.lov/ { print $2 }' )
10456         setfattr -n "trusted.lov" -v $lovea $testfile ||
10457                 error "$testfile doesn't ignore setting trusted.lov again"
10458         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10459                 error "$testfile allow setting invalid trusted.lov"
10460         rm -f $testfile
10461 }
10462 run_test 102a "user xattr test =================================="
10463
10464 check_102b_layout() {
10465         local layout="$*"
10466         local testfile=$DIR/$tfile
10467
10468         echo "test layout '$layout'"
10469         $LFS setstripe $layout $testfile || error "setstripe failed"
10470         $LFS getstripe -y $testfile
10471
10472         echo "get/set/list trusted.lov xattr ..." # b=10930
10473         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10474         [[ "$value" =~ "trusted.lov" ]] ||
10475                 error "can't get trusted.lov from $testfile"
10476         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10477                 error "getstripe failed"
10478
10479         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10480
10481         value=$(cut -d= -f2 <<<$value)
10482         # LU-13168: truncated xattr should fail if short lov_user_md header
10483         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10484                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10485         for len in $lens; do
10486                 echo "setfattr $len $testfile.2"
10487                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10488                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10489         done
10490         local stripe_size=$($LFS getstripe -S $testfile.2)
10491         local stripe_count=$($LFS getstripe -c $testfile.2)
10492         [[ $stripe_size -eq 65536 ]] ||
10493                 error "stripe size $stripe_size != 65536"
10494         [[ $stripe_count -eq $stripe_count_orig ]] ||
10495                 error "stripe count $stripe_count != $stripe_count_orig"
10496         rm $testfile $testfile.2
10497 }
10498
10499 test_102b() {
10500         [ -z "$(which setfattr 2>/dev/null)" ] &&
10501                 skip_env "could not find setfattr"
10502         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10503
10504         # check plain layout
10505         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10506
10507         # and also check composite layout
10508         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10509
10510 }
10511 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10512
10513 test_102c() {
10514         [ -z "$(which setfattr 2>/dev/null)" ] &&
10515                 skip_env "could not find setfattr"
10516         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10517
10518         # b10930: get/set/list lustre.lov xattr
10519         echo "get/set/list lustre.lov xattr ..."
10520         test_mkdir $DIR/$tdir
10521         chown $RUNAS_ID $DIR/$tdir
10522         local testfile=$DIR/$tdir/$tfile
10523         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10524                 error "setstripe failed"
10525         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10526                 error "getstripe failed"
10527         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10528         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10529
10530         local testfile2=${testfile}2
10531         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10532                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10533
10534         $RUNAS $MCREATE $testfile2
10535         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10536         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10537         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10538         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10539         [ $stripe_count -eq $STRIPECOUNT ] ||
10540                 error "stripe count $stripe_count != $STRIPECOUNT"
10541 }
10542 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10543
10544 compare_stripe_info1() {
10545         local stripe_index_all_zero=true
10546
10547         for num in 1 2 3 4; do
10548                 for count in $(seq 1 $STRIPE_COUNT); do
10549                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10550                                 local size=$((STRIPE_SIZE * num))
10551                                 local file=file"$num-$offset-$count"
10552                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10553                                 [[ $stripe_size -ne $size ]] &&
10554                                     error "$file: size $stripe_size != $size"
10555                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10556                                 # allow fewer stripes to be created, ORI-601
10557                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10558                                     error "$file: count $stripe_count != $count"
10559                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10560                                 [[ $stripe_index -ne 0 ]] &&
10561                                         stripe_index_all_zero=false
10562                         done
10563                 done
10564         done
10565         $stripe_index_all_zero &&
10566                 error "all files are being extracted starting from OST index 0"
10567         return 0
10568 }
10569
10570 have_xattrs_include() {
10571         tar --help | grep -q xattrs-include &&
10572                 echo --xattrs-include="lustre.*"
10573 }
10574
10575 test_102d() {
10576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10577         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10578
10579         XINC=$(have_xattrs_include)
10580         setup_test102
10581         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10582         cd $DIR/$tdir/$tdir
10583         compare_stripe_info1
10584 }
10585 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10586
10587 test_102f() {
10588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10589         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10590
10591         XINC=$(have_xattrs_include)
10592         setup_test102
10593         test_mkdir $DIR/$tdir.restore
10594         cd $DIR
10595         tar cf - --xattrs $tdir | tar xf - \
10596                 -C $DIR/$tdir.restore --xattrs $XINC
10597         cd $DIR/$tdir.restore/$tdir
10598         compare_stripe_info1
10599 }
10600 run_test 102f "tar copy files, not keep osts"
10601
10602 grow_xattr() {
10603         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10604                 skip "must have user_xattr"
10605         [ -z "$(which setfattr 2>/dev/null)" ] &&
10606                 skip_env "could not find setfattr"
10607         [ -z "$(which getfattr 2>/dev/null)" ] &&
10608                 skip_env "could not find getfattr"
10609
10610         local xsize=${1:-1024}  # in bytes
10611         local file=$DIR/$tfile
10612         local value="$(generate_string $xsize)"
10613         local xbig=trusted.big
10614         local toobig=$2
10615
10616         touch $file
10617         log "save $xbig on $file"
10618         if [ -z "$toobig" ]
10619         then
10620                 setfattr -n $xbig -v $value $file ||
10621                         error "saving $xbig on $file failed"
10622         else
10623                 setfattr -n $xbig -v $value $file &&
10624                         error "saving $xbig on $file succeeded"
10625                 return 0
10626         fi
10627
10628         local orig=$(get_xattr_value $xbig $file)
10629         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10630
10631         local xsml=trusted.sml
10632         log "save $xsml on $file"
10633         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10634
10635         local new=$(get_xattr_value $xbig $file)
10636         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10637
10638         log "grow $xsml on $file"
10639         setfattr -n $xsml -v "$value" $file ||
10640                 error "growing $xsml on $file failed"
10641
10642         new=$(get_xattr_value $xbig $file)
10643         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10644         log "$xbig still valid after growing $xsml"
10645
10646         rm -f $file
10647 }
10648
10649 test_102h() { # bug 15777
10650         grow_xattr 1024
10651 }
10652 run_test 102h "grow xattr from inside inode to external block"
10653
10654 test_102ha() {
10655         large_xattr_enabled || skip_env "ea_inode feature disabled"
10656
10657         echo "setting xattr of max xattr size: $(max_xattr_size)"
10658         grow_xattr $(max_xattr_size)
10659
10660         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10661         echo "This should fail:"
10662         grow_xattr $(($(max_xattr_size) + 10)) 1
10663 }
10664 run_test 102ha "grow xattr from inside inode to external inode"
10665
10666 test_102i() { # bug 17038
10667         [ -z "$(which getfattr 2>/dev/null)" ] &&
10668                 skip "could not find getfattr"
10669
10670         touch $DIR/$tfile
10671         ln -s $DIR/$tfile $DIR/${tfile}link
10672         getfattr -n trusted.lov $DIR/$tfile ||
10673                 error "lgetxattr on $DIR/$tfile failed"
10674         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10675                 grep -i "no such attr" ||
10676                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10677         rm -f $DIR/$tfile $DIR/${tfile}link
10678 }
10679 run_test 102i "lgetxattr test on symbolic link ============"
10680
10681 test_102j() {
10682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10683         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10684
10685         XINC=$(have_xattrs_include)
10686         setup_test102 "$RUNAS"
10687         chown $RUNAS_ID $DIR/$tdir
10688         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10689         cd $DIR/$tdir/$tdir
10690         compare_stripe_info1 "$RUNAS"
10691 }
10692 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10693
10694 test_102k() {
10695         [ -z "$(which setfattr 2>/dev/null)" ] &&
10696                 skip "could not find setfattr"
10697
10698         touch $DIR/$tfile
10699         # b22187 just check that does not crash for regular file.
10700         setfattr -n trusted.lov $DIR/$tfile
10701         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10702         local test_kdir=$DIR/$tdir
10703         test_mkdir $test_kdir
10704         local default_size=$($LFS getstripe -S $test_kdir)
10705         local default_count=$($LFS getstripe -c $test_kdir)
10706         local default_offset=$($LFS getstripe -i $test_kdir)
10707         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10708                 error 'dir setstripe failed'
10709         setfattr -n trusted.lov $test_kdir
10710         local stripe_size=$($LFS getstripe -S $test_kdir)
10711         local stripe_count=$($LFS getstripe -c $test_kdir)
10712         local stripe_offset=$($LFS getstripe -i $test_kdir)
10713         [ $stripe_size -eq $default_size ] ||
10714                 error "stripe size $stripe_size != $default_size"
10715         [ $stripe_count -eq $default_count ] ||
10716                 error "stripe count $stripe_count != $default_count"
10717         [ $stripe_offset -eq $default_offset ] ||
10718                 error "stripe offset $stripe_offset != $default_offset"
10719         rm -rf $DIR/$tfile $test_kdir
10720 }
10721 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10722
10723 test_102l() {
10724         [ -z "$(which getfattr 2>/dev/null)" ] &&
10725                 skip "could not find getfattr"
10726
10727         # LU-532 trusted. xattr is invisible to non-root
10728         local testfile=$DIR/$tfile
10729
10730         touch $testfile
10731
10732         echo "listxattr as user..."
10733         chown $RUNAS_ID $testfile
10734         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10735             grep -q "trusted" &&
10736                 error "$testfile trusted xattrs are user visible"
10737
10738         return 0;
10739 }
10740 run_test 102l "listxattr size test =================================="
10741
10742 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10743         local path=$DIR/$tfile
10744         touch $path
10745
10746         listxattr_size_check $path || error "listattr_size_check $path failed"
10747 }
10748 run_test 102m "Ensure listxattr fails on small bufffer ========"
10749
10750 cleanup_test102
10751
10752 getxattr() { # getxattr path name
10753         # Return the base64 encoding of the value of xattr name on path.
10754         local path=$1
10755         local name=$2
10756
10757         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10758         # file: $path
10759         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10760         #
10761         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10762
10763         getfattr --absolute-names --encoding=base64 --name=$name $path |
10764                 awk -F= -v name=$name '$1 == name {
10765                         print substr($0, index($0, "=") + 1);
10766         }'
10767 }
10768
10769 test_102n() { # LU-4101 mdt: protect internal xattrs
10770         [ -z "$(which setfattr 2>/dev/null)" ] &&
10771                 skip "could not find setfattr"
10772         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10773         then
10774                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10775         fi
10776
10777         local file0=$DIR/$tfile.0
10778         local file1=$DIR/$tfile.1
10779         local xattr0=$TMP/$tfile.0
10780         local xattr1=$TMP/$tfile.1
10781         local namelist="lov lma lmv link fid version som hsm"
10782         local name
10783         local value
10784
10785         rm -rf $file0 $file1 $xattr0 $xattr1
10786         touch $file0 $file1
10787
10788         # Get 'before' xattrs of $file1.
10789         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10790
10791         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10792                 namelist+=" lfsck_namespace"
10793         for name in $namelist; do
10794                 # Try to copy xattr from $file0 to $file1.
10795                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10796
10797                 setfattr --name=trusted.$name --value="$value" $file1 ||
10798                         error "setxattr 'trusted.$name' failed"
10799
10800                 # Try to set a garbage xattr.
10801                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10802
10803                 if [[ x$name == "xlov" ]]; then
10804                         setfattr --name=trusted.lov --value="$value" $file1 &&
10805                         error "setxattr invalid 'trusted.lov' success"
10806                 else
10807                         setfattr --name=trusted.$name --value="$value" $file1 ||
10808                                 error "setxattr invalid 'trusted.$name' failed"
10809                 fi
10810
10811                 # Try to remove the xattr from $file1. We don't care if this
10812                 # appears to succeed or fail, we just don't want there to be
10813                 # any changes or crashes.
10814                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10815         done
10816
10817         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10818         then
10819                 name="lfsck_ns"
10820                 # Try to copy xattr from $file0 to $file1.
10821                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10822
10823                 setfattr --name=trusted.$name --value="$value" $file1 ||
10824                         error "setxattr 'trusted.$name' failed"
10825
10826                 # Try to set a garbage xattr.
10827                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10828
10829                 setfattr --name=trusted.$name --value="$value" $file1 ||
10830                         error "setxattr 'trusted.$name' failed"
10831
10832                 # Try to remove the xattr from $file1. We don't care if this
10833                 # appears to succeed or fail, we just don't want there to be
10834                 # any changes or crashes.
10835                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10836         fi
10837
10838         # Get 'after' xattrs of file1.
10839         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10840
10841         if ! diff $xattr0 $xattr1; then
10842                 error "before and after xattrs of '$file1' differ"
10843         fi
10844
10845         rm -rf $file0 $file1 $xattr0 $xattr1
10846
10847         return 0
10848 }
10849 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10850
10851 test_102p() { # LU-4703 setxattr did not check ownership
10852         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10853                 skip "MDS needs to be at least 2.5.56"
10854
10855         local testfile=$DIR/$tfile
10856
10857         touch $testfile
10858
10859         echo "setfacl as user..."
10860         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10861         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10862
10863         echo "setfattr as user..."
10864         setfacl -m "u:$RUNAS_ID:---" $testfile
10865         $RUNAS setfattr -x system.posix_acl_access $testfile
10866         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10867 }
10868 run_test 102p "check setxattr(2) correctly fails without permission"
10869
10870 test_102q() {
10871         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10872                 skip "MDS needs to be at least 2.6.92"
10873
10874         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10875 }
10876 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10877
10878 test_102r() {
10879         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10880                 skip "MDS needs to be at least 2.6.93"
10881
10882         touch $DIR/$tfile || error "touch"
10883         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10884         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10885         rm $DIR/$tfile || error "rm"
10886
10887         #normal directory
10888         mkdir -p $DIR/$tdir || error "mkdir"
10889         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10890         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10891         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10892                 error "$testfile error deleting user.author1"
10893         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10894                 grep "user.$(basename $tdir)" &&
10895                 error "$tdir did not delete user.$(basename $tdir)"
10896         rmdir $DIR/$tdir || error "rmdir"
10897
10898         #striped directory
10899         test_mkdir $DIR/$tdir
10900         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10901         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10902         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10903                 error "$testfile error deleting user.author1"
10904         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10905                 grep "user.$(basename $tdir)" &&
10906                 error "$tdir did not delete user.$(basename $tdir)"
10907         rmdir $DIR/$tdir || error "rm striped dir"
10908 }
10909 run_test 102r "set EAs with empty values"
10910
10911 test_102s() {
10912         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10913                 skip "MDS needs to be at least 2.11.52"
10914
10915         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10916
10917         save_lustre_params client "llite.*.xattr_cache" > $save
10918
10919         for cache in 0 1; do
10920                 lctl set_param llite.*.xattr_cache=$cache
10921
10922                 rm -f $DIR/$tfile
10923                 touch $DIR/$tfile || error "touch"
10924                 for prefix in lustre security system trusted user; do
10925                         # Note getxattr() may fail with 'Operation not
10926                         # supported' or 'No such attribute' depending
10927                         # on prefix and cache.
10928                         getfattr -n $prefix.n102s $DIR/$tfile &&
10929                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10930                 done
10931         done
10932
10933         restore_lustre_params < $save
10934 }
10935 run_test 102s "getting nonexistent xattrs should fail"
10936
10937 test_102t() {
10938         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10939                 skip "MDS needs to be at least 2.11.52"
10940
10941         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10942
10943         save_lustre_params client "llite.*.xattr_cache" > $save
10944
10945         for cache in 0 1; do
10946                 lctl set_param llite.*.xattr_cache=$cache
10947
10948                 for buf_size in 0 256; do
10949                         rm -f $DIR/$tfile
10950                         touch $DIR/$tfile || error "touch"
10951                         setfattr -n user.multiop $DIR/$tfile
10952                         $MULTIOP $DIR/$tfile oa$buf_size ||
10953                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10954                 done
10955         done
10956
10957         restore_lustre_params < $save
10958 }
10959 run_test 102t "zero length xattr values handled correctly"
10960
10961 run_acl_subtest()
10962 {
10963     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10964     return $?
10965 }
10966
10967 test_103a() {
10968         [ "$UID" != 0 ] && skip "must run as root"
10969         $GSS && skip_env "could not run under gss"
10970         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10971                 skip_env "must have acl enabled"
10972         [ -z "$(which setfacl 2>/dev/null)" ] &&
10973                 skip_env "could not find setfacl"
10974         remote_mds_nodsh && skip "remote MDS with nodsh"
10975
10976         gpasswd -a daemon bin                           # LU-5641
10977         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10978
10979         declare -a identity_old
10980
10981         for num in $(seq $MDSCOUNT); do
10982                 switch_identity $num true || identity_old[$num]=$?
10983         done
10984
10985         SAVE_UMASK=$(umask)
10986         umask 0022
10987         mkdir -p $DIR/$tdir
10988         cd $DIR/$tdir
10989
10990         echo "performing cp ..."
10991         run_acl_subtest cp || error "run_acl_subtest cp failed"
10992         echo "performing getfacl-noacl..."
10993         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10994         echo "performing misc..."
10995         run_acl_subtest misc || error  "misc test failed"
10996         echo "performing permissions..."
10997         run_acl_subtest permissions || error "permissions failed"
10998         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10999         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11000                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11001                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11002         then
11003                 echo "performing permissions xattr..."
11004                 run_acl_subtest permissions_xattr ||
11005                         error "permissions_xattr failed"
11006         fi
11007         echo "performing setfacl..."
11008         run_acl_subtest setfacl || error  "setfacl test failed"
11009
11010         # inheritance test got from HP
11011         echo "performing inheritance..."
11012         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11013         chmod +x make-tree || error "chmod +x failed"
11014         run_acl_subtest inheritance || error "inheritance test failed"
11015         rm -f make-tree
11016
11017         echo "LU-974 ignore umask when acl is enabled..."
11018         run_acl_subtest 974 || error "LU-974 umask test failed"
11019         if [ $MDSCOUNT -ge 2 ]; then
11020                 run_acl_subtest 974_remote ||
11021                         error "LU-974 umask test failed under remote dir"
11022         fi
11023
11024         echo "LU-2561 newly created file is same size as directory..."
11025         if [ "$mds1_FSTYPE" != "zfs" ]; then
11026                 run_acl_subtest 2561 || error "LU-2561 test failed"
11027         else
11028                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11029         fi
11030
11031         run_acl_subtest 4924 || error "LU-4924 test failed"
11032
11033         cd $SAVE_PWD
11034         umask $SAVE_UMASK
11035
11036         for num in $(seq $MDSCOUNT); do
11037                 if [ "${identity_old[$num]}" = 1 ]; then
11038                         switch_identity $num false || identity_old[$num]=$?
11039                 fi
11040         done
11041 }
11042 run_test 103a "acl test"
11043
11044 test_103b() {
11045         declare -a pids
11046         local U
11047
11048         for U in {0..511}; do
11049                 {
11050                 local O=$(printf "%04o" $U)
11051
11052                 umask $(printf "%04o" $((511 ^ $O)))
11053                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11054                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11055
11056                 (( $S == ($O & 0666) )) ||
11057                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11058
11059                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11060                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11061                 (( $S == ($O & 0666) )) ||
11062                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11063
11064                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11065                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11066                 (( $S == ($O & 0666) )) ||
11067                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11068                 rm -f $DIR/$tfile.[smp]$0
11069                 } &
11070                 local pid=$!
11071
11072                 # limit the concurrently running threads to 64. LU-11878
11073                 local idx=$((U % 64))
11074                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11075                 pids[idx]=$pid
11076         done
11077         wait
11078 }
11079 run_test 103b "umask lfs setstripe"
11080
11081 test_103c() {
11082         mkdir -p $DIR/$tdir
11083         cp -rp $DIR/$tdir $DIR/$tdir.bak
11084
11085         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11086                 error "$DIR/$tdir shouldn't contain default ACL"
11087         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11088                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11089         true
11090 }
11091 run_test 103c "'cp -rp' won't set empty acl"
11092
11093 test_103e() {
11094         local numacl
11095         local fileacl
11096         local saved_debug=$($LCTL get_param -n debug)
11097
11098         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11099                 skip "MDS needs to be at least 2.14.0"
11100
11101         large_xattr_enabled || skip_env "ea_inode feature disabled"
11102
11103         mkdir -p $DIR/$tdir
11104         # add big LOV EA to cause reply buffer overflow earlier
11105         $LFS setstripe -C 1000 $DIR/$tdir
11106         lctl set_param mdc.*-mdc*.stats=clear
11107
11108         $LCTL set_param debug=0
11109         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11110         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11111
11112         # add a large number of default ACLs (expect 8000+ for 2.13+)
11113         for U in {2..7000}; do
11114                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11115                         error "Able to add just $U default ACLs"
11116         done
11117         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11118         echo "$numacl default ACLs created"
11119
11120         stat $DIR/$tdir || error "Cannot stat directory"
11121         # check file creation
11122         touch $DIR/$tdir/$tfile ||
11123                 error "failed to create $tfile with $numacl default ACLs"
11124         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11125         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11126         echo "$fileacl ACLs were inherited"
11127         (( $fileacl == $numacl )) ||
11128                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11129         # check that new ACLs creation adds new ACLs to inherited ACLs
11130         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11131                 error "Cannot set new ACL"
11132         numacl=$((numacl + 1))
11133         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11134         (( $fileacl == $numacl )) ||
11135                 error "failed to add new ACL: $fileacl != $numacl as expected"
11136         # adds more ACLs to a file to reach their maximum at 8000+
11137         numacl=0
11138         for U in {20000..25000}; do
11139                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11140                 numacl=$((numacl + 1))
11141         done
11142         echo "Added $numacl more ACLs to the file"
11143         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11144         echo "Total $fileacl ACLs in file"
11145         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11146         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11147         rmdir $DIR/$tdir || error "Cannot remove directory"
11148 }
11149 run_test 103e "inheritance of big amount of default ACLs"
11150
11151 test_103f() {
11152         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11153                 skip "MDS needs to be at least 2.14.51"
11154
11155         large_xattr_enabled || skip_env "ea_inode feature disabled"
11156
11157         # enable changelog to consume more internal MDD buffers
11158         changelog_register
11159
11160         mkdir -p $DIR/$tdir
11161         # add big LOV EA
11162         $LFS setstripe -C 1000 $DIR/$tdir
11163         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11164         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11165         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11166         rmdir $DIR/$tdir || error "Cannot remove directory"
11167 }
11168 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11169
11170 test_104a() {
11171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11172
11173         touch $DIR/$tfile
11174         lfs df || error "lfs df failed"
11175         lfs df -ih || error "lfs df -ih failed"
11176         lfs df -h $DIR || error "lfs df -h $DIR failed"
11177         lfs df -i $DIR || error "lfs df -i $DIR failed"
11178         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11179         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11180
11181         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11182         lctl --device %$OSC deactivate
11183         lfs df || error "lfs df with deactivated OSC failed"
11184         lctl --device %$OSC activate
11185         # wait the osc back to normal
11186         wait_osc_import_ready client ost
11187
11188         lfs df || error "lfs df with reactivated OSC failed"
11189         rm -f $DIR/$tfile
11190 }
11191 run_test 104a "lfs df [-ih] [path] test ========================="
11192
11193 test_104b() {
11194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11195         [ $RUNAS_ID -eq $UID ] &&
11196                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11197
11198         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11199                         grep "Permission denied" | wc -l)))
11200         if [ $denied_cnt -ne 0 ]; then
11201                 error "lfs check servers test failed"
11202         fi
11203 }
11204 run_test 104b "$RUNAS lfs check servers test ===================="
11205
11206 #
11207 # Verify $1 is within range of $2.
11208 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11209 # $1 is <= 2% of $2. Else Fail.
11210 #
11211 value_in_range() {
11212         # Strip all units (M, G, T)
11213         actual=$(echo $1 | tr -d A-Z)
11214         expect=$(echo $2 | tr -d A-Z)
11215
11216         expect_lo=$(($expect * 98 / 100)) # 2% below
11217         expect_hi=$(($expect * 102 / 100)) # 2% above
11218
11219         # permit 2% drift above and below
11220         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11221 }
11222
11223 test_104c() {
11224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11225         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11226
11227         local ost_param="osd-zfs.$FSNAME-OST0000."
11228         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11229         local ofacets=$(get_facets OST)
11230         local mfacets=$(get_facets MDS)
11231         local saved_ost_blocks=
11232         local saved_mdt_blocks=
11233
11234         echo "Before recordsize change"
11235         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11236         df=($(df -h | grep "/mnt/lustre"$))
11237
11238         # For checking.
11239         echo "lfs output : ${lfs_df[*]}"
11240         echo "df  output : ${df[*]}"
11241
11242         for facet in ${ofacets//,/ }; do
11243                 if [ -z $saved_ost_blocks ]; then
11244                         saved_ost_blocks=$(do_facet $facet \
11245                                 lctl get_param -n $ost_param.blocksize)
11246                         echo "OST Blocksize: $saved_ost_blocks"
11247                 fi
11248                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11249                 do_facet $facet zfs set recordsize=32768 $ost
11250         done
11251
11252         # BS too small. Sufficient for functional testing.
11253         for facet in ${mfacets//,/ }; do
11254                 if [ -z $saved_mdt_blocks ]; then
11255                         saved_mdt_blocks=$(do_facet $facet \
11256                                 lctl get_param -n $mdt_param.blocksize)
11257                         echo "MDT Blocksize: $saved_mdt_blocks"
11258                 fi
11259                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11260                 do_facet $facet zfs set recordsize=32768 $mdt
11261         done
11262
11263         # Give new values chance to reflect change
11264         sleep 2
11265
11266         echo "After recordsize change"
11267         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11268         df_after=($(df -h | grep "/mnt/lustre"$))
11269
11270         # For checking.
11271         echo "lfs output : ${lfs_df_after[*]}"
11272         echo "df  output : ${df_after[*]}"
11273
11274         # Verify lfs df
11275         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11276                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11277         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11278                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11279         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11280                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11281
11282         # Verify df
11283         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11284                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11285         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11286                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11287         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11288                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11289
11290         # Restore MDT recordize back to original
11291         for facet in ${mfacets//,/ }; do
11292                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11293                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11294         done
11295
11296         # Restore OST recordize back to original
11297         for facet in ${ofacets//,/ }; do
11298                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11299                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11300         done
11301
11302         return 0
11303 }
11304 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11305
11306 test_105a() {
11307         # doesn't work on 2.4 kernels
11308         touch $DIR/$tfile
11309         if $(flock_is_enabled); then
11310                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11311         else
11312                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11313         fi
11314         rm -f $DIR/$tfile
11315 }
11316 run_test 105a "flock when mounted without -o flock test ========"
11317
11318 test_105b() {
11319         touch $DIR/$tfile
11320         if $(flock_is_enabled); then
11321                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11322         else
11323                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11324         fi
11325         rm -f $DIR/$tfile
11326 }
11327 run_test 105b "fcntl when mounted without -o flock test ========"
11328
11329 test_105c() {
11330         touch $DIR/$tfile
11331         if $(flock_is_enabled); then
11332                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11333         else
11334                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11335         fi
11336         rm -f $DIR/$tfile
11337 }
11338 run_test 105c "lockf when mounted without -o flock test"
11339
11340 test_105d() { # bug 15924
11341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11342
11343         test_mkdir $DIR/$tdir
11344         flock_is_enabled || skip_env "mount w/o flock enabled"
11345         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11346         $LCTL set_param fail_loc=0x80000315
11347         flocks_test 2 $DIR/$tdir
11348 }
11349 run_test 105d "flock race (should not freeze) ========"
11350
11351 test_105e() { # bug 22660 && 22040
11352         flock_is_enabled || skip_env "mount w/o flock enabled"
11353
11354         touch $DIR/$tfile
11355         flocks_test 3 $DIR/$tfile
11356 }
11357 run_test 105e "Two conflicting flocks from same process"
11358
11359 test_106() { #bug 10921
11360         test_mkdir $DIR/$tdir
11361         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11362         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11363 }
11364 run_test 106 "attempt exec of dir followed by chown of that dir"
11365
11366 test_107() {
11367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11368
11369         CDIR=`pwd`
11370         local file=core
11371
11372         cd $DIR
11373         rm -f $file
11374
11375         local save_pattern=$(sysctl -n kernel.core_pattern)
11376         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11377         sysctl -w kernel.core_pattern=$file
11378         sysctl -w kernel.core_uses_pid=0
11379
11380         ulimit -c unlimited
11381         sleep 60 &
11382         SLEEPPID=$!
11383
11384         sleep 1
11385
11386         kill -s 11 $SLEEPPID
11387         wait $SLEEPPID
11388         if [ -e $file ]; then
11389                 size=`stat -c%s $file`
11390                 [ $size -eq 0 ] && error "Fail to create core file $file"
11391         else
11392                 error "Fail to create core file $file"
11393         fi
11394         rm -f $file
11395         sysctl -w kernel.core_pattern=$save_pattern
11396         sysctl -w kernel.core_uses_pid=$save_uses_pid
11397         cd $CDIR
11398 }
11399 run_test 107 "Coredump on SIG"
11400
11401 test_110() {
11402         test_mkdir $DIR/$tdir
11403         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11404         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11405                 error "mkdir with 256 char should fail, but did not"
11406         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11407                 error "create with 255 char failed"
11408         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11409                 error "create with 256 char should fail, but did not"
11410
11411         ls -l $DIR/$tdir
11412         rm -rf $DIR/$tdir
11413 }
11414 run_test 110 "filename length checking"
11415
11416 #
11417 # Purpose: To verify dynamic thread (OSS) creation.
11418 #
11419 test_115() {
11420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11421         remote_ost_nodsh && skip "remote OST with nodsh"
11422
11423         # Lustre does not stop service threads once they are started.
11424         # Reset number of running threads to default.
11425         stopall
11426         setupall
11427
11428         local OSTIO_pre
11429         local save_params="$TMP/sanity-$TESTNAME.parameters"
11430
11431         # Get ll_ost_io count before I/O
11432         OSTIO_pre=$(do_facet ost1 \
11433                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11434         # Exit if lustre is not running (ll_ost_io not running).
11435         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11436
11437         echo "Starting with $OSTIO_pre threads"
11438         local thread_max=$((OSTIO_pre * 2))
11439         local rpc_in_flight=$((thread_max * 2))
11440         # Number of I/O Process proposed to be started.
11441         local nfiles
11442         local facets=$(get_facets OST)
11443
11444         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11445         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11446
11447         # Set in_flight to $rpc_in_flight
11448         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11449                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11450         nfiles=${rpc_in_flight}
11451         # Set ost thread_max to $thread_max
11452         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11453
11454         # 5 Minutes should be sufficient for max number of OSS
11455         # threads(thread_max) to be created.
11456         local timeout=300
11457
11458         # Start I/O.
11459         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11460         test_mkdir $DIR/$tdir
11461         for i in $(seq $nfiles); do
11462                 local file=$DIR/$tdir/${tfile}-$i
11463                 $LFS setstripe -c -1 -i 0 $file
11464                 ($WTL $file $timeout)&
11465         done
11466
11467         # I/O Started - Wait for thread_started to reach thread_max or report
11468         # error if thread_started is more than thread_max.
11469         echo "Waiting for thread_started to reach thread_max"
11470         local thread_started=0
11471         local end_time=$((SECONDS + timeout))
11472
11473         while [ $SECONDS -le $end_time ] ; do
11474                 echo -n "."
11475                 # Get ost i/o thread_started count.
11476                 thread_started=$(do_facet ost1 \
11477                         "$LCTL get_param \
11478                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11479                 # Break out if thread_started is equal/greater than thread_max
11480                 if [[ $thread_started -ge $thread_max ]]; then
11481                         echo ll_ost_io thread_started $thread_started, \
11482                                 equal/greater than thread_max $thread_max
11483                         break
11484                 fi
11485                 sleep 1
11486         done
11487
11488         # Cleanup - We have the numbers, Kill i/o jobs if running.
11489         jobcount=($(jobs -p))
11490         for i in $(seq 0 $((${#jobcount[@]}-1)))
11491         do
11492                 kill -9 ${jobcount[$i]}
11493                 if [ $? -ne 0 ] ; then
11494                         echo Warning: \
11495                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11496                 fi
11497         done
11498
11499         # Cleanup files left by WTL binary.
11500         for i in $(seq $nfiles); do
11501                 local file=$DIR/$tdir/${tfile}-$i
11502                 rm -rf $file
11503                 if [ $? -ne 0 ] ; then
11504                         echo "Warning: Failed to delete file $file"
11505                 fi
11506         done
11507
11508         restore_lustre_params <$save_params
11509         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11510
11511         # Error out if no new thread has started or Thread started is greater
11512         # than thread max.
11513         if [[ $thread_started -le $OSTIO_pre ||
11514                         $thread_started -gt $thread_max ]]; then
11515                 error "ll_ost_io: thread_started $thread_started" \
11516                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11517                       "No new thread started or thread started greater " \
11518                       "than thread_max."
11519         fi
11520 }
11521 run_test 115 "verify dynamic thread creation===================="
11522
11523 free_min_max () {
11524         wait_delete_completed
11525         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11526         echo "OST kbytes available: ${AVAIL[@]}"
11527         MAXV=${AVAIL[0]}
11528         MAXI=0
11529         MINV=${AVAIL[0]}
11530         MINI=0
11531         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11532                 #echo OST $i: ${AVAIL[i]}kb
11533                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11534                         MAXV=${AVAIL[i]}
11535                         MAXI=$i
11536                 fi
11537                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11538                         MINV=${AVAIL[i]}
11539                         MINI=$i
11540                 fi
11541         done
11542         echo "Min free space: OST $MINI: $MINV"
11543         echo "Max free space: OST $MAXI: $MAXV"
11544 }
11545
11546 test_116a() { # was previously test_116()
11547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11548         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11549         remote_mds_nodsh && skip "remote MDS with nodsh"
11550
11551         echo -n "Free space priority "
11552         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11553                 head -n1
11554         declare -a AVAIL
11555         free_min_max
11556
11557         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11558         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11559         trap simple_cleanup_common EXIT
11560
11561         # Check if we need to generate uneven OSTs
11562         test_mkdir -p $DIR/$tdir/OST${MINI}
11563         local FILL=$((MINV / 4))
11564         local DIFF=$((MAXV - MINV))
11565         local DIFF2=$((DIFF * 100 / MINV))
11566
11567         local threshold=$(do_facet $SINGLEMDS \
11568                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11569         threshold=${threshold%%%}
11570         echo -n "Check for uneven OSTs: "
11571         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11572
11573         if [[ $DIFF2 -gt $threshold ]]; then
11574                 echo "ok"
11575                 echo "Don't need to fill OST$MINI"
11576         else
11577                 # generate uneven OSTs. Write 2% over the QOS threshold value
11578                 echo "no"
11579                 DIFF=$((threshold - DIFF2 + 2))
11580                 DIFF2=$((MINV * DIFF / 100))
11581                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11582                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11583                         error "setstripe failed"
11584                 DIFF=$((DIFF2 / 2048))
11585                 i=0
11586                 while [ $i -lt $DIFF ]; do
11587                         i=$((i + 1))
11588                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11589                                 bs=2M count=1 2>/dev/null
11590                         echo -n .
11591                 done
11592                 echo .
11593                 sync
11594                 sleep_maxage
11595                 free_min_max
11596         fi
11597
11598         DIFF=$((MAXV - MINV))
11599         DIFF2=$((DIFF * 100 / MINV))
11600         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11601         if [ $DIFF2 -gt $threshold ]; then
11602                 echo "ok"
11603         else
11604                 echo "failed - QOS mode won't be used"
11605                 simple_cleanup_common
11606                 skip "QOS imbalance criteria not met"
11607         fi
11608
11609         MINI1=$MINI
11610         MINV1=$MINV
11611         MAXI1=$MAXI
11612         MAXV1=$MAXV
11613
11614         # now fill using QOS
11615         $LFS setstripe -c 1 $DIR/$tdir
11616         FILL=$((FILL / 200))
11617         if [ $FILL -gt 600 ]; then
11618                 FILL=600
11619         fi
11620         echo "writing $FILL files to QOS-assigned OSTs"
11621         i=0
11622         while [ $i -lt $FILL ]; do
11623                 i=$((i + 1))
11624                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11625                         count=1 2>/dev/null
11626                 echo -n .
11627         done
11628         echo "wrote $i 200k files"
11629         sync
11630         sleep_maxage
11631
11632         echo "Note: free space may not be updated, so measurements might be off"
11633         free_min_max
11634         DIFF2=$((MAXV - MINV))
11635         echo "free space delta: orig $DIFF final $DIFF2"
11636         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11637         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11638         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11639         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11640         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11641         if [[ $DIFF -gt 0 ]]; then
11642                 FILL=$((DIFF2 * 100 / DIFF - 100))
11643                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11644         fi
11645
11646         # Figure out which files were written where
11647         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11648                awk '/'$MINI1': / {print $2; exit}')
11649         echo $UUID
11650         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11651         echo "$MINC files created on smaller OST $MINI1"
11652         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11653                awk '/'$MAXI1': / {print $2; exit}')
11654         echo $UUID
11655         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11656         echo "$MAXC files created on larger OST $MAXI1"
11657         if [[ $MINC -gt 0 ]]; then
11658                 FILL=$((MAXC * 100 / MINC - 100))
11659                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11660         fi
11661         [[ $MAXC -gt $MINC ]] ||
11662                 error_ignore LU-9 "stripe QOS didn't balance free space"
11663         simple_cleanup_common
11664 }
11665 run_test 116a "stripe QOS: free space balance ==================="
11666
11667 test_116b() { # LU-2093
11668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11669         remote_mds_nodsh && skip "remote MDS with nodsh"
11670
11671 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11672         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11673                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11674         [ -z "$old_rr" ] && skip "no QOS"
11675         do_facet $SINGLEMDS lctl set_param \
11676                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11677         mkdir -p $DIR/$tdir
11678         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11679         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11680         do_facet $SINGLEMDS lctl set_param fail_loc=0
11681         rm -rf $DIR/$tdir
11682         do_facet $SINGLEMDS lctl set_param \
11683                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11684 }
11685 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11686
11687 test_117() # bug 10891
11688 {
11689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11690
11691         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11692         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11693         lctl set_param fail_loc=0x21e
11694         > $DIR/$tfile || error "truncate failed"
11695         lctl set_param fail_loc=0
11696         echo "Truncate succeeded."
11697         rm -f $DIR/$tfile
11698 }
11699 run_test 117 "verify osd extend =========="
11700
11701 NO_SLOW_RESENDCOUNT=4
11702 export OLD_RESENDCOUNT=""
11703 set_resend_count () {
11704         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11705         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11706         lctl set_param -n $PROC_RESENDCOUNT $1
11707         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11708 }
11709
11710 # for reduce test_118* time (b=14842)
11711 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11712
11713 # Reset async IO behavior after error case
11714 reset_async() {
11715         FILE=$DIR/reset_async
11716
11717         # Ensure all OSCs are cleared
11718         $LFS setstripe -c -1 $FILE
11719         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11720         sync
11721         rm $FILE
11722 }
11723
11724 test_118a() #bug 11710
11725 {
11726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11727
11728         reset_async
11729
11730         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11731         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11732         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11733
11734         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11735                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11736                 return 1;
11737         fi
11738         rm -f $DIR/$tfile
11739 }
11740 run_test 118a "verify O_SYNC works =========="
11741
11742 test_118b()
11743 {
11744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11745         remote_ost_nodsh && skip "remote OST with nodsh"
11746
11747         reset_async
11748
11749         #define OBD_FAIL_SRV_ENOENT 0x217
11750         set_nodes_failloc "$(osts_nodes)" 0x217
11751         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11752         RC=$?
11753         set_nodes_failloc "$(osts_nodes)" 0
11754         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11755         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11756                     grep -c writeback)
11757
11758         if [[ $RC -eq 0 ]]; then
11759                 error "Must return error due to dropped pages, rc=$RC"
11760                 return 1;
11761         fi
11762
11763         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11764                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11765                 return 1;
11766         fi
11767
11768         echo "Dirty pages not leaked on ENOENT"
11769
11770         # Due to the above error the OSC will issue all RPCs syncronously
11771         # until a subsequent RPC completes successfully without error.
11772         $MULTIOP $DIR/$tfile Ow4096yc
11773         rm -f $DIR/$tfile
11774
11775         return 0
11776 }
11777 run_test 118b "Reclaim dirty pages on fatal error =========="
11778
11779 test_118c()
11780 {
11781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11782
11783         # for 118c, restore the original resend count, LU-1940
11784         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11785                                 set_resend_count $OLD_RESENDCOUNT
11786         remote_ost_nodsh && skip "remote OST with nodsh"
11787
11788         reset_async
11789
11790         #define OBD_FAIL_OST_EROFS               0x216
11791         set_nodes_failloc "$(osts_nodes)" 0x216
11792
11793         # multiop should block due to fsync until pages are written
11794         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11795         MULTIPID=$!
11796         sleep 1
11797
11798         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11799                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11800         fi
11801
11802         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11803                     grep -c writeback)
11804         if [[ $WRITEBACK -eq 0 ]]; then
11805                 error "No page in writeback, writeback=$WRITEBACK"
11806         fi
11807
11808         set_nodes_failloc "$(osts_nodes)" 0
11809         wait $MULTIPID
11810         RC=$?
11811         if [[ $RC -ne 0 ]]; then
11812                 error "Multiop fsync failed, rc=$RC"
11813         fi
11814
11815         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11816         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11817                     grep -c writeback)
11818         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11819                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11820         fi
11821
11822         rm -f $DIR/$tfile
11823         echo "Dirty pages flushed via fsync on EROFS"
11824         return 0
11825 }
11826 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11827
11828 # continue to use small resend count to reduce test_118* time (b=14842)
11829 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11830
11831 test_118d()
11832 {
11833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11834         remote_ost_nodsh && skip "remote OST with nodsh"
11835
11836         reset_async
11837
11838         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11839         set_nodes_failloc "$(osts_nodes)" 0x214
11840         # multiop should block due to fsync until pages are written
11841         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11842         MULTIPID=$!
11843         sleep 1
11844
11845         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11846                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11847         fi
11848
11849         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11850                     grep -c writeback)
11851         if [[ $WRITEBACK -eq 0 ]]; then
11852                 error "No page in writeback, writeback=$WRITEBACK"
11853         fi
11854
11855         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11856         set_nodes_failloc "$(osts_nodes)" 0
11857
11858         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11859         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11860                     grep -c writeback)
11861         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11862                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11863         fi
11864
11865         rm -f $DIR/$tfile
11866         echo "Dirty pages gaurenteed flushed via fsync"
11867         return 0
11868 }
11869 run_test 118d "Fsync validation inject a delay of the bulk =========="
11870
11871 test_118f() {
11872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11873
11874         reset_async
11875
11876         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11877         lctl set_param fail_loc=0x8000040a
11878
11879         # Should simulate EINVAL error which is fatal
11880         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11881         RC=$?
11882         if [[ $RC -eq 0 ]]; then
11883                 error "Must return error due to dropped pages, rc=$RC"
11884         fi
11885
11886         lctl set_param fail_loc=0x0
11887
11888         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11889         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11890         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11891                     grep -c writeback)
11892         if [[ $LOCKED -ne 0 ]]; then
11893                 error "Locked pages remain in cache, locked=$LOCKED"
11894         fi
11895
11896         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11897                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11898         fi
11899
11900         rm -f $DIR/$tfile
11901         echo "No pages locked after fsync"
11902
11903         reset_async
11904         return 0
11905 }
11906 run_test 118f "Simulate unrecoverable OSC side error =========="
11907
11908 test_118g() {
11909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11910
11911         reset_async
11912
11913         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11914         lctl set_param fail_loc=0x406
11915
11916         # simulate local -ENOMEM
11917         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11918         RC=$?
11919
11920         lctl set_param fail_loc=0
11921         if [[ $RC -eq 0 ]]; then
11922                 error "Must return error due to dropped pages, rc=$RC"
11923         fi
11924
11925         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11926         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11927         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11928                         grep -c writeback)
11929         if [[ $LOCKED -ne 0 ]]; then
11930                 error "Locked pages remain in cache, locked=$LOCKED"
11931         fi
11932
11933         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11934                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11935         fi
11936
11937         rm -f $DIR/$tfile
11938         echo "No pages locked after fsync"
11939
11940         reset_async
11941         return 0
11942 }
11943 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11944
11945 test_118h() {
11946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11947         remote_ost_nodsh && skip "remote OST with nodsh"
11948
11949         reset_async
11950
11951         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11952         set_nodes_failloc "$(osts_nodes)" 0x20e
11953         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11954         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11955         RC=$?
11956
11957         set_nodes_failloc "$(osts_nodes)" 0
11958         if [[ $RC -eq 0 ]]; then
11959                 error "Must return error due to dropped pages, rc=$RC"
11960         fi
11961
11962         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11963         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11964         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11965                     grep -c writeback)
11966         if [[ $LOCKED -ne 0 ]]; then
11967                 error "Locked pages remain in cache, locked=$LOCKED"
11968         fi
11969
11970         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11971                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11972         fi
11973
11974         rm -f $DIR/$tfile
11975         echo "No pages locked after fsync"
11976
11977         return 0
11978 }
11979 run_test 118h "Verify timeout in handling recoverables errors  =========="
11980
11981 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11982
11983 test_118i() {
11984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11985         remote_ost_nodsh && skip "remote OST with nodsh"
11986
11987         reset_async
11988
11989         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11990         set_nodes_failloc "$(osts_nodes)" 0x20e
11991
11992         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11993         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11994         PID=$!
11995         sleep 5
11996         set_nodes_failloc "$(osts_nodes)" 0
11997
11998         wait $PID
11999         RC=$?
12000         if [[ $RC -ne 0 ]]; then
12001                 error "got error, but should be not, rc=$RC"
12002         fi
12003
12004         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12005         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12006         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12007         if [[ $LOCKED -ne 0 ]]; then
12008                 error "Locked pages remain in cache, locked=$LOCKED"
12009         fi
12010
12011         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12012                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12013         fi
12014
12015         rm -f $DIR/$tfile
12016         echo "No pages locked after fsync"
12017
12018         return 0
12019 }
12020 run_test 118i "Fix error before timeout in recoverable error  =========="
12021
12022 [ "$SLOW" = "no" ] && set_resend_count 4
12023
12024 test_118j() {
12025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12026         remote_ost_nodsh && skip "remote OST with nodsh"
12027
12028         reset_async
12029
12030         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12031         set_nodes_failloc "$(osts_nodes)" 0x220
12032
12033         # return -EIO from OST
12034         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12035         RC=$?
12036         set_nodes_failloc "$(osts_nodes)" 0x0
12037         if [[ $RC -eq 0 ]]; then
12038                 error "Must return error due to dropped pages, rc=$RC"
12039         fi
12040
12041         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12042         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12043         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12044         if [[ $LOCKED -ne 0 ]]; then
12045                 error "Locked pages remain in cache, locked=$LOCKED"
12046         fi
12047
12048         # in recoverable error on OST we want resend and stay until it finished
12049         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12050                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12051         fi
12052
12053         rm -f $DIR/$tfile
12054         echo "No pages locked after fsync"
12055
12056         return 0
12057 }
12058 run_test 118j "Simulate unrecoverable OST side error =========="
12059
12060 test_118k()
12061 {
12062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12063         remote_ost_nodsh && skip "remote OSTs with nodsh"
12064
12065         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12066         set_nodes_failloc "$(osts_nodes)" 0x20e
12067         test_mkdir $DIR/$tdir
12068
12069         for ((i=0;i<10;i++)); do
12070                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12071                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12072                 SLEEPPID=$!
12073                 sleep 0.500s
12074                 kill $SLEEPPID
12075                 wait $SLEEPPID
12076         done
12077
12078         set_nodes_failloc "$(osts_nodes)" 0
12079         rm -rf $DIR/$tdir
12080 }
12081 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12082
12083 test_118l() # LU-646
12084 {
12085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12086
12087         test_mkdir $DIR/$tdir
12088         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12089         rm -rf $DIR/$tdir
12090 }
12091 run_test 118l "fsync dir"
12092
12093 test_118m() # LU-3066
12094 {
12095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12096
12097         test_mkdir $DIR/$tdir
12098         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12099         rm -rf $DIR/$tdir
12100 }
12101 run_test 118m "fdatasync dir ========="
12102
12103 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12104
12105 test_118n()
12106 {
12107         local begin
12108         local end
12109
12110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12111         remote_ost_nodsh && skip "remote OSTs with nodsh"
12112
12113         # Sleep to avoid a cached response.
12114         #define OBD_STATFS_CACHE_SECONDS 1
12115         sleep 2
12116
12117         # Inject a 10 second delay in the OST_STATFS handler.
12118         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12119         set_nodes_failloc "$(osts_nodes)" 0x242
12120
12121         begin=$SECONDS
12122         stat --file-system $MOUNT > /dev/null
12123         end=$SECONDS
12124
12125         set_nodes_failloc "$(osts_nodes)" 0
12126
12127         if ((end - begin > 20)); then
12128             error "statfs took $((end - begin)) seconds, expected 10"
12129         fi
12130 }
12131 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12132
12133 test_119a() # bug 11737
12134 {
12135         BSIZE=$((512 * 1024))
12136         directio write $DIR/$tfile 0 1 $BSIZE
12137         # We ask to read two blocks, which is more than a file size.
12138         # directio will indicate an error when requested and actual
12139         # sizes aren't equeal (a normal situation in this case) and
12140         # print actual read amount.
12141         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12142         if [ "$NOB" != "$BSIZE" ]; then
12143                 error "read $NOB bytes instead of $BSIZE"
12144         fi
12145         rm -f $DIR/$tfile
12146 }
12147 run_test 119a "Short directIO read must return actual read amount"
12148
12149 test_119b() # bug 11737
12150 {
12151         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12152
12153         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12154         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12155         sync
12156         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12157                 error "direct read failed"
12158         rm -f $DIR/$tfile
12159 }
12160 run_test 119b "Sparse directIO read must return actual read amount"
12161
12162 test_119c() # bug 13099
12163 {
12164         BSIZE=1048576
12165         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12166         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12167         rm -f $DIR/$tfile
12168 }
12169 run_test 119c "Testing for direct read hitting hole"
12170
12171 test_119d() # bug 15950
12172 {
12173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12174
12175         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12176         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12177         BSIZE=1048576
12178         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12179         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12180         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12181         lctl set_param fail_loc=0x40d
12182         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12183         pid_dio=$!
12184         sleep 1
12185         cat $DIR/$tfile > /dev/null &
12186         lctl set_param fail_loc=0
12187         pid_reads=$!
12188         wait $pid_dio
12189         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12190         sleep 2
12191         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12192         error "the read rpcs have not completed in 2s"
12193         rm -f $DIR/$tfile
12194         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12195 }
12196 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12197
12198 test_120a() {
12199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12200         remote_mds_nodsh && skip "remote MDS with nodsh"
12201         test_mkdir -i0 -c1 $DIR/$tdir
12202         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12203                 skip_env "no early lock cancel on server"
12204
12205         lru_resize_disable mdc
12206         lru_resize_disable osc
12207         cancel_lru_locks mdc
12208         # asynchronous object destroy at MDT could cause bl ast to client
12209         cancel_lru_locks osc
12210
12211         stat $DIR/$tdir > /dev/null
12212         can1=$(do_facet mds1 \
12213                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12214                awk '/ldlm_cancel/ {print $2}')
12215         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12216                awk '/ldlm_bl_callback/ {print $2}')
12217         test_mkdir -i0 -c1 $DIR/$tdir/d1
12218         can2=$(do_facet mds1 \
12219                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12220                awk '/ldlm_cancel/ {print $2}')
12221         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12222                awk '/ldlm_bl_callback/ {print $2}')
12223         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12224         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12225         lru_resize_enable mdc
12226         lru_resize_enable osc
12227 }
12228 run_test 120a "Early Lock Cancel: mkdir test"
12229
12230 test_120b() {
12231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12232         remote_mds_nodsh && skip "remote MDS with nodsh"
12233         test_mkdir $DIR/$tdir
12234         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12235                 skip_env "no early lock cancel on server"
12236
12237         lru_resize_disable mdc
12238         lru_resize_disable osc
12239         cancel_lru_locks mdc
12240         stat $DIR/$tdir > /dev/null
12241         can1=$(do_facet $SINGLEMDS \
12242                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12243                awk '/ldlm_cancel/ {print $2}')
12244         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12245                awk '/ldlm_bl_callback/ {print $2}')
12246         touch $DIR/$tdir/f1
12247         can2=$(do_facet $SINGLEMDS \
12248                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12249                awk '/ldlm_cancel/ {print $2}')
12250         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12251                awk '/ldlm_bl_callback/ {print $2}')
12252         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12253         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12254         lru_resize_enable mdc
12255         lru_resize_enable osc
12256 }
12257 run_test 120b "Early Lock Cancel: create test"
12258
12259 test_120c() {
12260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12261         remote_mds_nodsh && skip "remote MDS with nodsh"
12262         test_mkdir -i0 -c1 $DIR/$tdir
12263         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12264                 skip "no early lock cancel on server"
12265
12266         lru_resize_disable mdc
12267         lru_resize_disable osc
12268         test_mkdir -i0 -c1 $DIR/$tdir/d1
12269         test_mkdir -i0 -c1 $DIR/$tdir/d2
12270         touch $DIR/$tdir/d1/f1
12271         cancel_lru_locks mdc
12272         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12273         can1=$(do_facet mds1 \
12274                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12275                awk '/ldlm_cancel/ {print $2}')
12276         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12277                awk '/ldlm_bl_callback/ {print $2}')
12278         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12279         can2=$(do_facet mds1 \
12280                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12281                awk '/ldlm_cancel/ {print $2}')
12282         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12283                awk '/ldlm_bl_callback/ {print $2}')
12284         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12285         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12286         lru_resize_enable mdc
12287         lru_resize_enable osc
12288 }
12289 run_test 120c "Early Lock Cancel: link test"
12290
12291 test_120d() {
12292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12293         remote_mds_nodsh && skip "remote MDS with nodsh"
12294         test_mkdir -i0 -c1 $DIR/$tdir
12295         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12296                 skip_env "no early lock cancel on server"
12297
12298         lru_resize_disable mdc
12299         lru_resize_disable osc
12300         touch $DIR/$tdir
12301         cancel_lru_locks mdc
12302         stat $DIR/$tdir > /dev/null
12303         can1=$(do_facet mds1 \
12304                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12305                awk '/ldlm_cancel/ {print $2}')
12306         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12307                awk '/ldlm_bl_callback/ {print $2}')
12308         chmod a+x $DIR/$tdir
12309         can2=$(do_facet mds1 \
12310                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12311                awk '/ldlm_cancel/ {print $2}')
12312         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12313                awk '/ldlm_bl_callback/ {print $2}')
12314         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12315         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12316         lru_resize_enable mdc
12317         lru_resize_enable osc
12318 }
12319 run_test 120d "Early Lock Cancel: setattr test"
12320
12321 test_120e() {
12322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12323         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12324                 skip_env "no early lock cancel on server"
12325         remote_mds_nodsh && skip "remote MDS with nodsh"
12326
12327         local dlmtrace_set=false
12328
12329         test_mkdir -i0 -c1 $DIR/$tdir
12330         lru_resize_disable mdc
12331         lru_resize_disable osc
12332         ! $LCTL get_param debug | grep -q dlmtrace &&
12333                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12334         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12335         cancel_lru_locks mdc
12336         cancel_lru_locks osc
12337         dd if=$DIR/$tdir/f1 of=/dev/null
12338         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12339         # XXX client can not do early lock cancel of OST lock
12340         # during unlink (LU-4206), so cancel osc lock now.
12341         sleep 2
12342         cancel_lru_locks osc
12343         can1=$(do_facet mds1 \
12344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12345                awk '/ldlm_cancel/ {print $2}')
12346         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12347                awk '/ldlm_bl_callback/ {print $2}')
12348         unlink $DIR/$tdir/f1
12349         sleep 5
12350         can2=$(do_facet mds1 \
12351                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12352                awk '/ldlm_cancel/ {print $2}')
12353         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12354                awk '/ldlm_bl_callback/ {print $2}')
12355         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12356                 $LCTL dk $TMP/cancel.debug.txt
12357         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12358                 $LCTL dk $TMP/blocking.debug.txt
12359         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12360         lru_resize_enable mdc
12361         lru_resize_enable osc
12362 }
12363 run_test 120e "Early Lock Cancel: unlink test"
12364
12365 test_120f() {
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12368                 skip_env "no early lock cancel on server"
12369         remote_mds_nodsh && skip "remote MDS with nodsh"
12370
12371         test_mkdir -i0 -c1 $DIR/$tdir
12372         lru_resize_disable mdc
12373         lru_resize_disable osc
12374         test_mkdir -i0 -c1 $DIR/$tdir/d1
12375         test_mkdir -i0 -c1 $DIR/$tdir/d2
12376         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12377         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12378         cancel_lru_locks mdc
12379         cancel_lru_locks osc
12380         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12381         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12382         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12383         # XXX client can not do early lock cancel of OST lock
12384         # during rename (LU-4206), so cancel osc lock now.
12385         sleep 2
12386         cancel_lru_locks osc
12387         can1=$(do_facet mds1 \
12388                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12389                awk '/ldlm_cancel/ {print $2}')
12390         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12391                awk '/ldlm_bl_callback/ {print $2}')
12392         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12393         sleep 5
12394         can2=$(do_facet mds1 \
12395                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12396                awk '/ldlm_cancel/ {print $2}')
12397         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12398                awk '/ldlm_bl_callback/ {print $2}')
12399         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12400         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12401         lru_resize_enable mdc
12402         lru_resize_enable osc
12403 }
12404 run_test 120f "Early Lock Cancel: rename test"
12405
12406 test_120g() {
12407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12408         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12409                 skip_env "no early lock cancel on server"
12410         remote_mds_nodsh && skip "remote MDS with nodsh"
12411
12412         lru_resize_disable mdc
12413         lru_resize_disable osc
12414         count=10000
12415         echo create $count files
12416         test_mkdir $DIR/$tdir
12417         cancel_lru_locks mdc
12418         cancel_lru_locks osc
12419         t0=$(date +%s)
12420
12421         can0=$(do_facet $SINGLEMDS \
12422                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12423                awk '/ldlm_cancel/ {print $2}')
12424         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12425                awk '/ldlm_bl_callback/ {print $2}')
12426         createmany -o $DIR/$tdir/f $count
12427         sync
12428         can1=$(do_facet $SINGLEMDS \
12429                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12430                awk '/ldlm_cancel/ {print $2}')
12431         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12432                awk '/ldlm_bl_callback/ {print $2}')
12433         t1=$(date +%s)
12434         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12435         echo rm $count files
12436         rm -r $DIR/$tdir
12437         sync
12438         can2=$(do_facet $SINGLEMDS \
12439                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12440                awk '/ldlm_cancel/ {print $2}')
12441         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12442                awk '/ldlm_bl_callback/ {print $2}')
12443         t2=$(date +%s)
12444         echo total: $count removes in $((t2-t1))
12445         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12446         sleep 2
12447         # wait for commitment of removal
12448         lru_resize_enable mdc
12449         lru_resize_enable osc
12450 }
12451 run_test 120g "Early Lock Cancel: performance test"
12452
12453 test_121() { #bug #10589
12454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12455
12456         rm -rf $DIR/$tfile
12457         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12458 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12459         lctl set_param fail_loc=0x310
12460         cancel_lru_locks osc > /dev/null
12461         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12462         lctl set_param fail_loc=0
12463         [[ $reads -eq $writes ]] ||
12464                 error "read $reads blocks, must be $writes blocks"
12465 }
12466 run_test 121 "read cancel race ========="
12467
12468 test_123a_base() { # was test 123, statahead(bug 11401)
12469         local lsx="$1"
12470
12471         SLOWOK=0
12472         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12473                 log "testing UP system. Performance may be lower than expected."
12474                 SLOWOK=1
12475         fi
12476
12477         rm -rf $DIR/$tdir
12478         test_mkdir $DIR/$tdir
12479         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12480         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12481         MULT=10
12482         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12483                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12484
12485                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12486                 lctl set_param -n llite.*.statahead_max 0
12487                 lctl get_param llite.*.statahead_max
12488                 cancel_lru_locks mdc
12489                 cancel_lru_locks osc
12490                 stime=$(date +%s)
12491                 time $lsx $DIR/$tdir | wc -l
12492                 etime=$(date +%s)
12493                 delta=$((etime - stime))
12494                 log "$lsx $i files without statahead: $delta sec"
12495                 lctl set_param llite.*.statahead_max=$max
12496
12497                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12498                         grep "statahead wrong:" | awk '{print $3}')
12499                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12500                 cancel_lru_locks mdc
12501                 cancel_lru_locks osc
12502                 stime=$(date +%s)
12503                 time $lsx $DIR/$tdir | wc -l
12504                 etime=$(date +%s)
12505                 delta_sa=$((etime - stime))
12506                 log "$lsx $i files with statahead: $delta_sa sec"
12507                 lctl get_param -n llite.*.statahead_stats
12508                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12509                         grep "statahead wrong:" | awk '{print $3}')
12510
12511                 [[ $swrong -lt $ewrong ]] &&
12512                         log "statahead was stopped, maybe too many locks held!"
12513                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12514
12515                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12516                         max=$(lctl get_param -n llite.*.statahead_max |
12517                                 head -n 1)
12518                         lctl set_param -n llite.*.statahead_max 0
12519                         lctl get_param llite.*.statahead_max
12520                         cancel_lru_locks mdc
12521                         cancel_lru_locks osc
12522                         stime=$(date +%s)
12523                         time $lsx $DIR/$tdir | wc -l
12524                         etime=$(date +%s)
12525                         delta=$((etime - stime))
12526                         log "$lsx $i files again without statahead: $delta sec"
12527                         lctl set_param llite.*.statahead_max=$max
12528                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12529                                 if [  $SLOWOK -eq 0 ]; then
12530                                         error "$lsx $i files is slower with statahead!"
12531                                 else
12532                                         log "$lsx $i files is slower with statahead!"
12533                                 fi
12534                                 break
12535                         fi
12536                 fi
12537
12538                 [ $delta -gt 20 ] && break
12539                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12540                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12541         done
12542         log "$lsx done"
12543
12544         stime=$(date +%s)
12545         rm -r $DIR/$tdir
12546         sync
12547         etime=$(date +%s)
12548         delta=$((etime - stime))
12549         log "rm -r $DIR/$tdir/: $delta seconds"
12550         log "rm done"
12551         lctl get_param -n llite.*.statahead_stats
12552 }
12553
12554 test_123aa() {
12555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12556
12557         test_123a_base "ls -l"
12558 }
12559 run_test 123aa "verify statahead work"
12560
12561 test_123ab() {
12562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12563
12564         statx_supported || skip_env "Test must be statx() syscall supported"
12565
12566         test_123a_base "$STATX -l"
12567 }
12568 run_test 123ab "verify statahead work by using statx"
12569
12570 test_123ac() {
12571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12572
12573         statx_supported || skip_env "Test must be statx() syscall supported"
12574
12575         local rpcs_before
12576         local rpcs_after
12577         local agl_before
12578         local agl_after
12579
12580         cancel_lru_locks $OSC
12581         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12582         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12583                 awk '/agl.total:/ {print $3}')
12584         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12585         test_123a_base "$STATX --cached=always -D"
12586         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12587                 awk '/agl.total:/ {print $3}')
12588         [ $agl_before -eq $agl_after ] ||
12589                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12590         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12591         [ $rpcs_after -eq $rpcs_before ] ||
12592                 error "$STATX should not send glimpse RPCs to $OSC"
12593 }
12594 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12595
12596 test_123b () { # statahead(bug 15027)
12597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12598
12599         test_mkdir $DIR/$tdir
12600         createmany -o $DIR/$tdir/$tfile-%d 1000
12601
12602         cancel_lru_locks mdc
12603         cancel_lru_locks osc
12604
12605 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12606         lctl set_param fail_loc=0x80000803
12607         ls -lR $DIR/$tdir > /dev/null
12608         log "ls done"
12609         lctl set_param fail_loc=0x0
12610         lctl get_param -n llite.*.statahead_stats
12611         rm -r $DIR/$tdir
12612         sync
12613
12614 }
12615 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12616
12617 test_123c() {
12618         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12619
12620         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12621         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12622         touch $DIR/$tdir.1/{1..3}
12623         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12624
12625         remount_client $MOUNT
12626
12627         $MULTIOP $DIR/$tdir.0 Q
12628
12629         # let statahead to complete
12630         ls -l $DIR/$tdir.0 > /dev/null
12631
12632         testid=$(echo $TESTNAME | tr '_' ' ')
12633         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12634                 error "statahead warning" || true
12635 }
12636 run_test 123c "Can not initialize inode warning on DNE statahead"
12637
12638 test_124a() {
12639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12640         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12641                 skip_env "no lru resize on server"
12642
12643         local NR=2000
12644
12645         test_mkdir $DIR/$tdir
12646
12647         log "create $NR files at $DIR/$tdir"
12648         createmany -o $DIR/$tdir/f $NR ||
12649                 error "failed to create $NR files in $DIR/$tdir"
12650
12651         cancel_lru_locks mdc
12652         ls -l $DIR/$tdir > /dev/null
12653
12654         local NSDIR=""
12655         local LRU_SIZE=0
12656         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12657                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12658                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12659                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12660                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12661                         log "NSDIR=$NSDIR"
12662                         log "NS=$(basename $NSDIR)"
12663                         break
12664                 fi
12665         done
12666
12667         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12668                 skip "Not enough cached locks created!"
12669         fi
12670         log "LRU=$LRU_SIZE"
12671
12672         local SLEEP=30
12673
12674         # We know that lru resize allows one client to hold $LIMIT locks
12675         # for 10h. After that locks begin to be killed by client.
12676         local MAX_HRS=10
12677         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12678         log "LIMIT=$LIMIT"
12679         if [ $LIMIT -lt $LRU_SIZE ]; then
12680                 skip "Limit is too small $LIMIT"
12681         fi
12682
12683         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12684         # killing locks. Some time was spent for creating locks. This means
12685         # that up to the moment of sleep finish we must have killed some of
12686         # them (10-100 locks). This depends on how fast ther were created.
12687         # Many of them were touched in almost the same moment and thus will
12688         # be killed in groups.
12689         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12690
12691         # Use $LRU_SIZE_B here to take into account real number of locks
12692         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12693         local LRU_SIZE_B=$LRU_SIZE
12694         log "LVF=$LVF"
12695         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12696         log "OLD_LVF=$OLD_LVF"
12697         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12698
12699         # Let's make sure that we really have some margin. Client checks
12700         # cached locks every 10 sec.
12701         SLEEP=$((SLEEP+20))
12702         log "Sleep ${SLEEP} sec"
12703         local SEC=0
12704         while ((SEC<$SLEEP)); do
12705                 echo -n "..."
12706                 sleep 5
12707                 SEC=$((SEC+5))
12708                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12709                 echo -n "$LRU_SIZE"
12710         done
12711         echo ""
12712         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12713         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12714
12715         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12716                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12717                 unlinkmany $DIR/$tdir/f $NR
12718                 return
12719         }
12720
12721         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12722         log "unlink $NR files at $DIR/$tdir"
12723         unlinkmany $DIR/$tdir/f $NR
12724 }
12725 run_test 124a "lru resize ======================================="
12726
12727 get_max_pool_limit()
12728 {
12729         local limit=$($LCTL get_param \
12730                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
12731         local max=0
12732         for l in $limit; do
12733                 if [[ $l -gt $max ]]; then
12734                         max=$l
12735                 fi
12736         done
12737         echo $max
12738 }
12739
12740 test_124b() {
12741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12742         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12743                 skip_env "no lru resize on server"
12744
12745         LIMIT=$(get_max_pool_limit)
12746
12747         NR=$(($(default_lru_size)*20))
12748         if [[ $NR -gt $LIMIT ]]; then
12749                 log "Limit lock number by $LIMIT locks"
12750                 NR=$LIMIT
12751         fi
12752
12753         IFree=$(mdsrate_inodes_available)
12754         if [ $IFree -lt $NR ]; then
12755                 log "Limit lock number by $IFree inodes"
12756                 NR=$IFree
12757         fi
12758
12759         lru_resize_disable mdc
12760         test_mkdir -p $DIR/$tdir/disable_lru_resize
12761
12762         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
12763         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
12764         cancel_lru_locks mdc
12765         stime=`date +%s`
12766         PID=""
12767         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12768         PID="$PID $!"
12769         sleep 2
12770         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12771         PID="$PID $!"
12772         sleep 2
12773         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12774         PID="$PID $!"
12775         wait $PID
12776         etime=`date +%s`
12777         nolruresize_delta=$((etime-stime))
12778         log "ls -la time: $nolruresize_delta seconds"
12779         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12780         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12781
12782         lru_resize_enable mdc
12783         test_mkdir -p $DIR/$tdir/enable_lru_resize
12784
12785         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12786         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12787         cancel_lru_locks mdc
12788         stime=`date +%s`
12789         PID=""
12790         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12791         PID="$PID $!"
12792         sleep 2
12793         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12794         PID="$PID $!"
12795         sleep 2
12796         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12797         PID="$PID $!"
12798         wait $PID
12799         etime=`date +%s`
12800         lruresize_delta=$((etime-stime))
12801         log "ls -la time: $lruresize_delta seconds"
12802         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12803
12804         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12805                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12806         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12807                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12808         else
12809                 log "lru resize performs the same with no lru resize"
12810         fi
12811         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12812 }
12813 run_test 124b "lru resize (performance test) ======================="
12814
12815 test_124c() {
12816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12817         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12818                 skip_env "no lru resize on server"
12819
12820         # cache ununsed locks on client
12821         local nr=100
12822         cancel_lru_locks mdc
12823         test_mkdir $DIR/$tdir
12824         createmany -o $DIR/$tdir/f $nr ||
12825                 error "failed to create $nr files in $DIR/$tdir"
12826         ls -l $DIR/$tdir > /dev/null
12827
12828         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12829         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12830         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12831         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12832         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12833
12834         # set lru_max_age to 1 sec
12835         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12836         echo "sleep $((recalc_p * 2)) seconds..."
12837         sleep $((recalc_p * 2))
12838
12839         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12840         # restore lru_max_age
12841         $LCTL set_param -n $nsdir.lru_max_age $max_age
12842         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12843         unlinkmany $DIR/$tdir/f $nr
12844 }
12845 run_test 124c "LRUR cancel very aged locks"
12846
12847 test_124d() {
12848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12849         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12850                 skip_env "no lru resize on server"
12851
12852         # cache ununsed locks on client
12853         local nr=100
12854
12855         lru_resize_disable mdc
12856         stack_trap "lru_resize_enable mdc" EXIT
12857
12858         cancel_lru_locks mdc
12859
12860         # asynchronous object destroy at MDT could cause bl ast to client
12861         test_mkdir $DIR/$tdir
12862         createmany -o $DIR/$tdir/f $nr ||
12863                 error "failed to create $nr files in $DIR/$tdir"
12864         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12865
12866         ls -l $DIR/$tdir > /dev/null
12867
12868         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12869         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12870         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12871         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12872
12873         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12874
12875         # set lru_max_age to 1 sec
12876         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12877         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12878
12879         echo "sleep $((recalc_p * 2)) seconds..."
12880         sleep $((recalc_p * 2))
12881
12882         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12883
12884         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12885 }
12886 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12887
12888 test_125() { # 13358
12889         $LCTL get_param -n llite.*.client_type | grep -q local ||
12890                 skip "must run as local client"
12891         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12892                 skip_env "must have acl enabled"
12893         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12894
12895         test_mkdir $DIR/$tdir
12896         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12897         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12898         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12899 }
12900 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12901
12902 test_126() { # bug 12829/13455
12903         $GSS && skip_env "must run as gss disabled"
12904         $LCTL get_param -n llite.*.client_type | grep -q local ||
12905                 skip "must run as local client"
12906         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12907
12908         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12909         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12910         rm -f $DIR/$tfile
12911         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12912 }
12913 run_test 126 "check that the fsgid provided by the client is taken into account"
12914
12915 test_127a() { # bug 15521
12916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12917         local name count samp unit min max sum sumsq
12918
12919         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12920         echo "stats before reset"
12921         $LCTL get_param osc.*.stats
12922         $LCTL set_param osc.*.stats=0
12923         local fsize=$((2048 * 1024))
12924
12925         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12926         cancel_lru_locks osc
12927         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12928
12929         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12930         stack_trap "rm -f $TMP/$tfile.tmp"
12931         while read name count samp unit min max sum sumsq; do
12932                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12933                 [ ! $min ] && error "Missing min value for $name proc entry"
12934                 eval $name=$count || error "Wrong proc format"
12935
12936                 case $name in
12937                 read_bytes|write_bytes)
12938                         [[ "$unit" =~ "bytes" ]] ||
12939                                 error "unit is not 'bytes': $unit"
12940                         (( $min >= 4096 )) || error "min is too small: $min"
12941                         (( $min <= $fsize )) || error "min is too big: $min"
12942                         (( $max >= 4096 )) || error "max is too small: $max"
12943                         (( $max <= $fsize )) || error "max is too big: $max"
12944                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12945                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12946                                 error "sumsquare is too small: $sumsq"
12947                         (( $sumsq <= $fsize * $fsize )) ||
12948                                 error "sumsquare is too big: $sumsq"
12949                         ;;
12950                 ost_read|ost_write)
12951                         [[ "$unit" =~ "usec" ]] ||
12952                                 error "unit is not 'usec': $unit"
12953                         ;;
12954                 *)      ;;
12955                 esac
12956         done < $DIR/$tfile.tmp
12957
12958         #check that we actually got some stats
12959         [ "$read_bytes" ] || error "Missing read_bytes stats"
12960         [ "$write_bytes" ] || error "Missing write_bytes stats"
12961         [ "$read_bytes" != 0 ] || error "no read done"
12962         [ "$write_bytes" != 0 ] || error "no write done"
12963 }
12964 run_test 127a "verify the client stats are sane"
12965
12966 test_127b() { # bug LU-333
12967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12968         local name count samp unit min max sum sumsq
12969
12970         echo "stats before reset"
12971         $LCTL get_param llite.*.stats
12972         $LCTL set_param llite.*.stats=0
12973
12974         # perform 2 reads and writes so MAX is different from SUM.
12975         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12976         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12977         cancel_lru_locks osc
12978         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12979         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12980
12981         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12982         stack_trap "rm -f $TMP/$tfile.tmp"
12983         while read name count samp unit min max sum sumsq; do
12984                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12985                 eval $name=$count || error "Wrong proc format"
12986
12987                 case $name in
12988                 read_bytes|write_bytes)
12989                         [[ "$unit" =~ "bytes" ]] ||
12990                                 error "unit is not 'bytes': $unit"
12991                         (( $count == 2 )) || error "count is not 2: $count"
12992                         (( $min == $PAGE_SIZE )) ||
12993                                 error "min is not $PAGE_SIZE: $min"
12994                         (( $max == $PAGE_SIZE )) ||
12995                                 error "max is not $PAGE_SIZE: $max"
12996                         (( $sum == $PAGE_SIZE * 2 )) ||
12997                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12998                         ;;
12999                 read|write)
13000                         [[ "$unit" =~ "usec" ]] ||
13001                                 error "unit is not 'usec': $unit"
13002                         ;;
13003                 *)      ;;
13004                 esac
13005         done < $TMP/$tfile.tmp
13006
13007         #check that we actually got some stats
13008         [ "$read_bytes" ] || error "Missing read_bytes stats"
13009         [ "$write_bytes" ] || error "Missing write_bytes stats"
13010         [ "$read_bytes" != 0 ] || error "no read done"
13011         [ "$write_bytes" != 0 ] || error "no write done"
13012 }
13013 run_test 127b "verify the llite client stats are sane"
13014
13015 test_127c() { # LU-12394
13016         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13017         local size
13018         local bsize
13019         local reads
13020         local writes
13021         local count
13022
13023         $LCTL set_param llite.*.extents_stats=1
13024         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13025
13026         # Use two stripes so there is enough space in default config
13027         $LFS setstripe -c 2 $DIR/$tfile
13028
13029         # Extent stats start at 0-4K and go in power of two buckets
13030         # LL_HIST_START = 12 --> 2^12 = 4K
13031         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13032         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13033         # small configs
13034         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13035                 do
13036                 # Write and read, 2x each, second time at a non-zero offset
13037                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13038                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13039                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13040                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13041                 rm -f $DIR/$tfile
13042         done
13043
13044         $LCTL get_param llite.*.extents_stats
13045
13046         count=2
13047         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13048                 do
13049                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13050                                 grep -m 1 $bsize)
13051                 reads=$(echo $bucket | awk '{print $5}')
13052                 writes=$(echo $bucket | awk '{print $9}')
13053                 [ "$reads" -eq $count ] ||
13054                         error "$reads reads in < $bsize bucket, expect $count"
13055                 [ "$writes" -eq $count ] ||
13056                         error "$writes writes in < $bsize bucket, expect $count"
13057         done
13058
13059         # Test mmap write and read
13060         $LCTL set_param llite.*.extents_stats=c
13061         size=512
13062         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13063         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13064         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13065
13066         $LCTL get_param llite.*.extents_stats
13067
13068         count=$(((size*1024) / PAGE_SIZE))
13069
13070         bsize=$((2 * PAGE_SIZE / 1024))K
13071
13072         bucket=$($LCTL get_param -n llite.*.extents_stats |
13073                         grep -m 1 $bsize)
13074         reads=$(echo $bucket | awk '{print $5}')
13075         writes=$(echo $bucket | awk '{print $9}')
13076         # mmap writes fault in the page first, creating an additonal read
13077         [ "$reads" -eq $((2 * count)) ] ||
13078                 error "$reads reads in < $bsize bucket, expect $count"
13079         [ "$writes" -eq $count ] ||
13080                 error "$writes writes in < $bsize bucket, expect $count"
13081 }
13082 run_test 127c "test llite extent stats with regular & mmap i/o"
13083
13084 test_128() { # bug 15212
13085         touch $DIR/$tfile
13086         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13087                 find $DIR/$tfile
13088                 find $DIR/$tfile
13089         EOF
13090
13091         result=$(grep error $TMP/$tfile.log)
13092         rm -f $DIR/$tfile $TMP/$tfile.log
13093         [ -z "$result" ] ||
13094                 error "consecutive find's under interactive lfs failed"
13095 }
13096 run_test 128 "interactive lfs for 2 consecutive find's"
13097
13098 set_dir_limits () {
13099         local mntdev
13100         local canondev
13101         local node
13102
13103         local ldproc=/proc/fs/ldiskfs
13104         local facets=$(get_facets MDS)
13105
13106         for facet in ${facets//,/ }; do
13107                 canondev=$(ldiskfs_canon \
13108                            *.$(convert_facet2label $facet).mntdev $facet)
13109                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13110                         ldproc=/sys/fs/ldiskfs
13111                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13112                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13113         done
13114 }
13115
13116 check_mds_dmesg() {
13117         local facets=$(get_facets MDS)
13118         for facet in ${facets//,/ }; do
13119                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13120         done
13121         return 1
13122 }
13123
13124 test_129() {
13125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13126         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13127                 skip "Need MDS version with at least 2.5.56"
13128         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13129                 skip_env "ldiskfs only test"
13130         fi
13131         remote_mds_nodsh && skip "remote MDS with nodsh"
13132
13133         local ENOSPC=28
13134         local has_warning=false
13135
13136         rm -rf $DIR/$tdir
13137         mkdir -p $DIR/$tdir
13138
13139         # block size of mds1
13140         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13141         set_dir_limits $maxsize $((maxsize * 6 / 8))
13142         stack_trap "set_dir_limits 0 0"
13143         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13144         local dirsize=$(stat -c%s "$DIR/$tdir")
13145         local nfiles=0
13146         while (( $dirsize <= $maxsize )); do
13147                 $MCREATE $DIR/$tdir/file_base_$nfiles
13148                 rc=$?
13149                 # check two errors:
13150                 # ENOSPC for ext4 max_dir_size, which has been used since
13151                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13152                 if (( rc == ENOSPC )); then
13153                         set_dir_limits 0 0
13154                         echo "rc=$rc returned as expected after $nfiles files"
13155
13156                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13157                                 error "create failed w/o dir size limit"
13158
13159                         # messages may be rate limited if test is run repeatedly
13160                         check_mds_dmesg '"is approaching max"' ||
13161                                 echo "warning message should be output"
13162                         check_mds_dmesg '"has reached max"' ||
13163                                 echo "reached message should be output"
13164
13165                         dirsize=$(stat -c%s "$DIR/$tdir")
13166
13167                         [[ $dirsize -ge $maxsize ]] && return 0
13168                         error "dirsize $dirsize < $maxsize after $nfiles files"
13169                 elif (( rc != 0 )); then
13170                         break
13171                 fi
13172                 nfiles=$((nfiles + 1))
13173                 dirsize=$(stat -c%s "$DIR/$tdir")
13174         done
13175
13176         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13177 }
13178 run_test 129 "test directory size limit ========================"
13179
13180 OLDIFS="$IFS"
13181 cleanup_130() {
13182         trap 0
13183         IFS="$OLDIFS"
13184 }
13185
13186 test_130a() {
13187         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13188         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13189
13190         trap cleanup_130 EXIT RETURN
13191
13192         local fm_file=$DIR/$tfile
13193         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13194         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13195                 error "dd failed for $fm_file"
13196
13197         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13198         filefrag -ves $fm_file
13199         RC=$?
13200         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13201                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13202         [ $RC != 0 ] && error "filefrag $fm_file failed"
13203
13204         filefrag_op=$(filefrag -ve -k $fm_file |
13205                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13206         lun=$($LFS getstripe -i $fm_file)
13207
13208         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13209         IFS=$'\n'
13210         tot_len=0
13211         for line in $filefrag_op
13212         do
13213                 frag_lun=`echo $line | cut -d: -f5`
13214                 ext_len=`echo $line | cut -d: -f4`
13215                 if (( $frag_lun != $lun )); then
13216                         cleanup_130
13217                         error "FIEMAP on 1-stripe file($fm_file) failed"
13218                         return
13219                 fi
13220                 (( tot_len += ext_len ))
13221         done
13222
13223         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13224                 cleanup_130
13225                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13226                 return
13227         fi
13228
13229         cleanup_130
13230
13231         echo "FIEMAP on single striped file succeeded"
13232 }
13233 run_test 130a "FIEMAP (1-stripe file)"
13234
13235 test_130b() {
13236         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13237
13238         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13239         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13240
13241         trap cleanup_130 EXIT RETURN
13242
13243         local fm_file=$DIR/$tfile
13244         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13245                         error "setstripe on $fm_file"
13246         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13247                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13248
13249         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13250                 error "dd failed on $fm_file"
13251
13252         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13253         filefrag_op=$(filefrag -ve -k $fm_file |
13254                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13255
13256         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13257                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13258
13259         IFS=$'\n'
13260         tot_len=0
13261         num_luns=1
13262         for line in $filefrag_op
13263         do
13264                 frag_lun=$(echo $line | cut -d: -f5 |
13265                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13266                 ext_len=$(echo $line | cut -d: -f4)
13267                 if (( $frag_lun != $last_lun )); then
13268                         if (( tot_len != 1024 )); then
13269                                 cleanup_130
13270                                 error "FIEMAP on $fm_file failed; returned " \
13271                                 "len $tot_len for OST $last_lun instead of 1024"
13272                                 return
13273                         else
13274                                 (( num_luns += 1 ))
13275                                 tot_len=0
13276                         fi
13277                 fi
13278                 (( tot_len += ext_len ))
13279                 last_lun=$frag_lun
13280         done
13281         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13282                 cleanup_130
13283                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13284                         "luns or wrong len for OST $last_lun"
13285                 return
13286         fi
13287
13288         cleanup_130
13289
13290         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13291 }
13292 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13293
13294 test_130c() {
13295         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13296
13297         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13298         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13299
13300         trap cleanup_130 EXIT RETURN
13301
13302         local fm_file=$DIR/$tfile
13303         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13304         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13305                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13306
13307         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13308                         error "dd failed on $fm_file"
13309
13310         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13311         filefrag_op=$(filefrag -ve -k $fm_file |
13312                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13313
13314         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13315                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13316
13317         IFS=$'\n'
13318         tot_len=0
13319         num_luns=1
13320         for line in $filefrag_op
13321         do
13322                 frag_lun=$(echo $line | cut -d: -f5 |
13323                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13324                 ext_len=$(echo $line | cut -d: -f4)
13325                 if (( $frag_lun != $last_lun )); then
13326                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13327                         if (( logical != 512 )); then
13328                                 cleanup_130
13329                                 error "FIEMAP on $fm_file failed; returned " \
13330                                 "logical start for lun $logical instead of 512"
13331                                 return
13332                         fi
13333                         if (( tot_len != 512 )); then
13334                                 cleanup_130
13335                                 error "FIEMAP on $fm_file failed; returned " \
13336                                 "len $tot_len for OST $last_lun instead of 1024"
13337                                 return
13338                         else
13339                                 (( num_luns += 1 ))
13340                                 tot_len=0
13341                         fi
13342                 fi
13343                 (( tot_len += ext_len ))
13344                 last_lun=$frag_lun
13345         done
13346         if (( num_luns != 2 || tot_len != 512 )); then
13347                 cleanup_130
13348                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13349                         "luns or wrong len for OST $last_lun"
13350                 return
13351         fi
13352
13353         cleanup_130
13354
13355         echo "FIEMAP on 2-stripe file with hole succeeded"
13356 }
13357 run_test 130c "FIEMAP (2-stripe file with hole)"
13358
13359 test_130d() {
13360         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13361
13362         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13363         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13364
13365         trap cleanup_130 EXIT RETURN
13366
13367         local fm_file=$DIR/$tfile
13368         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13369                         error "setstripe on $fm_file"
13370         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13371                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13372
13373         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13374         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13375                 error "dd failed on $fm_file"
13376
13377         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13378         filefrag_op=$(filefrag -ve -k $fm_file |
13379                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13380
13381         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13382                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13383
13384         IFS=$'\n'
13385         tot_len=0
13386         num_luns=1
13387         for line in $filefrag_op
13388         do
13389                 frag_lun=$(echo $line | cut -d: -f5 |
13390                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13391                 ext_len=$(echo $line | cut -d: -f4)
13392                 if (( $frag_lun != $last_lun )); then
13393                         if (( tot_len != 1024 )); then
13394                                 cleanup_130
13395                                 error "FIEMAP on $fm_file failed; returned " \
13396                                 "len $tot_len for OST $last_lun instead of 1024"
13397                                 return
13398                         else
13399                                 (( num_luns += 1 ))
13400                                 tot_len=0
13401                         fi
13402                 fi
13403                 (( tot_len += ext_len ))
13404                 last_lun=$frag_lun
13405         done
13406         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13407                 cleanup_130
13408                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13409                         "luns or wrong len for OST $last_lun"
13410                 return
13411         fi
13412
13413         cleanup_130
13414
13415         echo "FIEMAP on N-stripe file succeeded"
13416 }
13417 run_test 130d "FIEMAP (N-stripe file)"
13418
13419 test_130e() {
13420         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13421
13422         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13423         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13424
13425         trap cleanup_130 EXIT RETURN
13426
13427         local fm_file=$DIR/$tfile
13428         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13429
13430         NUM_BLKS=512
13431         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13432         for ((i = 0; i < $NUM_BLKS; i++)); do
13433                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13434                         conv=notrunc > /dev/null 2>&1
13435         done
13436
13437         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13438         filefrag_op=$(filefrag -ve -k $fm_file |
13439                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13440
13441         last_lun=$(echo $filefrag_op | cut -d: -f5)
13442
13443         IFS=$'\n'
13444         tot_len=0
13445         num_luns=1
13446         for line in $filefrag_op; do
13447                 frag_lun=$(echo $line | cut -d: -f5)
13448                 ext_len=$(echo $line | cut -d: -f4)
13449                 if [[ "$frag_lun" != "$last_lun" ]]; then
13450                         if (( tot_len != $EXPECTED_LEN )); then
13451                                 cleanup_130
13452                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13453                         else
13454                                 (( num_luns += 1 ))
13455                                 tot_len=0
13456                         fi
13457                 fi
13458                 (( tot_len += ext_len ))
13459                 last_lun=$frag_lun
13460         done
13461         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13462                 cleanup_130
13463                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13464         fi
13465
13466         echo "FIEMAP with continuation calls succeeded"
13467 }
13468 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13469
13470 test_130f() {
13471         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13472         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13473
13474         local fm_file=$DIR/$tfile
13475         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13476                 error "multiop create with lov_delay_create on $fm_file"
13477
13478         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13479         filefrag_extents=$(filefrag -vek $fm_file |
13480                            awk '/extents? found/ { print $2 }')
13481         if [[ "$filefrag_extents" != "0" ]]; then
13482                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13483         fi
13484
13485         rm -f $fm_file
13486 }
13487 run_test 130f "FIEMAP (unstriped file)"
13488
13489 test_130g() {
13490         local file=$DIR/$tfile
13491         local nr=$((OSTCOUNT * 100))
13492
13493         $LFS setstripe -C $nr $file ||
13494                 error "failed to setstripe -C $nr $file"
13495
13496         dd if=/dev/zero of=$file count=$nr bs=1M
13497         sync
13498         nr=$($LFS getstripe -c $file)
13499
13500         local extents=$(filefrag -v $file |
13501                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13502
13503         echo "filefrag list $extents extents in file with stripecount $nr"
13504         if (( extents < nr )); then
13505                 $LFS getstripe $file
13506                 filefrag -v $file
13507                 error "filefrag printed $extents < $nr extents"
13508         fi
13509
13510         rm -f $file
13511 }
13512 run_test 130g "FIEMAP (overstripe file)"
13513
13514 # Test for writev/readv
13515 test_131a() {
13516         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13517                 error "writev test failed"
13518         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13519                 error "readv failed"
13520         rm -f $DIR/$tfile
13521 }
13522 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13523
13524 test_131b() {
13525         local fsize=$((524288 + 1048576 + 1572864))
13526         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13527                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13528                         error "append writev test failed"
13529
13530         ((fsize += 1572864 + 1048576))
13531         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13532                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13533                         error "append writev test failed"
13534         rm -f $DIR/$tfile
13535 }
13536 run_test 131b "test append writev"
13537
13538 test_131c() {
13539         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13540         error "NOT PASS"
13541 }
13542 run_test 131c "test read/write on file w/o objects"
13543
13544 test_131d() {
13545         rwv -f $DIR/$tfile -w -n 1 1572864
13546         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13547         if [ "$NOB" != 1572864 ]; then
13548                 error "Short read filed: read $NOB bytes instead of 1572864"
13549         fi
13550         rm -f $DIR/$tfile
13551 }
13552 run_test 131d "test short read"
13553
13554 test_131e() {
13555         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13556         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13557         error "read hitting hole failed"
13558         rm -f $DIR/$tfile
13559 }
13560 run_test 131e "test read hitting hole"
13561
13562 check_stats() {
13563         local facet=$1
13564         local op=$2
13565         local want=${3:-0}
13566         local res
13567
13568         case $facet in
13569         mds*) res=$(do_facet $facet \
13570                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13571                  ;;
13572         ost*) res=$(do_facet $facet \
13573                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13574                  ;;
13575         *) error "Wrong facet '$facet'" ;;
13576         esac
13577         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13578         # if the argument $3 is zero, it means any stat increment is ok.
13579         if [[ $want -gt 0 ]]; then
13580                 local count=$(echo $res | awk '{ print $2 }')
13581                 [[ $count -ne $want ]] &&
13582                         error "The $op counter on $facet is $count, not $want"
13583         fi
13584 }
13585
13586 test_133a() {
13587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13588         remote_ost_nodsh && skip "remote OST with nodsh"
13589         remote_mds_nodsh && skip "remote MDS with nodsh"
13590         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13591                 skip_env "MDS doesn't support rename stats"
13592
13593         local testdir=$DIR/${tdir}/stats_testdir
13594
13595         mkdir -p $DIR/${tdir}
13596
13597         # clear stats.
13598         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13599         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13600
13601         # verify mdt stats first.
13602         mkdir ${testdir} || error "mkdir failed"
13603         check_stats $SINGLEMDS "mkdir" 1
13604         touch ${testdir}/${tfile} || error "touch failed"
13605         check_stats $SINGLEMDS "open" 1
13606         check_stats $SINGLEMDS "close" 1
13607         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13608                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13609                 check_stats $SINGLEMDS "mknod" 2
13610         }
13611         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13612         check_stats $SINGLEMDS "unlink" 1
13613         rm -f ${testdir}/${tfile} || error "file remove failed"
13614         check_stats $SINGLEMDS "unlink" 2
13615
13616         # remove working dir and check mdt stats again.
13617         rmdir ${testdir} || error "rmdir failed"
13618         check_stats $SINGLEMDS "rmdir" 1
13619
13620         local testdir1=$DIR/${tdir}/stats_testdir1
13621         mkdir -p ${testdir}
13622         mkdir -p ${testdir1}
13623         touch ${testdir1}/test1
13624         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13625         check_stats $SINGLEMDS "crossdir_rename" 1
13626
13627         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13628         check_stats $SINGLEMDS "samedir_rename" 1
13629
13630         rm -rf $DIR/${tdir}
13631 }
13632 run_test 133a "Verifying MDT stats ========================================"
13633
13634 test_133b() {
13635         local res
13636
13637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13638         remote_ost_nodsh && skip "remote OST with nodsh"
13639         remote_mds_nodsh && skip "remote MDS with nodsh"
13640
13641         local testdir=$DIR/${tdir}/stats_testdir
13642
13643         mkdir -p ${testdir} || error "mkdir failed"
13644         touch ${testdir}/${tfile} || error "touch failed"
13645         cancel_lru_locks mdc
13646
13647         # clear stats.
13648         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13649         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13650
13651         # extra mdt stats verification.
13652         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13653         check_stats $SINGLEMDS "setattr" 1
13654         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13655         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13656         then            # LU-1740
13657                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13658                 check_stats $SINGLEMDS "getattr" 1
13659         fi
13660         rm -rf $DIR/${tdir}
13661
13662         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13663         # so the check below is not reliable
13664         [ $MDSCOUNT -eq 1 ] || return 0
13665
13666         # Sleep to avoid a cached response.
13667         #define OBD_STATFS_CACHE_SECONDS 1
13668         sleep 2
13669         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13670         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13671         $LFS df || error "lfs failed"
13672         check_stats $SINGLEMDS "statfs" 1
13673
13674         # check aggregated statfs (LU-10018)
13675         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13676                 return 0
13677         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13678                 return 0
13679         sleep 2
13680         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13681         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13682         df $DIR
13683         check_stats $SINGLEMDS "statfs" 1
13684
13685         # We want to check that the client didn't send OST_STATFS to
13686         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13687         # extra care is needed here.
13688         if remote_mds; then
13689                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13690                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13691
13692                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13693                 [ "$res" ] && error "OST got STATFS"
13694         fi
13695
13696         return 0
13697 }
13698 run_test 133b "Verifying extra MDT stats =================================="
13699
13700 test_133c() {
13701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13702         remote_ost_nodsh && skip "remote OST with nodsh"
13703         remote_mds_nodsh && skip "remote MDS with nodsh"
13704
13705         local testdir=$DIR/$tdir/stats_testdir
13706
13707         test_mkdir -p $testdir
13708
13709         # verify obdfilter stats.
13710         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13711         sync
13712         cancel_lru_locks osc
13713         wait_delete_completed
13714
13715         # clear stats.
13716         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13717         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13718
13719         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13720                 error "dd failed"
13721         sync
13722         cancel_lru_locks osc
13723         check_stats ost1 "write" 1
13724
13725         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13726         check_stats ost1 "read" 1
13727
13728         > $testdir/$tfile || error "truncate failed"
13729         check_stats ost1 "punch" 1
13730
13731         rm -f $testdir/$tfile || error "file remove failed"
13732         wait_delete_completed
13733         check_stats ost1 "destroy" 1
13734
13735         rm -rf $DIR/$tdir
13736 }
13737 run_test 133c "Verifying OST stats ========================================"
13738
13739 order_2() {
13740         local value=$1
13741         local orig=$value
13742         local order=1
13743
13744         while [ $value -ge 2 ]; do
13745                 order=$((order*2))
13746                 value=$((value/2))
13747         done
13748
13749         if [ $orig -gt $order ]; then
13750                 order=$((order*2))
13751         fi
13752         echo $order
13753 }
13754
13755 size_in_KMGT() {
13756     local value=$1
13757     local size=('K' 'M' 'G' 'T');
13758     local i=0
13759     local size_string=$value
13760
13761     while [ $value -ge 1024 ]; do
13762         if [ $i -gt 3 ]; then
13763             #T is the biggest unit we get here, if that is bigger,
13764             #just return XXXT
13765             size_string=${value}T
13766             break
13767         fi
13768         value=$((value >> 10))
13769         if [ $value -lt 1024 ]; then
13770             size_string=${value}${size[$i]}
13771             break
13772         fi
13773         i=$((i + 1))
13774     done
13775
13776     echo $size_string
13777 }
13778
13779 get_rename_size() {
13780         local size=$1
13781         local context=${2:-.}
13782         local sample=$(do_facet $SINGLEMDS $LCTL \
13783                 get_param mdt.$FSNAME-MDT0000.rename_stats |
13784                 grep -A1 $context |
13785                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13786         echo $sample
13787 }
13788
13789 test_133d() {
13790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13791         remote_ost_nodsh && skip "remote OST with nodsh"
13792         remote_mds_nodsh && skip "remote MDS with nodsh"
13793         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13794                 skip_env "MDS doesn't support rename stats"
13795
13796         local testdir1=$DIR/${tdir}/stats_testdir1
13797         local testdir2=$DIR/${tdir}/stats_testdir2
13798         mkdir -p $DIR/${tdir}
13799
13800         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13801
13802         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13803         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13804
13805         createmany -o $testdir1/test 512 || error "createmany failed"
13806
13807         # check samedir rename size
13808         mv ${testdir1}/test0 ${testdir1}/test_0
13809
13810         local testdir1_size=$(ls -l $DIR/${tdir} |
13811                 awk '/stats_testdir1/ {print $5}')
13812         local testdir2_size=$(ls -l $DIR/${tdir} |
13813                 awk '/stats_testdir2/ {print $5}')
13814
13815         testdir1_size=$(order_2 $testdir1_size)
13816         testdir2_size=$(order_2 $testdir2_size)
13817
13818         testdir1_size=$(size_in_KMGT $testdir1_size)
13819         testdir2_size=$(size_in_KMGT $testdir2_size)
13820
13821         echo "source rename dir size: ${testdir1_size}"
13822         echo "target rename dir size: ${testdir2_size}"
13823
13824         local cmd="do_facet $SINGLEMDS $LCTL "
13825         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13826
13827         eval $cmd || error "$cmd failed"
13828         local samedir=$($cmd | grep 'same_dir')
13829         local same_sample=$(get_rename_size $testdir1_size)
13830         [ -z "$samedir" ] && error "samedir_rename_size count error"
13831         [[ $same_sample -eq 1 ]] ||
13832                 error "samedir_rename_size error $same_sample"
13833         echo "Check same dir rename stats success"
13834
13835         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13836
13837         # check crossdir rename size
13838         mv ${testdir1}/test_0 ${testdir2}/test_0
13839
13840         testdir1_size=$(ls -l $DIR/${tdir} |
13841                 awk '/stats_testdir1/ {print $5}')
13842         testdir2_size=$(ls -l $DIR/${tdir} |
13843                 awk '/stats_testdir2/ {print $5}')
13844
13845         testdir1_size=$(order_2 $testdir1_size)
13846         testdir2_size=$(order_2 $testdir2_size)
13847
13848         testdir1_size=$(size_in_KMGT $testdir1_size)
13849         testdir2_size=$(size_in_KMGT $testdir2_size)
13850
13851         echo "source rename dir size: ${testdir1_size}"
13852         echo "target rename dir size: ${testdir2_size}"
13853
13854         eval $cmd || error "$cmd failed"
13855         local crossdir=$($cmd | grep 'crossdir')
13856         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13857         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13858         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13859         [[ $src_sample -eq 1 ]] ||
13860                 error "crossdir_rename_size error $src_sample"
13861         [[ $tgt_sample -eq 1 ]] ||
13862                 error "crossdir_rename_size error $tgt_sample"
13863         echo "Check cross dir rename stats success"
13864         rm -rf $DIR/${tdir}
13865 }
13866 run_test 133d "Verifying rename_stats ========================================"
13867
13868 test_133e() {
13869         remote_mds_nodsh && skip "remote MDS with nodsh"
13870         remote_ost_nodsh && skip "remote OST with nodsh"
13871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13872
13873         local testdir=$DIR/${tdir}/stats_testdir
13874         local ctr f0 f1 bs=32768 count=42 sum
13875
13876         mkdir -p ${testdir} || error "mkdir failed"
13877
13878         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13879
13880         for ctr in {write,read}_bytes; do
13881                 sync
13882                 cancel_lru_locks osc
13883
13884                 do_facet ost1 $LCTL set_param -n \
13885                         "obdfilter.*.exports.clear=clear"
13886
13887                 if [ $ctr = write_bytes ]; then
13888                         f0=/dev/zero
13889                         f1=${testdir}/${tfile}
13890                 else
13891                         f0=${testdir}/${tfile}
13892                         f1=/dev/null
13893                 fi
13894
13895                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13896                         error "dd failed"
13897                 sync
13898                 cancel_lru_locks osc
13899
13900                 sum=$(do_facet ost1 $LCTL get_param \
13901                         "obdfilter.*.exports.*.stats" |
13902                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13903                                 $1 == ctr { sum += $7 }
13904                                 END { printf("%0.0f", sum) }')
13905
13906                 if ((sum != bs * count)); then
13907                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13908                 fi
13909         done
13910
13911         rm -rf $DIR/${tdir}
13912 }
13913 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13914
13915 test_133f() {
13916         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13917                 skip "too old lustre for get_param -R ($facet_ver)"
13918
13919         # verifying readability.
13920         $LCTL get_param -R '*' &> /dev/null
13921
13922         # Verifing writability with badarea_io.
13923         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13924         local skipped_params='force_lbug|changelog_mask|daemon_file'
13925         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13926                 egrep -v "$skipped_params" |
13927                 xargs -n 1 find $proc_dirs -name |
13928                 xargs -n 1 badarea_io ||
13929                 error "client badarea_io failed"
13930
13931         # remount the FS in case writes/reads /proc break the FS
13932         cleanup || error "failed to unmount"
13933         setup || error "failed to setup"
13934 }
13935 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13936
13937 test_133g() {
13938         remote_mds_nodsh && skip "remote MDS with nodsh"
13939         remote_ost_nodsh && skip "remote OST with nodsh"
13940
13941         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
13942         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
13943         local facet
13944         for facet in mds1 ost1; do
13945                 local facet_ver=$(lustre_version_code $facet)
13946                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13947                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13948                 else
13949                         log "$facet: too old lustre for get_param -R"
13950                 fi
13951                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13952                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13953                                 tr -d = | egrep -v $skipped_params |
13954                                 xargs -n 1 find $proc_dirs -name |
13955                                 xargs -n 1 badarea_io" ||
13956                                         error "$facet badarea_io failed"
13957                 else
13958                         skip_noexit "$facet: too old lustre for get_param -R"
13959                 fi
13960         done
13961
13962         # remount the FS in case writes/reads /proc break the FS
13963         cleanup || error "failed to unmount"
13964         setup || error "failed to setup"
13965 }
13966 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13967
13968 test_133h() {
13969         remote_mds_nodsh && skip "remote MDS with nodsh"
13970         remote_ost_nodsh && skip "remote OST with nodsh"
13971         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13972                 skip "Need MDS version at least 2.9.54"
13973
13974         local facet
13975         for facet in client mds1 ost1; do
13976                 # Get the list of files that are missing the terminating newline
13977                 local plist=$(do_facet $facet
13978                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13979                 local ent
13980                 for ent in $plist; do
13981                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13982                                 awk -v FS='\v' -v RS='\v\v' \
13983                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13984                                         print FILENAME}'" 2>/dev/null)
13985                         [ -z $missing ] || {
13986                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13987                                 error "file does not end with newline: $facet-$ent"
13988                         }
13989                 done
13990         done
13991 }
13992 run_test 133h "Proc files should end with newlines"
13993
13994 test_134a() {
13995         remote_mds_nodsh && skip "remote MDS with nodsh"
13996         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13997                 skip "Need MDS version at least 2.7.54"
13998
13999         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14000         cancel_lru_locks mdc
14001
14002         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14003         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14004         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14005
14006         local nr=1000
14007         createmany -o $DIR/$tdir/f $nr ||
14008                 error "failed to create $nr files in $DIR/$tdir"
14009         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14010
14011         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14012         do_facet mds1 $LCTL set_param fail_loc=0x327
14013         do_facet mds1 $LCTL set_param fail_val=500
14014         touch $DIR/$tdir/m
14015
14016         echo "sleep 10 seconds ..."
14017         sleep 10
14018         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14019
14020         do_facet mds1 $LCTL set_param fail_loc=0
14021         do_facet mds1 $LCTL set_param fail_val=0
14022         [ $lck_cnt -lt $unused ] ||
14023                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14024
14025         rm $DIR/$tdir/m
14026         unlinkmany $DIR/$tdir/f $nr
14027 }
14028 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14029
14030 test_134b() {
14031         remote_mds_nodsh && skip "remote MDS with nodsh"
14032         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14033                 skip "Need MDS version at least 2.7.54"
14034
14035         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14036         cancel_lru_locks mdc
14037
14038         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14039                         ldlm.lock_reclaim_threshold_mb)
14040         # disable reclaim temporarily
14041         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14042
14043         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14044         do_facet mds1 $LCTL set_param fail_loc=0x328
14045         do_facet mds1 $LCTL set_param fail_val=500
14046
14047         $LCTL set_param debug=+trace
14048
14049         local nr=600
14050         createmany -o $DIR/$tdir/f $nr &
14051         local create_pid=$!
14052
14053         echo "Sleep $TIMEOUT seconds ..."
14054         sleep $TIMEOUT
14055         if ! ps -p $create_pid  > /dev/null 2>&1; then
14056                 do_facet mds1 $LCTL set_param fail_loc=0
14057                 do_facet mds1 $LCTL set_param fail_val=0
14058                 do_facet mds1 $LCTL set_param \
14059                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14060                 error "createmany finished incorrectly!"
14061         fi
14062         do_facet mds1 $LCTL set_param fail_loc=0
14063         do_facet mds1 $LCTL set_param fail_val=0
14064         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14065         wait $create_pid || return 1
14066
14067         unlinkmany $DIR/$tdir/f $nr
14068 }
14069 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14070
14071 test_135() {
14072         remote_mds_nodsh && skip "remote MDS with nodsh"
14073         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14074                 skip "Need MDS version at least 2.13.50"
14075         local fname
14076
14077         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14078
14079 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14080         #set only one record at plain llog
14081         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14082
14083         #fill already existed plain llog each 64767
14084         #wrapping whole catalog
14085         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14086
14087         createmany -o $DIR/$tdir/$tfile_ 64700
14088         for (( i = 0; i < 64700; i = i + 2 ))
14089         do
14090                 rm $DIR/$tdir/$tfile_$i &
14091                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14092                 local pid=$!
14093                 wait $pid
14094         done
14095
14096         #waiting osp synchronization
14097         wait_delete_completed
14098 }
14099 run_test 135 "Race catalog processing"
14100
14101 test_136() {
14102         remote_mds_nodsh && skip "remote MDS with nodsh"
14103         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14104                 skip "Need MDS version at least 2.13.50"
14105         local fname
14106
14107         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14108         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14109         #set only one record at plain llog
14110 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14111         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14112
14113         #fill already existed 2 plain llogs each 64767
14114         #wrapping whole catalog
14115         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14116         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14117         wait_delete_completed
14118
14119         createmany -o $DIR/$tdir/$tfile_ 10
14120         sleep 25
14121
14122         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14123         for (( i = 0; i < 10; i = i + 3 ))
14124         do
14125                 rm $DIR/$tdir/$tfile_$i &
14126                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14127                 local pid=$!
14128                 wait $pid
14129                 sleep 7
14130                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14131         done
14132
14133         #waiting osp synchronization
14134         wait_delete_completed
14135 }
14136 run_test 136 "Race catalog processing 2"
14137
14138 test_140() { #bug-17379
14139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14140
14141         test_mkdir $DIR/$tdir
14142         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14143         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14144
14145         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14146         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14147         local i=0
14148         while i=$((i + 1)); do
14149                 test_mkdir $i
14150                 cd $i || error "Changing to $i"
14151                 ln -s ../stat stat || error "Creating stat symlink"
14152                 # Read the symlink until ELOOP present,
14153                 # not LBUGing the system is considered success,
14154                 # we didn't overrun the stack.
14155                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14156                 if [ $ret -ne 0 ]; then
14157                         if [ $ret -eq 40 ]; then
14158                                 break  # -ELOOP
14159                         else
14160                                 error "Open stat symlink"
14161                                         return
14162                         fi
14163                 fi
14164         done
14165         i=$((i - 1))
14166         echo "The symlink depth = $i"
14167         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14168                 error "Invalid symlink depth"
14169
14170         # Test recursive symlink
14171         ln -s symlink_self symlink_self
14172         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14173         echo "open symlink_self returns $ret"
14174         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14175 }
14176 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14177
14178 test_150a() {
14179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14180
14181         local TF="$TMP/$tfile"
14182
14183         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14184         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14185         cp $TF $DIR/$tfile
14186         cancel_lru_locks $OSC
14187         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14188         remount_client $MOUNT
14189         df -P $MOUNT
14190         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14191
14192         $TRUNCATE $TF 6000
14193         $TRUNCATE $DIR/$tfile 6000
14194         cancel_lru_locks $OSC
14195         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14196
14197         echo "12345" >>$TF
14198         echo "12345" >>$DIR/$tfile
14199         cancel_lru_locks $OSC
14200         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14201
14202         echo "12345" >>$TF
14203         echo "12345" >>$DIR/$tfile
14204         cancel_lru_locks $OSC
14205         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14206 }
14207 run_test 150a "truncate/append tests"
14208
14209 test_150b() {
14210         check_set_fallocate_or_skip
14211
14212         touch $DIR/$tfile
14213         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14214         check_fallocate $DIR/$tfile || error "fallocate failed"
14215 }
14216 run_test 150b "Verify fallocate (prealloc) functionality"
14217
14218 test_150bb() {
14219         check_set_fallocate_or_skip
14220
14221         touch $DIR/$tfile
14222         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14223         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14224         > $DIR/$tfile
14225         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14226         # precomputed md5sum for 20MB of zeroes
14227         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14228         local sum=($(md5sum $DIR/$tfile))
14229
14230         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14231
14232         check_set_fallocate 1
14233
14234         > $DIR/$tfile
14235         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14236         sum=($(md5sum $DIR/$tfile))
14237
14238         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14239 }
14240 run_test 150bb "Verify fallocate modes both zero space"
14241
14242 test_150c() {
14243         check_set_fallocate_or_skip
14244         local striping="-c2"
14245
14246         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14247         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14248         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14249         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14250         local want=$((OSTCOUNT * 1048576))
14251
14252         # Must allocate all requested space, not more than 5% extra
14253         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14254                 error "bytes $bytes is not $want"
14255
14256         rm -f $DIR/$tfile
14257
14258         echo "verify fallocate on PFL file"
14259
14260         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14261
14262         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14263                 error "Create $DIR/$tfile failed"
14264         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14265                         error "fallocate failed"
14266         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14267         want=$((512 * 1048576))
14268
14269         # Must allocate all requested space, not more than 5% extra
14270         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14271                 error "bytes $bytes is not $want"
14272 }
14273 run_test 150c "Verify fallocate Size and Blocks"
14274
14275 test_150d() {
14276         check_set_fallocate_or_skip
14277         local striping="-c2"
14278
14279         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14280
14281         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14282         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14283                 error "setstripe failed"
14284         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14285         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14286         local want=$((OSTCOUNT * 1048576))
14287
14288         # Must allocate all requested space, not more than 5% extra
14289         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14290                 error "bytes $bytes is not $want"
14291 }
14292 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14293
14294 test_150e() {
14295         check_set_fallocate_or_skip
14296
14297         echo "df before:"
14298         $LFS df
14299         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14300         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14301                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14302
14303         # Find OST with Minimum Size
14304         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14305                        sort -un | head -1)
14306
14307         # Get 100MB per OST of the available space to reduce run time
14308         # else 60% of the available space if we are running SLOW tests
14309         if [ $SLOW == "no" ]; then
14310                 local space=$((1024 * 100 * OSTCOUNT))
14311         else
14312                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14313         fi
14314
14315         fallocate -l${space}k $DIR/$tfile ||
14316                 error "fallocate ${space}k $DIR/$tfile failed"
14317         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14318
14319         # get size immediately after fallocate. This should be correctly
14320         # updated
14321         local size=$(stat -c '%s' $DIR/$tfile)
14322         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14323
14324         # Sleep for a while for statfs to get updated. And not pull from cache.
14325         sleep 2
14326
14327         echo "df after fallocate:"
14328         $LFS df
14329
14330         (( size / 1024 == space )) || error "size $size != requested $space"
14331         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14332                 error "used $used < space $space"
14333
14334         rm $DIR/$tfile || error "rm failed"
14335         sync
14336         wait_delete_completed
14337
14338         echo "df after unlink:"
14339         $LFS df
14340 }
14341 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14342
14343 test_150f() {
14344         local size
14345         local blocks
14346         local want_size_before=20480 # in bytes
14347         local want_blocks_before=40 # 512 sized blocks
14348         local want_blocks_after=24  # 512 sized blocks
14349         local length=$(((want_blocks_before - want_blocks_after) * 512))
14350
14351         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14352                 skip "need at least 2.14.0 for fallocate punch"
14353
14354         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14355                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14356         fi
14357
14358         check_set_fallocate_or_skip
14359         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14360
14361         [[ "x$DOM" == "xyes" ]] &&
14362                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14363
14364         echo "Verify fallocate punch: Range within the file range"
14365         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14366                 error "dd failed for bs 4096 and count 5"
14367
14368         # Call fallocate with punch range which is within the file range
14369         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14370                 error "fallocate failed: offset 4096 and length $length"
14371         # client must see changes immediately after fallocate
14372         size=$(stat -c '%s' $DIR/$tfile)
14373         blocks=$(stat -c '%b' $DIR/$tfile)
14374
14375         # Verify punch worked.
14376         (( blocks == want_blocks_after )) ||
14377                 error "punch failed: blocks $blocks != $want_blocks_after"
14378
14379         (( size == want_size_before )) ||
14380                 error "punch failed: size $size != $want_size_before"
14381
14382         # Verify there is hole in file
14383         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14384         # precomputed md5sum
14385         local expect="4a9a834a2db02452929c0a348273b4aa"
14386
14387         cksum=($(md5sum $DIR/$tfile))
14388         [[ "${cksum[0]}" == "$expect" ]] ||
14389                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14390
14391         # Start second sub-case for fallocate punch.
14392         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14393         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14394                 error "dd failed for bs 4096 and count 5"
14395
14396         # Punch range less than block size will have no change in block count
14397         want_blocks_after=40  # 512 sized blocks
14398
14399         # Punch overlaps two blocks and less than blocksize
14400         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14401                 error "fallocate failed: offset 4000 length 3000"
14402         size=$(stat -c '%s' $DIR/$tfile)
14403         blocks=$(stat -c '%b' $DIR/$tfile)
14404
14405         # Verify punch worked.
14406         (( blocks == want_blocks_after )) ||
14407                 error "punch failed: blocks $blocks != $want_blocks_after"
14408
14409         (( size == want_size_before )) ||
14410                 error "punch failed: size $size != $want_size_before"
14411
14412         # Verify if range is really zero'ed out. We expect Zeros.
14413         # precomputed md5sum
14414         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14415         cksum=($(md5sum $DIR/$tfile))
14416         [[ "${cksum[0]}" == "$expect" ]] ||
14417                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14418 }
14419 run_test 150f "Verify fallocate punch functionality"
14420
14421 test_150g() {
14422         local space
14423         local size
14424         local blocks
14425         local blocks_after
14426         local size_after
14427         local BS=4096 # Block size in bytes
14428
14429         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14430                 skip "need at least 2.14.0 for fallocate punch"
14431
14432         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14433                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14434         fi
14435
14436         check_set_fallocate_or_skip
14437         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14438
14439         if [[ "x$DOM" == "xyes" ]]; then
14440                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14441                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14442         else
14443                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14444                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14445         fi
14446
14447         # Get 100MB per OST of the available space to reduce run time
14448         # else 60% of the available space if we are running SLOW tests
14449         if [ $SLOW == "no" ]; then
14450                 space=$((1024 * 100 * OSTCOUNT))
14451         else
14452                 # Find OST with Minimum Size
14453                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14454                         sort -un | head -1)
14455                 echo "min size OST: $space"
14456                 space=$(((space * 60)/100 * OSTCOUNT))
14457         fi
14458         # space in 1k units, round to 4k blocks
14459         local blkcount=$((space * 1024 / $BS))
14460
14461         echo "Verify fallocate punch: Very large Range"
14462         fallocate -l${space}k $DIR/$tfile ||
14463                 error "fallocate ${space}k $DIR/$tfile failed"
14464         # write 1M at the end, start and in the middle
14465         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14466                 error "dd failed: bs $BS count 256"
14467         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14468                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14469         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14470                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14471
14472         # Gather stats.
14473         size=$(stat -c '%s' $DIR/$tfile)
14474
14475         # gather punch length.
14476         local punch_size=$((size - (BS * 2)))
14477
14478         echo "punch_size = $punch_size"
14479         echo "size - punch_size: $((size - punch_size))"
14480         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14481
14482         # Call fallocate to punch all except 2 blocks. We leave the
14483         # first and the last block
14484         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14485         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14486                 error "fallocate failed: offset $BS length $punch_size"
14487
14488         size_after=$(stat -c '%s' $DIR/$tfile)
14489         blocks_after=$(stat -c '%b' $DIR/$tfile)
14490
14491         # Verify punch worked.
14492         # Size should be kept
14493         (( size == size_after )) ||
14494                 error "punch failed: size $size != $size_after"
14495
14496         # two 4k data blocks to remain plus possible 1 extra extent block
14497         (( blocks_after <= ((BS / 512) * 3) )) ||
14498                 error "too many blocks remains: $blocks_after"
14499
14500         # Verify that file has hole between the first and the last blocks
14501         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14502         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14503
14504         echo "Hole at [$hole_start, $hole_end)"
14505         (( hole_start == BS )) ||
14506                 error "no hole at offset $BS after punch"
14507
14508         (( hole_end == BS + punch_size )) ||
14509                 error "data at offset $hole_end < $((BS + punch_size))"
14510 }
14511 run_test 150g "Verify fallocate punch on large range"
14512
14513 #LU-2902 roc_hit was not able to read all values from lproc
14514 function roc_hit_init() {
14515         local list=$(comma_list $(osts_nodes))
14516         local dir=$DIR/$tdir-check
14517         local file=$dir/$tfile
14518         local BEFORE
14519         local AFTER
14520         local idx
14521
14522         test_mkdir $dir
14523         #use setstripe to do a write to every ost
14524         for i in $(seq 0 $((OSTCOUNT-1))); do
14525                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14526                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14527                 idx=$(printf %04x $i)
14528                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14529                         awk '$1 == "cache_access" {sum += $7}
14530                                 END { printf("%0.0f", sum) }')
14531
14532                 cancel_lru_locks osc
14533                 cat $file >/dev/null
14534
14535                 AFTER=$(get_osd_param $list *OST*$idx stats |
14536                         awk '$1 == "cache_access" {sum += $7}
14537                                 END { printf("%0.0f", sum) }')
14538
14539                 echo BEFORE:$BEFORE AFTER:$AFTER
14540                 if ! let "AFTER - BEFORE == 4"; then
14541                         rm -rf $dir
14542                         error "roc_hit is not safe to use"
14543                 fi
14544                 rm $file
14545         done
14546
14547         rm -rf $dir
14548 }
14549
14550 function roc_hit() {
14551         local list=$(comma_list $(osts_nodes))
14552         echo $(get_osd_param $list '' stats |
14553                 awk '$1 == "cache_hit" {sum += $7}
14554                         END { printf("%0.0f", sum) }')
14555 }
14556
14557 function set_cache() {
14558         local on=1
14559
14560         if [ "$2" == "off" ]; then
14561                 on=0;
14562         fi
14563         local list=$(comma_list $(osts_nodes))
14564         set_osd_param $list '' $1_cache_enable $on
14565
14566         cancel_lru_locks osc
14567 }
14568
14569 test_151() {
14570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14571         remote_ost_nodsh && skip "remote OST with nodsh"
14572
14573         local CPAGES=3
14574         local list=$(comma_list $(osts_nodes))
14575
14576         # check whether obdfilter is cache capable at all
14577         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14578                 skip "not cache-capable obdfilter"
14579         fi
14580
14581         # check cache is enabled on all obdfilters
14582         if get_osd_param $list '' read_cache_enable | grep 0; then
14583                 skip "oss cache is disabled"
14584         fi
14585
14586         set_osd_param $list '' writethrough_cache_enable 1
14587
14588         # check write cache is enabled on all obdfilters
14589         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14590                 skip "oss write cache is NOT enabled"
14591         fi
14592
14593         roc_hit_init
14594
14595         #define OBD_FAIL_OBD_NO_LRU  0x609
14596         do_nodes $list $LCTL set_param fail_loc=0x609
14597
14598         # pages should be in the case right after write
14599         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14600                 error "dd failed"
14601
14602         local BEFORE=$(roc_hit)
14603         cancel_lru_locks osc
14604         cat $DIR/$tfile >/dev/null
14605         local AFTER=$(roc_hit)
14606
14607         do_nodes $list $LCTL set_param fail_loc=0
14608
14609         if ! let "AFTER - BEFORE == CPAGES"; then
14610                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14611         fi
14612
14613         cancel_lru_locks osc
14614         # invalidates OST cache
14615         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14616         set_osd_param $list '' read_cache_enable 0
14617         cat $DIR/$tfile >/dev/null
14618
14619         # now data shouldn't be found in the cache
14620         BEFORE=$(roc_hit)
14621         cancel_lru_locks osc
14622         cat $DIR/$tfile >/dev/null
14623         AFTER=$(roc_hit)
14624         if let "AFTER - BEFORE != 0"; then
14625                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14626         fi
14627
14628         set_osd_param $list '' read_cache_enable 1
14629         rm -f $DIR/$tfile
14630 }
14631 run_test 151 "test cache on oss and controls ==============================="
14632
14633 test_152() {
14634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14635
14636         local TF="$TMP/$tfile"
14637
14638         # simulate ENOMEM during write
14639 #define OBD_FAIL_OST_NOMEM      0x226
14640         lctl set_param fail_loc=0x80000226
14641         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14642         cp $TF $DIR/$tfile
14643         sync || error "sync failed"
14644         lctl set_param fail_loc=0
14645
14646         # discard client's cache
14647         cancel_lru_locks osc
14648
14649         # simulate ENOMEM during read
14650         lctl set_param fail_loc=0x80000226
14651         cmp $TF $DIR/$tfile || error "cmp failed"
14652         lctl set_param fail_loc=0
14653
14654         rm -f $TF
14655 }
14656 run_test 152 "test read/write with enomem ============================"
14657
14658 test_153() {
14659         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14660 }
14661 run_test 153 "test if fdatasync does not crash ======================="
14662
14663 dot_lustre_fid_permission_check() {
14664         local fid=$1
14665         local ffid=$MOUNT/.lustre/fid/$fid
14666         local test_dir=$2
14667
14668         echo "stat fid $fid"
14669         stat $ffid > /dev/null || error "stat $ffid failed."
14670         echo "touch fid $fid"
14671         touch $ffid || error "touch $ffid failed."
14672         echo "write to fid $fid"
14673         cat /etc/hosts > $ffid || error "write $ffid failed."
14674         echo "read fid $fid"
14675         diff /etc/hosts $ffid || error "read $ffid failed."
14676         echo "append write to fid $fid"
14677         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14678         echo "rename fid $fid"
14679         mv $ffid $test_dir/$tfile.1 &&
14680                 error "rename $ffid to $tfile.1 should fail."
14681         touch $test_dir/$tfile.1
14682         mv $test_dir/$tfile.1 $ffid &&
14683                 error "rename $tfile.1 to $ffid should fail."
14684         rm -f $test_dir/$tfile.1
14685         echo "truncate fid $fid"
14686         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14687         echo "link fid $fid"
14688         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14689         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14690                 echo "setfacl fid $fid"
14691                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14692                 echo "getfacl fid $fid"
14693                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14694         fi
14695         echo "unlink fid $fid"
14696         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14697         echo "mknod fid $fid"
14698         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14699
14700         fid=[0xf00000400:0x1:0x0]
14701         ffid=$MOUNT/.lustre/fid/$fid
14702
14703         echo "stat non-exist fid $fid"
14704         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14705         echo "write to non-exist fid $fid"
14706         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14707         echo "link new fid $fid"
14708         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14709
14710         mkdir -p $test_dir/$tdir
14711         touch $test_dir/$tdir/$tfile
14712         fid=$($LFS path2fid $test_dir/$tdir)
14713         rc=$?
14714         [ $rc -ne 0 ] &&
14715                 error "error: could not get fid for $test_dir/$dir/$tfile."
14716
14717         ffid=$MOUNT/.lustre/fid/$fid
14718
14719         echo "ls $fid"
14720         ls $ffid > /dev/null || error "ls $ffid failed."
14721         echo "touch $fid/$tfile.1"
14722         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14723
14724         echo "touch $MOUNT/.lustre/fid/$tfile"
14725         touch $MOUNT/.lustre/fid/$tfile && \
14726                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14727
14728         echo "setxattr to $MOUNT/.lustre/fid"
14729         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
14730
14731         echo "listxattr for $MOUNT/.lustre/fid"
14732         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
14733
14734         echo "delxattr from $MOUNT/.lustre/fid"
14735         setfattr -x trusted.name1 $MOUNT/.lustre/fid
14736
14737         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
14738         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
14739                 error "touch invalid fid should fail."
14740
14741         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
14742         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
14743                 error "touch non-normal fid should fail."
14744
14745         echo "rename $tdir to $MOUNT/.lustre/fid"
14746         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
14747                 error "rename to $MOUNT/.lustre/fid should fail."
14748
14749         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
14750         then            # LU-3547
14751                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
14752                 local new_obf_mode=777
14753
14754                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
14755                 chmod $new_obf_mode $DIR/.lustre/fid ||
14756                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
14757
14758                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
14759                 [ $obf_mode -eq $new_obf_mode ] ||
14760                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
14761
14762                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
14763                 chmod $old_obf_mode $DIR/.lustre/fid ||
14764                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
14765         fi
14766
14767         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
14768         fid=$($LFS path2fid $test_dir/$tfile-2)
14769
14770         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
14771         then # LU-5424
14772                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
14773                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
14774                         error "create lov data thru .lustre failed"
14775         fi
14776         echo "cp /etc/passwd $test_dir/$tfile-2"
14777         cp /etc/passwd $test_dir/$tfile-2 ||
14778                 error "copy to $test_dir/$tfile-2 failed."
14779         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
14780         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
14781                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
14782
14783         rm -rf $test_dir/tfile.lnk
14784         rm -rf $test_dir/$tfile-2
14785 }
14786
14787 test_154A() {
14788         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14789                 skip "Need MDS version at least 2.4.1"
14790
14791         local tf=$DIR/$tfile
14792         touch $tf
14793
14794         local fid=$($LFS path2fid $tf)
14795         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
14796
14797         # check that we get the same pathname back
14798         local rootpath
14799         local found
14800         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
14801                 echo "$rootpath $fid"
14802                 found=$($LFS fid2path $rootpath "$fid")
14803                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
14804                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
14805         done
14806
14807         # check wrong root path format
14808         rootpath=$MOUNT"_wrong"
14809         found=$($LFS fid2path $rootpath "$fid")
14810         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
14811 }
14812 run_test 154A "lfs path2fid and fid2path basic checks"
14813
14814 test_154B() {
14815         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14816                 skip "Need MDS version at least 2.4.1"
14817
14818         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14819         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
14820         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
14821         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
14822
14823         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
14824         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
14825
14826         # check that we get the same pathname
14827         echo "PFID: $PFID, name: $name"
14828         local FOUND=$($LFS fid2path $MOUNT "$PFID")
14829         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
14830         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
14831                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
14832
14833         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
14834 }
14835 run_test 154B "verify the ll_decode_linkea tool"
14836
14837 test_154a() {
14838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14839         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14840         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14841                 skip "Need MDS version at least 2.2.51"
14842         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14843
14844         cp /etc/hosts $DIR/$tfile
14845
14846         fid=$($LFS path2fid $DIR/$tfile)
14847         rc=$?
14848         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
14849
14850         dot_lustre_fid_permission_check "$fid" $DIR ||
14851                 error "dot lustre permission check $fid failed"
14852
14853         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
14854
14855         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
14856
14857         touch $MOUNT/.lustre/file &&
14858                 error "creation is not allowed under .lustre"
14859
14860         mkdir $MOUNT/.lustre/dir &&
14861                 error "mkdir is not allowed under .lustre"
14862
14863         rm -rf $DIR/$tfile
14864 }
14865 run_test 154a "Open-by-FID"
14866
14867 test_154b() {
14868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14869         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14871         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
14872                 skip "Need MDS version at least 2.2.51"
14873
14874         local remote_dir=$DIR/$tdir/remote_dir
14875         local MDTIDX=1
14876         local rc=0
14877
14878         mkdir -p $DIR/$tdir
14879         $LFS mkdir -i $MDTIDX $remote_dir ||
14880                 error "create remote directory failed"
14881
14882         cp /etc/hosts $remote_dir/$tfile
14883
14884         fid=$($LFS path2fid $remote_dir/$tfile)
14885         rc=$?
14886         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
14887
14888         dot_lustre_fid_permission_check "$fid" $remote_dir ||
14889                 error "dot lustre permission check $fid failed"
14890         rm -rf $DIR/$tdir
14891 }
14892 run_test 154b "Open-by-FID for remote directory"
14893
14894 test_154c() {
14895         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
14896                 skip "Need MDS version at least 2.4.1"
14897
14898         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
14899         local FID1=$($LFS path2fid $DIR/$tfile.1)
14900         local FID2=$($LFS path2fid $DIR/$tfile.2)
14901         local FID3=$($LFS path2fid $DIR/$tfile.3)
14902
14903         local N=1
14904         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
14905                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
14906                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
14907                 local want=FID$N
14908                 [ "$FID" = "${!want}" ] ||
14909                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
14910                 N=$((N + 1))
14911         done
14912
14913         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
14914         do
14915                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
14916                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
14917                 N=$((N + 1))
14918         done
14919 }
14920 run_test 154c "lfs path2fid and fid2path multiple arguments"
14921
14922 test_154d() {
14923         remote_mds_nodsh && skip "remote MDS with nodsh"
14924         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
14925                 skip "Need MDS version at least 2.5.53"
14926
14927         if remote_mds; then
14928                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
14929         else
14930                 nid="0@lo"
14931         fi
14932         local proc_ofile="mdt.*.exports.'$nid'.open_files"
14933         local fd
14934         local cmd
14935
14936         rm -f $DIR/$tfile
14937         touch $DIR/$tfile
14938
14939         local fid=$($LFS path2fid $DIR/$tfile)
14940         # Open the file
14941         fd=$(free_fd)
14942         cmd="exec $fd<$DIR/$tfile"
14943         eval $cmd
14944         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
14945         echo "$fid_list" | grep "$fid"
14946         rc=$?
14947
14948         cmd="exec $fd>/dev/null"
14949         eval $cmd
14950         if [ $rc -ne 0 ]; then
14951                 error "FID $fid not found in open files list $fid_list"
14952         fi
14953 }
14954 run_test 154d "Verify open file fid"
14955
14956 test_154e()
14957 {
14958         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
14959                 skip "Need MDS version at least 2.6.50"
14960
14961         if ls -a $MOUNT | grep -q '^\.lustre$'; then
14962                 error ".lustre returned by readdir"
14963         fi
14964 }
14965 run_test 154e ".lustre is not returned by readdir"
14966
14967 test_154f() {
14968         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14969
14970         # create parent directory on a single MDT to avoid cross-MDT hardlinks
14971         mkdir_on_mdt0 $DIR/$tdir
14972         # test dirs inherit from its stripe
14973         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
14974         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
14975         cp /etc/hosts $DIR/$tdir/foo1/$tfile
14976         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
14977         touch $DIR/f
14978
14979         # get fid of parents
14980         local FID0=$($LFS path2fid $DIR/$tdir)
14981         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
14982         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
14983         local FID3=$($LFS path2fid $DIR)
14984
14985         # check that path2fid --parents returns expected <parent_fid>/name
14986         # 1) test for a directory (single parent)
14987         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
14988         [ "$parent" == "$FID0/foo1" ] ||
14989                 error "expected parent: $FID0/foo1, got: $parent"
14990
14991         # 2) test for a file with nlink > 1 (multiple parents)
14992         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
14993         echo "$parent" | grep -F "$FID1/$tfile" ||
14994                 error "$FID1/$tfile not returned in parent list"
14995         echo "$parent" | grep -F "$FID2/link" ||
14996                 error "$FID2/link not returned in parent list"
14997
14998         # 3) get parent by fid
14999         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15000         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15001         echo "$parent" | grep -F "$FID1/$tfile" ||
15002                 error "$FID1/$tfile not returned in parent list (by fid)"
15003         echo "$parent" | grep -F "$FID2/link" ||
15004                 error "$FID2/link not returned in parent list (by fid)"
15005
15006         # 4) test for entry in root directory
15007         parent=$($LFS path2fid --parents $DIR/f)
15008         echo "$parent" | grep -F "$FID3/f" ||
15009                 error "$FID3/f not returned in parent list"
15010
15011         # 5) test it on root directory
15012         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15013                 error "$MOUNT should not have parents"
15014
15015         # enable xattr caching and check that linkea is correctly updated
15016         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15017         save_lustre_params client "llite.*.xattr_cache" > $save
15018         lctl set_param llite.*.xattr_cache 1
15019
15020         # 6.1) linkea update on rename
15021         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15022
15023         # get parents by fid
15024         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15025         # foo1 should no longer be returned in parent list
15026         echo "$parent" | grep -F "$FID1" &&
15027                 error "$FID1 should no longer be in parent list"
15028         # the new path should appear
15029         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15030                 error "$FID2/$tfile.moved is not in parent list"
15031
15032         # 6.2) linkea update on unlink
15033         rm -f $DIR/$tdir/foo2/link
15034         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15035         # foo2/link should no longer be returned in parent list
15036         echo "$parent" | grep -F "$FID2/link" &&
15037                 error "$FID2/link should no longer be in parent list"
15038         true
15039
15040         rm -f $DIR/f
15041         restore_lustre_params < $save
15042         rm -f $save
15043 }
15044 run_test 154f "get parent fids by reading link ea"
15045
15046 test_154g()
15047 {
15048         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15049         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15050            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15051                 skip "Need MDS version at least 2.6.92"
15052
15053         mkdir_on_mdt0 $DIR/$tdir
15054         llapi_fid_test -d $DIR/$tdir
15055 }
15056 run_test 154g "various llapi FID tests"
15057
15058 test_155_small_load() {
15059     local temp=$TMP/$tfile
15060     local file=$DIR/$tfile
15061
15062     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15063         error "dd of=$temp bs=6096 count=1 failed"
15064     cp $temp $file
15065     cancel_lru_locks $OSC
15066     cmp $temp $file || error "$temp $file differ"
15067
15068     $TRUNCATE $temp 6000
15069     $TRUNCATE $file 6000
15070     cmp $temp $file || error "$temp $file differ (truncate1)"
15071
15072     echo "12345" >>$temp
15073     echo "12345" >>$file
15074     cmp $temp $file || error "$temp $file differ (append1)"
15075
15076     echo "12345" >>$temp
15077     echo "12345" >>$file
15078     cmp $temp $file || error "$temp $file differ (append2)"
15079
15080     rm -f $temp $file
15081     true
15082 }
15083
15084 test_155_big_load() {
15085         remote_ost_nodsh && skip "remote OST with nodsh"
15086
15087         local temp=$TMP/$tfile
15088         local file=$DIR/$tfile
15089
15090         free_min_max
15091         local cache_size=$(do_facet ost$((MAXI+1)) \
15092                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15093         local large_file_size=$((cache_size * 2))
15094
15095         echo "OSS cache size: $cache_size KB"
15096         echo "Large file size: $large_file_size KB"
15097
15098         [ $MAXV -le $large_file_size ] &&
15099                 skip_env "max available OST size needs > $large_file_size KB"
15100
15101         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15102
15103         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15104                 error "dd of=$temp bs=$large_file_size count=1k failed"
15105         cp $temp $file
15106         ls -lh $temp $file
15107         cancel_lru_locks osc
15108         cmp $temp $file || error "$temp $file differ"
15109
15110         rm -f $temp $file
15111         true
15112 }
15113
15114 save_writethrough() {
15115         local facets=$(get_facets OST)
15116
15117         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15118 }
15119
15120 test_155a() {
15121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15122
15123         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15124
15125         save_writethrough $p
15126
15127         set_cache read on
15128         set_cache writethrough on
15129         test_155_small_load
15130         restore_lustre_params < $p
15131         rm -f $p
15132 }
15133 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15134
15135 test_155b() {
15136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15137
15138         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15139
15140         save_writethrough $p
15141
15142         set_cache read on
15143         set_cache writethrough off
15144         test_155_small_load
15145         restore_lustre_params < $p
15146         rm -f $p
15147 }
15148 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15149
15150 test_155c() {
15151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15152
15153         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15154
15155         save_writethrough $p
15156
15157         set_cache read off
15158         set_cache writethrough on
15159         test_155_small_load
15160         restore_lustre_params < $p
15161         rm -f $p
15162 }
15163 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15164
15165 test_155d() {
15166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15167
15168         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15169
15170         save_writethrough $p
15171
15172         set_cache read off
15173         set_cache writethrough off
15174         test_155_small_load
15175         restore_lustre_params < $p
15176         rm -f $p
15177 }
15178 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15179
15180 test_155e() {
15181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15182
15183         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15184
15185         save_writethrough $p
15186
15187         set_cache read on
15188         set_cache writethrough on
15189         test_155_big_load
15190         restore_lustre_params < $p
15191         rm -f $p
15192 }
15193 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15194
15195 test_155f() {
15196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15197
15198         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15199
15200         save_writethrough $p
15201
15202         set_cache read on
15203         set_cache writethrough off
15204         test_155_big_load
15205         restore_lustre_params < $p
15206         rm -f $p
15207 }
15208 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15209
15210 test_155g() {
15211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15212
15213         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15214
15215         save_writethrough $p
15216
15217         set_cache read off
15218         set_cache writethrough on
15219         test_155_big_load
15220         restore_lustre_params < $p
15221         rm -f $p
15222 }
15223 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15224
15225 test_155h() {
15226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15227
15228         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15229
15230         save_writethrough $p
15231
15232         set_cache read off
15233         set_cache writethrough off
15234         test_155_big_load
15235         restore_lustre_params < $p
15236         rm -f $p
15237 }
15238 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15239
15240 test_156() {
15241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15242         remote_ost_nodsh && skip "remote OST with nodsh"
15243         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15244                 skip "stats not implemented on old servers"
15245         [ "$ost1_FSTYPE" = "zfs" ] &&
15246                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15247
15248         local CPAGES=3
15249         local BEFORE
15250         local AFTER
15251         local file="$DIR/$tfile"
15252         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15253
15254         save_writethrough $p
15255         roc_hit_init
15256
15257         log "Turn on read and write cache"
15258         set_cache read on
15259         set_cache writethrough on
15260
15261         log "Write data and read it back."
15262         log "Read should be satisfied from the cache."
15263         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15264         BEFORE=$(roc_hit)
15265         cancel_lru_locks osc
15266         cat $file >/dev/null
15267         AFTER=$(roc_hit)
15268         if ! let "AFTER - BEFORE == CPAGES"; then
15269                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15270         else
15271                 log "cache hits: before: $BEFORE, after: $AFTER"
15272         fi
15273
15274         log "Read again; it should be satisfied from the cache."
15275         BEFORE=$AFTER
15276         cancel_lru_locks osc
15277         cat $file >/dev/null
15278         AFTER=$(roc_hit)
15279         if ! let "AFTER - BEFORE == CPAGES"; then
15280                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15281         else
15282                 log "cache hits:: before: $BEFORE, after: $AFTER"
15283         fi
15284
15285         log "Turn off the read cache and turn on the write cache"
15286         set_cache read off
15287         set_cache writethrough on
15288
15289         log "Read again; it should be satisfied from the cache."
15290         BEFORE=$(roc_hit)
15291         cancel_lru_locks osc
15292         cat $file >/dev/null
15293         AFTER=$(roc_hit)
15294         if ! let "AFTER - BEFORE == CPAGES"; then
15295                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15296         else
15297                 log "cache hits:: before: $BEFORE, after: $AFTER"
15298         fi
15299
15300         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15301                 # > 2.12.56 uses pagecache if cached
15302                 log "Read again; it should not be satisfied from the cache."
15303                 BEFORE=$AFTER
15304                 cancel_lru_locks osc
15305                 cat $file >/dev/null
15306                 AFTER=$(roc_hit)
15307                 if ! let "AFTER - BEFORE == 0"; then
15308                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15309                 else
15310                         log "cache hits:: before: $BEFORE, after: $AFTER"
15311                 fi
15312         fi
15313
15314         log "Write data and read it back."
15315         log "Read should be satisfied from the cache."
15316         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15317         BEFORE=$(roc_hit)
15318         cancel_lru_locks osc
15319         cat $file >/dev/null
15320         AFTER=$(roc_hit)
15321         if ! let "AFTER - BEFORE == CPAGES"; then
15322                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15323         else
15324                 log "cache hits:: before: $BEFORE, after: $AFTER"
15325         fi
15326
15327         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15328                 # > 2.12.56 uses pagecache if cached
15329                 log "Read again; it should not be satisfied from the cache."
15330                 BEFORE=$AFTER
15331                 cancel_lru_locks osc
15332                 cat $file >/dev/null
15333                 AFTER=$(roc_hit)
15334                 if ! let "AFTER - BEFORE == 0"; then
15335                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15336                 else
15337                         log "cache hits:: before: $BEFORE, after: $AFTER"
15338                 fi
15339         fi
15340
15341         log "Turn off read and write cache"
15342         set_cache read off
15343         set_cache writethrough off
15344
15345         log "Write data and read it back"
15346         log "It should not be satisfied from the cache."
15347         rm -f $file
15348         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15349         cancel_lru_locks osc
15350         BEFORE=$(roc_hit)
15351         cat $file >/dev/null
15352         AFTER=$(roc_hit)
15353         if ! let "AFTER - BEFORE == 0"; then
15354                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15355         else
15356                 log "cache hits:: before: $BEFORE, after: $AFTER"
15357         fi
15358
15359         log "Turn on the read cache and turn off the write cache"
15360         set_cache read on
15361         set_cache writethrough off
15362
15363         log "Write data and read it back"
15364         log "It should not be satisfied from the cache."
15365         rm -f $file
15366         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15367         BEFORE=$(roc_hit)
15368         cancel_lru_locks osc
15369         cat $file >/dev/null
15370         AFTER=$(roc_hit)
15371         if ! let "AFTER - BEFORE == 0"; then
15372                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15373         else
15374                 log "cache hits:: before: $BEFORE, after: $AFTER"
15375         fi
15376
15377         log "Read again; it should be satisfied from the cache."
15378         BEFORE=$(roc_hit)
15379         cancel_lru_locks osc
15380         cat $file >/dev/null
15381         AFTER=$(roc_hit)
15382         if ! let "AFTER - BEFORE == CPAGES"; then
15383                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15384         else
15385                 log "cache hits:: before: $BEFORE, after: $AFTER"
15386         fi
15387
15388         restore_lustre_params < $p
15389         rm -f $p $file
15390 }
15391 run_test 156 "Verification of tunables"
15392
15393 test_160a() {
15394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15395         remote_mds_nodsh && skip "remote MDS with nodsh"
15396         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15397                 skip "Need MDS version at least 2.2.0"
15398
15399         changelog_register || error "changelog_register failed"
15400         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15401         changelog_users $SINGLEMDS | grep -q $cl_user ||
15402                 error "User $cl_user not found in changelog_users"
15403
15404         mkdir_on_mdt0 $DIR/$tdir
15405
15406         # change something
15407         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15408         changelog_clear 0 || error "changelog_clear failed"
15409         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15410         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15411         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15412         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15413         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15414         rm $DIR/$tdir/pics/desktop.jpg
15415
15416         echo "verifying changelog mask"
15417         changelog_chmask "-MKDIR"
15418         changelog_chmask "-CLOSE"
15419
15420         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15421         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15422
15423         changelog_chmask "+MKDIR"
15424         changelog_chmask "+CLOSE"
15425
15426         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15427         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15428
15429         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15430         CLOSES=$(changelog_dump | grep -c "CLOSE")
15431         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15432         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15433
15434         # verify contents
15435         echo "verifying target fid"
15436         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15437         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15438         [ "$fidc" == "$fidf" ] ||
15439                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15440         echo "verifying parent fid"
15441         # The FID returned from the Changelog may be the directory shard on
15442         # a different MDT, and not the FID returned by path2fid on the parent.
15443         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15444         # since this is what will matter when recreating this file in the tree.
15445         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15446         local pathp=$($LFS fid2path $MOUNT "$fidp")
15447         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15448                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15449
15450         echo "getting records for $cl_user"
15451         changelog_users $SINGLEMDS
15452         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15453         local nclr=3
15454         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15455                 error "changelog_clear failed"
15456         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15457         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15458         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15459                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15460
15461         local min0_rec=$(changelog_users $SINGLEMDS |
15462                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15463         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15464                           awk '{ print $1; exit; }')
15465
15466         changelog_dump | tail -n 5
15467         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15468         [ $first_rec == $((min0_rec + 1)) ] ||
15469                 error "first index should be $min0_rec + 1 not $first_rec"
15470
15471         # LU-3446 changelog index reset on MDT restart
15472         local cur_rec1=$(changelog_users $SINGLEMDS |
15473                          awk '/^current.index:/ { print $NF }')
15474         changelog_clear 0 ||
15475                 error "clear all changelog records for $cl_user failed"
15476         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15477         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15478                 error "Fail to start $SINGLEMDS"
15479         local cur_rec2=$(changelog_users $SINGLEMDS |
15480                          awk '/^current.index:/ { print $NF }')
15481         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15482         [ $cur_rec1 == $cur_rec2 ] ||
15483                 error "current index should be $cur_rec1 not $cur_rec2"
15484
15485         echo "verifying users from this test are deregistered"
15486         changelog_deregister || error "changelog_deregister failed"
15487         changelog_users $SINGLEMDS | grep -q $cl_user &&
15488                 error "User '$cl_user' still in changelog_users"
15489
15490         # lctl get_param -n mdd.*.changelog_users
15491         # current_index: 144
15492         # ID    index (idle seconds)
15493         # cl3   144   (2) mask=<list>
15494         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15495                 # this is the normal case where all users were deregistered
15496                 # make sure no new records are added when no users are present
15497                 local last_rec1=$(changelog_users $SINGLEMDS |
15498                                   awk '/^current.index:/ { print $NF }')
15499                 touch $DIR/$tdir/chloe
15500                 local last_rec2=$(changelog_users $SINGLEMDS |
15501                                   awk '/^current.index:/ { print $NF }')
15502                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15503                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15504         else
15505                 # any changelog users must be leftovers from a previous test
15506                 changelog_users $SINGLEMDS
15507                 echo "other changelog users; can't verify off"
15508         fi
15509 }
15510 run_test 160a "changelog sanity"
15511
15512 test_160b() { # LU-3587
15513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15514         remote_mds_nodsh && skip "remote MDS with nodsh"
15515         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15516                 skip "Need MDS version at least 2.2.0"
15517
15518         changelog_register || error "changelog_register failed"
15519         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15520         changelog_users $SINGLEMDS | grep -q $cl_user ||
15521                 error "User '$cl_user' not found in changelog_users"
15522
15523         local longname1=$(str_repeat a 255)
15524         local longname2=$(str_repeat b 255)
15525
15526         cd $DIR
15527         echo "creating very long named file"
15528         touch $longname1 || error "create of '$longname1' failed"
15529         echo "renaming very long named file"
15530         mv $longname1 $longname2
15531
15532         changelog_dump | grep RENME | tail -n 5
15533         rm -f $longname2
15534 }
15535 run_test 160b "Verify that very long rename doesn't crash in changelog"
15536
15537 test_160c() {
15538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15539         remote_mds_nodsh && skip "remote MDS with nodsh"
15540
15541         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15542                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15543                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15544                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15545
15546         local rc=0
15547
15548         # Registration step
15549         changelog_register || error "changelog_register failed"
15550
15551         rm -rf $DIR/$tdir
15552         mkdir -p $DIR/$tdir
15553         $MCREATE $DIR/$tdir/foo_160c
15554         changelog_chmask "-TRUNC"
15555         $TRUNCATE $DIR/$tdir/foo_160c 200
15556         changelog_chmask "+TRUNC"
15557         $TRUNCATE $DIR/$tdir/foo_160c 199
15558         changelog_dump | tail -n 5
15559         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15560         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15561 }
15562 run_test 160c "verify that changelog log catch the truncate event"
15563
15564 test_160d() {
15565         remote_mds_nodsh && skip "remote MDS with nodsh"
15566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15568         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15569                 skip "Need MDS version at least 2.7.60"
15570
15571         # Registration step
15572         changelog_register || error "changelog_register failed"
15573
15574         mkdir -p $DIR/$tdir/migrate_dir
15575         changelog_clear 0 || error "changelog_clear failed"
15576
15577         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15578         changelog_dump | tail -n 5
15579         local migrates=$(changelog_dump | grep -c "MIGRT")
15580         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15581 }
15582 run_test 160d "verify that changelog log catch the migrate event"
15583
15584 test_160e() {
15585         remote_mds_nodsh && skip "remote MDS with nodsh"
15586
15587         # Create a user
15588         changelog_register || error "changelog_register failed"
15589
15590         local MDT0=$(facet_svc $SINGLEMDS)
15591         local rc
15592
15593         # No user (expect fail)
15594         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15595         rc=$?
15596         if [ $rc -eq 0 ]; then
15597                 error "Should fail without user"
15598         elif [ $rc -ne 4 ]; then
15599                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15600         fi
15601
15602         # Delete a future user (expect fail)
15603         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15604         rc=$?
15605         if [ $rc -eq 0 ]; then
15606                 error "Deleted non-existant user cl77"
15607         elif [ $rc -ne 2 ]; then
15608                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15609         fi
15610
15611         # Clear to a bad index (1 billion should be safe)
15612         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15613         rc=$?
15614
15615         if [ $rc -eq 0 ]; then
15616                 error "Successfully cleared to invalid CL index"
15617         elif [ $rc -ne 22 ]; then
15618                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15619         fi
15620 }
15621 run_test 160e "changelog negative testing (should return errors)"
15622
15623 test_160f() {
15624         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15625         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15626                 skip "Need MDS version at least 2.10.56"
15627
15628         local mdts=$(comma_list $(mdts_nodes))
15629
15630         # Create a user
15631         changelog_register || error "first changelog_register failed"
15632         changelog_register || error "second changelog_register failed"
15633         local cl_users
15634         declare -A cl_user1
15635         declare -A cl_user2
15636         local user_rec1
15637         local user_rec2
15638         local i
15639
15640         # generate some changelog records to accumulate on each MDT
15641         # use all_char because created files should be evenly distributed
15642         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15643                 error "test_mkdir $tdir failed"
15644         log "$(date +%s): creating first files"
15645         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15646                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15647                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15648         done
15649
15650         # check changelogs have been generated
15651         local start=$SECONDS
15652         local idle_time=$((MDSCOUNT * 5 + 5))
15653         local nbcl=$(changelog_dump | wc -l)
15654         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15655
15656         for param in "changelog_max_idle_time=$idle_time" \
15657                      "changelog_gc=1" \
15658                      "changelog_min_gc_interval=2" \
15659                      "changelog_min_free_cat_entries=3"; do
15660                 local MDT0=$(facet_svc $SINGLEMDS)
15661                 local var="${param%=*}"
15662                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15663
15664                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15665                 do_nodes $mdts $LCTL set_param mdd.*.$param
15666         done
15667
15668         # force cl_user2 to be idle (1st part), but also cancel the
15669         # cl_user1 records so that it is not evicted later in the test.
15670         local sleep1=$((idle_time / 2))
15671         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15672         sleep $sleep1
15673
15674         # simulate changelog catalog almost full
15675         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15676         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15677
15678         for i in $(seq $MDSCOUNT); do
15679                 cl_users=(${CL_USERS[mds$i]})
15680                 cl_user1[mds$i]="${cl_users[0]}"
15681                 cl_user2[mds$i]="${cl_users[1]}"
15682
15683                 [ -n "${cl_user1[mds$i]}" ] ||
15684                         error "mds$i: no user registered"
15685                 [ -n "${cl_user2[mds$i]}" ] ||
15686                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15687
15688                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15689                 [ -n "$user_rec1" ] ||
15690                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15691                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15692                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15693                 [ -n "$user_rec2" ] ||
15694                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15695                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15696                      "$user_rec1 + 2 == $user_rec2"
15697                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15698                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15699                               "$user_rec1 + 2, but is $user_rec2"
15700                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15701                 [ -n "$user_rec2" ] ||
15702                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15703                 [ $user_rec1 == $user_rec2 ] ||
15704                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15705                               "$user_rec1, but is $user_rec2"
15706         done
15707
15708         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15709         local sleep2=$((idle_time - (SECONDS - start) + 1))
15710         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15711         sleep $sleep2
15712
15713         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15714         # cl_user1 should be OK because it recently processed records.
15715         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15716         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15717                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15718                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15719         done
15720
15721         # ensure gc thread is done
15722         for i in $(mdts_nodes); do
15723                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15724                         error "$i: GC-thread not done"
15725         done
15726
15727         local first_rec
15728         for (( i = 1; i <= MDSCOUNT; i++ )); do
15729                 # check cl_user1 still registered
15730                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15731                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15732                 # check cl_user2 unregistered
15733                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15734                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15735
15736                 # check changelogs are present and starting at $user_rec1 + 1
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                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15741                             awk '{ print $1; exit; }')
15742
15743                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15744                 [ $((user_rec1 + 1)) == $first_rec ] ||
15745                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15746         done
15747 }
15748 run_test 160f "changelog garbage collect (timestamped users)"
15749
15750 test_160g() {
15751         remote_mds_nodsh && skip "remote MDS with nodsh"
15752         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15753                 skip "Need MDS version at least 2.10.56"
15754
15755         local mdts=$(comma_list $(mdts_nodes))
15756
15757         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
15758         do_nodes $mdts $LCTL set_param fail_loc=0x1314
15759
15760         # Create a user
15761         changelog_register || error "first changelog_register failed"
15762         changelog_register || error "second changelog_register failed"
15763         local cl_users
15764         declare -A cl_user1
15765         declare -A cl_user2
15766         local user_rec1
15767         local user_rec2
15768         local i
15769
15770         # generate some changelog records to accumulate on each MDT
15771         # use all_char because created files should be evenly distributed
15772         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15773                 error "test_mkdir $tdir failed"
15774         for ((i = 0; i < MDSCOUNT; i++)); do
15775                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15776                         error "create $DIR/$tdir/d$i.1 failed"
15777         done
15778
15779         # check changelogs have been generated
15780         local nbcl=$(changelog_dump | wc -l)
15781         (( $nbcl > 0 )) || error "no changelogs found"
15782
15783         # reduce the max_idle_indexes value to make sure we exceed it
15784         for param in "changelog_max_idle_indexes=1" \
15785                      "changelog_gc=1" \
15786                      "changelog_min_gc_interval=2" \
15787                      "changelog_min_free_cat_entries=3"; do
15788                 local MDT0=$(facet_svc $SINGLEMDS)
15789                 local var="${param%=*}"
15790                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15791
15792                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15793                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
15794                         error "unable to set mdd.*.$param"
15795         done
15796
15797         # simulate changelog catalog almost full
15798         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15799         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15800
15801         local start=$SECONDS
15802         for i in $(seq $MDSCOUNT); do
15803                 cl_users=(${CL_USERS[mds$i]})
15804                 cl_user1[mds$i]="${cl_users[0]}"
15805                 cl_user2[mds$i]="${cl_users[1]}"
15806
15807                 [ -n "${cl_user1[mds$i]}" ] ||
15808                         error "mds$i: no user registered"
15809                 [ -n "${cl_user2[mds$i]}" ] ||
15810                         error "mds$i: only ${cl_user1[mds$i]} is registered"
15811
15812                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15813                 [ -n "$user_rec1" ] ||
15814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15815                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15816                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15817                 [ -n "$user_rec2" ] ||
15818                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15819                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15820                      "$user_rec1 + 2 == $user_rec2"
15821                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15822                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15823                               "$user_rec1 + 2, but is $user_rec2"
15824                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15825                 [ -n "$user_rec2" ] ||
15826                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15827                 [ $user_rec1 == $user_rec2 ] ||
15828                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15829                               "$user_rec1, but is $user_rec2"
15830         done
15831
15832         # ensure we are past the previous changelog_min_gc_interval set above
15833         local sleep2=$((start + 2 - SECONDS))
15834         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
15835
15836         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15837         # cl_user1 should be OK because it recently processed records.
15838         for ((i = 0; i < MDSCOUNT; i++)); do
15839                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
15840                         error "create $DIR/$tdir/d$i.3 failed"
15841         done
15842
15843         # ensure gc thread is done
15844         for i in $(mdts_nodes); do
15845                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15846                         error "$i: GC-thread not done"
15847         done
15848
15849         local first_rec
15850         for (( i = 1; i <= MDSCOUNT; i++ )); do
15851                 # check cl_user1 still registered
15852                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15853                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15854                 # check cl_user2 unregistered
15855                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15856                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15857
15858                 # check changelogs are present and starting at $user_rec1 + 1
15859                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15860                 [ -n "$user_rec1" ] ||
15861                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15862                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15863                             awk '{ print $1; exit; }')
15864
15865                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
15866                 [ $((user_rec1 + 1)) == $first_rec ] ||
15867                         error "mds$i: rec $first_rec != $user_rec1 + 1"
15868         done
15869 }
15870 run_test 160g "changelog garbage collect (old users)"
15871
15872 test_160h() {
15873         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15874         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15875                 skip "Need MDS version at least 2.10.56"
15876
15877         local mdts=$(comma_list $(mdts_nodes))
15878
15879         # Create a user
15880         changelog_register || error "first changelog_register failed"
15881         changelog_register || error "second changelog_register failed"
15882         local cl_users
15883         declare -A cl_user1
15884         declare -A cl_user2
15885         local user_rec1
15886         local user_rec2
15887         local i
15888
15889         # generate some changelog records to accumulate on each MDT
15890         # use all_char because created files should be evenly distributed
15891         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15892                 error "test_mkdir $tdir failed"
15893         for ((i = 0; i < MDSCOUNT; i++)); do
15894                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
15895                         error "create $DIR/$tdir/d$i.1 failed"
15896         done
15897
15898         # check changelogs have been generated
15899         local nbcl=$(changelog_dump | wc -l)
15900         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15901
15902         for param in "changelog_max_idle_time=10" \
15903                      "changelog_gc=1" \
15904                      "changelog_min_gc_interval=2"; do
15905                 local MDT0=$(facet_svc $SINGLEMDS)
15906                 local var="${param%=*}"
15907                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15908
15909                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15910                 do_nodes $mdts $LCTL set_param mdd.*.$param
15911         done
15912
15913         # force cl_user2 to be idle (1st part)
15914         sleep 9
15915
15916         for i in $(seq $MDSCOUNT); do
15917                 cl_users=(${CL_USERS[mds$i]})
15918                 cl_user1[mds$i]="${cl_users[0]}"
15919                 cl_user2[mds$i]="${cl_users[1]}"
15920
15921                 [ -n "${cl_user1[mds$i]}" ] ||
15922                         error "mds$i: no user registered"
15923                 [ -n "${cl_user2[mds$i]}" ] ||
15924                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15925
15926                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15927                 [ -n "$user_rec1" ] ||
15928                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15929                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15930                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15931                 [ -n "$user_rec2" ] ||
15932                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15933                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15934                      "$user_rec1 + 2 == $user_rec2"
15935                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15936                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15937                               "$user_rec1 + 2, but is $user_rec2"
15938                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15939                 [ -n "$user_rec2" ] ||
15940                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15941                 [ $user_rec1 == $user_rec2 ] ||
15942                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15943                               "$user_rec1, but is $user_rec2"
15944         done
15945
15946         # force cl_user2 to be idle (2nd part) and to reach
15947         # changelog_max_idle_time
15948         sleep 2
15949
15950         # force each GC-thread start and block then
15951         # one per MDT/MDD, set fail_val accordingly
15952         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
15953         do_nodes $mdts $LCTL set_param fail_loc=0x1316
15954
15955         # generate more changelogs to trigger fail_loc
15956         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15957                 error "create $DIR/$tdir/${tfile}bis failed"
15958
15959         # stop MDT to stop GC-thread, should be done in back-ground as it will
15960         # block waiting for the thread to be released and exit
15961         declare -A stop_pids
15962         for i in $(seq $MDSCOUNT); do
15963                 stop mds$i &
15964                 stop_pids[mds$i]=$!
15965         done
15966
15967         for i in $(mdts_nodes); do
15968                 local facet
15969                 local nb=0
15970                 local facets=$(facets_up_on_host $i)
15971
15972                 for facet in ${facets//,/ }; do
15973                         if [[ $facet == mds* ]]; then
15974                                 nb=$((nb + 1))
15975                         fi
15976                 done
15977                 # ensure each MDS's gc threads are still present and all in "R"
15978                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
15979                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
15980                         error "$i: expected $nb GC-thread"
15981                 wait_update $i \
15982                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
15983                         "R" 20 ||
15984                         error "$i: GC-thread not found in R-state"
15985                 # check umounts of each MDT on MDS have reached kthread_stop()
15986                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
15987                         error "$i: expected $nb umount"
15988                 wait_update $i \
15989                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
15990                         error "$i: umount not found in D-state"
15991         done
15992
15993         # release all GC-threads
15994         do_nodes $mdts $LCTL set_param fail_loc=0
15995
15996         # wait for MDT stop to complete
15997         for i in $(seq $MDSCOUNT); do
15998                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15999         done
16000
16001         # XXX
16002         # may try to check if any orphan changelog records are present
16003         # via ldiskfs/zfs and llog_reader...
16004
16005         # re-start/mount MDTs
16006         for i in $(seq $MDSCOUNT); do
16007                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16008                         error "Fail to start mds$i"
16009         done
16010
16011         local first_rec
16012         for i in $(seq $MDSCOUNT); do
16013                 # check cl_user1 still registered
16014                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16015                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16016                 # check cl_user2 unregistered
16017                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16018                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16019
16020                 # check changelogs are present and starting at $user_rec1 + 1
16021                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16022                 [ -n "$user_rec1" ] ||
16023                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16024                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16025                             awk '{ print $1; exit; }')
16026
16027                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16028                 [ $((user_rec1 + 1)) == $first_rec ] ||
16029                         error "mds$i: first index should be $user_rec1 + 1, " \
16030                               "but is $first_rec"
16031         done
16032 }
16033 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16034               "during mount"
16035
16036 test_160i() {
16037
16038         local mdts=$(comma_list $(mdts_nodes))
16039
16040         changelog_register || error "first changelog_register failed"
16041
16042         # generate some changelog records to accumulate on each MDT
16043         # use all_char because created files should be evenly distributed
16044         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16045                 error "test_mkdir $tdir failed"
16046         for ((i = 0; i < MDSCOUNT; i++)); do
16047                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16048                         error "create $DIR/$tdir/d$i.1 failed"
16049         done
16050
16051         # check changelogs have been generated
16052         local nbcl=$(changelog_dump | wc -l)
16053         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16054
16055         # simulate race between register and unregister
16056         # XXX as fail_loc is set per-MDS, with DNE configs the race
16057         # simulation will only occur for one MDT per MDS and for the
16058         # others the normal race scenario will take place
16059         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16060         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16061         do_nodes $mdts $LCTL set_param fail_val=1
16062
16063         # unregister 1st user
16064         changelog_deregister &
16065         local pid1=$!
16066         # wait some time for deregister work to reach race rdv
16067         sleep 2
16068         # register 2nd user
16069         changelog_register || error "2nd user register failed"
16070
16071         wait $pid1 || error "1st user deregister failed"
16072
16073         local i
16074         local last_rec
16075         declare -A LAST_REC
16076         for i in $(seq $MDSCOUNT); do
16077                 if changelog_users mds$i | grep "^cl"; then
16078                         # make sure new records are added with one user present
16079                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16080                                           awk '/^current.index:/ { print $NF }')
16081                 else
16082                         error "mds$i has no user registered"
16083                 fi
16084         done
16085
16086         # generate more changelog records to accumulate on each MDT
16087         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16088                 error "create $DIR/$tdir/${tfile}bis failed"
16089
16090         for i in $(seq $MDSCOUNT); do
16091                 last_rec=$(changelog_users $SINGLEMDS |
16092                            awk '/^current.index:/ { print $NF }')
16093                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16094                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16095                         error "changelogs are off on mds$i"
16096         done
16097 }
16098 run_test 160i "changelog user register/unregister race"
16099
16100 test_160j() {
16101         remote_mds_nodsh && skip "remote MDS with nodsh"
16102         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16103                 skip "Need MDS version at least 2.12.56"
16104
16105         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16106         stack_trap "umount $MOUNT2" EXIT
16107
16108         changelog_register || error "first changelog_register failed"
16109         stack_trap "changelog_deregister" EXIT
16110
16111         # generate some changelog
16112         # use all_char because created files should be evenly distributed
16113         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16114                 error "mkdir $tdir failed"
16115         for ((i = 0; i < MDSCOUNT; i++)); do
16116                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16117                         error "create $DIR/$tdir/d$i.1 failed"
16118         done
16119
16120         # open the changelog device
16121         exec 3>/dev/changelog-$FSNAME-MDT0000
16122         stack_trap "exec 3>&-" EXIT
16123         exec 4</dev/changelog-$FSNAME-MDT0000
16124         stack_trap "exec 4<&-" EXIT
16125
16126         # umount the first lustre mount
16127         umount $MOUNT
16128         stack_trap "mount_client $MOUNT" EXIT
16129
16130         # read changelog, which may or may not fail, but should not crash
16131         cat <&4 >/dev/null
16132
16133         # clear changelog
16134         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16135         changelog_users $SINGLEMDS | grep -q $cl_user ||
16136                 error "User $cl_user not found in changelog_users"
16137
16138         printf 'clear:'$cl_user':0' >&3
16139 }
16140 run_test 160j "client can be umounted while its chanangelog is being used"
16141
16142 test_160k() {
16143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16144         remote_mds_nodsh && skip "remote MDS with nodsh"
16145
16146         mkdir -p $DIR/$tdir/1/1
16147
16148         changelog_register || error "changelog_register failed"
16149         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16150
16151         changelog_users $SINGLEMDS | grep -q $cl_user ||
16152                 error "User '$cl_user' not found in changelog_users"
16153 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16154         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16155         rmdir $DIR/$tdir/1/1 & sleep 1
16156         mkdir $DIR/$tdir/2
16157         touch $DIR/$tdir/2/2
16158         rm -rf $DIR/$tdir/2
16159
16160         wait
16161         sleep 4
16162
16163         changelog_dump | grep rmdir || error "rmdir not recorded"
16164 }
16165 run_test 160k "Verify that changelog records are not lost"
16166
16167 # Verifies that a file passed as a parameter has recently had an operation
16168 # performed on it that has generated an MTIME changelog which contains the
16169 # correct parent FID. As files might reside on a different MDT from the
16170 # parent directory in DNE configurations, the FIDs are translated to paths
16171 # before being compared, which should be identical
16172 compare_mtime_changelog() {
16173         local file="${1}"
16174         local mdtidx
16175         local mtime
16176         local cl_fid
16177         local pdir
16178         local dir
16179
16180         mdtidx=$($LFS getstripe --mdt-index $file)
16181         mdtidx=$(printf "%04x" $mdtidx)
16182
16183         # Obtain the parent FID from the MTIME changelog
16184         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16185         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16186
16187         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16188         [ -z "$cl_fid" ] && error "parent FID not present"
16189
16190         # Verify that the path for the parent FID is the same as the path for
16191         # the test directory
16192         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16193
16194         dir=$(dirname $1)
16195
16196         [[ "${pdir%/}" == "$dir" ]] ||
16197                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16198 }
16199
16200 test_160l() {
16201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16202
16203         remote_mds_nodsh && skip "remote MDS with nodsh"
16204         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16205                 skip "Need MDS version at least 2.13.55"
16206
16207         local cl_user
16208
16209         changelog_register || error "changelog_register failed"
16210         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16211
16212         changelog_users $SINGLEMDS | grep -q $cl_user ||
16213                 error "User '$cl_user' not found in changelog_users"
16214
16215         # Clear some types so that MTIME changelogs are generated
16216         changelog_chmask "-CREAT"
16217         changelog_chmask "-CLOSE"
16218
16219         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16220
16221         # Test CL_MTIME during setattr
16222         touch $DIR/$tdir/$tfile
16223         compare_mtime_changelog $DIR/$tdir/$tfile
16224
16225         # Test CL_MTIME during close
16226         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16227         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16228 }
16229 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16230
16231 test_160m() {
16232         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16233         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16234                 skip "Need MDS version at least 2.14.51"
16235         local cl_users
16236         local cl_user1
16237         local cl_user2
16238         local pid1
16239
16240         # Create a user
16241         changelog_register || error "first changelog_register failed"
16242         changelog_register || error "second changelog_register failed"
16243
16244         cl_users=(${CL_USERS[mds1]})
16245         cl_user1="${cl_users[0]}"
16246         cl_user2="${cl_users[1]}"
16247         # generate some changelog records to accumulate on MDT0
16248         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16249         createmany -m $DIR/$tdir/$tfile 50 ||
16250                 error "create $DIR/$tdir/$tfile failed"
16251         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16252         rm -f $DIR/$tdir
16253
16254         # check changelogs have been generated
16255         local nbcl=$(changelog_dump | wc -l)
16256         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16257
16258 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16259         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16260
16261         __changelog_clear mds1 $cl_user1 +10
16262         __changelog_clear mds1 $cl_user2 0 &
16263         pid1=$!
16264         sleep 2
16265         __changelog_clear mds1 $cl_user1 0 ||
16266                 error "fail to cancel record for $cl_user1"
16267         wait $pid1
16268         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16269 }
16270 run_test 160m "Changelog clear race"
16271
16272 test_160n() {
16273         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16274         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16275                 skip "Need MDS version at least 2.14.51"
16276         local cl_users
16277         local cl_user1
16278         local cl_user2
16279         local pid1
16280         local first_rec
16281         local last_rec=0
16282
16283         # Create a user
16284         changelog_register || error "first changelog_register failed"
16285
16286         cl_users=(${CL_USERS[mds1]})
16287         cl_user1="${cl_users[0]}"
16288
16289         # generate some changelog records to accumulate on MDT0
16290         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16291         first_rec=$(changelog_users $SINGLEMDS |
16292                         awk '/^current.index:/ { print $NF }')
16293         while (( last_rec < (( first_rec + 65000)) )); do
16294                 createmany -m $DIR/$tdir/$tfile 10000 ||
16295                         error "create $DIR/$tdir/$tfile failed"
16296
16297                 for i in $(seq 0 10000); do
16298                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16299                                 > /dev/null
16300                 done
16301
16302                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16303                         error "unlinkmany failed unlink"
16304                 last_rec=$(changelog_users $SINGLEMDS |
16305                         awk '/^current.index:/ { print $NF }')
16306                 echo last record $last_rec
16307                 (( last_rec == 0 )) && error "no changelog found"
16308         done
16309
16310 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16311         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16312
16313         __changelog_clear mds1 $cl_user1 0 &
16314         pid1=$!
16315         sleep 2
16316         __changelog_clear mds1 $cl_user1 0 ||
16317                 error "fail to cancel record for $cl_user1"
16318         wait $pid1
16319         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16320 }
16321 run_test 160n "Changelog destroy race"
16322
16323 test_160o() {
16324         local mdt="$(facet_svc $SINGLEMDS)"
16325
16326         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16327         remote_mds_nodsh && skip "remote MDS with nodsh"
16328         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16329                 skip "Need MDS version at least 2.14.52"
16330
16331         changelog_register --user test_160o -m unlnk+close+open ||
16332                 error "changelog_register failed"
16333         # drop server mask so it doesn't interfere
16334         do_facet $SINGLEMDS $LCTL --device $mdt \
16335                                 changelog_register -u "Tt3_-#" &&
16336                 error "bad symbols in name should fail"
16337
16338         do_facet $SINGLEMDS $LCTL --device $mdt \
16339                                 changelog_register -u test_160o &&
16340                 error "the same name registration should fail"
16341
16342         do_facet $SINGLEMDS $LCTL --device $mdt \
16343                         changelog_register -u test_160toolongname &&
16344                 error "too long name registration should fail"
16345
16346         changelog_chmask "MARK+HSM"
16347         lctl get_param mdd.*.changelog*mask
16348         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16349         changelog_users $SINGLEMDS | grep -q $cl_user ||
16350                 error "User $cl_user not found in changelog_users"
16351         #verify username
16352         echo $cl_user | grep -q test_160o ||
16353                 error "User $cl_user has no specific name 'test160o'"
16354
16355         # change something
16356         changelog_clear 0 || error "changelog_clear failed"
16357         # generate some changelog records to accumulate on MDT0
16358         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16359         touch $DIR/$tdir/$tfile                 # open 1
16360
16361         OPENS=$(changelog_dump | grep -c "OPEN")
16362         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16363
16364         # must be no MKDIR it wasn't set as user mask
16365         MKDIR=$(changelog_dump | grep -c "MKDIR")
16366         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16367
16368         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16369                                 mdd.$mdt.changelog_current_mask -n)
16370         # register maskless user
16371         changelog_register || error "changelog_register failed"
16372         # effective mask should be not changed because it is not minimal
16373         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16374                                 mdd.$mdt.changelog_current_mask -n)
16375         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16376         # set server mask to minimal value
16377         changelog_chmask "MARK"
16378         # check effective mask again, should be treated as DEFMASK now
16379         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16380                                 mdd.$mdt.changelog_current_mask -n)
16381         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16382
16383         do_facet $SINGLEMDS $LCTL --device $mdt \
16384                                 changelog_deregister -u test_160o ||
16385                 error "cannot deregister by name"
16386 }
16387 run_test 160o "changelog user name and mask"
16388
16389 test_160p() {
16390         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16391         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16392                 skip "Need MDS version at least 2.14.51"
16393         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16394         local cl_users
16395         local cl_user1
16396         local entry_count
16397
16398         # Create a user
16399         changelog_register || error "first changelog_register failed"
16400
16401         cl_users=(${CL_USERS[mds1]})
16402         cl_user1="${cl_users[0]}"
16403
16404         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16405         createmany -m $DIR/$tdir/$tfile 50 ||
16406                 error "create $DIR/$tdir/$tfile failed"
16407         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16408         rm -rf $DIR/$tdir
16409
16410         # check changelogs have been generated
16411         entry_count=$(changelog_dump | wc -l)
16412         ((entry_count != 0)) || error "no changelog entries found"
16413
16414         # remove changelog_users and check that orphan entries are removed
16415         stop mds1
16416         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16417         start mds1 || error "cannot start mdt"
16418         entry_count=$(changelog_dump | wc -l)
16419         ((entry_count == 0)) ||
16420                 error "found $entry_count changelog entries, expected none"
16421 }
16422 run_test 160p "Changelog orphan cleanup with no users"
16423
16424 test_161a() {
16425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16426
16427         test_mkdir -c1 $DIR/$tdir
16428         cp /etc/hosts $DIR/$tdir/$tfile
16429         test_mkdir -c1 $DIR/$tdir/foo1
16430         test_mkdir -c1 $DIR/$tdir/foo2
16431         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16432         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16433         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16434         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16435         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16436         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16437                 $LFS fid2path $DIR $FID
16438                 error "bad link ea"
16439         fi
16440         # middle
16441         rm $DIR/$tdir/foo2/zachary
16442         # last
16443         rm $DIR/$tdir/foo2/thor
16444         # first
16445         rm $DIR/$tdir/$tfile
16446         # rename
16447         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16448         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16449                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16450         rm $DIR/$tdir/foo2/maggie
16451
16452         # overflow the EA
16453         local longname=$tfile.avg_len_is_thirty_two_
16454         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16455                 error_noexit 'failed to unlink many hardlinks'" EXIT
16456         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16457                 error "failed to hardlink many files"
16458         links=$($LFS fid2path $DIR $FID | wc -l)
16459         echo -n "${links}/1000 links in link EA"
16460         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16461 }
16462 run_test 161a "link ea sanity"
16463
16464 test_161b() {
16465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16466         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16467
16468         local MDTIDX=1
16469         local remote_dir=$DIR/$tdir/remote_dir
16470
16471         mkdir -p $DIR/$tdir
16472         $LFS mkdir -i $MDTIDX $remote_dir ||
16473                 error "create remote directory failed"
16474
16475         cp /etc/hosts $remote_dir/$tfile
16476         mkdir -p $remote_dir/foo1
16477         mkdir -p $remote_dir/foo2
16478         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16479         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16480         ln $remote_dir/$tfile $remote_dir/foo1/luna
16481         ln $remote_dir/$tfile $remote_dir/foo2/thor
16482
16483         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16484                      tr -d ']')
16485         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16486                 $LFS fid2path $DIR $FID
16487                 error "bad link ea"
16488         fi
16489         # middle
16490         rm $remote_dir/foo2/zachary
16491         # last
16492         rm $remote_dir/foo2/thor
16493         # first
16494         rm $remote_dir/$tfile
16495         # rename
16496         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16497         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16498         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16499                 $LFS fid2path $DIR $FID
16500                 error "bad link rename"
16501         fi
16502         rm $remote_dir/foo2/maggie
16503
16504         # overflow the EA
16505         local longname=filename_avg_len_is_thirty_two_
16506         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16507                 error "failed to hardlink many files"
16508         links=$($LFS fid2path $DIR $FID | wc -l)
16509         echo -n "${links}/1000 links in link EA"
16510         [[ ${links} -gt 60 ]] ||
16511                 error "expected at least 60 links in link EA"
16512         unlinkmany $remote_dir/foo2/$longname 1000 ||
16513         error "failed to unlink many hardlinks"
16514 }
16515 run_test 161b "link ea sanity under remote directory"
16516
16517 test_161c() {
16518         remote_mds_nodsh && skip "remote MDS with nodsh"
16519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16520         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16521                 skip "Need MDS version at least 2.1.5"
16522
16523         # define CLF_RENAME_LAST 0x0001
16524         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16525         changelog_register || error "changelog_register failed"
16526
16527         rm -rf $DIR/$tdir
16528         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16529         touch $DIR/$tdir/foo_161c
16530         touch $DIR/$tdir/bar_161c
16531         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16532         changelog_dump | grep RENME | tail -n 5
16533         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16534         changelog_clear 0 || error "changelog_clear failed"
16535         if [ x$flags != "x0x1" ]; then
16536                 error "flag $flags is not 0x1"
16537         fi
16538
16539         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16540         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16541         touch $DIR/$tdir/foo_161c
16542         touch $DIR/$tdir/bar_161c
16543         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16544         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16545         changelog_dump | grep RENME | tail -n 5
16546         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16547         changelog_clear 0 || error "changelog_clear failed"
16548         if [ x$flags != "x0x0" ]; then
16549                 error "flag $flags is not 0x0"
16550         fi
16551         echo "rename overwrite a target having nlink > 1," \
16552                 "changelog record has flags of $flags"
16553
16554         # rename doesn't overwrite a target (changelog flag 0x0)
16555         touch $DIR/$tdir/foo_161c
16556         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16557         changelog_dump | grep RENME | tail -n 5
16558         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16559         changelog_clear 0 || error "changelog_clear failed"
16560         if [ x$flags != "x0x0" ]; then
16561                 error "flag $flags is not 0x0"
16562         fi
16563         echo "rename doesn't overwrite a target," \
16564                 "changelog record has flags of $flags"
16565
16566         # define CLF_UNLINK_LAST 0x0001
16567         # unlink a file having nlink = 1 (changelog flag 0x1)
16568         rm -f $DIR/$tdir/foo2_161c
16569         changelog_dump | grep UNLNK | tail -n 5
16570         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16571         changelog_clear 0 || error "changelog_clear failed"
16572         if [ x$flags != "x0x1" ]; then
16573                 error "flag $flags is not 0x1"
16574         fi
16575         echo "unlink a file having nlink = 1," \
16576                 "changelog record has flags of $flags"
16577
16578         # unlink a file having nlink > 1 (changelog flag 0x0)
16579         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16580         rm -f $DIR/$tdir/foobar_161c
16581         changelog_dump | grep UNLNK | tail -n 5
16582         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16583         changelog_clear 0 || error "changelog_clear failed"
16584         if [ x$flags != "x0x0" ]; then
16585                 error "flag $flags is not 0x0"
16586         fi
16587         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16588 }
16589 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16590
16591 test_161d() {
16592         remote_mds_nodsh && skip "remote MDS with nodsh"
16593         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16594
16595         local pid
16596         local fid
16597
16598         changelog_register || error "changelog_register failed"
16599
16600         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16601         # interfer with $MOUNT/.lustre/fid/ access
16602         mkdir $DIR/$tdir
16603         [[ $? -eq 0 ]] || error "mkdir failed"
16604
16605         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16606         $LCTL set_param fail_loc=0x8000140c
16607         # 5s pause
16608         $LCTL set_param fail_val=5
16609
16610         # create file
16611         echo foofoo > $DIR/$tdir/$tfile &
16612         pid=$!
16613
16614         # wait for create to be delayed
16615         sleep 2
16616
16617         ps -p $pid
16618         [[ $? -eq 0 ]] || error "create should be blocked"
16619
16620         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16621         stack_trap "rm -f $tempfile"
16622         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16623         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16624         # some delay may occur during ChangeLog publishing and file read just
16625         # above, that could allow file write to happen finally
16626         [[ -s $tempfile ]] && echo "file should be empty"
16627
16628         $LCTL set_param fail_loc=0
16629
16630         wait $pid
16631         [[ $? -eq 0 ]] || error "create failed"
16632 }
16633 run_test 161d "create with concurrent .lustre/fid access"
16634
16635 check_path() {
16636         local expected="$1"
16637         shift
16638         local fid="$2"
16639
16640         local path
16641         path=$($LFS fid2path "$@")
16642         local rc=$?
16643
16644         if [ $rc -ne 0 ]; then
16645                 error "path looked up of '$expected' failed: rc=$rc"
16646         elif [ "$path" != "$expected" ]; then
16647                 error "path looked up '$path' instead of '$expected'"
16648         else
16649                 echo "FID '$fid' resolves to path '$path' as expected"
16650         fi
16651 }
16652
16653 test_162a() { # was test_162
16654         test_mkdir -p -c1 $DIR/$tdir/d2
16655         touch $DIR/$tdir/d2/$tfile
16656         touch $DIR/$tdir/d2/x1
16657         touch $DIR/$tdir/d2/x2
16658         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16659         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16660         # regular file
16661         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16662         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16663
16664         # softlink
16665         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16666         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16667         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16668
16669         # softlink to wrong file
16670         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16671         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16672         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16673
16674         # hardlink
16675         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16676         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16677         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16678         # fid2path dir/fsname should both work
16679         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16680         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16681
16682         # hardlink count: check that there are 2 links
16683         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16684         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16685
16686         # hardlink indexing: remove the first link
16687         rm $DIR/$tdir/d2/p/q/r/hlink
16688         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16689 }
16690 run_test 162a "path lookup sanity"
16691
16692 test_162b() {
16693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16694         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16695
16696         mkdir $DIR/$tdir
16697         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16698                                 error "create striped dir failed"
16699
16700         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16701                                         tail -n 1 | awk '{print $2}')
16702         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16703
16704         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16705         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16706
16707         # regular file
16708         for ((i=0;i<5;i++)); do
16709                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
16710                         error "get fid for f$i failed"
16711                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
16712
16713                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
16714                         error "get fid for d$i failed"
16715                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
16716         done
16717
16718         return 0
16719 }
16720 run_test 162b "striped directory path lookup sanity"
16721
16722 # LU-4239: Verify fid2path works with paths 100 or more directories deep
16723 test_162c() {
16724         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
16725                 skip "Need MDS version at least 2.7.51"
16726
16727         local lpath=$tdir.local
16728         local rpath=$tdir.remote
16729
16730         test_mkdir $DIR/$lpath
16731         test_mkdir $DIR/$rpath
16732
16733         for ((i = 0; i <= 101; i++)); do
16734                 lpath="$lpath/$i"
16735                 mkdir $DIR/$lpath
16736                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
16737                         error "get fid for local directory $DIR/$lpath failed"
16738                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
16739
16740                 rpath="$rpath/$i"
16741                 test_mkdir $DIR/$rpath
16742                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
16743                         error "get fid for remote directory $DIR/$rpath failed"
16744                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
16745         done
16746
16747         return 0
16748 }
16749 run_test 162c "fid2path works with paths 100 or more directories deep"
16750
16751 oalr_event_count() {
16752         local event="${1}"
16753         local trace="${2}"
16754
16755         awk -v name="${FSNAME}-OST0000" \
16756             -v event="${event}" \
16757             '$1 == "TRACE" && $2 == event && $3 == name' \
16758             "${trace}" |
16759         wc -l
16760 }
16761
16762 oalr_expect_event_count() {
16763         local event="${1}"
16764         local trace="${2}"
16765         local expect="${3}"
16766         local count
16767
16768         count=$(oalr_event_count "${event}" "${trace}")
16769         if ((count == expect)); then
16770                 return 0
16771         fi
16772
16773         error_noexit "${event} event count was '${count}', expected ${expect}"
16774         cat "${trace}" >&2
16775         exit 1
16776 }
16777
16778 cleanup_165() {
16779         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
16780         stop ost1
16781         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
16782 }
16783
16784 setup_165() {
16785         sync # Flush previous IOs so we can count log entries.
16786         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
16787         stack_trap cleanup_165 EXIT
16788 }
16789
16790 test_165a() {
16791         local trace="/tmp/${tfile}.trace"
16792         local rc
16793         local count
16794
16795         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16796                 skip "OFD access log unsupported"
16797
16798         setup_165
16799         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16800         sleep 5
16801
16802         do_facet ost1 ofd_access_log_reader --list
16803         stop ost1
16804
16805         do_facet ost1 killall -TERM ofd_access_log_reader
16806         wait
16807         rc=$?
16808
16809         if ((rc != 0)); then
16810                 error "ofd_access_log_reader exited with rc = '${rc}'"
16811         fi
16812
16813         # Parse trace file for discovery events:
16814         oalr_expect_event_count alr_log_add "${trace}" 1
16815         oalr_expect_event_count alr_log_eof "${trace}" 1
16816         oalr_expect_event_count alr_log_free "${trace}" 1
16817 }
16818 run_test 165a "ofd access log discovery"
16819
16820 test_165b() {
16821         local trace="/tmp/${tfile}.trace"
16822         local file="${DIR}/${tfile}"
16823         local pfid1
16824         local pfid2
16825         local -a entry
16826         local rc
16827         local count
16828         local size
16829         local flags
16830
16831         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16832                 skip "OFD access log unsupported"
16833
16834         setup_165
16835         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16836         sleep 5
16837
16838         do_facet ost1 ofd_access_log_reader --list
16839
16840         lfs setstripe -c 1 -i 0 "${file}"
16841         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16842                 error "cannot create '${file}'"
16843
16844         sleep 5
16845         do_facet ost1 killall -TERM ofd_access_log_reader
16846         wait
16847         rc=$?
16848
16849         if ((rc != 0)); then
16850                 error "ofd_access_log_reader exited with rc = '${rc}'"
16851         fi
16852
16853         oalr_expect_event_count alr_log_entry "${trace}" 1
16854
16855         pfid1=$($LFS path2fid "${file}")
16856
16857         # 1     2             3   4    5     6   7    8    9     10
16858         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
16859         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16860
16861         echo "entry = '${entry[*]}'" >&2
16862
16863         pfid2=${entry[4]}
16864         if [[ "${pfid1}" != "${pfid2}" ]]; then
16865                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16866         fi
16867
16868         size=${entry[8]}
16869         if ((size != 1048576)); then
16870                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
16871         fi
16872
16873         flags=${entry[10]}
16874         if [[ "${flags}" != "w" ]]; then
16875                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
16876         fi
16877
16878         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16879         sleep 5
16880
16881         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
16882                 error "cannot read '${file}'"
16883         sleep 5
16884
16885         do_facet ost1 killall -TERM ofd_access_log_reader
16886         wait
16887         rc=$?
16888
16889         if ((rc != 0)); then
16890                 error "ofd_access_log_reader exited with rc = '${rc}'"
16891         fi
16892
16893         oalr_expect_event_count alr_log_entry "${trace}" 1
16894
16895         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
16896         echo "entry = '${entry[*]}'" >&2
16897
16898         pfid2=${entry[4]}
16899         if [[ "${pfid1}" != "${pfid2}" ]]; then
16900                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
16901         fi
16902
16903         size=${entry[8]}
16904         if ((size != 524288)); then
16905                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
16906         fi
16907
16908         flags=${entry[10]}
16909         if [[ "${flags}" != "r" ]]; then
16910                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
16911         fi
16912 }
16913 run_test 165b "ofd access log entries are produced and consumed"
16914
16915 test_165c() {
16916         local trace="/tmp/${tfile}.trace"
16917         local file="${DIR}/${tdir}/${tfile}"
16918
16919         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16920                 skip "OFD access log unsupported"
16921
16922         test_mkdir "${DIR}/${tdir}"
16923
16924         setup_165
16925         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
16926         sleep 5
16927
16928         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
16929
16930         # 4096 / 64 = 64. Create twice as many entries.
16931         for ((i = 0; i < 128; i++)); do
16932                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
16933                         error "cannot create file"
16934         done
16935
16936         sync
16937
16938         do_facet ost1 killall -TERM ofd_access_log_reader
16939         wait
16940         rc=$?
16941         if ((rc != 0)); then
16942                 error "ofd_access_log_reader exited with rc = '${rc}'"
16943         fi
16944
16945         unlinkmany  "${file}-%d" 128
16946 }
16947 run_test 165c "full ofd access logs do not block IOs"
16948
16949 oal_get_read_count() {
16950         local stats="$1"
16951
16952         # STATS lustre-OST0001 alr_read_count 1
16953
16954         do_facet ost1 cat "${stats}" |
16955         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
16956              END { print count; }'
16957 }
16958
16959 oal_expect_read_count() {
16960         local stats="$1"
16961         local count
16962         local expect="$2"
16963
16964         # Ask ofd_access_log_reader to write stats.
16965         do_facet ost1 killall -USR1 ofd_access_log_reader
16966
16967         # Allow some time for things to happen.
16968         sleep 1
16969
16970         count=$(oal_get_read_count "${stats}")
16971         if ((count == expect)); then
16972                 return 0
16973         fi
16974
16975         error_noexit "bad read count, got ${count}, expected ${expect}"
16976         do_facet ost1 cat "${stats}" >&2
16977         exit 1
16978 }
16979
16980 test_165d() {
16981         local stats="/tmp/${tfile}.stats"
16982         local file="${DIR}/${tdir}/${tfile}"
16983         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
16984
16985         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
16986                 skip "OFD access log unsupported"
16987
16988         test_mkdir "${DIR}/${tdir}"
16989
16990         setup_165
16991         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
16992         sleep 5
16993
16994         lfs setstripe -c 1 -i 0 "${file}"
16995
16996         do_facet ost1 lctl set_param "${param}=rw"
16997         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
16998                 error "cannot create '${file}'"
16999         oal_expect_read_count "${stats}" 1
17000
17001         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17002                 error "cannot read '${file}'"
17003         oal_expect_read_count "${stats}" 2
17004
17005         do_facet ost1 lctl set_param "${param}=r"
17006         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17007                 error "cannot create '${file}'"
17008         oal_expect_read_count "${stats}" 2
17009
17010         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17011                 error "cannot read '${file}'"
17012         oal_expect_read_count "${stats}" 3
17013
17014         do_facet ost1 lctl set_param "${param}=w"
17015         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17016                 error "cannot create '${file}'"
17017         oal_expect_read_count "${stats}" 4
17018
17019         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17020                 error "cannot read '${file}'"
17021         oal_expect_read_count "${stats}" 4
17022
17023         do_facet ost1 lctl set_param "${param}=0"
17024         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17025                 error "cannot create '${file}'"
17026         oal_expect_read_count "${stats}" 4
17027
17028         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17029                 error "cannot read '${file}'"
17030         oal_expect_read_count "${stats}" 4
17031
17032         do_facet ost1 killall -TERM ofd_access_log_reader
17033         wait
17034         rc=$?
17035         if ((rc != 0)); then
17036                 error "ofd_access_log_reader exited with rc = '${rc}'"
17037         fi
17038 }
17039 run_test 165d "ofd_access_log mask works"
17040
17041 test_165e() {
17042         local stats="/tmp/${tfile}.stats"
17043         local file0="${DIR}/${tdir}-0/${tfile}"
17044         local file1="${DIR}/${tdir}-1/${tfile}"
17045
17046         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17047                 skip "OFD access log unsupported"
17048
17049         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17050
17051         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17052         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17053
17054         lfs setstripe -c 1 -i 0 "${file0}"
17055         lfs setstripe -c 1 -i 0 "${file1}"
17056
17057         setup_165
17058         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17059         sleep 5
17060
17061         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17062                 error "cannot create '${file0}'"
17063         sync
17064         oal_expect_read_count "${stats}" 0
17065
17066         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17067                 error "cannot create '${file1}'"
17068         sync
17069         oal_expect_read_count "${stats}" 1
17070
17071         do_facet ost1 killall -TERM ofd_access_log_reader
17072         wait
17073         rc=$?
17074         if ((rc != 0)); then
17075                 error "ofd_access_log_reader exited with rc = '${rc}'"
17076         fi
17077 }
17078 run_test 165e "ofd_access_log MDT index filter works"
17079
17080 test_165f() {
17081         local trace="/tmp/${tfile}.trace"
17082         local rc
17083         local count
17084
17085         setup_165
17086         do_facet ost1 timeout 60 ofd_access_log_reader \
17087                 --exit-on-close --debug=- --trace=- > "${trace}" &
17088         sleep 5
17089         stop ost1
17090
17091         wait
17092         rc=$?
17093
17094         if ((rc != 0)); then
17095                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17096                 cat "${trace}"
17097                 exit 1
17098         fi
17099 }
17100 run_test 165f "ofd_access_log_reader --exit-on-close works"
17101
17102 test_169() {
17103         # do directio so as not to populate the page cache
17104         log "creating a 10 Mb file"
17105         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17106                 error "multiop failed while creating a file"
17107         log "starting reads"
17108         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17109         log "truncating the file"
17110         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17111                 error "multiop failed while truncating the file"
17112         log "killing dd"
17113         kill %+ || true # reads might have finished
17114         echo "wait until dd is finished"
17115         wait
17116         log "removing the temporary file"
17117         rm -rf $DIR/$tfile || error "tmp file removal failed"
17118 }
17119 run_test 169 "parallel read and truncate should not deadlock"
17120
17121 test_170() {
17122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17123
17124         $LCTL clear     # bug 18514
17125         $LCTL debug_daemon start $TMP/${tfile}_log_good
17126         touch $DIR/$tfile
17127         $LCTL debug_daemon stop
17128         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17129                 error "sed failed to read log_good"
17130
17131         $LCTL debug_daemon start $TMP/${tfile}_log_good
17132         rm -rf $DIR/$tfile
17133         $LCTL debug_daemon stop
17134
17135         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17136                error "lctl df log_bad failed"
17137
17138         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17139         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17140
17141         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17142         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17143
17144         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17145                 error "bad_line good_line1 good_line2 are empty"
17146
17147         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17148         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17149         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17150
17151         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17152         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17153         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17154
17155         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17156                 error "bad_line_new good_line_new are empty"
17157
17158         local expected_good=$((good_line1 + good_line2*2))
17159
17160         rm -f $TMP/${tfile}*
17161         # LU-231, short malformed line may not be counted into bad lines
17162         if [ $bad_line -ne $bad_line_new ] &&
17163                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17164                 error "expected $bad_line bad lines, but got $bad_line_new"
17165                 return 1
17166         fi
17167
17168         if [ $expected_good -ne $good_line_new ]; then
17169                 error "expected $expected_good good lines, but got $good_line_new"
17170                 return 2
17171         fi
17172         true
17173 }
17174 run_test 170 "test lctl df to handle corrupted log ====================="
17175
17176 test_171() { # bug20592
17177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17178
17179         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17180         $LCTL set_param fail_loc=0x50e
17181         $LCTL set_param fail_val=3000
17182         multiop_bg_pause $DIR/$tfile O_s || true
17183         local MULTIPID=$!
17184         kill -USR1 $MULTIPID
17185         # cause log dump
17186         sleep 3
17187         wait $MULTIPID
17188         if dmesg | grep "recursive fault"; then
17189                 error "caught a recursive fault"
17190         fi
17191         $LCTL set_param fail_loc=0
17192         true
17193 }
17194 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17195
17196 # it would be good to share it with obdfilter-survey/iokit-libecho code
17197 setup_obdecho_osc () {
17198         local rc=0
17199         local ost_nid=$1
17200         local obdfilter_name=$2
17201         echo "Creating new osc for $obdfilter_name on $ost_nid"
17202         # make sure we can find loopback nid
17203         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17204
17205         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17206                            ${obdfilter_name}_osc_UUID || rc=2; }
17207         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17208                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17209         return $rc
17210 }
17211
17212 cleanup_obdecho_osc () {
17213         local obdfilter_name=$1
17214         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17215         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17216         return 0
17217 }
17218
17219 obdecho_test() {
17220         local OBD=$1
17221         local node=$2
17222         local pages=${3:-64}
17223         local rc=0
17224         local id
17225
17226         local count=10
17227         local obd_size=$(get_obd_size $node $OBD)
17228         local page_size=$(get_page_size $node)
17229         if [[ -n "$obd_size" ]]; then
17230                 local new_count=$((obd_size / (pages * page_size / 1024)))
17231                 [[ $new_count -ge $count ]] || count=$new_count
17232         fi
17233
17234         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17235         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17236                            rc=2; }
17237         if [ $rc -eq 0 ]; then
17238             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17239             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17240         fi
17241         echo "New object id is $id"
17242         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17243                            rc=4; }
17244         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17245                            "test_brw $count w v $pages $id" || rc=4; }
17246         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17247                            rc=4; }
17248         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17249                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17250         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17251                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17252         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17253         return $rc
17254 }
17255
17256 test_180a() {
17257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17258
17259         if ! [ -d /sys/fs/lustre/echo_client ] &&
17260            ! module_loaded obdecho; then
17261                 load_module obdecho/obdecho &&
17262                         stack_trap "rmmod obdecho" EXIT ||
17263                         error "unable to load obdecho on client"
17264         fi
17265
17266         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17267         local host=$($LCTL get_param -n osc.$osc.import |
17268                      awk '/current_connection:/ { print $2 }' )
17269         local target=$($LCTL get_param -n osc.$osc.import |
17270                        awk '/target:/ { print $2 }' )
17271         target=${target%_UUID}
17272
17273         if [ -n "$target" ]; then
17274                 setup_obdecho_osc $host $target &&
17275                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17276                         { error "obdecho setup failed with $?"; return; }
17277
17278                 obdecho_test ${target}_osc client ||
17279                         error "obdecho_test failed on ${target}_osc"
17280         else
17281                 $LCTL get_param osc.$osc.import
17282                 error "there is no osc.$osc.import target"
17283         fi
17284 }
17285 run_test 180a "test obdecho on osc"
17286
17287 test_180b() {
17288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17289         remote_ost_nodsh && skip "remote OST with nodsh"
17290
17291         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17292                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17293                 error "failed to load module obdecho"
17294
17295         local target=$(do_facet ost1 $LCTL dl |
17296                        awk '/obdfilter/ { print $4; exit; }')
17297
17298         if [ -n "$target" ]; then
17299                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17300         else
17301                 do_facet ost1 $LCTL dl
17302                 error "there is no obdfilter target on ost1"
17303         fi
17304 }
17305 run_test 180b "test obdecho directly on obdfilter"
17306
17307 test_180c() { # LU-2598
17308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17309         remote_ost_nodsh && skip "remote OST with nodsh"
17310         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17311                 skip "Need MDS version at least 2.4.0"
17312
17313         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17314                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17315                 error "failed to load module obdecho"
17316
17317         local target=$(do_facet ost1 $LCTL dl |
17318                        awk '/obdfilter/ { print $4; exit; }')
17319
17320         if [ -n "$target" ]; then
17321                 local pages=16384 # 64MB bulk I/O RPC size
17322
17323                 obdecho_test "$target" ost1 "$pages" ||
17324                         error "obdecho_test with pages=$pages failed with $?"
17325         else
17326                 do_facet ost1 $LCTL dl
17327                 error "there is no obdfilter target on ost1"
17328         fi
17329 }
17330 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17331
17332 test_181() { # bug 22177
17333         test_mkdir $DIR/$tdir
17334         # create enough files to index the directory
17335         createmany -o $DIR/$tdir/foobar 4000
17336         # print attributes for debug purpose
17337         lsattr -d .
17338         # open dir
17339         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17340         MULTIPID=$!
17341         # remove the files & current working dir
17342         unlinkmany $DIR/$tdir/foobar 4000
17343         rmdir $DIR/$tdir
17344         kill -USR1 $MULTIPID
17345         wait $MULTIPID
17346         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17347         return 0
17348 }
17349 run_test 181 "Test open-unlinked dir ========================"
17350
17351 test_182() {
17352         local fcount=1000
17353         local tcount=10
17354
17355         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17356
17357         $LCTL set_param mdc.*.rpc_stats=clear
17358
17359         for (( i = 0; i < $tcount; i++ )) ; do
17360                 mkdir $DIR/$tdir/$i
17361         done
17362
17363         for (( i = 0; i < $tcount; i++ )) ; do
17364                 createmany -o $DIR/$tdir/$i/f- $fcount &
17365         done
17366         wait
17367
17368         for (( i = 0; i < $tcount; i++ )) ; do
17369                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17370         done
17371         wait
17372
17373         $LCTL get_param mdc.*.rpc_stats
17374
17375         rm -rf $DIR/$tdir
17376 }
17377 run_test 182 "Test parallel modify metadata operations ================"
17378
17379 test_183() { # LU-2275
17380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17381         remote_mds_nodsh && skip "remote MDS with nodsh"
17382         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17383                 skip "Need MDS version at least 2.3.56"
17384
17385         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17386         echo aaa > $DIR/$tdir/$tfile
17387
17388 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17389         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17390
17391         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17392         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17393
17394         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17395
17396         # Flush negative dentry cache
17397         touch $DIR/$tdir/$tfile
17398
17399         # We are not checking for any leaked references here, they'll
17400         # become evident next time we do cleanup with module unload.
17401         rm -rf $DIR/$tdir
17402 }
17403 run_test 183 "No crash or request leak in case of strange dispositions ========"
17404
17405 # test suite 184 is for LU-2016, LU-2017
17406 test_184a() {
17407         check_swap_layouts_support
17408
17409         dir0=$DIR/$tdir/$testnum
17410         test_mkdir -p -c1 $dir0
17411         ref1=/etc/passwd
17412         ref2=/etc/group
17413         file1=$dir0/f1
17414         file2=$dir0/f2
17415         $LFS setstripe -c1 $file1
17416         cp $ref1 $file1
17417         $LFS setstripe -c2 $file2
17418         cp $ref2 $file2
17419         gen1=$($LFS getstripe -g $file1)
17420         gen2=$($LFS getstripe -g $file2)
17421
17422         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17423         gen=$($LFS getstripe -g $file1)
17424         [[ $gen1 != $gen ]] ||
17425                 "Layout generation on $file1 does not change"
17426         gen=$($LFS getstripe -g $file2)
17427         [[ $gen2 != $gen ]] ||
17428                 "Layout generation on $file2 does not change"
17429
17430         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17431         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17432
17433         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17434 }
17435 run_test 184a "Basic layout swap"
17436
17437 test_184b() {
17438         check_swap_layouts_support
17439
17440         dir0=$DIR/$tdir/$testnum
17441         mkdir -p $dir0 || error "creating dir $dir0"
17442         file1=$dir0/f1
17443         file2=$dir0/f2
17444         file3=$dir0/f3
17445         dir1=$dir0/d1
17446         dir2=$dir0/d2
17447         mkdir $dir1 $dir2
17448         $LFS setstripe -c1 $file1
17449         $LFS setstripe -c2 $file2
17450         $LFS setstripe -c1 $file3
17451         chown $RUNAS_ID $file3
17452         gen1=$($LFS getstripe -g $file1)
17453         gen2=$($LFS getstripe -g $file2)
17454
17455         $LFS swap_layouts $dir1 $dir2 &&
17456                 error "swap of directories layouts should fail"
17457         $LFS swap_layouts $dir1 $file1 &&
17458                 error "swap of directory and file layouts should fail"
17459         $RUNAS $LFS swap_layouts $file1 $file2 &&
17460                 error "swap of file we cannot write should fail"
17461         $LFS swap_layouts $file1 $file3 &&
17462                 error "swap of file with different owner should fail"
17463         /bin/true # to clear error code
17464 }
17465 run_test 184b "Forbidden layout swap (will generate errors)"
17466
17467 test_184c() {
17468         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17469         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17470         check_swap_layouts_support
17471         check_swap_layout_no_dom $DIR
17472
17473         local dir0=$DIR/$tdir/$testnum
17474         mkdir -p $dir0 || error "creating dir $dir0"
17475
17476         local ref1=$dir0/ref1
17477         local ref2=$dir0/ref2
17478         local file1=$dir0/file1
17479         local file2=$dir0/file2
17480         # create a file large enough for the concurrent test
17481         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17482         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17483         echo "ref file size: ref1($(stat -c %s $ref1))," \
17484              "ref2($(stat -c %s $ref2))"
17485
17486         cp $ref2 $file2
17487         dd if=$ref1 of=$file1 bs=16k &
17488         local DD_PID=$!
17489
17490         # Make sure dd starts to copy file, but wait at most 5 seconds
17491         local loops=0
17492         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17493
17494         $LFS swap_layouts $file1 $file2
17495         local rc=$?
17496         wait $DD_PID
17497         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17498         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17499
17500         # how many bytes copied before swapping layout
17501         local copied=$(stat -c %s $file2)
17502         local remaining=$(stat -c %s $ref1)
17503         remaining=$((remaining - copied))
17504         echo "Copied $copied bytes before swapping layout..."
17505
17506         cmp -n $copied $file1 $ref2 | grep differ &&
17507                 error "Content mismatch [0, $copied) of ref2 and file1"
17508         cmp -n $copied $file2 $ref1 ||
17509                 error "Content mismatch [0, $copied) of ref1 and file2"
17510         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17511                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17512
17513         # clean up
17514         rm -f $ref1 $ref2 $file1 $file2
17515 }
17516 run_test 184c "Concurrent write and layout swap"
17517
17518 test_184d() {
17519         check_swap_layouts_support
17520         check_swap_layout_no_dom $DIR
17521         [ -z "$(which getfattr 2>/dev/null)" ] &&
17522                 skip_env "no getfattr command"
17523
17524         local file1=$DIR/$tdir/$tfile-1
17525         local file2=$DIR/$tdir/$tfile-2
17526         local file3=$DIR/$tdir/$tfile-3
17527         local lovea1
17528         local lovea2
17529
17530         mkdir -p $DIR/$tdir
17531         touch $file1 || error "create $file1 failed"
17532         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17533                 error "create $file2 failed"
17534         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17535                 error "create $file3 failed"
17536         lovea1=$(get_layout_param $file1)
17537
17538         $LFS swap_layouts $file2 $file3 ||
17539                 error "swap $file2 $file3 layouts failed"
17540         $LFS swap_layouts $file1 $file2 ||
17541                 error "swap $file1 $file2 layouts failed"
17542
17543         lovea2=$(get_layout_param $file2)
17544         echo "$lovea1"
17545         echo "$lovea2"
17546         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17547
17548         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17549         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17550 }
17551 run_test 184d "allow stripeless layouts swap"
17552
17553 test_184e() {
17554         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17555                 skip "Need MDS version at least 2.6.94"
17556         check_swap_layouts_support
17557         check_swap_layout_no_dom $DIR
17558         [ -z "$(which getfattr 2>/dev/null)" ] &&
17559                 skip_env "no getfattr command"
17560
17561         local file1=$DIR/$tdir/$tfile-1
17562         local file2=$DIR/$tdir/$tfile-2
17563         local file3=$DIR/$tdir/$tfile-3
17564         local lovea
17565
17566         mkdir -p $DIR/$tdir
17567         touch $file1 || error "create $file1 failed"
17568         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17569                 error "create $file2 failed"
17570         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17571                 error "create $file3 failed"
17572
17573         $LFS swap_layouts $file1 $file2 ||
17574                 error "swap $file1 $file2 layouts failed"
17575
17576         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17577         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17578
17579         echo 123 > $file1 || error "Should be able to write into $file1"
17580
17581         $LFS swap_layouts $file1 $file3 ||
17582                 error "swap $file1 $file3 layouts failed"
17583
17584         echo 123 > $file1 || error "Should be able to write into $file1"
17585
17586         rm -rf $file1 $file2 $file3
17587 }
17588 run_test 184e "Recreate layout after stripeless layout swaps"
17589
17590 test_184f() {
17591         # Create a file with name longer than sizeof(struct stat) ==
17592         # 144 to see if we can get chars from the file name to appear
17593         # in the returned striping. Note that 'f' == 0x66.
17594         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17595
17596         mkdir -p $DIR/$tdir
17597         mcreate $DIR/$tdir/$file
17598         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17599                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17600         fi
17601 }
17602 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17603
17604 test_185() { # LU-2441
17605         # LU-3553 - no volatile file support in old servers
17606         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17607                 skip "Need MDS version at least 2.3.60"
17608
17609         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17610         touch $DIR/$tdir/spoo
17611         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17612         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17613                 error "cannot create/write a volatile file"
17614         [ "$FILESET" == "" ] &&
17615         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17616                 error "FID is still valid after close"
17617
17618         multiop_bg_pause $DIR/$tdir vVw4096_c
17619         local multi_pid=$!
17620
17621         local OLD_IFS=$IFS
17622         IFS=":"
17623         local fidv=($fid)
17624         IFS=$OLD_IFS
17625         # assume that the next FID for this client is sequential, since stdout
17626         # is unfortunately eaten by multiop_bg_pause
17627         local n=$((${fidv[1]} + 1))
17628         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17629         if [ "$FILESET" == "" ]; then
17630                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17631                         error "FID is missing before close"
17632         fi
17633         kill -USR1 $multi_pid
17634         # 1 second delay, so if mtime change we will see it
17635         sleep 1
17636         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17637         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17638 }
17639 run_test 185 "Volatile file support"
17640
17641 function create_check_volatile() {
17642         local idx=$1
17643         local tgt
17644
17645         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17646         local PID=$!
17647         sleep 1
17648         local FID=$(cat /tmp/${tfile}.fid)
17649         [ "$FID" == "" ] && error "can't get FID for volatile"
17650         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17651         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17652         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17653         kill -USR1 $PID
17654         wait
17655         sleep 1
17656         cancel_lru_locks mdc # flush opencache
17657         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17658         return 0
17659 }
17660
17661 test_185a(){
17662         # LU-12516 - volatile creation via .lustre
17663         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17664                 skip "Need MDS version at least 2.3.55"
17665
17666         create_check_volatile 0
17667         [ $MDSCOUNT -lt 2 ] && return 0
17668
17669         # DNE case
17670         create_check_volatile 1
17671
17672         return 0
17673 }
17674 run_test 185a "Volatile file creation in .lustre/fid/"
17675
17676 test_187a() {
17677         remote_mds_nodsh && skip "remote MDS with nodsh"
17678         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17679                 skip "Need MDS version at least 2.3.0"
17680
17681         local dir0=$DIR/$tdir/$testnum
17682         mkdir -p $dir0 || error "creating dir $dir0"
17683
17684         local file=$dir0/file1
17685         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17686         local dv1=$($LFS data_version $file)
17687         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17688         local dv2=$($LFS data_version $file)
17689         [[ $dv1 != $dv2 ]] ||
17690                 error "data version did not change on write $dv1 == $dv2"
17691
17692         # clean up
17693         rm -f $file1
17694 }
17695 run_test 187a "Test data version change"
17696
17697 test_187b() {
17698         remote_mds_nodsh && skip "remote MDS with nodsh"
17699         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17700                 skip "Need MDS version at least 2.3.0"
17701
17702         local dir0=$DIR/$tdir/$testnum
17703         mkdir -p $dir0 || error "creating dir $dir0"
17704
17705         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17706         [[ ${DV[0]} != ${DV[1]} ]] ||
17707                 error "data version did not change on write"\
17708                       " ${DV[0]} == ${DV[1]}"
17709
17710         # clean up
17711         rm -f $file1
17712 }
17713 run_test 187b "Test data version change on volatile file"
17714
17715 test_200() {
17716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17717         remote_mgs_nodsh && skip "remote MGS with nodsh"
17718         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17719
17720         local POOL=${POOL:-cea1}
17721         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
17722         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
17723         # Pool OST targets
17724         local first_ost=0
17725         local last_ost=$(($OSTCOUNT - 1))
17726         local ost_step=2
17727         local ost_list=$(seq $first_ost $ost_step $last_ost)
17728         local ost_range="$first_ost $last_ost $ost_step"
17729         local test_path=$POOL_ROOT/$POOL_DIR_NAME
17730         local file_dir=$POOL_ROOT/file_tst
17731         local subdir=$test_path/subdir
17732         local rc=0
17733
17734         while : ; do
17735                 # former test_200a test_200b
17736                 pool_add $POOL                          || { rc=$? ; break; }
17737                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
17738                 # former test_200c test_200d
17739                 mkdir -p $test_path
17740                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
17741                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
17742                 mkdir -p $subdir
17743                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
17744                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
17745                                                         || { rc=$? ; break; }
17746                 # former test_200e test_200f
17747                 local files=$((OSTCOUNT*3))
17748                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
17749                                                         || { rc=$? ; break; }
17750                 pool_create_files $POOL $file_dir $files "$ost_list" \
17751                                                         || { rc=$? ; break; }
17752                 # former test_200g test_200h
17753                 pool_lfs_df $POOL                       || { rc=$? ; break; }
17754                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
17755
17756                 # former test_201a test_201b test_201c
17757                 pool_remove_first_target $POOL          || { rc=$? ; break; }
17758
17759                 local f=$test_path/$tfile
17760                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
17761                 pool_remove $POOL $f                    || { rc=$? ; break; }
17762                 break
17763         done
17764
17765         destroy_test_pools
17766
17767         return $rc
17768 }
17769 run_test 200 "OST pools"
17770
17771 # usage: default_attr <count | size | offset>
17772 default_attr() {
17773         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
17774 }
17775
17776 # usage: check_default_stripe_attr
17777 check_default_stripe_attr() {
17778         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
17779         case $1 in
17780         --stripe-count|-c)
17781                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
17782         --stripe-size|-S)
17783                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
17784         --stripe-index|-i)
17785                 EXPECTED=-1;;
17786         *)
17787                 error "unknown getstripe attr '$1'"
17788         esac
17789
17790         [ $ACTUAL == $EXPECTED ] ||
17791                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
17792 }
17793
17794 test_204a() {
17795         test_mkdir $DIR/$tdir
17796         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
17797
17798         check_default_stripe_attr --stripe-count
17799         check_default_stripe_attr --stripe-size
17800         check_default_stripe_attr --stripe-index
17801 }
17802 run_test 204a "Print default stripe attributes"
17803
17804 test_204b() {
17805         test_mkdir $DIR/$tdir
17806         $LFS setstripe --stripe-count 1 $DIR/$tdir
17807
17808         check_default_stripe_attr --stripe-size
17809         check_default_stripe_attr --stripe-index
17810 }
17811 run_test 204b "Print default stripe size and offset"
17812
17813 test_204c() {
17814         test_mkdir $DIR/$tdir
17815         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17816
17817         check_default_stripe_attr --stripe-count
17818         check_default_stripe_attr --stripe-index
17819 }
17820 run_test 204c "Print default stripe count and offset"
17821
17822 test_204d() {
17823         test_mkdir $DIR/$tdir
17824         $LFS setstripe --stripe-index 0 $DIR/$tdir
17825
17826         check_default_stripe_attr --stripe-count
17827         check_default_stripe_attr --stripe-size
17828 }
17829 run_test 204d "Print default stripe count and size"
17830
17831 test_204e() {
17832         test_mkdir $DIR/$tdir
17833         $LFS setstripe -d $DIR/$tdir
17834
17835         check_default_stripe_attr --stripe-count --raw
17836         check_default_stripe_attr --stripe-size --raw
17837         check_default_stripe_attr --stripe-index --raw
17838 }
17839 run_test 204e "Print raw stripe attributes"
17840
17841 test_204f() {
17842         test_mkdir $DIR/$tdir
17843         $LFS setstripe --stripe-count 1 $DIR/$tdir
17844
17845         check_default_stripe_attr --stripe-size --raw
17846         check_default_stripe_attr --stripe-index --raw
17847 }
17848 run_test 204f "Print raw stripe size and offset"
17849
17850 test_204g() {
17851         test_mkdir $DIR/$tdir
17852         $LFS setstripe --stripe-size 65536 $DIR/$tdir
17853
17854         check_default_stripe_attr --stripe-count --raw
17855         check_default_stripe_attr --stripe-index --raw
17856 }
17857 run_test 204g "Print raw stripe count and offset"
17858
17859 test_204h() {
17860         test_mkdir $DIR/$tdir
17861         $LFS setstripe --stripe-index 0 $DIR/$tdir
17862
17863         check_default_stripe_attr --stripe-count --raw
17864         check_default_stripe_attr --stripe-size --raw
17865 }
17866 run_test 204h "Print raw stripe count and size"
17867
17868 # Figure out which job scheduler is being used, if any,
17869 # or use a fake one
17870 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
17871         JOBENV=SLURM_JOB_ID
17872 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
17873         JOBENV=LSB_JOBID
17874 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
17875         JOBENV=PBS_JOBID
17876 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
17877         JOBENV=LOADL_STEP_ID
17878 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
17879         JOBENV=JOB_ID
17880 else
17881         $LCTL list_param jobid_name > /dev/null 2>&1
17882         if [ $? -eq 0 ]; then
17883                 JOBENV=nodelocal
17884         else
17885                 JOBENV=FAKE_JOBID
17886         fi
17887 fi
17888 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
17889
17890 verify_jobstats() {
17891         local cmd=($1)
17892         shift
17893         local facets="$@"
17894
17895 # we don't really need to clear the stats for this test to work, since each
17896 # command has a unique jobid, but it makes debugging easier if needed.
17897 #       for facet in $facets; do
17898 #               local dev=$(convert_facet2label $facet)
17899 #               # clear old jobstats
17900 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
17901 #       done
17902
17903         # use a new JobID for each test, or we might see an old one
17904         [ "$JOBENV" = "FAKE_JOBID" ] &&
17905                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
17906
17907         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
17908
17909         [ "$JOBENV" = "nodelocal" ] && {
17910                 FAKE_JOBID=id.$testnum.%e.$RANDOM
17911                 $LCTL set_param jobid_name=$FAKE_JOBID
17912                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
17913         }
17914
17915         log "Test: ${cmd[*]}"
17916         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
17917
17918         if [ $JOBENV = "FAKE_JOBID" ]; then
17919                 FAKE_JOBID=$JOBVAL ${cmd[*]}
17920         else
17921                 ${cmd[*]}
17922         fi
17923
17924         # all files are created on OST0000
17925         for facet in $facets; do
17926                 local stats="*.$(convert_facet2label $facet).job_stats"
17927
17928                 # strip out libtool wrappers for in-tree executables
17929                 if [ $(do_facet $facet lctl get_param $stats |
17930                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
17931                         do_facet $facet lctl get_param $stats
17932                         error "No jobstats for $JOBVAL found on $facet::$stats"
17933                 fi
17934         done
17935 }
17936
17937 jobstats_set() {
17938         local new_jobenv=$1
17939
17940         set_persistent_param_and_check client "jobid_var" \
17941                 "$FSNAME.sys.jobid_var" $new_jobenv
17942 }
17943
17944 test_205a() { # Job stats
17945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17946         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
17947                 skip "Need MDS version with at least 2.7.1"
17948         remote_mgs_nodsh && skip "remote MGS with nodsh"
17949         remote_mds_nodsh && skip "remote MDS with nodsh"
17950         remote_ost_nodsh && skip "remote OST with nodsh"
17951         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
17952                 skip "Server doesn't support jobstats"
17953         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
17954
17955         local old_jobenv=$($LCTL get_param -n jobid_var)
17956         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
17957
17958         if [[ $PERM_CMD == *"set_param -P"* ]]; then
17959                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
17960         else
17961                 stack_trap "do_facet mgs $PERM_CMD \
17962                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
17963         fi
17964         changelog_register
17965
17966         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
17967                                 mdt.*.job_cleanup_interval | head -n 1)
17968         local new_interval=5
17969         do_facet $SINGLEMDS \
17970                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
17971         stack_trap "do_facet $SINGLEMDS \
17972                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
17973         local start=$SECONDS
17974
17975         local cmd
17976         # mkdir
17977         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
17978         verify_jobstats "$cmd" "$SINGLEMDS"
17979         # rmdir
17980         cmd="rmdir $DIR/$tdir"
17981         verify_jobstats "$cmd" "$SINGLEMDS"
17982         # mkdir on secondary MDT
17983         if [ $MDSCOUNT -gt 1 ]; then
17984                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
17985                 verify_jobstats "$cmd" "mds2"
17986         fi
17987         # mknod
17988         cmd="mknod $DIR/$tfile c 1 3"
17989         verify_jobstats "$cmd" "$SINGLEMDS"
17990         # unlink
17991         cmd="rm -f $DIR/$tfile"
17992         verify_jobstats "$cmd" "$SINGLEMDS"
17993         # create all files on OST0000 so verify_jobstats can find OST stats
17994         # open & close
17995         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
17996         verify_jobstats "$cmd" "$SINGLEMDS"
17997         # setattr
17998         cmd="touch $DIR/$tfile"
17999         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18000         # write
18001         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18002         verify_jobstats "$cmd" "ost1"
18003         # read
18004         cancel_lru_locks osc
18005         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18006         verify_jobstats "$cmd" "ost1"
18007         # truncate
18008         cmd="$TRUNCATE $DIR/$tfile 0"
18009         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18010         # rename
18011         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18012         verify_jobstats "$cmd" "$SINGLEMDS"
18013         # jobstats expiry - sleep until old stats should be expired
18014         local left=$((new_interval + 5 - (SECONDS - start)))
18015         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18016                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18017                         "0" $left
18018         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18019         verify_jobstats "$cmd" "$SINGLEMDS"
18020         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18021             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18022
18023         # Ensure that jobid are present in changelog (if supported by MDS)
18024         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18025                 changelog_dump | tail -10
18026                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18027                 [ $jobids -eq 9 ] ||
18028                         error "Wrong changelog jobid count $jobids != 9"
18029
18030                 # LU-5862
18031                 JOBENV="disable"
18032                 jobstats_set $JOBENV
18033                 touch $DIR/$tfile
18034                 changelog_dump | grep $tfile
18035                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18036                 [ $jobids -eq 0 ] ||
18037                         error "Unexpected jobids when jobid_var=$JOBENV"
18038         fi
18039
18040         # test '%j' access to environment variable - if supported
18041         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18042                 JOBENV="JOBCOMPLEX"
18043                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18044
18045                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18046         fi
18047
18048         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18049                 JOBENV="JOBCOMPLEX"
18050                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18051
18052                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18053         fi
18054
18055         # test '%j' access to per-session jobid - if supported
18056         if lctl list_param jobid_this_session > /dev/null 2>&1
18057         then
18058                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18059                 lctl set_param jobid_this_session=$USER
18060
18061                 JOBENV="JOBCOMPLEX"
18062                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18063
18064                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18065         fi
18066 }
18067 run_test 205a "Verify job stats"
18068
18069 # LU-13117, LU-13597
18070 test_205b() {
18071         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18072                 skip "Need MDS version at least 2.13.54.91"
18073
18074         job_stats="mdt.*.job_stats"
18075         $LCTL set_param $job_stats=clear
18076         # Setting jobid_var to USER might not be supported
18077         $LCTL set_param jobid_var=USER || true
18078         $LCTL set_param jobid_name="%e.%u"
18079         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18080         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18081                 grep "job_id:.*foolish" &&
18082                         error "Unexpected jobid found"
18083         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18084                 grep "open:.*min.*max.*sum" ||
18085                         error "wrong job_stats format found"
18086 }
18087 run_test 205b "Verify job stats jobid and output format"
18088
18089 # LU-13733
18090 test_205c() {
18091         $LCTL set_param llite.*.stats=0
18092         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18093         $LCTL get_param llite.*.stats
18094         $LCTL get_param llite.*.stats | grep \
18095                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18096                         error "wrong client stats format found"
18097 }
18098 run_test 205c "Verify client stats format"
18099
18100 # LU-1480, LU-1773 and LU-1657
18101 test_206() {
18102         mkdir -p $DIR/$tdir
18103         $LFS setstripe -c -1 $DIR/$tdir
18104 #define OBD_FAIL_LOV_INIT 0x1403
18105         $LCTL set_param fail_loc=0xa0001403
18106         $LCTL set_param fail_val=1
18107         touch $DIR/$tdir/$tfile || true
18108 }
18109 run_test 206 "fail lov_init_raid0() doesn't lbug"
18110
18111 test_207a() {
18112         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18113         local fsz=`stat -c %s $DIR/$tfile`
18114         cancel_lru_locks mdc
18115
18116         # do not return layout in getattr intent
18117 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18118         $LCTL set_param fail_loc=0x170
18119         local sz=`stat -c %s $DIR/$tfile`
18120
18121         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18122
18123         rm -rf $DIR/$tfile
18124 }
18125 run_test 207a "can refresh layout at glimpse"
18126
18127 test_207b() {
18128         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18129         local cksum=`md5sum $DIR/$tfile`
18130         local fsz=`stat -c %s $DIR/$tfile`
18131         cancel_lru_locks mdc
18132         cancel_lru_locks osc
18133
18134         # do not return layout in getattr intent
18135 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18136         $LCTL set_param fail_loc=0x171
18137
18138         # it will refresh layout after the file is opened but before read issues
18139         echo checksum is "$cksum"
18140         echo "$cksum" |md5sum -c --quiet || error "file differs"
18141
18142         rm -rf $DIR/$tfile
18143 }
18144 run_test 207b "can refresh layout at open"
18145
18146 test_208() {
18147         # FIXME: in this test suite, only RD lease is used. This is okay
18148         # for now as only exclusive open is supported. After generic lease
18149         # is done, this test suite should be revised. - Jinshan
18150
18151         remote_mds_nodsh && skip "remote MDS with nodsh"
18152         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18153                 skip "Need MDS version at least 2.4.52"
18154
18155         echo "==== test 1: verify get lease work"
18156         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18157
18158         echo "==== test 2: verify lease can be broken by upcoming open"
18159         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18160         local PID=$!
18161         sleep 1
18162
18163         $MULTIOP $DIR/$tfile oO_RDONLY:c
18164         kill -USR1 $PID && wait $PID || error "break lease error"
18165
18166         echo "==== test 3: verify lease can't be granted if an open already exists"
18167         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
18168         local PID=$!
18169         sleep 1
18170
18171         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
18172         kill -USR1 $PID && wait $PID || error "open file error"
18173
18174         echo "==== test 4: lease can sustain over recovery"
18175         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18176         PID=$!
18177         sleep 1
18178
18179         fail mds1
18180
18181         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18182
18183         echo "==== test 5: lease broken can't be regained by replay"
18184         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
18185         PID=$!
18186         sleep 1
18187
18188         # open file to break lease and then recovery
18189         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18190         fail mds1
18191
18192         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18193
18194         rm -f $DIR/$tfile
18195 }
18196 run_test 208 "Exclusive open"
18197
18198 test_209() {
18199         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18200                 skip_env "must have disp_stripe"
18201
18202         touch $DIR/$tfile
18203         sync; sleep 5; sync;
18204
18205         echo 3 > /proc/sys/vm/drop_caches
18206         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18207                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18208         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18209
18210         # open/close 500 times
18211         for i in $(seq 500); do
18212                 cat $DIR/$tfile
18213         done
18214
18215         echo 3 > /proc/sys/vm/drop_caches
18216         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18217                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18218         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18219
18220         echo "before: $req_before, after: $req_after"
18221         [ $((req_after - req_before)) -ge 300 ] &&
18222                 error "open/close requests are not freed"
18223         return 0
18224 }
18225 run_test 209 "read-only open/close requests should be freed promptly"
18226
18227 test_210() {
18228         local pid
18229
18230         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18231         pid=$!
18232         sleep 1
18233
18234         $LFS getstripe $DIR/$tfile
18235         kill -USR1 $pid
18236         wait $pid || error "multiop failed"
18237
18238         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18239         pid=$!
18240         sleep 1
18241
18242         $LFS getstripe $DIR/$tfile
18243         kill -USR1 $pid
18244         wait $pid || error "multiop failed"
18245 }
18246 run_test 210 "lfs getstripe does not break leases"
18247
18248 test_212() {
18249         size=`date +%s`
18250         size=$((size % 8192 + 1))
18251         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18252         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18253         rm -f $DIR/f212 $DIR/f212.xyz
18254 }
18255 run_test 212 "Sendfile test ============================================"
18256
18257 test_213() {
18258         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18259         cancel_lru_locks osc
18260         lctl set_param fail_loc=0x8000040f
18261         # generate a read lock
18262         cat $DIR/$tfile > /dev/null
18263         # write to the file, it will try to cancel the above read lock.
18264         cat /etc/hosts >> $DIR/$tfile
18265 }
18266 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18267
18268 test_214() { # for bug 20133
18269         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18270         for (( i=0; i < 340; i++ )) ; do
18271                 touch $DIR/$tdir/d214c/a$i
18272         done
18273
18274         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18275         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18276         ls $DIR/d214c || error "ls $DIR/d214c failed"
18277         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18278         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18279 }
18280 run_test 214 "hash-indexed directory test - bug 20133"
18281
18282 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18283 create_lnet_proc_files() {
18284         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18285 }
18286
18287 # counterpart of create_lnet_proc_files
18288 remove_lnet_proc_files() {
18289         rm -f $TMP/lnet_$1.sys
18290 }
18291
18292 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18293 # 3rd arg as regexp for body
18294 check_lnet_proc_stats() {
18295         local l=$(cat "$TMP/lnet_$1" |wc -l)
18296         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18297
18298         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18299 }
18300
18301 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18302 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18303 # optional and can be regexp for 2nd line (lnet.routes case)
18304 check_lnet_proc_entry() {
18305         local blp=2          # blp stands for 'position of 1st line of body'
18306         [ -z "$5" ] || blp=3 # lnet.routes case
18307
18308         local l=$(cat "$TMP/lnet_$1" |wc -l)
18309         # subtracting one from $blp because the body can be empty
18310         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18311
18312         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18313                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18314
18315         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18316                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18317
18318         # bail out if any unexpected line happened
18319         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18320         [ "$?" != 0 ] || error "$2 misformatted"
18321 }
18322
18323 test_215() { # for bugs 18102, 21079, 21517
18324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18325
18326         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18327         local P='[1-9][0-9]*'           # positive numeric
18328         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18329         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18330         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18331         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18332
18333         local L1 # regexp for 1st line
18334         local L2 # regexp for 2nd line (optional)
18335         local BR # regexp for the rest (body)
18336
18337         # lnet.stats should look as 11 space-separated non-negative numerics
18338         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18339         create_lnet_proc_files "stats"
18340         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18341         remove_lnet_proc_files "stats"
18342
18343         # lnet.routes should look like this:
18344         # Routing disabled/enabled
18345         # net hops priority state router
18346         # where net is a string like tcp0, hops > 0, priority >= 0,
18347         # state is up/down,
18348         # router is a string like 192.168.1.1@tcp2
18349         L1="^Routing (disabled|enabled)$"
18350         L2="^net +hops +priority +state +router$"
18351         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18352         create_lnet_proc_files "routes"
18353         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18354         remove_lnet_proc_files "routes"
18355
18356         # lnet.routers should look like this:
18357         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18358         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18359         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18360         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18361         L1="^ref +rtr_ref +alive +router$"
18362         BR="^$P +$P +(up|down) +$NID$"
18363         create_lnet_proc_files "routers"
18364         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18365         remove_lnet_proc_files "routers"
18366
18367         # lnet.peers should look like this:
18368         # nid refs state last max rtr min tx min queue
18369         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18370         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18371         # numeric (0 or >0 or <0), queue >= 0.
18372         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18373         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18374         create_lnet_proc_files "peers"
18375         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18376         remove_lnet_proc_files "peers"
18377
18378         # lnet.buffers  should look like this:
18379         # pages count credits min
18380         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18381         L1="^pages +count +credits +min$"
18382         BR="^ +$N +$N +$I +$I$"
18383         create_lnet_proc_files "buffers"
18384         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18385         remove_lnet_proc_files "buffers"
18386
18387         # lnet.nis should look like this:
18388         # nid status alive refs peer rtr max tx min
18389         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18390         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18391         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18392         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18393         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18394         create_lnet_proc_files "nis"
18395         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18396         remove_lnet_proc_files "nis"
18397
18398         # can we successfully write to lnet.stats?
18399         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18400 }
18401 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18402
18403 test_216() { # bug 20317
18404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18405         remote_ost_nodsh && skip "remote OST with nodsh"
18406
18407         local node
18408         local facets=$(get_facets OST)
18409         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18410
18411         save_lustre_params client "osc.*.contention_seconds" > $p
18412         save_lustre_params $facets \
18413                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18414         save_lustre_params $facets \
18415                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18416         save_lustre_params $facets \
18417                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18418         clear_stats osc.*.osc_stats
18419
18420         # agressive lockless i/o settings
18421         do_nodes $(comma_list $(osts_nodes)) \
18422                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18423                         ldlm.namespaces.filter-*.contended_locks=0 \
18424                         ldlm.namespaces.filter-*.contention_seconds=60"
18425         lctl set_param -n osc.*.contention_seconds=60
18426
18427         $DIRECTIO write $DIR/$tfile 0 10 4096
18428         $CHECKSTAT -s 40960 $DIR/$tfile
18429
18430         # disable lockless i/o
18431         do_nodes $(comma_list $(osts_nodes)) \
18432                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18433                         ldlm.namespaces.filter-*.contended_locks=32 \
18434                         ldlm.namespaces.filter-*.contention_seconds=0"
18435         lctl set_param -n osc.*.contention_seconds=0
18436         clear_stats osc.*.osc_stats
18437
18438         dd if=/dev/zero of=$DIR/$tfile count=0
18439         $CHECKSTAT -s 0 $DIR/$tfile
18440
18441         restore_lustre_params <$p
18442         rm -f $p
18443         rm $DIR/$tfile
18444 }
18445 run_test 216 "check lockless direct write updates file size and kms correctly"
18446
18447 test_217() { # bug 22430
18448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18449
18450         local node
18451         local nid
18452
18453         for node in $(nodes_list); do
18454                 nid=$(host_nids_address $node $NETTYPE)
18455                 if [[ $nid = *-* ]] ; then
18456                         echo "lctl ping $(h2nettype $nid)"
18457                         lctl ping $(h2nettype $nid)
18458                 else
18459                         echo "skipping $node (no hyphen detected)"
18460                 fi
18461         done
18462 }
18463 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18464
18465 test_218() {
18466        # do directio so as not to populate the page cache
18467        log "creating a 10 Mb file"
18468        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18469        log "starting reads"
18470        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18471        log "truncating the file"
18472        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18473        log "killing dd"
18474        kill %+ || true # reads might have finished
18475        echo "wait until dd is finished"
18476        wait
18477        log "removing the temporary file"
18478        rm -rf $DIR/$tfile || error "tmp file removal failed"
18479 }
18480 run_test 218 "parallel read and truncate should not deadlock"
18481
18482 test_219() {
18483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18484
18485         # write one partial page
18486         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18487         # set no grant so vvp_io_commit_write will do sync write
18488         $LCTL set_param fail_loc=0x411
18489         # write a full page at the end of file
18490         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18491
18492         $LCTL set_param fail_loc=0
18493         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18494         $LCTL set_param fail_loc=0x411
18495         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18496
18497         # LU-4201
18498         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18499         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18500 }
18501 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18502
18503 test_220() { #LU-325
18504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18505         remote_ost_nodsh && skip "remote OST with nodsh"
18506         remote_mds_nodsh && skip "remote MDS with nodsh"
18507         remote_mgs_nodsh && skip "remote MGS with nodsh"
18508
18509         local OSTIDX=0
18510
18511         # create on MDT0000 so the last_id and next_id are correct
18512         mkdir_on_mdt0 $DIR/$tdir
18513         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18514         OST=${OST%_UUID}
18515
18516         # on the mdt's osc
18517         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18518         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18519                         osp.$mdtosc_proc1.prealloc_last_id)
18520         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18521                         osp.$mdtosc_proc1.prealloc_next_id)
18522
18523         $LFS df -i
18524
18525         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18526         #define OBD_FAIL_OST_ENOINO              0x229
18527         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18528         create_pool $FSNAME.$TESTNAME || return 1
18529         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18530
18531         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18532
18533         MDSOBJS=$((last_id - next_id))
18534         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18535
18536         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18537         echo "OST still has $count kbytes free"
18538
18539         echo "create $MDSOBJS files @next_id..."
18540         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18541
18542         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18543                         osp.$mdtosc_proc1.prealloc_last_id)
18544         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18545                         osp.$mdtosc_proc1.prealloc_next_id)
18546
18547         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18548         $LFS df -i
18549
18550         echo "cleanup..."
18551
18552         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18553         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18554
18555         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18556                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18557         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18558                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18559         echo "unlink $MDSOBJS files @$next_id..."
18560         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18561 }
18562 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18563
18564 test_221() {
18565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18566
18567         dd if=`which date` of=$MOUNT/date oflag=sync
18568         chmod +x $MOUNT/date
18569
18570         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18571         $LCTL set_param fail_loc=0x80001401
18572
18573         $MOUNT/date > /dev/null
18574         rm -f $MOUNT/date
18575 }
18576 run_test 221 "make sure fault and truncate race to not cause OOM"
18577
18578 test_222a () {
18579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18580
18581         rm -rf $DIR/$tdir
18582         test_mkdir $DIR/$tdir
18583         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18584         createmany -o $DIR/$tdir/$tfile 10
18585         cancel_lru_locks mdc
18586         cancel_lru_locks osc
18587         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18588         $LCTL set_param fail_loc=0x31a
18589         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18590         $LCTL set_param fail_loc=0
18591         rm -r $DIR/$tdir
18592 }
18593 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18594
18595 test_222b () {
18596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18597
18598         rm -rf $DIR/$tdir
18599         test_mkdir $DIR/$tdir
18600         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18601         createmany -o $DIR/$tdir/$tfile 10
18602         cancel_lru_locks mdc
18603         cancel_lru_locks osc
18604         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18605         $LCTL set_param fail_loc=0x31a
18606         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18607         $LCTL set_param fail_loc=0
18608 }
18609 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18610
18611 test_223 () {
18612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18613
18614         rm -rf $DIR/$tdir
18615         test_mkdir $DIR/$tdir
18616         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18617         createmany -o $DIR/$tdir/$tfile 10
18618         cancel_lru_locks mdc
18619         cancel_lru_locks osc
18620         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18621         $LCTL set_param fail_loc=0x31b
18622         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18623         $LCTL set_param fail_loc=0
18624         rm -r $DIR/$tdir
18625 }
18626 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18627
18628 test_224a() { # LU-1039, MRP-303
18629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18630
18631         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18632         $LCTL set_param fail_loc=0x508
18633         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
18634         $LCTL set_param fail_loc=0
18635         df $DIR
18636 }
18637 run_test 224a "Don't panic on bulk IO failure"
18638
18639 test_224b() { # LU-1039, MRP-303
18640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18641
18642         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
18643         cancel_lru_locks osc
18644         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18645         $LCTL set_param fail_loc=0x515
18646         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
18647         $LCTL set_param fail_loc=0
18648         df $DIR
18649 }
18650 run_test 224b "Don't panic on bulk IO failure"
18651
18652 test_224c() { # LU-6441
18653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18654         remote_mds_nodsh && skip "remote MDS with nodsh"
18655
18656         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18657         save_writethrough $p
18658         set_cache writethrough on
18659
18660         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18661         local at_max=$($LCTL get_param -n at_max)
18662         local timeout=$($LCTL get_param -n timeout)
18663         local test_at="at_max"
18664         local param_at="$FSNAME.sys.at_max"
18665         local test_timeout="timeout"
18666         local param_timeout="$FSNAME.sys.timeout"
18667
18668         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18669
18670         set_persistent_param_and_check client "$test_at" "$param_at" 0
18671         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18672
18673         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18674         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18675         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18676         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18677         sync
18678         do_facet ost1 "$LCTL set_param fail_loc=0"
18679
18680         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18681         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18682                 $timeout
18683
18684         $LCTL set_param -n $pages_per_rpc
18685         restore_lustre_params < $p
18686         rm -f $p
18687 }
18688 run_test 224c "Don't hang if one of md lost during large bulk RPC"
18689
18690 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
18691 test_225a () {
18692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18693         if [ -z ${MDSSURVEY} ]; then
18694                 skip_env "mds-survey not found"
18695         fi
18696         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18697                 skip "Need MDS version at least 2.2.51"
18698
18699         local mds=$(facet_host $SINGLEMDS)
18700         local target=$(do_nodes $mds 'lctl dl' |
18701                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18702
18703         local cmd1="file_count=1000 thrhi=4"
18704         local cmd2="dir_count=2 layer=mdd stripe_count=0"
18705         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18706         local cmd="$cmd1 $cmd2 $cmd3"
18707
18708         rm -f ${TMP}/mds_survey*
18709         echo + $cmd
18710         eval $cmd || error "mds-survey with zero-stripe failed"
18711         cat ${TMP}/mds_survey*
18712         rm -f ${TMP}/mds_survey*
18713 }
18714 run_test 225a "Metadata survey sanity with zero-stripe"
18715
18716 test_225b () {
18717         if [ -z ${MDSSURVEY} ]; then
18718                 skip_env "mds-survey not found"
18719         fi
18720         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
18721                 skip "Need MDS version at least 2.2.51"
18722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18723         remote_mds_nodsh && skip "remote MDS with nodsh"
18724         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
18725                 skip_env "Need to mount OST to test"
18726         fi
18727
18728         local mds=$(facet_host $SINGLEMDS)
18729         local target=$(do_nodes $mds 'lctl dl' |
18730                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
18731
18732         local cmd1="file_count=1000 thrhi=4"
18733         local cmd2="dir_count=2 layer=mdd stripe_count=1"
18734         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
18735         local cmd="$cmd1 $cmd2 $cmd3"
18736
18737         rm -f ${TMP}/mds_survey*
18738         echo + $cmd
18739         eval $cmd || error "mds-survey with stripe_count failed"
18740         cat ${TMP}/mds_survey*
18741         rm -f ${TMP}/mds_survey*
18742 }
18743 run_test 225b "Metadata survey sanity with stripe_count = 1"
18744
18745 mcreate_path2fid () {
18746         local mode=$1
18747         local major=$2
18748         local minor=$3
18749         local name=$4
18750         local desc=$5
18751         local path=$DIR/$tdir/$name
18752         local fid
18753         local rc
18754         local fid_path
18755
18756         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
18757                 error "cannot create $desc"
18758
18759         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
18760         rc=$?
18761         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
18762
18763         fid_path=$($LFS fid2path $MOUNT $fid)
18764         rc=$?
18765         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
18766
18767         [ "$path" == "$fid_path" ] ||
18768                 error "fid2path returned $fid_path, expected $path"
18769
18770         echo "pass with $path and $fid"
18771 }
18772
18773 test_226a () {
18774         rm -rf $DIR/$tdir
18775         mkdir -p $DIR/$tdir
18776
18777         mcreate_path2fid 0010666 0 0 fifo "FIFO"
18778         mcreate_path2fid 0020666 1 3 null "character special file (null)"
18779         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
18780         mcreate_path2fid 0040666 0 0 dir "directory"
18781         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
18782         mcreate_path2fid 0100666 0 0 file "regular file"
18783         mcreate_path2fid 0120666 0 0 link "symbolic link"
18784         mcreate_path2fid 0140666 0 0 sock "socket"
18785 }
18786 run_test 226a "call path2fid and fid2path on files of all type"
18787
18788 test_226b () {
18789         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18790
18791         local MDTIDX=1
18792
18793         rm -rf $DIR/$tdir
18794         mkdir -p $DIR/$tdir
18795         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
18796                 error "create remote directory failed"
18797         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
18798         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
18799                                 "character special file (null)"
18800         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
18801                                 "character special file (no device)"
18802         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
18803         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
18804                                 "block special file (loop)"
18805         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
18806         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
18807         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
18808 }
18809 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
18810
18811 test_226c () {
18812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18813         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18814                 skip "Need MDS version at least 2.13.55"
18815
18816         local submnt=/mnt/submnt
18817         local srcfile=/etc/passwd
18818         local dstfile=$submnt/passwd
18819         local path
18820         local fid
18821
18822         rm -rf $DIR/$tdir
18823         rm -rf $submnt
18824         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
18825                 error "create remote directory failed"
18826         mkdir -p $submnt || error "create $submnt failed"
18827         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
18828                 error "mount $submnt failed"
18829         stack_trap "umount $submnt" EXIT
18830
18831         cp $srcfile $dstfile
18832         fid=$($LFS path2fid $dstfile)
18833         path=$($LFS fid2path $submnt "$fid")
18834         [ "$path" = "$dstfile" ] ||
18835                 error "fid2path $submnt $fid failed ($path != $dstfile)"
18836 }
18837 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
18838
18839 # LU-1299 Executing or running ldd on a truncated executable does not
18840 # cause an out-of-memory condition.
18841 test_227() {
18842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18843         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
18844
18845         dd if=$(which date) of=$MOUNT/date bs=1k count=1
18846         chmod +x $MOUNT/date
18847
18848         $MOUNT/date > /dev/null
18849         ldd $MOUNT/date > /dev/null
18850         rm -f $MOUNT/date
18851 }
18852 run_test 227 "running truncated executable does not cause OOM"
18853
18854 # LU-1512 try to reuse idle OI blocks
18855 test_228a() {
18856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18857         remote_mds_nodsh && skip "remote MDS with nodsh"
18858         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18859
18860         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18861         local myDIR=$DIR/$tdir
18862
18863         mkdir -p $myDIR
18864         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18865         $LCTL set_param fail_loc=0x80001002
18866         createmany -o $myDIR/t- 10000
18867         $LCTL set_param fail_loc=0
18868         # The guard is current the largest FID holder
18869         touch $myDIR/guard
18870         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18871                     tr -d '[')
18872         local IDX=$(($SEQ % 64))
18873
18874         do_facet $SINGLEMDS sync
18875         # Make sure journal flushed.
18876         sleep 6
18877         local blk1=$(do_facet $SINGLEMDS \
18878                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18879                      grep Blockcount | awk '{print $4}')
18880
18881         # Remove old files, some OI blocks will become idle.
18882         unlinkmany $myDIR/t- 10000
18883         # Create new files, idle OI blocks should be reused.
18884         createmany -o $myDIR/t- 2000
18885         do_facet $SINGLEMDS sync
18886         # Make sure journal flushed.
18887         sleep 6
18888         local blk2=$(do_facet $SINGLEMDS \
18889                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18890                      grep Blockcount | awk '{print $4}')
18891
18892         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18893 }
18894 run_test 228a "try to reuse idle OI blocks"
18895
18896 test_228b() {
18897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18898         remote_mds_nodsh && skip "remote MDS with nodsh"
18899         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18900
18901         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18902         local myDIR=$DIR/$tdir
18903
18904         mkdir -p $myDIR
18905         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18906         $LCTL set_param fail_loc=0x80001002
18907         createmany -o $myDIR/t- 10000
18908         $LCTL set_param fail_loc=0
18909         # The guard is current the largest FID holder
18910         touch $myDIR/guard
18911         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18912                     tr -d '[')
18913         local IDX=$(($SEQ % 64))
18914
18915         do_facet $SINGLEMDS sync
18916         # Make sure journal flushed.
18917         sleep 6
18918         local blk1=$(do_facet $SINGLEMDS \
18919                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18920                      grep Blockcount | awk '{print $4}')
18921
18922         # Remove old files, some OI blocks will become idle.
18923         unlinkmany $myDIR/t- 10000
18924
18925         # stop the MDT
18926         stop $SINGLEMDS || error "Fail to stop MDT."
18927         # remount the MDT
18928         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
18929
18930         df $MOUNT || error "Fail to df."
18931         # Create new files, idle OI blocks should be reused.
18932         createmany -o $myDIR/t- 2000
18933         do_facet $SINGLEMDS sync
18934         # Make sure journal flushed.
18935         sleep 6
18936         local blk2=$(do_facet $SINGLEMDS \
18937                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18938                      grep Blockcount | awk '{print $4}')
18939
18940         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18941 }
18942 run_test 228b "idle OI blocks can be reused after MDT restart"
18943
18944 #LU-1881
18945 test_228c() {
18946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18947         remote_mds_nodsh && skip "remote MDS with nodsh"
18948         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
18949
18950         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
18951         local myDIR=$DIR/$tdir
18952
18953         mkdir -p $myDIR
18954         #define OBD_FAIL_SEQ_EXHAUST             0x1002
18955         $LCTL set_param fail_loc=0x80001002
18956         # 20000 files can guarantee there are index nodes in the OI file
18957         createmany -o $myDIR/t- 20000
18958         $LCTL set_param fail_loc=0
18959         # The guard is current the largest FID holder
18960         touch $myDIR/guard
18961         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
18962                     tr -d '[')
18963         local IDX=$(($SEQ % 64))
18964
18965         do_facet $SINGLEMDS sync
18966         # Make sure journal flushed.
18967         sleep 6
18968         local blk1=$(do_facet $SINGLEMDS \
18969                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18970                      grep Blockcount | awk '{print $4}')
18971
18972         # Remove old files, some OI blocks will become idle.
18973         unlinkmany $myDIR/t- 20000
18974         rm -f $myDIR/guard
18975         # The OI file should become empty now
18976
18977         # Create new files, idle OI blocks should be reused.
18978         createmany -o $myDIR/t- 2000
18979         do_facet $SINGLEMDS sync
18980         # Make sure journal flushed.
18981         sleep 6
18982         local blk2=$(do_facet $SINGLEMDS \
18983                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
18984                      grep Blockcount | awk '{print $4}')
18985
18986         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
18987 }
18988 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
18989
18990 test_229() { # LU-2482, LU-3448
18991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18992         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
18993         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
18994                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
18995
18996         rm -f $DIR/$tfile
18997
18998         # Create a file with a released layout and stripe count 2.
18999         $MULTIOP $DIR/$tfile H2c ||
19000                 error "failed to create file with released layout"
19001
19002         $LFS getstripe -v $DIR/$tfile
19003
19004         local pattern=$($LFS getstripe -L $DIR/$tfile)
19005         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19006
19007         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19008                 error "getstripe"
19009         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19010         stat $DIR/$tfile || error "failed to stat released file"
19011
19012         chown $RUNAS_ID $DIR/$tfile ||
19013                 error "chown $RUNAS_ID $DIR/$tfile failed"
19014
19015         chgrp $RUNAS_ID $DIR/$tfile ||
19016                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19017
19018         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19019         rm $DIR/$tfile || error "failed to remove released file"
19020 }
19021 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19022
19023 test_230a() {
19024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19025         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19026         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19027                 skip "Need MDS version at least 2.11.52"
19028
19029         local MDTIDX=1
19030
19031         test_mkdir $DIR/$tdir
19032         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19033         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19034         [ $mdt_idx -ne 0 ] &&
19035                 error "create local directory on wrong MDT $mdt_idx"
19036
19037         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19038                         error "create remote directory failed"
19039         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19040         [ $mdt_idx -ne $MDTIDX ] &&
19041                 error "create remote directory on wrong MDT $mdt_idx"
19042
19043         createmany -o $DIR/$tdir/test_230/t- 10 ||
19044                 error "create files on remote directory failed"
19045         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19046         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19047         rm -r $DIR/$tdir || error "unlink remote directory failed"
19048 }
19049 run_test 230a "Create remote directory and files under the remote directory"
19050
19051 test_230b() {
19052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19053         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19054         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19055                 skip "Need MDS version at least 2.11.52"
19056
19057         local MDTIDX=1
19058         local mdt_index
19059         local i
19060         local file
19061         local pid
19062         local stripe_count
19063         local migrate_dir=$DIR/$tdir/migrate_dir
19064         local other_dir=$DIR/$tdir/other_dir
19065
19066         test_mkdir $DIR/$tdir
19067         test_mkdir -i0 -c1 $migrate_dir
19068         test_mkdir -i0 -c1 $other_dir
19069         for ((i=0; i<10; i++)); do
19070                 mkdir -p $migrate_dir/dir_${i}
19071                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19072                         error "create files under remote dir failed $i"
19073         done
19074
19075         cp /etc/passwd $migrate_dir/$tfile
19076         cp /etc/passwd $other_dir/$tfile
19077         chattr +SAD $migrate_dir
19078         chattr +SAD $migrate_dir/$tfile
19079
19080         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19081         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19082         local old_dir_mode=$(stat -c%f $migrate_dir)
19083         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19084
19085         mkdir -p $migrate_dir/dir_default_stripe2
19086         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19087         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19088
19089         mkdir -p $other_dir
19090         ln $migrate_dir/$tfile $other_dir/luna
19091         ln $migrate_dir/$tfile $migrate_dir/sofia
19092         ln $other_dir/$tfile $migrate_dir/david
19093         ln -s $migrate_dir/$tfile $other_dir/zachary
19094         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19095         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19096
19097         local len
19098         local lnktgt
19099
19100         # inline symlink
19101         for len in 58 59 60; do
19102                 lnktgt=$(str_repeat 'l' $len)
19103                 touch $migrate_dir/$lnktgt
19104                 ln -s $lnktgt $migrate_dir/${len}char_ln
19105         done
19106
19107         # PATH_MAX
19108         for len in 4094 4095; do
19109                 lnktgt=$(str_repeat 'l' $len)
19110                 ln -s $lnktgt $migrate_dir/${len}char_ln
19111         done
19112
19113         # NAME_MAX
19114         for len in 254 255; do
19115                 touch $migrate_dir/$(str_repeat 'l' $len)
19116         done
19117
19118         $LFS migrate -m $MDTIDX $migrate_dir ||
19119                 error "fails on migrating remote dir to MDT1"
19120
19121         echo "migratate to MDT1, then checking.."
19122         for ((i = 0; i < 10; i++)); do
19123                 for file in $(find $migrate_dir/dir_${i}); do
19124                         mdt_index=$($LFS getstripe -m $file)
19125                         # broken symlink getstripe will fail
19126                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19127                                 error "$file is not on MDT${MDTIDX}"
19128                 done
19129         done
19130
19131         # the multiple link file should still in MDT0
19132         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19133         [ $mdt_index == 0 ] ||
19134                 error "$file is not on MDT${MDTIDX}"
19135
19136         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19137         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19138                 error " expect $old_dir_flag get $new_dir_flag"
19139
19140         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19141         [ "$old_file_flag" = "$new_file_flag" ] ||
19142                 error " expect $old_file_flag get $new_file_flag"
19143
19144         local new_dir_mode=$(stat -c%f $migrate_dir)
19145         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19146                 error "expect mode $old_dir_mode get $new_dir_mode"
19147
19148         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19149         [ "$old_file_mode" = "$new_file_mode" ] ||
19150                 error "expect mode $old_file_mode get $new_file_mode"
19151
19152         diff /etc/passwd $migrate_dir/$tfile ||
19153                 error "$tfile different after migration"
19154
19155         diff /etc/passwd $other_dir/luna ||
19156                 error "luna different after migration"
19157
19158         diff /etc/passwd $migrate_dir/sofia ||
19159                 error "sofia different after migration"
19160
19161         diff /etc/passwd $migrate_dir/david ||
19162                 error "david different after migration"
19163
19164         diff /etc/passwd $other_dir/zachary ||
19165                 error "zachary different after migration"
19166
19167         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19168                 error "${tfile}_ln different after migration"
19169
19170         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19171                 error "${tfile}_ln_other different after migration"
19172
19173         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19174         [ $stripe_count = 2 ] ||
19175                 error "dir strpe_count $d != 2 after migration."
19176
19177         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19178         [ $stripe_count = 2 ] ||
19179                 error "file strpe_count $d != 2 after migration."
19180
19181         #migrate back to MDT0
19182         MDTIDX=0
19183
19184         $LFS migrate -m $MDTIDX $migrate_dir ||
19185                 error "fails on migrating remote dir to MDT0"
19186
19187         echo "migrate back to MDT0, checking.."
19188         for file in $(find $migrate_dir); do
19189                 mdt_index=$($LFS getstripe -m $file)
19190                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19191                         error "$file is not on MDT${MDTIDX}"
19192         done
19193
19194         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19195         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19196                 error " expect $old_dir_flag get $new_dir_flag"
19197
19198         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19199         [ "$old_file_flag" = "$new_file_flag" ] ||
19200                 error " expect $old_file_flag get $new_file_flag"
19201
19202         local new_dir_mode=$(stat -c%f $migrate_dir)
19203         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19204                 error "expect mode $old_dir_mode get $new_dir_mode"
19205
19206         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19207         [ "$old_file_mode" = "$new_file_mode" ] ||
19208                 error "expect mode $old_file_mode get $new_file_mode"
19209
19210         diff /etc/passwd ${migrate_dir}/$tfile ||
19211                 error "$tfile different after migration"
19212
19213         diff /etc/passwd ${other_dir}/luna ||
19214                 error "luna different after migration"
19215
19216         diff /etc/passwd ${migrate_dir}/sofia ||
19217                 error "sofia different after migration"
19218
19219         diff /etc/passwd ${other_dir}/zachary ||
19220                 error "zachary different after migration"
19221
19222         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19223                 error "${tfile}_ln different after migration"
19224
19225         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19226                 error "${tfile}_ln_other different after migration"
19227
19228         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19229         [ $stripe_count = 2 ] ||
19230                 error "dir strpe_count $d != 2 after migration."
19231
19232         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19233         [ $stripe_count = 2 ] ||
19234                 error "file strpe_count $d != 2 after migration."
19235
19236         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19237 }
19238 run_test 230b "migrate directory"
19239
19240 test_230c() {
19241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19243         remote_mds_nodsh && skip "remote MDS with nodsh"
19244         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19245                 skip "Need MDS version at least 2.11.52"
19246
19247         local MDTIDX=1
19248         local total=3
19249         local mdt_index
19250         local file
19251         local migrate_dir=$DIR/$tdir/migrate_dir
19252
19253         #If migrating directory fails in the middle, all entries of
19254         #the directory is still accessiable.
19255         test_mkdir $DIR/$tdir
19256         test_mkdir -i0 -c1 $migrate_dir
19257         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19258         stat $migrate_dir
19259         createmany -o $migrate_dir/f $total ||
19260                 error "create files under ${migrate_dir} failed"
19261
19262         # fail after migrating top dir, and this will fail only once, so the
19263         # first sub file migration will fail (currently f3), others succeed.
19264         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19265         do_facet mds1 lctl set_param fail_loc=0x1801
19266         local t=$(ls $migrate_dir | wc -l)
19267         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19268                 error "migrate should fail"
19269         local u=$(ls $migrate_dir | wc -l)
19270         [ "$u" == "$t" ] || error "$u != $t during migration"
19271
19272         # add new dir/file should succeed
19273         mkdir $migrate_dir/dir ||
19274                 error "mkdir failed under migrating directory"
19275         touch $migrate_dir/file ||
19276                 error "create file failed under migrating directory"
19277
19278         # add file with existing name should fail
19279         for file in $migrate_dir/f*; do
19280                 stat $file > /dev/null || error "stat $file failed"
19281                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19282                         error "open(O_CREAT|O_EXCL) $file should fail"
19283                 $MULTIOP $file m && error "create $file should fail"
19284                 touch $DIR/$tdir/remote_dir/$tfile ||
19285                         error "touch $tfile failed"
19286                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19287                         error "link $file should fail"
19288                 mdt_index=$($LFS getstripe -m $file)
19289                 if [ $mdt_index == 0 ]; then
19290                         # file failed to migrate is not allowed to rename to
19291                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19292                                 error "rename to $file should fail"
19293                 else
19294                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19295                                 error "rename to $file failed"
19296                 fi
19297                 echo hello >> $file || error "write $file failed"
19298         done
19299
19300         # resume migration with different options should fail
19301         $LFS migrate -m 0 $migrate_dir &&
19302                 error "migrate -m 0 $migrate_dir should fail"
19303
19304         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19305                 error "migrate -c 2 $migrate_dir should fail"
19306
19307         # resume migration should succeed
19308         $LFS migrate -m $MDTIDX $migrate_dir ||
19309                 error "migrate $migrate_dir failed"
19310
19311         echo "Finish migration, then checking.."
19312         for file in $(find $migrate_dir); do
19313                 mdt_index=$($LFS getstripe -m $file)
19314                 [ $mdt_index == $MDTIDX ] ||
19315                         error "$file is not on MDT${MDTIDX}"
19316         done
19317
19318         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19319 }
19320 run_test 230c "check directory accessiblity if migration failed"
19321
19322 test_230d() {
19323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19324         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19325         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19326                 skip "Need MDS version at least 2.11.52"
19327         # LU-11235
19328         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19329
19330         local migrate_dir=$DIR/$tdir/migrate_dir
19331         local old_index
19332         local new_index
19333         local old_count
19334         local new_count
19335         local new_hash
19336         local mdt_index
19337         local i
19338         local j
19339
19340         old_index=$((RANDOM % MDSCOUNT))
19341         old_count=$((MDSCOUNT - old_index))
19342         new_index=$((RANDOM % MDSCOUNT))
19343         new_count=$((MDSCOUNT - new_index))
19344         new_hash=1 # for all_char
19345
19346         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19347         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19348
19349         test_mkdir $DIR/$tdir
19350         test_mkdir -i $old_index -c $old_count $migrate_dir
19351
19352         for ((i=0; i<100; i++)); do
19353                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19354                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19355                         error "create files under remote dir failed $i"
19356         done
19357
19358         echo -n "Migrate from MDT$old_index "
19359         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19360         echo -n "to MDT$new_index"
19361         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19362         echo
19363
19364         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19365         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19366                 error "migrate remote dir error"
19367
19368         echo "Finish migration, then checking.."
19369         for file in $(find $migrate_dir); do
19370                 mdt_index=$($LFS getstripe -m $file)
19371                 if [ $mdt_index -lt $new_index ] ||
19372                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19373                         error "$file is on MDT$mdt_index"
19374                 fi
19375         done
19376
19377         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19378 }
19379 run_test 230d "check migrate big directory"
19380
19381 test_230e() {
19382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19383         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19384         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19385                 skip "Need MDS version at least 2.11.52"
19386
19387         local i
19388         local j
19389         local a_fid
19390         local b_fid
19391
19392         mkdir_on_mdt0 $DIR/$tdir
19393         mkdir $DIR/$tdir/migrate_dir
19394         mkdir $DIR/$tdir/other_dir
19395         touch $DIR/$tdir/migrate_dir/a
19396         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19397         ls $DIR/$tdir/other_dir
19398
19399         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19400                 error "migrate dir fails"
19401
19402         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19403         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19404
19405         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19406         [ $mdt_index == 0 ] || error "a is not on MDT0"
19407
19408         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19409                 error "migrate dir fails"
19410
19411         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19412         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19413
19414         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19415         [ $mdt_index == 1 ] || error "a is not on MDT1"
19416
19417         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19418         [ $mdt_index == 1 ] || error "b is not on MDT1"
19419
19420         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19421         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19422
19423         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19424
19425         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19426 }
19427 run_test 230e "migrate mulitple local link files"
19428
19429 test_230f() {
19430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19432         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19433                 skip "Need MDS version at least 2.11.52"
19434
19435         local a_fid
19436         local ln_fid
19437
19438         mkdir -p $DIR/$tdir
19439         mkdir $DIR/$tdir/migrate_dir
19440         $LFS mkdir -i1 $DIR/$tdir/other_dir
19441         touch $DIR/$tdir/migrate_dir/a
19442         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19443         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19444         ls $DIR/$tdir/other_dir
19445
19446         # a should be migrated to MDT1, since no other links on MDT0
19447         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19448                 error "#1 migrate dir fails"
19449         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19450         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19451         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19452         [ $mdt_index == 1 ] || error "a is not on MDT1"
19453
19454         # a should stay on MDT1, because it is a mulitple link file
19455         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19456                 error "#2 migrate dir fails"
19457         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19458         [ $mdt_index == 1 ] || error "a is not on MDT1"
19459
19460         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19461                 error "#3 migrate dir fails"
19462
19463         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19464         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19465         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19466
19467         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19468         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19469
19470         # a should be migrated to MDT0, since no other links on MDT1
19471         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19472                 error "#4 migrate dir fails"
19473         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19474         [ $mdt_index == 0 ] || error "a is not on MDT0"
19475
19476         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19477 }
19478 run_test 230f "migrate mulitple remote link files"
19479
19480 test_230g() {
19481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19483         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19484                 skip "Need MDS version at least 2.11.52"
19485
19486         mkdir -p $DIR/$tdir/migrate_dir
19487
19488         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19489                 error "migrating dir to non-exist MDT succeeds"
19490         true
19491 }
19492 run_test 230g "migrate dir to non-exist MDT"
19493
19494 test_230h() {
19495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19497         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19498                 skip "Need MDS version at least 2.11.52"
19499
19500         local mdt_index
19501
19502         mkdir -p $DIR/$tdir/migrate_dir
19503
19504         $LFS migrate -m1 $DIR &&
19505                 error "migrating mountpoint1 should fail"
19506
19507         $LFS migrate -m1 $DIR/$tdir/.. &&
19508                 error "migrating mountpoint2 should fail"
19509
19510         # same as mv
19511         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19512                 error "migrating $tdir/migrate_dir/.. should fail"
19513
19514         true
19515 }
19516 run_test 230h "migrate .. and root"
19517
19518 test_230i() {
19519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19521         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19522                 skip "Need MDS version at least 2.11.52"
19523
19524         mkdir -p $DIR/$tdir/migrate_dir
19525
19526         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19527                 error "migration fails with a tailing slash"
19528
19529         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19530                 error "migration fails with two tailing slashes"
19531 }
19532 run_test 230i "lfs migrate -m tolerates trailing slashes"
19533
19534 test_230j() {
19535         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19536         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19537                 skip "Need MDS version at least 2.11.52"
19538
19539         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19540         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19541                 error "create $tfile failed"
19542         cat /etc/passwd > $DIR/$tdir/$tfile
19543
19544         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19545
19546         cmp /etc/passwd $DIR/$tdir/$tfile ||
19547                 error "DoM file mismatch after migration"
19548 }
19549 run_test 230j "DoM file data not changed after dir migration"
19550
19551 test_230k() {
19552         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19553         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19554                 skip "Need MDS version at least 2.11.56"
19555
19556         local total=20
19557         local files_on_starting_mdt=0
19558
19559         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19560         $LFS getdirstripe $DIR/$tdir
19561         for i in $(seq $total); do
19562                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19563                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19564                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19565         done
19566
19567         echo "$files_on_starting_mdt files on MDT0"
19568
19569         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19570         $LFS getdirstripe $DIR/$tdir
19571
19572         files_on_starting_mdt=0
19573         for i in $(seq $total); do
19574                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19575                         error "file $tfile.$i mismatch after migration"
19576                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19577                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19578         done
19579
19580         echo "$files_on_starting_mdt files on MDT1 after migration"
19581         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19582
19583         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19584         $LFS getdirstripe $DIR/$tdir
19585
19586         files_on_starting_mdt=0
19587         for i in $(seq $total); do
19588                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19589                         error "file $tfile.$i mismatch after 2nd migration"
19590                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19591                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19592         done
19593
19594         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19595         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19596
19597         true
19598 }
19599 run_test 230k "file data not changed after dir migration"
19600
19601 test_230l() {
19602         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19603         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19604                 skip "Need MDS version at least 2.11.56"
19605
19606         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19607         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19608                 error "create files under remote dir failed $i"
19609         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19610 }
19611 run_test 230l "readdir between MDTs won't crash"
19612
19613 test_230m() {
19614         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19615         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19616                 skip "Need MDS version at least 2.11.56"
19617
19618         local MDTIDX=1
19619         local mig_dir=$DIR/$tdir/migrate_dir
19620         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19621         local shortstr="b"
19622         local val
19623
19624         echo "Creating files and dirs with xattrs"
19625         test_mkdir $DIR/$tdir
19626         test_mkdir -i0 -c1 $mig_dir
19627         mkdir $mig_dir/dir
19628         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19629                 error "cannot set xattr attr1 on dir"
19630         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19631                 error "cannot set xattr attr2 on dir"
19632         touch $mig_dir/dir/f0
19633         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19634                 error "cannot set xattr attr1 on file"
19635         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19636                 error "cannot set xattr attr2 on file"
19637         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19638         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19639         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19640         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19641         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19642         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19643         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19644         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19645         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19646
19647         echo "Migrating to MDT1"
19648         $LFS migrate -m $MDTIDX $mig_dir ||
19649                 error "fails on migrating dir to MDT1"
19650
19651         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19652         echo "Checking xattrs"
19653         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19654         [ "$val" = $longstr ] ||
19655                 error "expecting xattr1 $longstr on dir, found $val"
19656         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19657         [ "$val" = $shortstr ] ||
19658                 error "expecting xattr2 $shortstr on dir, found $val"
19659         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19660         [ "$val" = $longstr ] ||
19661                 error "expecting xattr1 $longstr on file, found $val"
19662         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19663         [ "$val" = $shortstr ] ||
19664                 error "expecting xattr2 $shortstr on file, found $val"
19665 }
19666 run_test 230m "xattrs not changed after dir migration"
19667
19668 test_230n() {
19669         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19670         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19671                 skip "Need MDS version at least 2.13.53"
19672
19673         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19674         cat /etc/hosts > $DIR/$tdir/$tfile
19675         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19676         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19677
19678         cmp /etc/hosts $DIR/$tdir/$tfile ||
19679                 error "File data mismatch after migration"
19680 }
19681 run_test 230n "Dir migration with mirrored file"
19682
19683 test_230o() {
19684         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
19685         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19686                 skip "Need MDS version at least 2.13.52"
19687
19688         local mdts=$(comma_list $(mdts_nodes))
19689         local timeout=100
19690         local restripe_status
19691         local delta
19692         local i
19693
19694         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19695
19696         # in case "crush" hash type is not set
19697         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19698
19699         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19700                            mdt.*MDT0000.enable_dir_restripe)
19701         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19702         stack_trap "do_nodes $mdts $LCTL set_param \
19703                     mdt.*.enable_dir_restripe=$restripe_status"
19704
19705         mkdir $DIR/$tdir
19706         createmany -m $DIR/$tdir/f 100 ||
19707                 error "create files under remote dir failed $i"
19708         createmany -d $DIR/$tdir/d 100 ||
19709                 error "create dirs under remote dir failed $i"
19710
19711         for i in $(seq 2 $MDSCOUNT); do
19712                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19713                 $LFS setdirstripe -c $i $DIR/$tdir ||
19714                         error "split -c $i $tdir failed"
19715                 wait_update $HOSTNAME \
19716                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
19717                         error "dir split not finished"
19718                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19719                         awk '/migrate/ {sum += $2} END { print sum }')
19720                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
19721                 # delta is around total_files/stripe_count
19722                 (( $delta < 200 / (i - 1) + 4 )) ||
19723                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
19724         done
19725 }
19726 run_test 230o "dir split"
19727
19728 test_230p() {
19729         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
19730         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19731                 skip "Need MDS version at least 2.13.52"
19732
19733         local mdts=$(comma_list $(mdts_nodes))
19734         local timeout=100
19735         local restripe_status
19736         local delta
19737         local c
19738
19739         [[ $mds1_FSTYPE == zfs ]] && timeout=300
19740
19741         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19742
19743         restripe_status=$(do_facet mds1 $LCTL get_param -n \
19744                            mdt.*MDT0000.enable_dir_restripe)
19745         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
19746         stack_trap "do_nodes $mdts $LCTL set_param \
19747                     mdt.*.enable_dir_restripe=$restripe_status"
19748
19749         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
19750         createmany -m $DIR/$tdir/f 100 ||
19751                 error "create files under remote dir failed"
19752         createmany -d $DIR/$tdir/d 100 ||
19753                 error "create dirs under remote dir failed"
19754
19755         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
19756                 local mdt_hash="crush"
19757
19758                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
19759                 $LFS setdirstripe -c $c $DIR/$tdir ||
19760                         error "split -c $c $tdir failed"
19761                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
19762                         mdt_hash="$mdt_hash,fixed"
19763                 elif [ $c -eq 1 ]; then
19764                         mdt_hash="none"
19765                 fi
19766                 wait_update $HOSTNAME \
19767                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
19768                         error "dir merge not finished"
19769                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
19770                         awk '/migrate/ {sum += $2} END { print sum }')
19771                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
19772                 # delta is around total_files/stripe_count
19773                 (( delta < 200 / c + 4 )) ||
19774                         error "$delta files migrated >= $((200 / c + 4))"
19775         done
19776 }
19777 run_test 230p "dir merge"
19778
19779 test_230q() {
19780         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
19781         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
19782                 skip "Need MDS version at least 2.13.52"
19783
19784         local mdts=$(comma_list $(mdts_nodes))
19785         local saved_threshold=$(do_facet mds1 \
19786                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
19787         local saved_delta=$(do_facet mds1 \
19788                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
19789         local threshold=100
19790         local delta=2
19791         local total=0
19792         local stripe_count=0
19793         local stripe_index
19794         local nr_files
19795         local create
19796
19797         # test with fewer files on ZFS
19798         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
19799
19800         stack_trap "do_nodes $mdts $LCTL set_param \
19801                     mdt.*.dir_split_count=$saved_threshold"
19802         stack_trap "do_nodes $mdts $LCTL set_param \
19803                     mdt.*.dir_split_delta=$saved_delta"
19804         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
19805         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
19806         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
19807         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
19808         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
19809         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
19810
19811         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19812         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19813
19814         create=$((threshold * 3 / 2))
19815         while [ $stripe_count -lt $MDSCOUNT ]; do
19816                 createmany -m $DIR/$tdir/f $total $create ||
19817                         error "create sub files failed"
19818                 stat $DIR/$tdir > /dev/null
19819                 total=$((total + create))
19820                 stripe_count=$((stripe_count + delta))
19821                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
19822
19823                 wait_update $HOSTNAME \
19824                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
19825                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
19826
19827                 wait_update $HOSTNAME \
19828                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
19829                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
19830
19831                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
19832                 echo "$nr_files/$total files on MDT$stripe_index after split"
19833                 # allow 10% margin of imbalance with crush hash
19834                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
19835                         error "$nr_files files on MDT$stripe_index after split"
19836
19837                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
19838                 [ $nr_files -eq $total ] ||
19839                         error "total sub files $nr_files != $total"
19840         done
19841
19842         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
19843
19844         echo "fixed layout directory won't auto split"
19845         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
19846         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
19847                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
19848         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
19849                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
19850 }
19851 run_test 230q "dir auto split"
19852
19853 test_230r() {
19854         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
19855         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19856         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
19857                 skip "Need MDS version at least 2.13.54"
19858
19859         # maximum amount of local locks:
19860         # parent striped dir - 2 locks
19861         # new stripe in parent to migrate to - 1 lock
19862         # source and target - 2 locks
19863         # Total 5 locks for regular file
19864         mkdir -p $DIR/$tdir
19865         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
19866         touch $DIR/$tdir/dir1/eee
19867
19868         # create 4 hardlink for 4 more locks
19869         # Total: 9 locks > RS_MAX_LOCKS (8)
19870         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
19871         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
19872         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
19873         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
19874         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
19875         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
19876         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
19877         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
19878
19879         cancel_lru_locks mdc
19880
19881         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
19882                 error "migrate dir fails"
19883
19884         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19885 }
19886 run_test 230r "migrate with too many local locks"
19887
19888 test_230s() {
19889         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
19890                 skip "Need MDS version at least 2.13.57"
19891
19892         local mdts=$(comma_list $(mdts_nodes))
19893         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
19894                                 mdt.*MDT0000.enable_dir_restripe)
19895
19896         stack_trap "do_nodes $mdts $LCTL set_param \
19897                     mdt.*.enable_dir_restripe=$restripe_status"
19898
19899         local st
19900         for st in 0 1; do
19901                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
19902                 test_mkdir $DIR/$tdir
19903                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
19904                         error "$LFS mkdir doesn't return -EEXIST if target exists"
19905                 rmdir $DIR/$tdir
19906         done
19907 }
19908 run_test 230s "lfs mkdir should return -EEXIST if target exists"
19909
19910 test_230t()
19911 {
19912         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
19913         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
19914                 skip "Need MDS version at least 2.14.50"
19915
19916         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
19917         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
19918         $LFS project -p 1 -s $DIR/$tdir ||
19919                 error "set $tdir project id failed"
19920         $LFS project -p 2 -s $DIR/$tdir/subdir ||
19921                 error "set subdir project id failed"
19922         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
19923 }
19924 run_test 230t "migrate directory with project ID set"
19925
19926 test_231a()
19927 {
19928         # For simplicity this test assumes that max_pages_per_rpc
19929         # is the same across all OSCs
19930         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
19931         local bulk_size=$((max_pages * PAGE_SIZE))
19932         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
19933                                        head -n 1)
19934
19935         mkdir -p $DIR/$tdir
19936         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
19937                 error "failed to set stripe with -S ${brw_size}M option"
19938
19939         # clear the OSC stats
19940         $LCTL set_param osc.*.stats=0 &>/dev/null
19941         stop_writeback
19942
19943         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
19944         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
19945                 oflag=direct &>/dev/null || error "dd failed"
19946
19947         sync; sleep 1; sync # just to be safe
19948         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
19949         if [ x$nrpcs != "x1" ]; then
19950                 $LCTL get_param osc.*.stats
19951                 error "found $nrpcs ost_write RPCs, not 1 as expected"
19952         fi
19953
19954         start_writeback
19955         # Drop the OSC cache, otherwise we will read from it
19956         cancel_lru_locks osc
19957
19958         # clear the OSC stats
19959         $LCTL set_param osc.*.stats=0 &>/dev/null
19960
19961         # Client reads $bulk_size.
19962         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
19963                 iflag=direct &>/dev/null || error "dd failed"
19964
19965         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
19966         if [ x$nrpcs != "x1" ]; then
19967                 $LCTL get_param osc.*.stats
19968                 error "found $nrpcs ost_read RPCs, not 1 as expected"
19969         fi
19970 }
19971 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
19972
19973 test_231b() {
19974         mkdir -p $DIR/$tdir
19975         local i
19976         for i in {0..1023}; do
19977                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
19978                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
19979                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
19980         done
19981         sync
19982 }
19983 run_test 231b "must not assert on fully utilized OST request buffer"
19984
19985 test_232a() {
19986         mkdir -p $DIR/$tdir
19987         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
19988
19989         #define OBD_FAIL_LDLM_OST_LVB            0x31c
19990         do_facet ost1 $LCTL set_param fail_loc=0x31c
19991
19992         # ignore dd failure
19993         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
19994
19995         do_facet ost1 $LCTL set_param fail_loc=0
19996         umount_client $MOUNT || error "umount failed"
19997         mount_client $MOUNT || error "mount failed"
19998         stop ost1 || error "cannot stop ost1"
19999         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20000 }
20001 run_test 232a "failed lock should not block umount"
20002
20003 test_232b() {
20004         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20005                 skip "Need MDS version at least 2.10.58"
20006
20007         mkdir -p $DIR/$tdir
20008         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20009         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20010         sync
20011         cancel_lru_locks osc
20012
20013         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20014         do_facet ost1 $LCTL set_param fail_loc=0x31c
20015
20016         # ignore failure
20017         $LFS data_version $DIR/$tdir/$tfile || true
20018
20019         do_facet ost1 $LCTL set_param fail_loc=0
20020         umount_client $MOUNT || error "umount failed"
20021         mount_client $MOUNT || error "mount failed"
20022         stop ost1 || error "cannot stop ost1"
20023         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20024 }
20025 run_test 232b "failed data version lock should not block umount"
20026
20027 test_233a() {
20028         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20029                 skip "Need MDS version at least 2.3.64"
20030         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20031
20032         local fid=$($LFS path2fid $MOUNT)
20033
20034         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20035                 error "cannot access $MOUNT using its FID '$fid'"
20036 }
20037 run_test 233a "checking that OBF of the FS root succeeds"
20038
20039 test_233b() {
20040         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20041                 skip "Need MDS version at least 2.5.90"
20042         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20043
20044         local fid=$($LFS path2fid $MOUNT/.lustre)
20045
20046         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20047                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20048
20049         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20050         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20051                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20052 }
20053 run_test 233b "checking that OBF of the FS .lustre succeeds"
20054
20055 test_234() {
20056         local p="$TMP/sanityN-$TESTNAME.parameters"
20057         save_lustre_params client "llite.*.xattr_cache" > $p
20058         lctl set_param llite.*.xattr_cache 1 ||
20059                 skip_env "xattr cache is not supported"
20060
20061         mkdir -p $DIR/$tdir || error "mkdir failed"
20062         touch $DIR/$tdir/$tfile || error "touch failed"
20063         # OBD_FAIL_LLITE_XATTR_ENOMEM
20064         $LCTL set_param fail_loc=0x1405
20065         getfattr -n user.attr $DIR/$tdir/$tfile &&
20066                 error "getfattr should have failed with ENOMEM"
20067         $LCTL set_param fail_loc=0x0
20068         rm -rf $DIR/$tdir
20069
20070         restore_lustre_params < $p
20071         rm -f $p
20072 }
20073 run_test 234 "xattr cache should not crash on ENOMEM"
20074
20075 test_235() {
20076         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20077                 skip "Need MDS version at least 2.4.52"
20078
20079         flock_deadlock $DIR/$tfile
20080         local RC=$?
20081         case $RC in
20082                 0)
20083                 ;;
20084                 124) error "process hangs on a deadlock"
20085                 ;;
20086                 *) error "error executing flock_deadlock $DIR/$tfile"
20087                 ;;
20088         esac
20089 }
20090 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20091
20092 #LU-2935
20093 test_236() {
20094         check_swap_layouts_support
20095
20096         local ref1=/etc/passwd
20097         local ref2=/etc/group
20098         local file1=$DIR/$tdir/f1
20099         local file2=$DIR/$tdir/f2
20100
20101         test_mkdir -c1 $DIR/$tdir
20102         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20103         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20104         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20105         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20106         local fd=$(free_fd)
20107         local cmd="exec $fd<>$file2"
20108         eval $cmd
20109         rm $file2
20110         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20111                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20112         cmd="exec $fd>&-"
20113         eval $cmd
20114         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20115
20116         #cleanup
20117         rm -rf $DIR/$tdir
20118 }
20119 run_test 236 "Layout swap on open unlinked file"
20120
20121 # LU-4659 linkea consistency
20122 test_238() {
20123         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20124                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20125                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20126                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20127
20128         touch $DIR/$tfile
20129         ln $DIR/$tfile $DIR/$tfile.lnk
20130         touch $DIR/$tfile.new
20131         mv $DIR/$tfile.new $DIR/$tfile
20132         local fid1=$($LFS path2fid $DIR/$tfile)
20133         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20134         local path1=$($LFS fid2path $FSNAME "$fid1")
20135         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20136         local path2=$($LFS fid2path $FSNAME "$fid2")
20137         [ $tfile.lnk == $path2 ] ||
20138                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20139         rm -f $DIR/$tfile*
20140 }
20141 run_test 238 "Verify linkea consistency"
20142
20143 test_239A() { # was test_239
20144         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20145                 skip "Need MDS version at least 2.5.60"
20146
20147         local list=$(comma_list $(mdts_nodes))
20148
20149         mkdir -p $DIR/$tdir
20150         createmany -o $DIR/$tdir/f- 5000
20151         unlinkmany $DIR/$tdir/f- 5000
20152         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20153                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20154         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20155                         osp.*MDT*.sync_in_flight" | calc_sum)
20156         [ "$changes" -eq 0 ] || error "$changes not synced"
20157 }
20158 run_test 239A "osp_sync test"
20159
20160 test_239a() { #LU-5297
20161         remote_mds_nodsh && skip "remote MDS with nodsh"
20162
20163         touch $DIR/$tfile
20164         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20165         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20166         chgrp $RUNAS_GID $DIR/$tfile
20167         wait_delete_completed
20168 }
20169 run_test 239a "process invalid osp sync record correctly"
20170
20171 test_239b() { #LU-5297
20172         remote_mds_nodsh && skip "remote MDS with nodsh"
20173
20174         touch $DIR/$tfile1
20175         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20176         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20177         chgrp $RUNAS_GID $DIR/$tfile1
20178         wait_delete_completed
20179         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20180         touch $DIR/$tfile2
20181         chgrp $RUNAS_GID $DIR/$tfile2
20182         wait_delete_completed
20183 }
20184 run_test 239b "process osp sync record with ENOMEM error correctly"
20185
20186 test_240() {
20187         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20188         remote_mds_nodsh && skip "remote MDS with nodsh"
20189
20190         mkdir -p $DIR/$tdir
20191
20192         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20193                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20194         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20195                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20196
20197         umount_client $MOUNT || error "umount failed"
20198         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20199         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20200         mount_client $MOUNT || error "failed to mount client"
20201
20202         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20203         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20204 }
20205 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20206
20207 test_241_bio() {
20208         local count=$1
20209         local bsize=$2
20210
20211         for LOOP in $(seq $count); do
20212                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20213                 cancel_lru_locks $OSC || true
20214         done
20215 }
20216
20217 test_241_dio() {
20218         local count=$1
20219         local bsize=$2
20220
20221         for LOOP in $(seq $1); do
20222                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20223                         2>/dev/null
20224         done
20225 }
20226
20227 test_241a() { # was test_241
20228         local bsize=$PAGE_SIZE
20229
20230         (( bsize < 40960 )) && bsize=40960
20231         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20232         ls -la $DIR/$tfile
20233         cancel_lru_locks $OSC
20234         test_241_bio 1000 $bsize &
20235         PID=$!
20236         test_241_dio 1000 $bsize
20237         wait $PID
20238 }
20239 run_test 241a "bio vs dio"
20240
20241 test_241b() {
20242         local bsize=$PAGE_SIZE
20243
20244         (( bsize < 40960 )) && bsize=40960
20245         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20246         ls -la $DIR/$tfile
20247         test_241_dio 1000 $bsize &
20248         PID=$!
20249         test_241_dio 1000 $bsize
20250         wait $PID
20251 }
20252 run_test 241b "dio vs dio"
20253
20254 test_242() {
20255         remote_mds_nodsh && skip "remote MDS with nodsh"
20256
20257         mkdir_on_mdt0 $DIR/$tdir
20258         touch $DIR/$tdir/$tfile
20259
20260         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20261         do_facet mds1 lctl set_param fail_loc=0x105
20262         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20263
20264         do_facet mds1 lctl set_param fail_loc=0
20265         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20266 }
20267 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20268
20269 test_243()
20270 {
20271         test_mkdir $DIR/$tdir
20272         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20273 }
20274 run_test 243 "various group lock tests"
20275
20276 test_244a()
20277 {
20278         test_mkdir $DIR/$tdir
20279         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20280         sendfile_grouplock $DIR/$tdir/$tfile || \
20281                 error "sendfile+grouplock failed"
20282         rm -rf $DIR/$tdir
20283 }
20284 run_test 244a "sendfile with group lock tests"
20285
20286 test_244b()
20287 {
20288         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20289
20290         local threads=50
20291         local size=$((1024*1024))
20292
20293         test_mkdir $DIR/$tdir
20294         for i in $(seq 1 $threads); do
20295                 local file=$DIR/$tdir/file_$((i / 10))
20296                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20297                 local pids[$i]=$!
20298         done
20299         for i in $(seq 1 $threads); do
20300                 wait ${pids[$i]}
20301         done
20302 }
20303 run_test 244b "multi-threaded write with group lock"
20304
20305 test_245() {
20306         local flagname="multi_mod_rpcs"
20307         local connect_data_name="max_mod_rpcs"
20308         local out
20309
20310         # check if multiple modify RPCs flag is set
20311         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20312                 grep "connect_flags:")
20313         echo "$out"
20314
20315         echo "$out" | grep -qw $flagname
20316         if [ $? -ne 0 ]; then
20317                 echo "connect flag $flagname is not set"
20318                 return
20319         fi
20320
20321         # check if multiple modify RPCs data is set
20322         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20323         echo "$out"
20324
20325         echo "$out" | grep -qw $connect_data_name ||
20326                 error "import should have connect data $connect_data_name"
20327 }
20328 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20329
20330 cleanup_247() {
20331         local submount=$1
20332
20333         trap 0
20334         umount_client $submount
20335         rmdir $submount
20336 }
20337
20338 test_247a() {
20339         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20340                 grep -q subtree ||
20341                 skip_env "Fileset feature is not supported"
20342
20343         local submount=${MOUNT}_$tdir
20344
20345         mkdir $MOUNT/$tdir
20346         mkdir -p $submount || error "mkdir $submount failed"
20347         FILESET="$FILESET/$tdir" mount_client $submount ||
20348                 error "mount $submount failed"
20349         trap "cleanup_247 $submount" EXIT
20350         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20351         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20352                 error "read $MOUNT/$tdir/$tfile failed"
20353         cleanup_247 $submount
20354 }
20355 run_test 247a "mount subdir as fileset"
20356
20357 test_247b() {
20358         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20359                 skip_env "Fileset feature is not supported"
20360
20361         local submount=${MOUNT}_$tdir
20362
20363         rm -rf $MOUNT/$tdir
20364         mkdir -p $submount || error "mkdir $submount failed"
20365         SKIP_FILESET=1
20366         FILESET="$FILESET/$tdir" mount_client $submount &&
20367                 error "mount $submount should fail"
20368         rmdir $submount
20369 }
20370 run_test 247b "mount subdir that dose not exist"
20371
20372 test_247c() {
20373         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20374                 skip_env "Fileset feature is not supported"
20375
20376         local submount=${MOUNT}_$tdir
20377
20378         mkdir -p $MOUNT/$tdir/dir1
20379         mkdir -p $submount || error "mkdir $submount failed"
20380         trap "cleanup_247 $submount" EXIT
20381         FILESET="$FILESET/$tdir" mount_client $submount ||
20382                 error "mount $submount failed"
20383         local fid=$($LFS path2fid $MOUNT/)
20384         $LFS fid2path $submount $fid && error "fid2path should fail"
20385         cleanup_247 $submount
20386 }
20387 run_test 247c "running fid2path outside subdirectory root"
20388
20389 test_247d() {
20390         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20391                 skip "Fileset feature is not supported"
20392
20393         local submount=${MOUNT}_$tdir
20394
20395         mkdir -p $MOUNT/$tdir/dir1
20396         mkdir -p $submount || error "mkdir $submount failed"
20397         FILESET="$FILESET/$tdir" mount_client $submount ||
20398                 error "mount $submount failed"
20399         trap "cleanup_247 $submount" EXIT
20400
20401         local td=$submount/dir1
20402         local fid=$($LFS path2fid $td)
20403         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20404
20405         # check that we get the same pathname back
20406         local rootpath
20407         local found
20408         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20409                 echo "$rootpath $fid"
20410                 found=$($LFS fid2path $rootpath "$fid")
20411                 [ -n "found" ] || error "fid2path should succeed"
20412                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20413         done
20414         # check wrong root path format
20415         rootpath=$submount"_wrong"
20416         found=$($LFS fid2path $rootpath "$fid")
20417         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20418
20419         cleanup_247 $submount
20420 }
20421 run_test 247d "running fid2path inside subdirectory root"
20422
20423 # LU-8037
20424 test_247e() {
20425         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20426                 grep -q subtree ||
20427                 skip "Fileset feature is not supported"
20428
20429         local submount=${MOUNT}_$tdir
20430
20431         mkdir $MOUNT/$tdir
20432         mkdir -p $submount || error "mkdir $submount failed"
20433         FILESET="$FILESET/.." mount_client $submount &&
20434                 error "mount $submount should fail"
20435         rmdir $submount
20436 }
20437 run_test 247e "mount .. as fileset"
20438
20439 test_247f() {
20440         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20441         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20442                 skip "Need at least version 2.13.52"
20443         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20444                 skip "Need at least version 2.14.50"
20445         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20446                 grep -q subtree ||
20447                 skip "Fileset feature is not supported"
20448
20449         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20450         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20451                 error "mkdir remote failed"
20452         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20453                 error "mkdir remote/subdir failed"
20454         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20455                 error "mkdir striped failed"
20456         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20457
20458         local submount=${MOUNT}_$tdir
20459
20460         mkdir -p $submount || error "mkdir $submount failed"
20461         stack_trap "rmdir $submount"
20462
20463         local dir
20464         local stat
20465         local fileset=$FILESET
20466         local mdts=$(comma_list $(mdts_nodes))
20467
20468         stat=$(do_facet mds1 $LCTL get_param -n \
20469                 mdt.*MDT0000.enable_remote_subdir_mount)
20470         stack_trap "do_nodes $mdts $LCTL set_param \
20471                 mdt.*.enable_remote_subdir_mount=$stat"
20472
20473         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20474         stack_trap "umount_client $submount"
20475         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20476                 error "mount remote dir $dir should fail"
20477
20478         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20479                 $tdir/striped/. ; do
20480                 FILESET="$fileset/$dir" mount_client $submount ||
20481                         error "mount $dir failed"
20482                 umount_client $submount
20483         done
20484
20485         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20486         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20487                 error "mount $tdir/remote failed"
20488 }
20489 run_test 247f "mount striped or remote directory as fileset"
20490
20491 test_247g() {
20492         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20493         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20494                 skip "Need at least version 2.14.50"
20495
20496         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20497                 error "mkdir $tdir failed"
20498         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20499
20500         local submount=${MOUNT}_$tdir
20501
20502         mkdir -p $submount || error "mkdir $submount failed"
20503         stack_trap "rmdir $submount"
20504
20505         FILESET="$fileset/$tdir" mount_client $submount ||
20506                 error "mount $dir failed"
20507         stack_trap "umount $submount"
20508
20509         local mdts=$(comma_list $(mdts_nodes))
20510
20511         local nrpcs
20512
20513         stat $submount > /dev/null
20514         cancel_lru_locks $MDC
20515         stat $submount > /dev/null
20516         stat $submount/$tfile > /dev/null
20517         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20518         stat $submount/$tfile > /dev/null
20519         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20520                 awk '/getattr/ {sum += $2} END {print sum}')
20521
20522         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20523 }
20524 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20525
20526 test_248a() {
20527         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20528         [ -z "$fast_read_sav" ] && skip "no fast read support"
20529
20530         # create a large file for fast read verification
20531         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20532
20533         # make sure the file is created correctly
20534         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20535                 { rm -f $DIR/$tfile; skip "file creation error"; }
20536
20537         echo "Test 1: verify that fast read is 4 times faster on cache read"
20538
20539         # small read with fast read enabled
20540         $LCTL set_param -n llite.*.fast_read=1
20541         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20542                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20543                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20544         # small read with fast read disabled
20545         $LCTL set_param -n llite.*.fast_read=0
20546         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20547                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20548                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20549
20550         # verify that fast read is 4 times faster for cache read
20551         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20552                 error_not_in_vm "fast read was not 4 times faster: " \
20553                            "$t_fast vs $t_slow"
20554
20555         echo "Test 2: verify the performance between big and small read"
20556         $LCTL set_param -n llite.*.fast_read=1
20557
20558         # 1k non-cache read
20559         cancel_lru_locks osc
20560         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20561                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20562                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20563
20564         # 1M non-cache read
20565         cancel_lru_locks osc
20566         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20567                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20568                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20569
20570         # verify that big IO is not 4 times faster than small IO
20571         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20572                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20573
20574         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20575         rm -f $DIR/$tfile
20576 }
20577 run_test 248a "fast read verification"
20578
20579 test_248b() {
20580         # Default short_io_bytes=16384, try both smaller and larger sizes.
20581         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20582         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20583         echo "bs=53248 count=113 normal buffered write"
20584         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20585                 error "dd of initial data file failed"
20586         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20587
20588         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20589         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20590                 error "dd with sync normal writes failed"
20591         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20592
20593         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20594         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20595                 error "dd with sync small writes failed"
20596         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20597
20598         cancel_lru_locks osc
20599
20600         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20601         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20602         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20603         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20604                 iflag=direct || error "dd with O_DIRECT small read failed"
20605         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20606         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20607                 error "compare $TMP/$tfile.1 failed"
20608
20609         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20610         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20611
20612         # just to see what the maximum tunable value is, and test parsing
20613         echo "test invalid parameter 2MB"
20614         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20615                 error "too-large short_io_bytes allowed"
20616         echo "test maximum parameter 512KB"
20617         # if we can set a larger short_io_bytes, run test regardless of version
20618         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20619                 # older clients may not allow setting it this large, that's OK
20620                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20621                         skip "Need at least client version 2.13.50"
20622                 error "medium short_io_bytes failed"
20623         fi
20624         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20625         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20626
20627         echo "test large parameter 64KB"
20628         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20629         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20630
20631         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20632         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20633                 error "dd with sync large writes failed"
20634         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20635
20636         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20637         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
20638         num=$((113 * 4096 / PAGE_SIZE))
20639         echo "bs=$size count=$num oflag=direct large write $tfile.3"
20640         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
20641                 error "dd with O_DIRECT large writes failed"
20642         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
20643                 error "compare $DIR/$tfile.3 failed"
20644
20645         cancel_lru_locks osc
20646
20647         echo "bs=$size count=$num iflag=direct large read $tfile.2"
20648         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
20649                 error "dd with O_DIRECT large read failed"
20650         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
20651                 error "compare $TMP/$tfile.2 failed"
20652
20653         echo "bs=$size count=$num iflag=direct large read $tfile.3"
20654         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
20655                 error "dd with O_DIRECT large read failed"
20656         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
20657                 error "compare $TMP/$tfile.3 failed"
20658 }
20659 run_test 248b "test short_io read and write for both small and large sizes"
20660
20661 test_249() { # LU-7890
20662         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
20663                 skip "Need at least version 2.8.54"
20664
20665         rm -f $DIR/$tfile
20666         $LFS setstripe -c 1 $DIR/$tfile
20667         # Offset 2T == 4k * 512M
20668         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
20669                 error "dd to 2T offset failed"
20670 }
20671 run_test 249 "Write above 2T file size"
20672
20673 test_250() {
20674         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
20675          && skip "no 16TB file size limit on ZFS"
20676
20677         $LFS setstripe -c 1 $DIR/$tfile
20678         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
20679         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
20680         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
20681         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
20682                 conv=notrunc,fsync && error "append succeeded"
20683         return 0
20684 }
20685 run_test 250 "Write above 16T limit"
20686
20687 test_251() {
20688         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
20689
20690         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
20691         #Skip once - writing the first stripe will succeed
20692         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20693         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
20694                 error "short write happened"
20695
20696         $LCTL set_param fail_loc=0xa0001407 fail_val=1
20697         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
20698                 error "short read happened"
20699
20700         rm -f $DIR/$tfile
20701 }
20702 run_test 251 "Handling short read and write correctly"
20703
20704 test_252() {
20705         remote_mds_nodsh && skip "remote MDS with nodsh"
20706         remote_ost_nodsh && skip "remote OST with nodsh"
20707         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
20708                 skip_env "ldiskfs only test"
20709         fi
20710
20711         local tgt
20712         local dev
20713         local out
20714         local uuid
20715         local num
20716         local gen
20717
20718         # check lr_reader on OST0000
20719         tgt=ost1
20720         dev=$(facet_device $tgt)
20721         out=$(do_facet $tgt $LR_READER $dev)
20722         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20723         echo "$out"
20724         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
20725         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
20726                 error "Invalid uuid returned by $LR_READER on target $tgt"
20727         echo -e "uuid returned by $LR_READER is '$uuid'\n"
20728
20729         # check lr_reader -c on MDT0000
20730         tgt=mds1
20731         dev=$(facet_device $tgt)
20732         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
20733                 skip "$LR_READER does not support additional options"
20734         fi
20735         out=$(do_facet $tgt $LR_READER -c $dev)
20736         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20737         echo "$out"
20738         num=$(echo "$out" | grep -c "mdtlov")
20739         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
20740                 error "Invalid number of mdtlov clients returned by $LR_READER"
20741         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
20742
20743         # check lr_reader -cr on MDT0000
20744         out=$(do_facet $tgt $LR_READER -cr $dev)
20745         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
20746         echo "$out"
20747         echo "$out" | grep -q "^reply_data:$" ||
20748                 error "$LR_READER should have returned 'reply_data' section"
20749         num=$(echo "$out" | grep -c "client_generation")
20750         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
20751 }
20752 run_test 252 "check lr_reader tool"
20753
20754 test_253() {
20755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20756         remote_mds_nodsh && skip "remote MDS with nodsh"
20757         remote_mgs_nodsh && skip "remote MGS with nodsh"
20758
20759         local ostidx=0
20760         local rc=0
20761         local ost_name=$(ostname_from_index $ostidx)
20762
20763         # on the mdt's osc
20764         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
20765         do_facet $SINGLEMDS $LCTL get_param -n \
20766                 osp.$mdtosc_proc1.reserved_mb_high ||
20767                 skip  "remote MDS does not support reserved_mb_high"
20768
20769         rm -rf $DIR/$tdir
20770         wait_mds_ost_sync
20771         wait_delete_completed
20772         mkdir $DIR/$tdir
20773
20774         pool_add $TESTNAME || error "Pool creation failed"
20775         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
20776
20777         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
20778                 error "Setstripe failed"
20779
20780         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
20781
20782         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
20783                     grep "watermarks")
20784         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
20785
20786         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20787                         osp.$mdtosc_proc1.prealloc_status)
20788         echo "prealloc_status $oa_status"
20789
20790         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
20791                 error "File creation should fail"
20792
20793         #object allocation was stopped, but we still able to append files
20794         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
20795                 oflag=append || error "Append failed"
20796
20797         rm -f $DIR/$tdir/$tfile.0
20798
20799         # For this test, we want to delete the files we created to go out of
20800         # space but leave the watermark, so we remain nearly out of space
20801         ost_watermarks_enospc_delete_files $tfile $ostidx
20802
20803         wait_delete_completed
20804
20805         sleep_maxage
20806
20807         for i in $(seq 10 12); do
20808                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
20809                         2>/dev/null || error "File creation failed after rm"
20810         done
20811
20812         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
20813                         osp.$mdtosc_proc1.prealloc_status)
20814         echo "prealloc_status $oa_status"
20815
20816         if (( oa_status != 0 )); then
20817                 error "Object allocation still disable after rm"
20818         fi
20819 }
20820 run_test 253 "Check object allocation limit"
20821
20822 test_254() {
20823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20824         remote_mds_nodsh && skip "remote MDS with nodsh"
20825         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
20826                 skip "MDS does not support changelog_size"
20827
20828         local cl_user
20829         local MDT0=$(facet_svc $SINGLEMDS)
20830
20831         changelog_register || error "changelog_register failed"
20832
20833         changelog_clear 0 || error "changelog_clear failed"
20834
20835         local size1=$(do_facet $SINGLEMDS \
20836                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20837         echo "Changelog size $size1"
20838
20839         rm -rf $DIR/$tdir
20840         $LFS mkdir -i 0 $DIR/$tdir
20841         # change something
20842         mkdir -p $DIR/$tdir/pics/2008/zachy
20843         touch $DIR/$tdir/pics/2008/zachy/timestamp
20844         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
20845         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
20846         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
20847         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
20848         rm $DIR/$tdir/pics/desktop.jpg
20849
20850         local size2=$(do_facet $SINGLEMDS \
20851                       $LCTL get_param -n mdd.$MDT0.changelog_size)
20852         echo "Changelog size after work $size2"
20853
20854         (( $size2 > $size1 )) ||
20855                 error "new Changelog size=$size2 less than old size=$size1"
20856 }
20857 run_test 254 "Check changelog size"
20858
20859 ladvise_no_type()
20860 {
20861         local type=$1
20862         local file=$2
20863
20864         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
20865                 awk -F: '{print $2}' | grep $type > /dev/null
20866         if [ $? -ne 0 ]; then
20867                 return 0
20868         fi
20869         return 1
20870 }
20871
20872 ladvise_no_ioctl()
20873 {
20874         local file=$1
20875
20876         lfs ladvise -a willread $file > /dev/null 2>&1
20877         if [ $? -eq 0 ]; then
20878                 return 1
20879         fi
20880
20881         lfs ladvise -a willread $file 2>&1 |
20882                 grep "Inappropriate ioctl for device" > /dev/null
20883         if [ $? -eq 0 ]; then
20884                 return 0
20885         fi
20886         return 1
20887 }
20888
20889 percent() {
20890         bc <<<"scale=2; ($1 - $2) * 100 / $2"
20891 }
20892
20893 # run a random read IO workload
20894 # usage: random_read_iops <filename> <filesize> <iosize>
20895 random_read_iops() {
20896         local file=$1
20897         local fsize=$2
20898         local iosize=${3:-4096}
20899
20900         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
20901                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
20902 }
20903
20904 drop_file_oss_cache() {
20905         local file="$1"
20906         local nodes="$2"
20907
20908         $LFS ladvise -a dontneed $file 2>/dev/null ||
20909                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
20910 }
20911
20912 ladvise_willread_performance()
20913 {
20914         local repeat=10
20915         local average_origin=0
20916         local average_cache=0
20917         local average_ladvise=0
20918
20919         for ((i = 1; i <= $repeat; i++)); do
20920                 echo "Iter $i/$repeat: reading without willread hint"
20921                 cancel_lru_locks osc
20922                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20923                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
20924                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
20925                 average_origin=$(bc <<<"$average_origin + $speed_origin")
20926
20927                 cancel_lru_locks osc
20928                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
20929                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
20930                 average_cache=$(bc <<<"$average_cache + $speed_cache")
20931
20932                 cancel_lru_locks osc
20933                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
20934                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
20935                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
20936                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
20937                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
20938         done
20939         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
20940         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
20941         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
20942
20943         speedup_cache=$(percent $average_cache $average_origin)
20944         speedup_ladvise=$(percent $average_ladvise $average_origin)
20945
20946         echo "Average uncached read: $average_origin"
20947         echo "Average speedup with OSS cached read: " \
20948                 "$average_cache = +$speedup_cache%"
20949         echo "Average speedup with ladvise willread: " \
20950                 "$average_ladvise = +$speedup_ladvise%"
20951
20952         local lowest_speedup=20
20953         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
20954                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
20955                         "got $average_cache%. Skipping ladvise willread check."
20956                 return 0
20957         fi
20958
20959         # the test won't work on ZFS until it supports 'ladvise dontneed', but
20960         # it is still good to run until then to exercise 'ladvise willread'
20961         ! $LFS ladvise -a dontneed $DIR/$tfile &&
20962                 [ "$ost1_FSTYPE" = "zfs" ] &&
20963                 echo "osd-zfs does not support dontneed or drop_caches" &&
20964                 return 0
20965
20966         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
20967         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
20968                 error_not_in_vm "Speedup with willread is less than " \
20969                         "$lowest_speedup%, got $average_ladvise%"
20970 }
20971
20972 test_255a() {
20973         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
20974                 skip "lustre < 2.8.54 does not support ladvise "
20975         remote_ost_nodsh && skip "remote OST with nodsh"
20976
20977         stack_trap "rm -f $DIR/$tfile"
20978         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
20979
20980         ladvise_no_type willread $DIR/$tfile &&
20981                 skip "willread ladvise is not supported"
20982
20983         ladvise_no_ioctl $DIR/$tfile &&
20984                 skip "ladvise ioctl is not supported"
20985
20986         local size_mb=100
20987         local size=$((size_mb * 1048576))
20988         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
20989                 error "dd to $DIR/$tfile failed"
20990
20991         lfs ladvise -a willread $DIR/$tfile ||
20992                 error "Ladvise failed with no range argument"
20993
20994         lfs ladvise -a willread -s 0 $DIR/$tfile ||
20995                 error "Ladvise failed with no -l or -e argument"
20996
20997         lfs ladvise -a willread -e 1 $DIR/$tfile ||
20998                 error "Ladvise failed with only -e argument"
20999
21000         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21001                 error "Ladvise failed with only -l argument"
21002
21003         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21004                 error "End offset should not be smaller than start offset"
21005
21006         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21007                 error "End offset should not be equal to start offset"
21008
21009         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21010                 error "Ladvise failed with overflowing -s argument"
21011
21012         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21013                 error "Ladvise failed with overflowing -e argument"
21014
21015         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21016                 error "Ladvise failed with overflowing -l argument"
21017
21018         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21019                 error "Ladvise succeeded with conflicting -l and -e arguments"
21020
21021         echo "Synchronous ladvise should wait"
21022         local delay=4
21023 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21024         do_nodes $(comma_list $(osts_nodes)) \
21025                 $LCTL set_param fail_val=$delay fail_loc=0x237
21026
21027         local start_ts=$SECONDS
21028         lfs ladvise -a willread $DIR/$tfile ||
21029                 error "Ladvise failed with no range argument"
21030         local end_ts=$SECONDS
21031         local inteval_ts=$((end_ts - start_ts))
21032
21033         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21034                 error "Synchronous advice didn't wait reply"
21035         fi
21036
21037         echo "Asynchronous ladvise shouldn't wait"
21038         local start_ts=$SECONDS
21039         lfs ladvise -a willread -b $DIR/$tfile ||
21040                 error "Ladvise failed with no range argument"
21041         local end_ts=$SECONDS
21042         local inteval_ts=$((end_ts - start_ts))
21043
21044         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21045                 error "Asynchronous advice blocked"
21046         fi
21047
21048         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21049         ladvise_willread_performance
21050 }
21051 run_test 255a "check 'lfs ladvise -a willread'"
21052
21053 facet_meminfo() {
21054         local facet=$1
21055         local info=$2
21056
21057         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21058 }
21059
21060 test_255b() {
21061         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21062                 skip "lustre < 2.8.54 does not support ladvise "
21063         remote_ost_nodsh && skip "remote OST with nodsh"
21064
21065         stack_trap "rm -f $DIR/$tfile"
21066         lfs setstripe -c 1 -i 0 $DIR/$tfile
21067
21068         ladvise_no_type dontneed $DIR/$tfile &&
21069                 skip "dontneed ladvise is not supported"
21070
21071         ladvise_no_ioctl $DIR/$tfile &&
21072                 skip "ladvise ioctl is not supported"
21073
21074         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21075                 [ "$ost1_FSTYPE" = "zfs" ] &&
21076                 skip "zfs-osd does not support 'ladvise dontneed'"
21077
21078         local size_mb=100
21079         local size=$((size_mb * 1048576))
21080         # In order to prevent disturbance of other processes, only check 3/4
21081         # of the memory usage
21082         local kibibytes=$((size_mb * 1024 * 3 / 4))
21083
21084         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21085                 error "dd to $DIR/$tfile failed"
21086
21087         #force write to complete before dropping OST cache & checking memory
21088         sync
21089
21090         local total=$(facet_meminfo ost1 MemTotal)
21091         echo "Total memory: $total KiB"
21092
21093         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21094         local before_read=$(facet_meminfo ost1 Cached)
21095         echo "Cache used before read: $before_read KiB"
21096
21097         lfs ladvise -a willread $DIR/$tfile ||
21098                 error "Ladvise willread failed"
21099         local after_read=$(facet_meminfo ost1 Cached)
21100         echo "Cache used after read: $after_read KiB"
21101
21102         lfs ladvise -a dontneed $DIR/$tfile ||
21103                 error "Ladvise dontneed again failed"
21104         local no_read=$(facet_meminfo ost1 Cached)
21105         echo "Cache used after dontneed ladvise: $no_read KiB"
21106
21107         if [ $total -lt $((before_read + kibibytes)) ]; then
21108                 echo "Memory is too small, abort checking"
21109                 return 0
21110         fi
21111
21112         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21113                 error "Ladvise willread should use more memory" \
21114                         "than $kibibytes KiB"
21115         fi
21116
21117         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21118                 error "Ladvise dontneed should release more memory" \
21119                         "than $kibibytes KiB"
21120         fi
21121 }
21122 run_test 255b "check 'lfs ladvise -a dontneed'"
21123
21124 test_255c() {
21125         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21126                 skip "lustre < 2.10.50 does not support lockahead"
21127
21128         local ost1_imp=$(get_osc_import_name client ost1)
21129         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21130                          cut -d'.' -f2)
21131         local count
21132         local new_count
21133         local difference
21134         local i
21135         local rc
21136
21137         test_mkdir -p $DIR/$tdir
21138         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21139
21140         #test 10 returns only success/failure
21141         i=10
21142         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21143         rc=$?
21144         if [ $rc -eq 255 ]; then
21145                 error "Ladvise test${i} failed, ${rc}"
21146         fi
21147
21148         #test 11 counts lock enqueue requests, all others count new locks
21149         i=11
21150         count=$(do_facet ost1 \
21151                 $LCTL get_param -n ost.OSS.ost.stats)
21152         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21153
21154         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21155         rc=$?
21156         if [ $rc -eq 255 ]; then
21157                 error "Ladvise test${i} failed, ${rc}"
21158         fi
21159
21160         new_count=$(do_facet ost1 \
21161                 $LCTL get_param -n ost.OSS.ost.stats)
21162         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21163                    awk '{ print $2 }')
21164
21165         difference="$((new_count - count))"
21166         if [ $difference -ne $rc ]; then
21167                 error "Ladvise test${i}, bad enqueue count, returned " \
21168                       "${rc}, actual ${difference}"
21169         fi
21170
21171         for i in $(seq 12 21); do
21172                 # If we do not do this, we run the risk of having too many
21173                 # locks and starting lock cancellation while we are checking
21174                 # lock counts.
21175                 cancel_lru_locks osc
21176
21177                 count=$($LCTL get_param -n \
21178                        ldlm.namespaces.$imp_name.lock_unused_count)
21179
21180                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21181                 rc=$?
21182                 if [ $rc -eq 255 ]; then
21183                         error "Ladvise test ${i} failed, ${rc}"
21184                 fi
21185
21186                 new_count=$($LCTL get_param -n \
21187                        ldlm.namespaces.$imp_name.lock_unused_count)
21188                 difference="$((new_count - count))"
21189
21190                 # Test 15 output is divided by 100 to map down to valid return
21191                 if [ $i -eq 15 ]; then
21192                         rc="$((rc * 100))"
21193                 fi
21194
21195                 if [ $difference -ne $rc ]; then
21196                         error "Ladvise test ${i}, bad lock count, returned " \
21197                               "${rc}, actual ${difference}"
21198                 fi
21199         done
21200
21201         #test 22 returns only success/failure
21202         i=22
21203         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21204         rc=$?
21205         if [ $rc -eq 255 ]; then
21206                 error "Ladvise test${i} failed, ${rc}"
21207         fi
21208 }
21209 run_test 255c "suite of ladvise lockahead tests"
21210
21211 test_256() {
21212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21213         remote_mds_nodsh && skip "remote MDS with nodsh"
21214         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21215         changelog_users $SINGLEMDS | grep "^cl" &&
21216                 skip "active changelog user"
21217
21218         local cl_user
21219         local cat_sl
21220         local mdt_dev
21221
21222         mdt_dev=$(mdsdevname 1)
21223         echo $mdt_dev
21224
21225         changelog_register || error "changelog_register failed"
21226
21227         rm -rf $DIR/$tdir
21228         mkdir_on_mdt0 $DIR/$tdir
21229
21230         changelog_clear 0 || error "changelog_clear failed"
21231
21232         # change something
21233         touch $DIR/$tdir/{1..10}
21234
21235         # stop the MDT
21236         stop $SINGLEMDS || error "Fail to stop MDT"
21237
21238         # remount the MDT
21239
21240         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21241
21242         #after mount new plainllog is used
21243         touch $DIR/$tdir/{11..19}
21244         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21245         stack_trap "rm -f $tmpfile"
21246         cat_sl=$(do_facet $SINGLEMDS "sync; \
21247                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21248                  llog_reader $tmpfile | grep -c type=1064553b")
21249         do_facet $SINGLEMDS llog_reader $tmpfile
21250
21251         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21252
21253         changelog_clear 0 || error "changelog_clear failed"
21254
21255         cat_sl=$(do_facet $SINGLEMDS "sync; \
21256                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21257                  llog_reader $tmpfile | grep -c type=1064553b")
21258
21259         if (( cat_sl == 2 )); then
21260                 error "Empty plain llog was not deleted from changelog catalog"
21261         elif (( cat_sl != 1 )); then
21262                 error "Active plain llog shouldn't be deleted from catalog"
21263         fi
21264 }
21265 run_test 256 "Check llog delete for empty and not full state"
21266
21267 test_257() {
21268         remote_mds_nodsh && skip "remote MDS with nodsh"
21269         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21270                 skip "Need MDS version at least 2.8.55"
21271
21272         test_mkdir $DIR/$tdir
21273
21274         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21275                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21276         stat $DIR/$tdir
21277
21278 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21279         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21280         local facet=mds$((mdtidx + 1))
21281         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21282         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21283
21284         stop $facet || error "stop MDS failed"
21285         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21286                 error "start MDS fail"
21287         wait_recovery_complete $facet
21288 }
21289 run_test 257 "xattr locks are not lost"
21290
21291 # Verify we take the i_mutex when security requires it
21292 test_258a() {
21293 #define OBD_FAIL_IMUTEX_SEC 0x141c
21294         $LCTL set_param fail_loc=0x141c
21295         touch $DIR/$tfile
21296         chmod u+s $DIR/$tfile
21297         chmod a+rwx $DIR/$tfile
21298         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21299         RC=$?
21300         if [ $RC -ne 0 ]; then
21301                 error "error, failed to take i_mutex, rc=$?"
21302         fi
21303         rm -f $DIR/$tfile
21304 }
21305 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21306
21307 # Verify we do NOT take the i_mutex in the normal case
21308 test_258b() {
21309 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21310         $LCTL set_param fail_loc=0x141d
21311         touch $DIR/$tfile
21312         chmod a+rwx $DIR
21313         chmod a+rw $DIR/$tfile
21314         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21315         RC=$?
21316         if [ $RC -ne 0 ]; then
21317                 error "error, took i_mutex unnecessarily, rc=$?"
21318         fi
21319         rm -f $DIR/$tfile
21320
21321 }
21322 run_test 258b "verify i_mutex security behavior"
21323
21324 test_259() {
21325         local file=$DIR/$tfile
21326         local before
21327         local after
21328
21329         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21330
21331         stack_trap "rm -f $file" EXIT
21332
21333         wait_delete_completed
21334         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21335         echo "before: $before"
21336
21337         $LFS setstripe -i 0 -c 1 $file
21338         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21339         sync_all_data
21340         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21341         echo "after write: $after"
21342
21343 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21344         do_facet ost1 $LCTL set_param fail_loc=0x2301
21345         $TRUNCATE $file 0
21346         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21347         echo "after truncate: $after"
21348
21349         stop ost1
21350         do_facet ost1 $LCTL set_param fail_loc=0
21351         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21352         sleep 2
21353         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21354         echo "after restart: $after"
21355         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21356                 error "missing truncate?"
21357
21358         return 0
21359 }
21360 run_test 259 "crash at delayed truncate"
21361
21362 test_260() {
21363 #define OBD_FAIL_MDC_CLOSE               0x806
21364         $LCTL set_param fail_loc=0x80000806
21365         touch $DIR/$tfile
21366
21367 }
21368 run_test 260 "Check mdc_close fail"
21369
21370 ### Data-on-MDT sanity tests ###
21371 test_270a() {
21372         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21373                 skip "Need MDS version at least 2.10.55 for DoM"
21374
21375         # create DoM file
21376         local dom=$DIR/$tdir/dom_file
21377         local tmp=$DIR/$tdir/tmp_file
21378
21379         mkdir_on_mdt0 $DIR/$tdir
21380
21381         # basic checks for DoM component creation
21382         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21383                 error "Can set MDT layout to non-first entry"
21384
21385         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21386                 error "Can define multiple entries as MDT layout"
21387
21388         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21389
21390         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21391         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21392         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21393
21394         local mdtidx=$($LFS getstripe -m $dom)
21395         local mdtname=MDT$(printf %04x $mdtidx)
21396         local facet=mds$((mdtidx + 1))
21397         local space_check=1
21398
21399         # Skip free space checks with ZFS
21400         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21401
21402         # write
21403         sync
21404         local size_tmp=$((65536 * 3))
21405         local mdtfree1=$(do_facet $facet \
21406                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21407
21408         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21409         # check also direct IO along write
21410         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21411         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21412         sync
21413         cmp $tmp $dom || error "file data is different"
21414         [ $(stat -c%s $dom) == $size_tmp ] ||
21415                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21416         if [ $space_check == 1 ]; then
21417                 local mdtfree2=$(do_facet $facet \
21418                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21419
21420                 # increase in usage from by $size_tmp
21421                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21422                         error "MDT free space wrong after write: " \
21423                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21424         fi
21425
21426         # truncate
21427         local size_dom=10000
21428
21429         $TRUNCATE $dom $size_dom
21430         [ $(stat -c%s $dom) == $size_dom ] ||
21431                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21432         if [ $space_check == 1 ]; then
21433                 mdtfree1=$(do_facet $facet \
21434                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21435                 # decrease in usage from $size_tmp to new $size_dom
21436                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21437                   $(((size_tmp - size_dom) / 1024)) ] ||
21438                         error "MDT free space is wrong after truncate: " \
21439                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21440         fi
21441
21442         # append
21443         cat $tmp >> $dom
21444         sync
21445         size_dom=$((size_dom + size_tmp))
21446         [ $(stat -c%s $dom) == $size_dom ] ||
21447                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21448         if [ $space_check == 1 ]; then
21449                 mdtfree2=$(do_facet $facet \
21450                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21451                 # increase in usage by $size_tmp from previous
21452                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21453                         error "MDT free space is wrong after append: " \
21454                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21455         fi
21456
21457         # delete
21458         rm $dom
21459         if [ $space_check == 1 ]; then
21460                 mdtfree1=$(do_facet $facet \
21461                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21462                 # decrease in usage by $size_dom from previous
21463                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21464                         error "MDT free space is wrong after removal: " \
21465                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21466         fi
21467
21468         # combined striping
21469         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21470                 error "Can't create DoM + OST striping"
21471
21472         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21473         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21474         # check also direct IO along write
21475         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21476         sync
21477         cmp $tmp $dom || error "file data is different"
21478         [ $(stat -c%s $dom) == $size_tmp ] ||
21479                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21480         rm $dom $tmp
21481
21482         return 0
21483 }
21484 run_test 270a "DoM: basic functionality tests"
21485
21486 test_270b() {
21487         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21488                 skip "Need MDS version at least 2.10.55"
21489
21490         local dom=$DIR/$tdir/dom_file
21491         local max_size=1048576
21492
21493         mkdir -p $DIR/$tdir
21494         $LFS setstripe -E $max_size -L mdt $dom
21495
21496         # truncate over the limit
21497         $TRUNCATE $dom $(($max_size + 1)) &&
21498                 error "successful truncate over the maximum size"
21499         # write over the limit
21500         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21501                 error "successful write over the maximum size"
21502         # append over the limit
21503         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21504         echo "12345" >> $dom && error "successful append over the maximum size"
21505         rm $dom
21506
21507         return 0
21508 }
21509 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21510
21511 test_270c() {
21512         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21513                 skip "Need MDS version at least 2.10.55"
21514
21515         mkdir -p $DIR/$tdir
21516         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21517
21518         # check files inherit DoM EA
21519         touch $DIR/$tdir/first
21520         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21521                 error "bad pattern"
21522         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21523                 error "bad stripe count"
21524         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21525                 error "bad stripe size"
21526
21527         # check directory inherits DoM EA and uses it as default
21528         mkdir $DIR/$tdir/subdir
21529         touch $DIR/$tdir/subdir/second
21530         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21531                 error "bad pattern in sub-directory"
21532         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21533                 error "bad stripe count in sub-directory"
21534         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21535                 error "bad stripe size in sub-directory"
21536         return 0
21537 }
21538 run_test 270c "DoM: DoM EA inheritance tests"
21539
21540 test_270d() {
21541         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21542                 skip "Need MDS version at least 2.10.55"
21543
21544         mkdir -p $DIR/$tdir
21545         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21546
21547         # inherit default DoM striping
21548         mkdir $DIR/$tdir/subdir
21549         touch $DIR/$tdir/subdir/f1
21550
21551         # change default directory striping
21552         $LFS setstripe -c 1 $DIR/$tdir/subdir
21553         touch $DIR/$tdir/subdir/f2
21554         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21555                 error "wrong default striping in file 2"
21556         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21557                 error "bad pattern in file 2"
21558         return 0
21559 }
21560 run_test 270d "DoM: change striping from DoM to RAID0"
21561
21562 test_270e() {
21563         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21564                 skip "Need MDS version at least 2.10.55"
21565
21566         mkdir -p $DIR/$tdir/dom
21567         mkdir -p $DIR/$tdir/norm
21568         DOMFILES=20
21569         NORMFILES=10
21570         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21571         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21572
21573         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21574         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21575
21576         # find DoM files by layout
21577         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21578         [ $NUM -eq  $DOMFILES ] ||
21579                 error "lfs find -L: found $NUM, expected $DOMFILES"
21580         echo "Test 1: lfs find 20 DOM files by layout: OK"
21581
21582         # there should be 1 dir with default DOM striping
21583         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21584         [ $NUM -eq  1 ] ||
21585                 error "lfs find -L: found $NUM, expected 1 dir"
21586         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21587
21588         # find DoM files by stripe size
21589         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21590         [ $NUM -eq  $DOMFILES ] ||
21591                 error "lfs find -S: found $NUM, expected $DOMFILES"
21592         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21593
21594         # find files by stripe offset except DoM files
21595         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21596         [ $NUM -eq  $NORMFILES ] ||
21597                 error "lfs find -i: found $NUM, expected $NORMFILES"
21598         echo "Test 5: lfs find no DOM files by stripe index: OK"
21599         return 0
21600 }
21601 run_test 270e "DoM: lfs find with DoM files test"
21602
21603 test_270f() {
21604         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21605                 skip "Need MDS version at least 2.10.55"
21606
21607         local mdtname=${FSNAME}-MDT0000-mdtlov
21608         local dom=$DIR/$tdir/dom_file
21609         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21610                                                 lod.$mdtname.dom_stripesize)
21611         local dom_limit=131072
21612
21613         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21614         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21615                                                 lod.$mdtname.dom_stripesize)
21616         [ ${dom_limit} -eq ${dom_current} ] ||
21617                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21618
21619         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21620         $LFS setstripe -d $DIR/$tdir
21621         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21622                 error "Can't set directory default striping"
21623
21624         # exceed maximum stripe size
21625         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21626                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21627         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21628                 error "Able to create DoM component size more than LOD limit"
21629
21630         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21631         dom_current=$(do_facet mds1 $LCTL get_param -n \
21632                                                 lod.$mdtname.dom_stripesize)
21633         [ 0 -eq ${dom_current} ] ||
21634                 error "Can't set zero DoM stripe limit"
21635         rm $dom
21636
21637         # attempt to create DoM file on server with disabled DoM should
21638         # remove DoM entry from layout and be succeed
21639         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
21640                 error "Can't create DoM file (DoM is disabled)"
21641         [ $($LFS getstripe -L $dom) == "mdt" ] &&
21642                 error "File has DoM component while DoM is disabled"
21643         rm $dom
21644
21645         # attempt to create DoM file with only DoM stripe should return error
21646         $LFS setstripe -E $dom_limit -L mdt $dom &&
21647                 error "Able to create DoM-only file while DoM is disabled"
21648
21649         # too low values to be aligned with smallest stripe size 64K
21650         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
21651         dom_current=$(do_facet mds1 $LCTL get_param -n \
21652                                                 lod.$mdtname.dom_stripesize)
21653         [ 30000 -eq ${dom_current} ] &&
21654                 error "Can set too small DoM stripe limit"
21655
21656         # 64K is a minimal stripe size in Lustre, expect limit of that size
21657         [ 65536 -eq ${dom_current} ] ||
21658                 error "Limit is not set to 64K but ${dom_current}"
21659
21660         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
21661         dom_current=$(do_facet mds1 $LCTL get_param -n \
21662                                                 lod.$mdtname.dom_stripesize)
21663         echo $dom_current
21664         [ 2147483648 -eq ${dom_current} ] &&
21665                 error "Can set too large DoM stripe limit"
21666
21667         do_facet mds1 $LCTL set_param -n \
21668                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
21669         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21670                 error "Can't create DoM component size after limit change"
21671         do_facet mds1 $LCTL set_param -n \
21672                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
21673         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
21674                 error "Can't create DoM file after limit decrease"
21675         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
21676                 error "Can create big DoM component after limit decrease"
21677         touch ${dom}_def ||
21678                 error "Can't create file with old default layout"
21679
21680         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
21681         return 0
21682 }
21683 run_test 270f "DoM: maximum DoM stripe size checks"
21684
21685 test_270g() {
21686         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21687                 skip "Need MDS version at least 2.13.52"
21688         local dom=$DIR/$tdir/$tfile
21689
21690         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21691         local lodname=${FSNAME}-MDT0000-mdtlov
21692
21693         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21694         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
21695         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
21696         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21697
21698         local dom_limit=1024
21699         local dom_threshold="50%"
21700
21701         $LFS setstripe -d $DIR/$tdir
21702         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
21703                 error "Can't set directory default striping"
21704
21705         do_facet mds1 $LCTL set_param -n \
21706                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
21707         # set 0 threshold and create DOM file to change tunable stripesize
21708         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
21709         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21710                 error "Failed to create $dom file"
21711         # now tunable dom_cur_stripesize should reach maximum
21712         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21713                                         lod.${lodname}.dom_stripesize_cur_kb)
21714         [[ $dom_current == $dom_limit ]] ||
21715                 error "Current DOM stripesize is not maximum"
21716         rm $dom
21717
21718         # set threshold for further tests
21719         do_facet mds1 $LCTL set_param -n \
21720                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
21721         echo "DOM threshold is $dom_threshold free space"
21722         local dom_def
21723         local dom_set
21724         # Spoof bfree to exceed threshold
21725         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
21726         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
21727         for spfree in 40 20 0 15 30 55; do
21728                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
21729                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
21730                         error "Failed to create $dom file"
21731                 dom_def=$(do_facet mds1 $LCTL get_param -n \
21732                                         lod.${lodname}.dom_stripesize_cur_kb)
21733                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
21734                 [[ $dom_def != $dom_current ]] ||
21735                         error "Default stripe size was not changed"
21736                 if [[ $spfree > 0 ]] ; then
21737                         dom_set=$($LFS getstripe -S $dom)
21738                         [[ $dom_set == $((dom_def * 1024)) ]] ||
21739                                 error "DOM component size is still old"
21740                 else
21741                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21742                                 error "DoM component is set with no free space"
21743                 fi
21744                 rm $dom
21745                 dom_current=$dom_def
21746         done
21747 }
21748 run_test 270g "DoM: default DoM stripe size depends on free space"
21749
21750 test_270h() {
21751         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21752                 skip "Need MDS version at least 2.13.53"
21753
21754         local mdtname=${FSNAME}-MDT0000-mdtlov
21755         local dom=$DIR/$tdir/$tfile
21756         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21757
21758         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
21759         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21760
21761         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21762         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
21763                 error "can't create OST file"
21764         # mirrored file with DOM entry in the second mirror
21765         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
21766                 error "can't create mirror with DoM component"
21767
21768         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21769
21770         # DOM component in the middle and has other enries in the same mirror,
21771         # should succeed but lost DoM component
21772         $LFS setstripe --copy=${dom}_1 $dom ||
21773                 error "Can't create file from OST|DOM mirror layout"
21774         # check new file has no DoM layout after all
21775         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
21776                 error "File has DoM component while DoM is disabled"
21777 }
21778 run_test 270h "DoM: DoM stripe removal when disabled on server"
21779
21780 test_271a() {
21781         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21782                 skip "Need MDS version at least 2.10.55"
21783
21784         local dom=$DIR/$tdir/dom
21785
21786         mkdir -p $DIR/$tdir
21787
21788         $LFS setstripe -E 1024K -L mdt $dom
21789
21790         lctl set_param -n mdc.*.stats=clear
21791         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21792         cat $dom > /dev/null
21793         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
21794         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
21795         ls $dom
21796         rm -f $dom
21797 }
21798 run_test 271a "DoM: data is cached for read after write"
21799
21800 test_271b() {
21801         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21802                 skip "Need MDS version at least 2.10.55"
21803
21804         local dom=$DIR/$tdir/dom
21805
21806         mkdir -p $DIR/$tdir
21807
21808         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21809
21810         lctl set_param -n mdc.*.stats=clear
21811         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
21812         cancel_lru_locks mdc
21813         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
21814         # second stat to check size is cached on client
21815         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
21816         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21817         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
21818         rm -f $dom
21819 }
21820 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
21821
21822 test_271ba() {
21823         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21824                 skip "Need MDS version at least 2.10.55"
21825
21826         local dom=$DIR/$tdir/dom
21827
21828         mkdir -p $DIR/$tdir
21829
21830         $LFS setstripe -E 1024K -L mdt -E EOF $dom
21831
21832         lctl set_param -n mdc.*.stats=clear
21833         lctl set_param -n osc.*.stats=clear
21834         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
21835         cancel_lru_locks mdc
21836         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21837         # second stat to check size is cached on client
21838         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
21839         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
21840         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
21841         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
21842         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
21843         rm -f $dom
21844 }
21845 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
21846
21847
21848 get_mdc_stats() {
21849         local mdtidx=$1
21850         local param=$2
21851         local mdt=MDT$(printf %04x $mdtidx)
21852
21853         if [ -z $param ]; then
21854                 lctl get_param -n mdc.*$mdt*.stats
21855         else
21856                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
21857         fi
21858 }
21859
21860 test_271c() {
21861         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21862                 skip "Need MDS version at least 2.10.55"
21863
21864         local dom=$DIR/$tdir/dom
21865
21866         mkdir -p $DIR/$tdir
21867
21868         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21869
21870         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21871         local facet=mds$((mdtidx + 1))
21872
21873         cancel_lru_locks mdc
21874         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
21875         createmany -o $dom 1000
21876         lctl set_param -n mdc.*.stats=clear
21877         smalliomany -w $dom 1000 200
21878         get_mdc_stats $mdtidx
21879         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21880         # Each file has 1 open, 1 IO enqueues, total 2000
21881         # but now we have also +1 getxattr for security.capability, total 3000
21882         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
21883         unlinkmany $dom 1000
21884
21885         cancel_lru_locks mdc
21886         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
21887         createmany -o $dom 1000
21888         lctl set_param -n mdc.*.stats=clear
21889         smalliomany -w $dom 1000 200
21890         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
21891         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
21892         # for OPEN and IO lock.
21893         [ $((enq - enq_2)) -ge 1000 ] ||
21894                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
21895         unlinkmany $dom 1000
21896         return 0
21897 }
21898 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
21899
21900 cleanup_271def_tests() {
21901         trap 0
21902         rm -f $1
21903 }
21904
21905 test_271d() {
21906         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21907                 skip "Need MDS version at least 2.10.57"
21908
21909         local dom=$DIR/$tdir/dom
21910         local tmp=$TMP/$tfile
21911         trap "cleanup_271def_tests $tmp" EXIT
21912
21913         mkdir -p $DIR/$tdir
21914
21915         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21916
21917         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21918
21919         cancel_lru_locks mdc
21920         dd if=/dev/urandom of=$tmp bs=1000 count=1
21921         dd if=$tmp of=$dom bs=1000 count=1
21922         cancel_lru_locks mdc
21923
21924         cat /etc/hosts >> $tmp
21925         lctl set_param -n mdc.*.stats=clear
21926
21927         # append data to the same file it should update local page
21928         echo "Append to the same page"
21929         cat /etc/hosts >> $dom
21930         local num=$(get_mdc_stats $mdtidx ost_read)
21931         local ra=$(get_mdc_stats $mdtidx req_active)
21932         local rw=$(get_mdc_stats $mdtidx req_waittime)
21933
21934         [ -z $num ] || error "$num READ RPC occured"
21935         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21936         echo "... DONE"
21937
21938         # compare content
21939         cmp $tmp $dom || error "file miscompare"
21940
21941         cancel_lru_locks mdc
21942         lctl set_param -n mdc.*.stats=clear
21943
21944         echo "Open and read file"
21945         cat $dom > /dev/null
21946         local num=$(get_mdc_stats $mdtidx ost_read)
21947         local ra=$(get_mdc_stats $mdtidx req_active)
21948         local rw=$(get_mdc_stats $mdtidx req_waittime)
21949
21950         [ -z $num ] || error "$num READ RPC occured"
21951         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21952         echo "... DONE"
21953
21954         # compare content
21955         cmp $tmp $dom || error "file miscompare"
21956
21957         return 0
21958 }
21959 run_test 271d "DoM: read on open (1K file in reply buffer)"
21960
21961 test_271f() {
21962         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
21963                 skip "Need MDS version at least 2.10.57"
21964
21965         local dom=$DIR/$tdir/dom
21966         local tmp=$TMP/$tfile
21967         trap "cleanup_271def_tests $tmp" EXIT
21968
21969         mkdir -p $DIR/$tdir
21970
21971         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21972
21973         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
21974
21975         cancel_lru_locks mdc
21976         dd if=/dev/urandom of=$tmp bs=265000 count=1
21977         dd if=$tmp of=$dom bs=265000 count=1
21978         cancel_lru_locks mdc
21979         cat /etc/hosts >> $tmp
21980         lctl set_param -n mdc.*.stats=clear
21981
21982         echo "Append to the same page"
21983         cat /etc/hosts >> $dom
21984         local num=$(get_mdc_stats $mdtidx ost_read)
21985         local ra=$(get_mdc_stats $mdtidx req_active)
21986         local rw=$(get_mdc_stats $mdtidx req_waittime)
21987
21988         [ -z $num ] || error "$num READ RPC occured"
21989         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
21990         echo "... DONE"
21991
21992         # compare content
21993         cmp $tmp $dom || error "file miscompare"
21994
21995         cancel_lru_locks mdc
21996         lctl set_param -n mdc.*.stats=clear
21997
21998         echo "Open and read file"
21999         cat $dom > /dev/null
22000         local num=$(get_mdc_stats $mdtidx ost_read)
22001         local ra=$(get_mdc_stats $mdtidx req_active)
22002         local rw=$(get_mdc_stats $mdtidx req_waittime)
22003
22004         [ -z $num ] && num=0
22005         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22006         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22007         echo "... DONE"
22008
22009         # compare content
22010         cmp $tmp $dom || error "file miscompare"
22011
22012         return 0
22013 }
22014 run_test 271f "DoM: read on open (200K file and read tail)"
22015
22016 test_271g() {
22017         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22018                 skip "Skipping due to old client or server version"
22019
22020         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22021         # to get layout
22022         $CHECKSTAT -t file $DIR1/$tfile
22023
22024         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22025         MULTIOP_PID=$!
22026         sleep 1
22027         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22028         $LCTL set_param fail_loc=0x80000314
22029         rm $DIR1/$tfile || error "Unlink fails"
22030         RC=$?
22031         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22032         [ $RC -eq 0 ] || error "Failed write to stale object"
22033 }
22034 run_test 271g "Discard DoM data vs client flush race"
22035
22036 test_272a() {
22037         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22038                 skip "Need MDS version at least 2.11.50"
22039
22040         local dom=$DIR/$tdir/dom
22041         mkdir -p $DIR/$tdir
22042
22043         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22044         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22045                 error "failed to write data into $dom"
22046         local old_md5=$(md5sum $dom)
22047
22048         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22049                 error "failed to migrate to the same DoM component"
22050
22051         local new_md5=$(md5sum $dom)
22052
22053         [ "$old_md5" == "$new_md5" ] ||
22054                 error "md5sum differ: $old_md5, $new_md5"
22055
22056         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22057                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22058 }
22059 run_test 272a "DoM migration: new layout with the same DOM component"
22060
22061 test_272b() {
22062         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22063                 skip "Need MDS version at least 2.11.50"
22064
22065         local dom=$DIR/$tdir/dom
22066         mkdir -p $DIR/$tdir
22067         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22068
22069         local mdtidx=$($LFS getstripe -m $dom)
22070         local mdtname=MDT$(printf %04x $mdtidx)
22071         local facet=mds$((mdtidx + 1))
22072
22073         local mdtfree1=$(do_facet $facet \
22074                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22075         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22076                 error "failed to write data into $dom"
22077         local old_md5=$(md5sum $dom)
22078         cancel_lru_locks mdc
22079         local mdtfree1=$(do_facet $facet \
22080                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22081
22082         $LFS migrate -c2 $dom ||
22083                 error "failed to migrate to the new composite layout"
22084         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22085                 error "MDT stripe was not removed"
22086
22087         cancel_lru_locks mdc
22088         local new_md5=$(md5sum $dom)
22089         [ "$old_md5" == "$new_md5" ] ||
22090                 error "$old_md5 != $new_md5"
22091
22092         # Skip free space checks with ZFS
22093         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22094                 local mdtfree2=$(do_facet $facet \
22095                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22096                 [ $mdtfree2 -gt $mdtfree1 ] ||
22097                         error "MDT space is not freed after migration"
22098         fi
22099         return 0
22100 }
22101 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22102
22103 test_272c() {
22104         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22105                 skip "Need MDS version at least 2.11.50"
22106
22107         local dom=$DIR/$tdir/$tfile
22108         mkdir -p $DIR/$tdir
22109         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22110
22111         local mdtidx=$($LFS getstripe -m $dom)
22112         local mdtname=MDT$(printf %04x $mdtidx)
22113         local facet=mds$((mdtidx + 1))
22114
22115         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22116                 error "failed to write data into $dom"
22117         local old_md5=$(md5sum $dom)
22118         cancel_lru_locks mdc
22119         local mdtfree1=$(do_facet $facet \
22120                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22121
22122         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22123                 error "failed to migrate to the new composite layout"
22124         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22125                 error "MDT stripe was not removed"
22126
22127         cancel_lru_locks mdc
22128         local new_md5=$(md5sum $dom)
22129         [ "$old_md5" == "$new_md5" ] ||
22130                 error "$old_md5 != $new_md5"
22131
22132         # Skip free space checks with ZFS
22133         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22134                 local mdtfree2=$(do_facet $facet \
22135                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22136                 [ $mdtfree2 -gt $mdtfree1 ] ||
22137                         error "MDS space is not freed after migration"
22138         fi
22139         return 0
22140 }
22141 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22142
22143 test_272d() {
22144         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22145                 skip "Need MDS version at least 2.12.55"
22146
22147         local dom=$DIR/$tdir/$tfile
22148         mkdir -p $DIR/$tdir
22149         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22150
22151         local mdtidx=$($LFS getstripe -m $dom)
22152         local mdtname=MDT$(printf %04x $mdtidx)
22153         local facet=mds$((mdtidx + 1))
22154
22155         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22156                 error "failed to write data into $dom"
22157         local old_md5=$(md5sum $dom)
22158         cancel_lru_locks mdc
22159         local mdtfree1=$(do_facet $facet \
22160                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22161
22162         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22163                 error "failed mirroring to the new composite layout"
22164         $LFS mirror resync $dom ||
22165                 error "failed mirror resync"
22166         $LFS mirror split --mirror-id 1 -d $dom ||
22167                 error "failed mirror split"
22168
22169         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22170                 error "MDT stripe was not removed"
22171
22172         cancel_lru_locks mdc
22173         local new_md5=$(md5sum $dom)
22174         [ "$old_md5" == "$new_md5" ] ||
22175                 error "$old_md5 != $new_md5"
22176
22177         # Skip free space checks with ZFS
22178         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22179                 local mdtfree2=$(do_facet $facet \
22180                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22181                 [ $mdtfree2 -gt $mdtfree1 ] ||
22182                         error "MDS space is not freed after DOM mirror deletion"
22183         fi
22184         return 0
22185 }
22186 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22187
22188 test_272e() {
22189         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22190                 skip "Need MDS version at least 2.12.55"
22191
22192         local dom=$DIR/$tdir/$tfile
22193         mkdir -p $DIR/$tdir
22194         $LFS setstripe -c 2 $dom
22195
22196         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22197                 error "failed to write data into $dom"
22198         local old_md5=$(md5sum $dom)
22199         cancel_lru_locks mdc
22200
22201         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22202                 error "failed mirroring to the DOM layout"
22203         $LFS mirror resync $dom ||
22204                 error "failed mirror resync"
22205         $LFS mirror split --mirror-id 1 -d $dom ||
22206                 error "failed mirror split"
22207
22208         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22209                 error "MDT stripe was not removed"
22210
22211         cancel_lru_locks mdc
22212         local new_md5=$(md5sum $dom)
22213         [ "$old_md5" == "$new_md5" ] ||
22214                 error "$old_md5 != $new_md5"
22215
22216         return 0
22217 }
22218 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22219
22220 test_272f() {
22221         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22222                 skip "Need MDS version at least 2.12.55"
22223
22224         local dom=$DIR/$tdir/$tfile
22225         mkdir -p $DIR/$tdir
22226         $LFS setstripe -c 2 $dom
22227
22228         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22229                 error "failed to write data into $dom"
22230         local old_md5=$(md5sum $dom)
22231         cancel_lru_locks mdc
22232
22233         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22234                 error "failed migrating to the DOM file"
22235
22236         cancel_lru_locks mdc
22237         local new_md5=$(md5sum $dom)
22238         [ "$old_md5" != "$new_md5" ] &&
22239                 error "$old_md5 != $new_md5"
22240
22241         return 0
22242 }
22243 run_test 272f "DoM migration: OST-striped file to DOM file"
22244
22245 test_273a() {
22246         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22247                 skip "Need MDS version at least 2.11.50"
22248
22249         # Layout swap cannot be done if either file has DOM component,
22250         # this will never be supported, migration should be used instead
22251
22252         local dom=$DIR/$tdir/$tfile
22253         mkdir -p $DIR/$tdir
22254
22255         $LFS setstripe -c2 ${dom}_plain
22256         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22257         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22258                 error "can swap layout with DoM component"
22259         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22260                 error "can swap layout with DoM component"
22261
22262         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22263         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22264                 error "can swap layout with DoM component"
22265         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22266                 error "can swap layout with DoM component"
22267         return 0
22268 }
22269 run_test 273a "DoM: layout swapping should fail with DOM"
22270
22271 test_273b() {
22272         mkdir -p $DIR/$tdir
22273         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22274
22275 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22276         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22277
22278         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22279 }
22280 run_test 273b "DoM: race writeback and object destroy"
22281
22282 test_275() {
22283         remote_ost_nodsh && skip "remote OST with nodsh"
22284         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22285                 skip "Need OST version >= 2.10.57"
22286
22287         local file=$DIR/$tfile
22288         local oss
22289
22290         oss=$(comma_list $(osts_nodes))
22291
22292         dd if=/dev/urandom of=$file bs=1M count=2 ||
22293                 error "failed to create a file"
22294         cancel_lru_locks osc
22295
22296         #lock 1
22297         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22298                 error "failed to read a file"
22299
22300 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22301         $LCTL set_param fail_loc=0x8000031f
22302
22303         cancel_lru_locks osc &
22304         sleep 1
22305
22306 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22307         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22308         #IO takes another lock, but matches the PENDING one
22309         #and places it to the IO RPC
22310         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22311                 error "failed to read a file with PENDING lock"
22312 }
22313 run_test 275 "Read on a canceled duplicate lock"
22314
22315 test_276() {
22316         remote_ost_nodsh && skip "remote OST with nodsh"
22317         local pid
22318
22319         do_facet ost1 "(while true; do \
22320                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22321                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22322         pid=$!
22323
22324         for LOOP in $(seq 20); do
22325                 stop ost1
22326                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22327         done
22328         kill -9 $pid
22329         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22330                 rm $TMP/sanity_276_pid"
22331 }
22332 run_test 276 "Race between mount and obd_statfs"
22333
22334 test_277() {
22335         $LCTL set_param ldlm.namespaces.*.lru_size=0
22336         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22337         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22338                         grep ^used_mb | awk '{print $2}')
22339         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22340         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22341                 oflag=direct conv=notrunc
22342         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22343                         grep ^used_mb | awk '{print $2}')
22344         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22345 }
22346 run_test 277 "Direct IO shall drop page cache"
22347
22348 test_278() {
22349         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22350         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22351         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22352                 skip "needs the same host for mdt1 mdt2" && return
22353
22354         local pid1
22355         local pid2
22356
22357 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22358         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22359         stop mds2 &
22360         pid2=$!
22361
22362         stop mds1
22363
22364         echo "Starting MDTs"
22365         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22366         wait $pid2
22367 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22368 #will return NULL
22369         do_facet mds2 $LCTL set_param fail_loc=0
22370
22371         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22372         wait_recovery_complete mds2
22373 }
22374 run_test 278 "Race starting MDS between MDTs stop/start"
22375
22376 test_280() {
22377         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22378                 skip "Need MGS version at least 2.13.52"
22379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22380         combined_mgs_mds || skip "needs combined MGS/MDT"
22381
22382         umount_client $MOUNT
22383 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22384         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22385
22386         mount_client $MOUNT &
22387         sleep 1
22388         stop mgs || error "stop mgs failed"
22389         #for a race mgs would crash
22390         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22391         # make sure we unmount client before remounting
22392         wait
22393         umount_client $MOUNT
22394         mount_client $MOUNT || error "mount client failed"
22395 }
22396 run_test 280 "Race between MGS umount and client llog processing"
22397
22398 cleanup_test_300() {
22399         trap 0
22400         umask $SAVE_UMASK
22401 }
22402 test_striped_dir() {
22403         local mdt_index=$1
22404         local stripe_count
22405         local stripe_index
22406
22407         mkdir -p $DIR/$tdir
22408
22409         SAVE_UMASK=$(umask)
22410         trap cleanup_test_300 RETURN EXIT
22411
22412         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22413                                                 $DIR/$tdir/striped_dir ||
22414                 error "set striped dir error"
22415
22416         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22417         [ "$mode" = "755" ] || error "expect 755 got $mode"
22418
22419         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22420                 error "getdirstripe failed"
22421         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22422         if [ "$stripe_count" != "2" ]; then
22423                 error "1:stripe_count is $stripe_count, expect 2"
22424         fi
22425         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22426         if [ "$stripe_count" != "2" ]; then
22427                 error "2:stripe_count is $stripe_count, expect 2"
22428         fi
22429
22430         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22431         if [ "$stripe_index" != "$mdt_index" ]; then
22432                 error "stripe_index is $stripe_index, expect $mdt_index"
22433         fi
22434
22435         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22436                 error "nlink error after create striped dir"
22437
22438         mkdir $DIR/$tdir/striped_dir/a
22439         mkdir $DIR/$tdir/striped_dir/b
22440
22441         stat $DIR/$tdir/striped_dir/a ||
22442                 error "create dir under striped dir failed"
22443         stat $DIR/$tdir/striped_dir/b ||
22444                 error "create dir under striped dir failed"
22445
22446         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22447                 error "nlink error after mkdir"
22448
22449         rmdir $DIR/$tdir/striped_dir/a
22450         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22451                 error "nlink error after rmdir"
22452
22453         rmdir $DIR/$tdir/striped_dir/b
22454         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22455                 error "nlink error after rmdir"
22456
22457         chattr +i $DIR/$tdir/striped_dir
22458         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22459                 error "immutable flags not working under striped dir!"
22460         chattr -i $DIR/$tdir/striped_dir
22461
22462         rmdir $DIR/$tdir/striped_dir ||
22463                 error "rmdir striped dir error"
22464
22465         cleanup_test_300
22466
22467         true
22468 }
22469
22470 test_300a() {
22471         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22472                 skip "skipped for lustre < 2.7.0"
22473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22475
22476         test_striped_dir 0 || error "failed on striped dir on MDT0"
22477         test_striped_dir 1 || error "failed on striped dir on MDT0"
22478 }
22479 run_test 300a "basic striped dir sanity test"
22480
22481 test_300b() {
22482         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22483                 skip "skipped for lustre < 2.7.0"
22484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22486
22487         local i
22488         local mtime1
22489         local mtime2
22490         local mtime3
22491
22492         test_mkdir $DIR/$tdir || error "mkdir fail"
22493         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22494                 error "set striped dir error"
22495         for i in {0..9}; do
22496                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22497                 sleep 1
22498                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22499                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22500                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22501                 sleep 1
22502                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22503                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22504                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22505         done
22506         true
22507 }
22508 run_test 300b "check ctime/mtime for striped dir"
22509
22510 test_300c() {
22511         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22512                 skip "skipped for lustre < 2.7.0"
22513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22514         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22515
22516         local file_count
22517
22518         mkdir_on_mdt0 $DIR/$tdir
22519         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22520                 error "set striped dir error"
22521
22522         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22523                 error "chown striped dir failed"
22524
22525         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22526                 error "create 5k files failed"
22527
22528         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22529
22530         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22531
22532         rm -rf $DIR/$tdir
22533 }
22534 run_test 300c "chown && check ls under striped directory"
22535
22536 test_300d() {
22537         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22538                 skip "skipped for lustre < 2.7.0"
22539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22541
22542         local stripe_count
22543         local file
22544
22545         mkdir -p $DIR/$tdir
22546         $LFS setstripe -c 2 $DIR/$tdir
22547
22548         #local striped directory
22549         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22550                 error "set striped dir error"
22551         #look at the directories for debug purposes
22552         ls -l $DIR/$tdir
22553         $LFS getdirstripe $DIR/$tdir
22554         ls -l $DIR/$tdir/striped_dir
22555         $LFS getdirstripe $DIR/$tdir/striped_dir
22556         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22557                 error "create 10 files failed"
22558
22559         #remote striped directory
22560         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22561                 error "set striped dir error"
22562         #look at the directories for debug purposes
22563         ls -l $DIR/$tdir
22564         $LFS getdirstripe $DIR/$tdir
22565         ls -l $DIR/$tdir/remote_striped_dir
22566         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22567         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22568                 error "create 10 files failed"
22569
22570         for file in $(find $DIR/$tdir); do
22571                 stripe_count=$($LFS getstripe -c $file)
22572                 [ $stripe_count -eq 2 ] ||
22573                         error "wrong stripe $stripe_count for $file"
22574         done
22575
22576         rm -rf $DIR/$tdir
22577 }
22578 run_test 300d "check default stripe under striped directory"
22579
22580 test_300e() {
22581         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22582                 skip "Need MDS version at least 2.7.55"
22583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22584         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22585
22586         local stripe_count
22587         local file
22588
22589         mkdir -p $DIR/$tdir
22590
22591         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22592                 error "set striped dir error"
22593
22594         touch $DIR/$tdir/striped_dir/a
22595         touch $DIR/$tdir/striped_dir/b
22596         touch $DIR/$tdir/striped_dir/c
22597
22598         mkdir $DIR/$tdir/striped_dir/dir_a
22599         mkdir $DIR/$tdir/striped_dir/dir_b
22600         mkdir $DIR/$tdir/striped_dir/dir_c
22601
22602         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22603                 error "set striped adir under striped dir error"
22604
22605         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22606                 error "set striped bdir under striped dir error"
22607
22608         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22609                 error "set striped cdir under striped dir error"
22610
22611         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22612                 error "rename dir under striped dir fails"
22613
22614         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22615                 error "rename dir under different stripes fails"
22616
22617         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22618                 error "rename file under striped dir should succeed"
22619
22620         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22621                 error "rename dir under striped dir should succeed"
22622
22623         rm -rf $DIR/$tdir
22624 }
22625 run_test 300e "check rename under striped directory"
22626
22627 test_300f() {
22628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22629         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22630         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22631                 skip "Need MDS version at least 2.7.55"
22632
22633         local stripe_count
22634         local file
22635
22636         rm -rf $DIR/$tdir
22637         mkdir -p $DIR/$tdir
22638
22639         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22640                 error "set striped dir error"
22641
22642         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
22643                 error "set striped dir error"
22644
22645         touch $DIR/$tdir/striped_dir/a
22646         mkdir $DIR/$tdir/striped_dir/dir_a
22647         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
22648                 error "create striped dir under striped dir fails"
22649
22650         touch $DIR/$tdir/striped_dir1/b
22651         mkdir $DIR/$tdir/striped_dir1/dir_b
22652         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
22653                 error "create striped dir under striped dir fails"
22654
22655         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
22656                 error "rename dir under different striped dir should fail"
22657
22658         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
22659                 error "rename striped dir under diff striped dir should fail"
22660
22661         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
22662                 error "rename file under diff striped dirs fails"
22663
22664         rm -rf $DIR/$tdir
22665 }
22666 run_test 300f "check rename cross striped directory"
22667
22668 test_300_check_default_striped_dir()
22669 {
22670         local dirname=$1
22671         local default_count=$2
22672         local default_index=$3
22673         local stripe_count
22674         local stripe_index
22675         local dir_stripe_index
22676         local dir
22677
22678         echo "checking $dirname $default_count $default_index"
22679         $LFS setdirstripe -D -c $default_count -i $default_index \
22680                                 -H all_char $DIR/$tdir/$dirname ||
22681                 error "set default stripe on striped dir error"
22682         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
22683         [ $stripe_count -eq $default_count ] ||
22684                 error "expect $default_count get $stripe_count for $dirname"
22685
22686         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
22687         [ $stripe_index -eq $default_index ] ||
22688                 error "expect $default_index get $stripe_index for $dirname"
22689
22690         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
22691                                                 error "create dirs failed"
22692
22693         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
22694         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
22695         for dir in $(find $DIR/$tdir/$dirname/*); do
22696                 stripe_count=$($LFS getdirstripe -c $dir)
22697                 (( $stripe_count == $default_count )) ||
22698                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
22699                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
22700                 error "stripe count $default_count != $stripe_count for $dir"
22701
22702                 stripe_index=$($LFS getdirstripe -i $dir)
22703                 [ $default_index -eq -1 ] ||
22704                         [ $stripe_index -eq $default_index ] ||
22705                         error "$stripe_index != $default_index for $dir"
22706
22707                 #check default stripe
22708                 stripe_count=$($LFS getdirstripe -D -c $dir)
22709                 [ $stripe_count -eq $default_count ] ||
22710                 error "default count $default_count != $stripe_count for $dir"
22711
22712                 stripe_index=$($LFS getdirstripe -D -i $dir)
22713                 [ $stripe_index -eq $default_index ] ||
22714                 error "default index $default_index != $stripe_index for $dir"
22715         done
22716         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
22717 }
22718
22719 test_300g() {
22720         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22721         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22722                 skip "Need MDS version at least 2.7.55"
22723
22724         local dir
22725         local stripe_count
22726         local stripe_index
22727
22728         mkdir_on_mdt0 $DIR/$tdir
22729         mkdir $DIR/$tdir/normal_dir
22730
22731         #Checking when client cache stripe index
22732         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
22733         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
22734                 error "create striped_dir failed"
22735
22736         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
22737                 error "create dir0 fails"
22738         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
22739         [ $stripe_index -eq 0 ] ||
22740                 error "dir0 expect index 0 got $stripe_index"
22741
22742         mkdir $DIR/$tdir/striped_dir/dir1 ||
22743                 error "create dir1 fails"
22744         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
22745         [ $stripe_index -eq 1 ] ||
22746                 error "dir1 expect index 1 got $stripe_index"
22747
22748         #check default stripe count/stripe index
22749         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
22750         test_300_check_default_striped_dir normal_dir 1 0
22751         test_300_check_default_striped_dir normal_dir -1 1
22752         test_300_check_default_striped_dir normal_dir 2 -1
22753
22754         #delete default stripe information
22755         echo "delete default stripeEA"
22756         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
22757                 error "set default stripe on striped dir error"
22758
22759         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
22760         for dir in $(find $DIR/$tdir/normal_dir/*); do
22761                 stripe_count=$($LFS getdirstripe -c $dir)
22762                 [ $stripe_count -eq 0 ] ||
22763                         error "expect 1 get $stripe_count for $dir"
22764         done
22765 }
22766 run_test 300g "check default striped directory for normal directory"
22767
22768 test_300h() {
22769         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22770         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22771                 skip "Need MDS version at least 2.7.55"
22772
22773         local dir
22774         local stripe_count
22775
22776         mkdir $DIR/$tdir
22777         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22778                 error "set striped dir error"
22779
22780         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
22781         test_300_check_default_striped_dir striped_dir 1 0
22782         test_300_check_default_striped_dir striped_dir -1 1
22783         test_300_check_default_striped_dir striped_dir 2 -1
22784
22785         #delete default stripe information
22786         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
22787                 error "set default stripe on striped dir error"
22788
22789         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
22790         for dir in $(find $DIR/$tdir/striped_dir/*); do
22791                 stripe_count=$($LFS getdirstripe -c $dir)
22792                 [ $stripe_count -eq 0 ] ||
22793                         error "expect 1 get $stripe_count for $dir"
22794         done
22795 }
22796 run_test 300h "check default striped directory for striped directory"
22797
22798 test_300i() {
22799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22800         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22801         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22802                 skip "Need MDS version at least 2.7.55"
22803
22804         local stripe_count
22805         local file
22806
22807         mkdir $DIR/$tdir
22808
22809         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22810                 error "set striped dir error"
22811
22812         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22813                 error "create files under striped dir failed"
22814
22815         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
22816                 error "set striped hashdir error"
22817
22818         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
22819                 error "create dir0 under hash dir failed"
22820         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
22821                 error "create dir1 under hash dir failed"
22822         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
22823                 error "create dir2 under hash dir failed"
22824
22825         # unfortunately, we need to umount to clear dir layout cache for now
22826         # once we fully implement dir layout, we can drop this
22827         umount_client $MOUNT || error "umount failed"
22828         mount_client $MOUNT || error "mount failed"
22829
22830         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
22831         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
22832         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
22833
22834         #set the stripe to be unknown hash type
22835         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
22836         $LCTL set_param fail_loc=0x1901
22837         for ((i = 0; i < 10; i++)); do
22838                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
22839                         error "stat f-$i failed"
22840                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
22841         done
22842
22843         touch $DIR/$tdir/striped_dir/f0 &&
22844                 error "create under striped dir with unknown hash should fail"
22845
22846         $LCTL set_param fail_loc=0
22847
22848         umount_client $MOUNT || error "umount failed"
22849         mount_client $MOUNT || error "mount failed"
22850
22851         return 0
22852 }
22853 run_test 300i "client handle unknown hash type striped directory"
22854
22855 test_300j() {
22856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22858         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22859                 skip "Need MDS version at least 2.7.55"
22860
22861         local stripe_count
22862         local file
22863
22864         mkdir $DIR/$tdir
22865
22866         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
22867         $LCTL set_param fail_loc=0x1702
22868         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
22869                 error "set striped dir error"
22870
22871         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
22872                 error "create files under striped dir failed"
22873
22874         $LCTL set_param fail_loc=0
22875
22876         rm -rf $DIR/$tdir || error "unlink striped dir fails"
22877
22878         return 0
22879 }
22880 run_test 300j "test large update record"
22881
22882 test_300k() {
22883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22885         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22886                 skip "Need MDS version at least 2.7.55"
22887
22888         # this test needs a huge transaction
22889         local kb
22890         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
22891              osd*.$FSNAME-MDT0000.kbytestotal")
22892         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
22893
22894         local stripe_count
22895         local file
22896
22897         mkdir $DIR/$tdir
22898
22899         #define OBD_FAIL_LARGE_STRIPE   0x1703
22900         $LCTL set_param fail_loc=0x1703
22901         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
22902                 error "set striped dir error"
22903         $LCTL set_param fail_loc=0
22904
22905         $LFS getdirstripe $DIR/$tdir/striped_dir ||
22906                 error "getstripeddir fails"
22907         rm -rf $DIR/$tdir/striped_dir ||
22908                 error "unlink striped dir fails"
22909
22910         return 0
22911 }
22912 run_test 300k "test large striped directory"
22913
22914 test_300l() {
22915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22916         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22917         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22918                 skip "Need MDS version at least 2.7.55"
22919
22920         local stripe_index
22921
22922         test_mkdir -p $DIR/$tdir/striped_dir
22923         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
22924                         error "chown $RUNAS_ID failed"
22925         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
22926                 error "set default striped dir failed"
22927
22928         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
22929         $LCTL set_param fail_loc=0x80000158
22930         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
22931
22932         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
22933         [ $stripe_index -eq 1 ] ||
22934                 error "expect 1 get $stripe_index for $dir"
22935 }
22936 run_test 300l "non-root user to create dir under striped dir with stale layout"
22937
22938 test_300m() {
22939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22940         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
22941         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22942                 skip "Need MDS version at least 2.7.55"
22943
22944         mkdir -p $DIR/$tdir/striped_dir
22945         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
22946                 error "set default stripes dir error"
22947
22948         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
22949
22950         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
22951         [ $stripe_count -eq 0 ] ||
22952                         error "expect 0 get $stripe_count for a"
22953
22954         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
22955                 error "set default stripes dir error"
22956
22957         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
22958
22959         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
22960         [ $stripe_count -eq 0 ] ||
22961                         error "expect 0 get $stripe_count for b"
22962
22963         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
22964                 error "set default stripes dir error"
22965
22966         mkdir $DIR/$tdir/striped_dir/c &&
22967                 error "default stripe_index is invalid, mkdir c should fails"
22968
22969         rm -rf $DIR/$tdir || error "rmdir fails"
22970 }
22971 run_test 300m "setstriped directory on single MDT FS"
22972
22973 cleanup_300n() {
22974         local list=$(comma_list $(mdts_nodes))
22975
22976         trap 0
22977         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
22978 }
22979
22980 test_300n() {
22981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22982         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22983         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22984                 skip "Need MDS version at least 2.7.55"
22985         remote_mds_nodsh && skip "remote MDS with nodsh"
22986
22987         local stripe_index
22988         local list=$(comma_list $(mdts_nodes))
22989
22990         trap cleanup_300n RETURN EXIT
22991         mkdir -p $DIR/$tdir
22992         chmod 777 $DIR/$tdir
22993         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
22994                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
22995                 error "create striped dir succeeds with gid=0"
22996
22997         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
22998         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
22999                 error "create striped dir fails with gid=-1"
23000
23001         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23002         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23003                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23004                 error "set default striped dir succeeds with gid=0"
23005
23006
23007         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23008         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23009                 error "set default striped dir fails with gid=-1"
23010
23011
23012         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23013         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23014                                         error "create test_dir fails"
23015         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23016                                         error "create test_dir1 fails"
23017         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23018                                         error "create test_dir2 fails"
23019         cleanup_300n
23020 }
23021 run_test 300n "non-root user to create dir under striped dir with default EA"
23022
23023 test_300o() {
23024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23025         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23026         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23027                 skip "Need MDS version at least 2.7.55"
23028
23029         local numfree1
23030         local numfree2
23031
23032         mkdir -p $DIR/$tdir
23033
23034         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23035         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23036         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23037                 skip "not enough free inodes $numfree1 $numfree2"
23038         fi
23039
23040         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23041         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23042         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23043                 skip "not enough free space $numfree1 $numfree2"
23044         fi
23045
23046         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23047                 error "setdirstripe fails"
23048
23049         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23050                 error "create dirs fails"
23051
23052         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23053         ls $DIR/$tdir/striped_dir > /dev/null ||
23054                 error "ls striped dir fails"
23055         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23056                 error "unlink big striped dir fails"
23057 }
23058 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23059
23060 test_300p() {
23061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23062         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23063         remote_mds_nodsh && skip "remote MDS with nodsh"
23064
23065         mkdir_on_mdt0 $DIR/$tdir
23066
23067         #define OBD_FAIL_OUT_ENOSPC     0x1704
23068         do_facet mds2 lctl set_param fail_loc=0x80001704
23069         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23070                  && error "create striped directory should fail"
23071
23072         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23073
23074         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23075         true
23076 }
23077 run_test 300p "create striped directory without space"
23078
23079 test_300q() {
23080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23082
23083         local fd=$(free_fd)
23084         local cmd="exec $fd<$tdir"
23085         cd $DIR
23086         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23087         eval $cmd
23088         cmd="exec $fd<&-"
23089         trap "eval $cmd" EXIT
23090         cd $tdir || error "cd $tdir fails"
23091         rmdir  ../$tdir || error "rmdir $tdir fails"
23092         mkdir local_dir && error "create dir succeeds"
23093         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23094         eval $cmd
23095         return 0
23096 }
23097 run_test 300q "create remote directory under orphan directory"
23098
23099 test_300r() {
23100         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23101                 skip "Need MDS version at least 2.7.55" && return
23102         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23103
23104         mkdir $DIR/$tdir
23105
23106         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23107                 error "set striped dir error"
23108
23109         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23110                 error "getstripeddir fails"
23111
23112         local stripe_count
23113         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23114                       awk '/lmv_stripe_count:/ { print $2 }')
23115
23116         [ $MDSCOUNT -ne $stripe_count ] &&
23117                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23118
23119         rm -rf $DIR/$tdir/striped_dir ||
23120                 error "unlink striped dir fails"
23121 }
23122 run_test 300r "test -1 striped directory"
23123
23124 test_300s_helper() {
23125         local count=$1
23126
23127         local stripe_dir=$DIR/$tdir/striped_dir.$count
23128
23129         $LFS mkdir -c $count $stripe_dir ||
23130                 error "lfs mkdir -c error"
23131
23132         $LFS getdirstripe $stripe_dir ||
23133                 error "lfs getdirstripe fails"
23134
23135         local stripe_count
23136         stripe_count=$($LFS getdirstripe $stripe_dir |
23137                       awk '/lmv_stripe_count:/ { print $2 }')
23138
23139         [ $count -ne $stripe_count ] &&
23140                 error_noexit "bad stripe count $stripe_count expected $count"
23141
23142         local dupe_stripes
23143         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23144                 awk '/0x/ {count[$1] += 1}; END {
23145                         for (idx in count) {
23146                                 if (count[idx]>1) {
23147                                         print "index " idx " count " count[idx]
23148                                 }
23149                         }
23150                 }')
23151
23152         if [[ -n "$dupe_stripes" ]] ; then
23153                 lfs getdirstripe $stripe_dir
23154                 error_noexit "Dupe MDT above: $dupe_stripes "
23155         fi
23156
23157         rm -rf $stripe_dir ||
23158                 error_noexit "unlink $stripe_dir fails"
23159 }
23160
23161 test_300s() {
23162         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23163                 skip "Need MDS version at least 2.7.55" && return
23164         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23165
23166         mkdir $DIR/$tdir
23167         for count in $(seq 2 $MDSCOUNT); do
23168                 test_300s_helper $count
23169         done
23170 }
23171 run_test 300s "test lfs mkdir -c without -i"
23172
23173
23174 prepare_remote_file() {
23175         mkdir $DIR/$tdir/src_dir ||
23176                 error "create remote source failed"
23177
23178         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23179                  error "cp to remote source failed"
23180         touch $DIR/$tdir/src_dir/a
23181
23182         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23183                 error "create remote target dir failed"
23184
23185         touch $DIR/$tdir/tgt_dir/b
23186
23187         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23188                 error "rename dir cross MDT failed!"
23189
23190         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23191                 error "src_child still exists after rename"
23192
23193         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23194                 error "missing file(a) after rename"
23195
23196         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23197                 error "diff after rename"
23198 }
23199
23200 test_310a() {
23201         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23203
23204         local remote_file=$DIR/$tdir/tgt_dir/b
23205
23206         mkdir -p $DIR/$tdir
23207
23208         prepare_remote_file || error "prepare remote file failed"
23209
23210         #open-unlink file
23211         $OPENUNLINK $remote_file $remote_file ||
23212                 error "openunlink $remote_file failed"
23213         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23214 }
23215 run_test 310a "open unlink remote file"
23216
23217 test_310b() {
23218         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23220
23221         local remote_file=$DIR/$tdir/tgt_dir/b
23222
23223         mkdir -p $DIR/$tdir
23224
23225         prepare_remote_file || error "prepare remote file failed"
23226
23227         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23228         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23229         $CHECKSTAT -t file $remote_file || error "check file failed"
23230 }
23231 run_test 310b "unlink remote file with multiple links while open"
23232
23233 test_310c() {
23234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23235         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23236
23237         local remote_file=$DIR/$tdir/tgt_dir/b
23238
23239         mkdir -p $DIR/$tdir
23240
23241         prepare_remote_file || error "prepare remote file failed"
23242
23243         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23244         multiop_bg_pause $remote_file O_uc ||
23245                         error "mulitop failed for remote file"
23246         MULTIPID=$!
23247         $MULTIOP $DIR/$tfile Ouc
23248         kill -USR1 $MULTIPID
23249         wait $MULTIPID
23250 }
23251 run_test 310c "open-unlink remote file with multiple links"
23252
23253 #LU-4825
23254 test_311() {
23255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23256         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23257         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23258                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23259         remote_mds_nodsh && skip "remote MDS with nodsh"
23260
23261         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23262         local mdts=$(comma_list $(mdts_nodes))
23263
23264         mkdir -p $DIR/$tdir
23265         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23266         createmany -o $DIR/$tdir/$tfile. 1000
23267
23268         # statfs data is not real time, let's just calculate it
23269         old_iused=$((old_iused + 1000))
23270
23271         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23272                         osp.*OST0000*MDT0000.create_count")
23273         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23274                                 osp.*OST0000*MDT0000.max_create_count")
23275         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23276
23277         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23278         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23279         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23280
23281         unlinkmany $DIR/$tdir/$tfile. 1000
23282
23283         do_nodes $mdts "$LCTL set_param -n \
23284                         osp.*OST0000*.max_create_count=$max_count"
23285         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23286                 do_nodes $mdts "$LCTL set_param -n \
23287                                 osp.*OST0000*.create_count=$count"
23288         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23289                         grep "=0" && error "create_count is zero"
23290
23291         local new_iused
23292         for i in $(seq 120); do
23293                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23294                 # system may be too busy to destroy all objs in time, use
23295                 # a somewhat small value to not fail autotest
23296                 [ $((old_iused - new_iused)) -gt 400 ] && break
23297                 sleep 1
23298         done
23299
23300         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23301         [ $((old_iused - new_iused)) -gt 400 ] ||
23302                 error "objs not destroyed after unlink"
23303 }
23304 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23305
23306 zfs_oid_to_objid()
23307 {
23308         local ost=$1
23309         local objid=$2
23310
23311         local vdevdir=$(dirname $(facet_vdevice $ost))
23312         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23313         local zfs_zapid=$(do_facet $ost $cmd |
23314                           grep -w "/O/0/d$((objid%32))" -C 5 |
23315                           awk '/Object/{getline; print $1}')
23316         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23317                           awk "/$objid = /"'{printf $3}')
23318
23319         echo $zfs_objid
23320 }
23321
23322 zfs_object_blksz() {
23323         local ost=$1
23324         local objid=$2
23325
23326         local vdevdir=$(dirname $(facet_vdevice $ost))
23327         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23328         local blksz=$(do_facet $ost $cmd $objid |
23329                       awk '/dblk/{getline; printf $4}')
23330
23331         case "${blksz: -1}" in
23332                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23333                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23334                 *) ;;
23335         esac
23336
23337         echo $blksz
23338 }
23339
23340 test_312() { # LU-4856
23341         remote_ost_nodsh && skip "remote OST with nodsh"
23342         [ "$ost1_FSTYPE" = "zfs" ] ||
23343                 skip_env "the test only applies to zfs"
23344
23345         local max_blksz=$(do_facet ost1 \
23346                           $ZFS get -p recordsize $(facet_device ost1) |
23347                           awk '!/VALUE/{print $3}')
23348
23349         # to make life a little bit easier
23350         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23351         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23352
23353         local tf=$DIR/$tdir/$tfile
23354         touch $tf
23355         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23356
23357         # Get ZFS object id
23358         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23359         # block size change by sequential overwrite
23360         local bs
23361
23362         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23363                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23364
23365                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23366                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23367         done
23368         rm -f $tf
23369
23370         # block size change by sequential append write
23371         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23372         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23373         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23374         local count
23375
23376         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23377                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23378                         oflag=sync conv=notrunc
23379
23380                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23381                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23382                         error "blksz error, actual $blksz, " \
23383                                 "expected: 2 * $count * $PAGE_SIZE"
23384         done
23385         rm -f $tf
23386
23387         # random write
23388         touch $tf
23389         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23390         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23391
23392         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23393         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23394         [ $blksz -eq $PAGE_SIZE ] ||
23395                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23396
23397         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23398         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23399         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23400
23401         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23402         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23403         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23404 }
23405 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23406
23407 test_313() {
23408         remote_ost_nodsh && skip "remote OST with nodsh"
23409
23410         local file=$DIR/$tfile
23411
23412         rm -f $file
23413         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23414
23415         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23416         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23417         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23418                 error "write should failed"
23419         do_facet ost1 "$LCTL set_param fail_loc=0"
23420         rm -f $file
23421 }
23422 run_test 313 "io should fail after last_rcvd update fail"
23423
23424 test_314() {
23425         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23426
23427         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23428         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23429         rm -f $DIR/$tfile
23430         wait_delete_completed
23431         do_facet ost1 "$LCTL set_param fail_loc=0"
23432 }
23433 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23434
23435 test_315() { # LU-618
23436         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23437
23438         local file=$DIR/$tfile
23439         rm -f $file
23440
23441         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23442                 error "multiop file write failed"
23443         $MULTIOP $file oO_RDONLY:r4063232_c &
23444         PID=$!
23445
23446         sleep 2
23447
23448         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23449         kill -USR1 $PID
23450
23451         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23452         rm -f $file
23453 }
23454 run_test 315 "read should be accounted"
23455
23456 test_316() {
23457         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23458         large_xattr_enabled || skip_env "ea_inode feature disabled"
23459
23460         rm -rf $DIR/$tdir/d
23461         mkdir -p $DIR/$tdir/d
23462         chown nobody $DIR/$tdir/d
23463         touch $DIR/$tdir/d/file
23464
23465         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23466 }
23467 run_test 316 "lfs mv"
23468
23469 test_317() {
23470         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23471                 skip "Need MDS version at least 2.11.53"
23472         if [ "$ost1_FSTYPE" == "zfs" ]; then
23473                 skip "LU-10370: no implementation for ZFS"
23474         fi
23475
23476         local trunc_sz
23477         local grant_blk_size
23478
23479         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23480                         awk '/grant_block_size:/ { print $2; exit; }')
23481         #
23482         # Create File of size 5M. Truncate it to below size's and verify
23483         # blocks count.
23484         #
23485         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23486                 error "Create file $DIR/$tfile failed"
23487         stack_trap "rm -f $DIR/$tfile" EXIT
23488
23489         for trunc_sz in 2097152 4097 4000 509 0; do
23490                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23491                         error "truncate $tfile to $trunc_sz failed"
23492                 local sz=$(stat --format=%s $DIR/$tfile)
23493                 local blk=$(stat --format=%b $DIR/$tfile)
23494                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23495                                      grant_blk_size) * 8))
23496
23497                 if [[ $blk -ne $trunc_blk ]]; then
23498                         $(which stat) $DIR/$tfile
23499                         error "Expected Block $trunc_blk got $blk for $tfile"
23500                 fi
23501
23502                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23503                         error "Expected Size $trunc_sz got $sz for $tfile"
23504         done
23505
23506         #
23507         # sparse file test
23508         # Create file with a hole and write actual two blocks. Block count
23509         # must be 16.
23510         #
23511         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
23512                 conv=fsync || error "Create file : $DIR/$tfile"
23513
23514         # Calculate the final truncate size.
23515         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
23516
23517         #
23518         # truncate to size $trunc_sz bytes. Strip the last block
23519         # The block count must drop to 8
23520         #
23521         $TRUNCATE $DIR/$tfile $trunc_sz ||
23522                 error "truncate $tfile to $trunc_sz failed"
23523
23524         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23525         sz=$(stat --format=%s $DIR/$tfile)
23526         blk=$(stat --format=%b $DIR/$tfile)
23527
23528         if [[ $blk -ne $trunc_bsz ]]; then
23529                 $(which stat) $DIR/$tfile
23530                 error "Expected Block $trunc_bsz got $blk for $tfile"
23531         fi
23532
23533         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23534                 error "Expected Size $trunc_sz got $sz for $tfile"
23535 }
23536 run_test 317 "Verify blocks get correctly update after truncate"
23537
23538 test_318() {
23539         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23540         local old_max_active=$($LCTL get_param -n \
23541                             ${llite_name}.max_read_ahead_async_active \
23542                             2>/dev/null)
23543
23544         $LCTL set_param llite.*.max_read_ahead_async_active=256
23545         local max_active=$($LCTL get_param -n \
23546                            ${llite_name}.max_read_ahead_async_active \
23547                            2>/dev/null)
23548         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23549
23550         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23551                 error "set max_read_ahead_async_active should succeed"
23552
23553         $LCTL set_param llite.*.max_read_ahead_async_active=512
23554         max_active=$($LCTL get_param -n \
23555                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23556         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23557
23558         # restore @max_active
23559         [ $old_max_active -ne 0 ] && $LCTL set_param \
23560                 llite.*.max_read_ahead_async_active=$old_max_active
23561
23562         local old_threshold=$($LCTL get_param -n \
23563                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23564         local max_per_file_mb=$($LCTL get_param -n \
23565                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23566
23567         local invalid=$(($max_per_file_mb + 1))
23568         $LCTL set_param \
23569                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23570                         && error "set $invalid should fail"
23571
23572         local valid=$(($invalid - 1))
23573         $LCTL set_param \
23574                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23575                         error "set $valid should succeed"
23576         local threshold=$($LCTL get_param -n \
23577                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23578         [ $threshold -eq $valid ] || error \
23579                 "expect threshold $valid got $threshold"
23580         $LCTL set_param \
23581                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23582 }
23583 run_test 318 "Verify async readahead tunables"
23584
23585 test_319() {
23586         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23587
23588         local before=$(date +%s)
23589         local evict
23590         local mdir=$DIR/$tdir
23591         local file=$mdir/xxx
23592
23593         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23594         touch $file
23595
23596 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23597         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23598         $LFS mv -m1 $file &
23599
23600         sleep 1
23601         dd if=$file of=/dev/null
23602         wait
23603         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23604           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23605
23606         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23607 }
23608 run_test 319 "lost lease lock on migrate error"
23609
23610 test_398a() { # LU-4198
23611         local ost1_imp=$(get_osc_import_name client ost1)
23612         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23613                          cut -d'.' -f2)
23614
23615         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23616         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23617
23618         # request a new lock on client
23619         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23620
23621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23622         local lock_count=$($LCTL get_param -n \
23623                            ldlm.namespaces.$imp_name.lru_size)
23624         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23625
23626         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
23627
23628         # no lock cached, should use lockless IO and not enqueue new lock
23629         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23630         lock_count=$($LCTL get_param -n \
23631                      ldlm.namespaces.$imp_name.lru_size)
23632         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
23633 }
23634 run_test 398a "direct IO should cancel lock otherwise lockless"
23635
23636 test_398b() { # LU-4198
23637         which fio || skip_env "no fio installed"
23638         $LFS setstripe -c -1 $DIR/$tfile
23639
23640         local size=12
23641         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
23642
23643         local njobs=4
23644         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
23645         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23646                 --numjobs=$njobs --fallocate=none \
23647                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23648                 --filename=$DIR/$tfile &
23649         bg_pid=$!
23650
23651         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
23652         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
23653                 --numjobs=$njobs --fallocate=none \
23654                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23655                 --filename=$DIR/$tfile || true
23656         wait $bg_pid
23657
23658         rm -f $DIR/$tfile
23659 }
23660 run_test 398b "DIO and buffer IO race"
23661
23662 test_398c() { # LU-4198
23663         local ost1_imp=$(get_osc_import_name client ost1)
23664         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23665                          cut -d'.' -f2)
23666
23667         which fio || skip_env "no fio installed"
23668
23669         saved_debug=$($LCTL get_param -n debug)
23670         $LCTL set_param debug=0
23671
23672         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
23673         ((size /= 1024)) # by megabytes
23674         ((size /= 2)) # write half of the OST at most
23675         [ $size -gt 40 ] && size=40 #reduce test time anyway
23676
23677         $LFS setstripe -c 1 $DIR/$tfile
23678
23679         # it seems like ldiskfs reserves more space than necessary if the
23680         # writing blocks are not mapped, so it extends the file firstly
23681         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
23682         cancel_lru_locks osc
23683
23684         # clear and verify rpc_stats later
23685         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
23686
23687         local njobs=4
23688         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
23689         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
23690                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23691                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23692                 --filename=$DIR/$tfile
23693         [ $? -eq 0 ] || error "fio write error"
23694
23695         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
23696                 error "Locks were requested while doing AIO"
23697
23698         # get the percentage of 1-page I/O
23699         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
23700                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
23701                 awk '{print $7}')
23702         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
23703
23704         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
23705         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
23706                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
23707                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
23708                 --filename=$DIR/$tfile
23709         [ $? -eq 0 ] || error "fio mixed read write error"
23710
23711         echo "AIO with large block size ${size}M"
23712         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
23713                 --numjobs=1 --fallocate=none --ioengine=libaio \
23714                 --iodepth=16 --allow_file_create=0 --size=${size}M \
23715                 --filename=$DIR/$tfile
23716         [ $? -eq 0 ] || error "fio large block size failed"
23717
23718         rm -f $DIR/$tfile
23719         $LCTL set_param debug="$saved_debug"
23720 }
23721 run_test 398c "run fio to test AIO"
23722
23723 test_398d() { #  LU-13846
23724         which aiocp || skip_env "no aiocp installed"
23725         local aio_file=$DIR/$tfile.aio
23726
23727         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23728
23729         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
23730         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
23731         stack_trap "rm -f $DIR/$tfile $aio_file"
23732
23733         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
23734
23735         # make sure we don't crash and fail properly
23736         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23737                 error "aio not aligned with PAGE SIZE should fail"
23738
23739         rm -f $DIR/$tfile $aio_file
23740 }
23741 run_test 398d "run aiocp to verify block size > stripe size"
23742
23743 test_398e() {
23744         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
23745         touch $DIR/$tfile.new
23746         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
23747 }
23748 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
23749
23750 test_398f() { #  LU-14687
23751         which aiocp || skip_env "no aiocp installed"
23752         local aio_file=$DIR/$tfile.aio
23753
23754         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
23755
23756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
23757         stack_trap "rm -f $DIR/$tfile $aio_file"
23758
23759         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23760         $LCTL set_param fail_loc=0x1418
23761         # make sure we don't crash and fail properly
23762         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
23763                 error "aio with page allocation failure succeeded"
23764         $LCTL set_param fail_loc=0
23765         diff $DIR/$tfile $aio_file
23766         [[ $? != 0 ]] || error "no diff after failed aiocp"
23767 }
23768 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
23769
23770 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
23771 # stripe and i/o size must be > stripe size
23772 # Old style synchronous DIO waits after submitting each chunk, resulting in a
23773 # single RPC in flight.  This test shows async DIO submission is working by
23774 # showing multiple RPCs in flight.
23775 test_398g() { #  LU-13798
23776         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23777
23778         # We need to do some i/o first to acquire enough grant to put our RPCs
23779         # in flight; otherwise a new connection may not have enough grant
23780         # available
23781         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23782                 error "parallel dio failed"
23783         stack_trap "rm -f $DIR/$tfile"
23784
23785         # Reduce RPC size to 1M to avoid combination in to larger RPCs
23786         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23787         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23788         stack_trap "$LCTL set_param -n $pages_per_rpc"
23789
23790         # Recreate file so it's empty
23791         rm -f $DIR/$tfile
23792         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
23793         #Pause rpc completion to guarantee we see multiple rpcs in flight
23794         #define OBD_FAIL_OST_BRW_PAUSE_BULK
23795         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
23796         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23797
23798         # Clear rpc stats
23799         $LCTL set_param osc.*.rpc_stats=c
23800
23801         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23802                 error "parallel dio failed"
23803         stack_trap "rm -f $DIR/$tfile"
23804
23805         $LCTL get_param osc.*-OST0000-*.rpc_stats
23806         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23807                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23808                 grep "8:" | awk '{print $8}')
23809         # We look at the "8 rpcs in flight" field, and verify A) it is present
23810         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
23811         # as expected for an 8M DIO to a file with 1M stripes.
23812         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
23813
23814         # Verify turning off parallel dio works as expected
23815         # Clear rpc stats
23816         $LCTL set_param osc.*.rpc_stats=c
23817         $LCTL set_param llite.*.parallel_dio=0
23818         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
23819
23820         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
23821                 error "dio with parallel dio disabled failed"
23822
23823         # Ideally, we would see only one RPC in flight here, but there is an
23824         # unavoidable race between i/o completion and RPC in flight counting,
23825         # so while only 1 i/o is in flight at a time, the RPC in flight counter
23826         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
23827         # So instead we just verify it's always < 8.
23828         $LCTL get_param osc.*-OST0000-*.rpc_stats
23829         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
23830                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
23831                 grep '^$' -B1 | grep . | awk '{print $1}')
23832         [ $ret != "8:" ] ||
23833                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
23834 }
23835 run_test 398g "verify parallel dio async RPC submission"
23836
23837 test_398h() { #  LU-13798
23838         local dio_file=$DIR/$tfile.dio
23839
23840         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23841
23842         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23843         stack_trap "rm -f $DIR/$tfile $dio_file"
23844
23845         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
23846                 error "parallel dio failed"
23847         diff $DIR/$tfile $dio_file
23848         [[ $? == 0 ]] || error "file diff after aiocp"
23849 }
23850 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
23851
23852 test_398i() { #  LU-13798
23853         local dio_file=$DIR/$tfile.dio
23854
23855         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
23856
23857         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23858         stack_trap "rm -f $DIR/$tfile $dio_file"
23859
23860         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
23861         $LCTL set_param fail_loc=0x1418
23862         # make sure we don't crash and fail properly
23863         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
23864                 error "parallel dio page allocation failure succeeded"
23865         diff $DIR/$tfile $dio_file
23866         [[ $? != 0 ]] || error "no diff after failed aiocp"
23867 }
23868 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
23869
23870 test_398j() { #  LU-13798
23871         # Stripe size > RPC size but less than i/o size tests split across
23872         # stripes and RPCs for individual i/o op
23873         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
23874
23875         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
23876         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
23877         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
23878         stack_trap "$LCTL set_param -n $pages_per_rpc"
23879
23880         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23881                 error "parallel dio write failed"
23882         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
23883
23884         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
23885                 error "parallel dio read failed"
23886         diff $DIR/$tfile $DIR/$tfile.2
23887         [[ $? == 0 ]] || error "file diff after parallel dio read"
23888 }
23889 run_test 398j "test parallel dio where stripe size > rpc_size"
23890
23891 test_398k() { #  LU-13798
23892         wait_delete_completed
23893         wait_mds_ost_sync
23894
23895         # 4 stripe file; we will cause out of space on OST0
23896         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23897
23898         # Fill OST0 (if it's not too large)
23899         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23900                    head -n1)
23901         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23902                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23903         fi
23904         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23905         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23906                 error "dd should fill OST0"
23907         stack_trap "rm -f $DIR/$tfile.1"
23908
23909         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
23910         err=$?
23911
23912         ls -la $DIR/$tfile
23913         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
23914                 error "file is not 0 bytes in size"
23915
23916         # dd above should not succeed, but don't error until here so we can
23917         # get debug info above
23918         [[ $err != 0 ]] ||
23919                 error "parallel dio write with enospc succeeded"
23920         stack_trap "rm -f $DIR/$tfile"
23921 }
23922 run_test 398k "test enospc on first stripe"
23923
23924 test_398l() { #  LU-13798
23925         wait_delete_completed
23926         wait_mds_ost_sync
23927
23928         # 4 stripe file; we will cause out of space on OST0
23929         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
23930         # happens on the second i/o chunk we issue
23931         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
23932
23933         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
23934         stack_trap "rm -f $DIR/$tfile"
23935
23936         # Fill OST0 (if it's not too large)
23937         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
23938                    head -n1)
23939         if [[ $ORIGFREE -gt $MAXFREE ]]; then
23940                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
23941         fi
23942         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
23943         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
23944                 error "dd should fill OST0"
23945         stack_trap "rm -f $DIR/$tfile.1"
23946
23947         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
23948         err=$?
23949         stack_trap "rm -f $DIR/$tfile.2"
23950
23951         # Check that short write completed as expected
23952         ls -la $DIR/$tfile.2
23953         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
23954                 error "file is not 1M in size"
23955
23956         # dd above should not succeed, but don't error until here so we can
23957         # get debug info above
23958         [[ $err != 0 ]] ||
23959                 error "parallel dio write with enospc succeeded"
23960
23961         # Truncate source file to same length as output file and diff them
23962         $TRUNCATE $DIR/$tfile 1048576
23963         diff $DIR/$tfile $DIR/$tfile.2
23964         [[ $? == 0 ]] || error "data incorrect after short write"
23965 }
23966 run_test 398l "test enospc on intermediate stripe/RPC"
23967
23968 test_398m() { #  LU-13798
23969         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
23970
23971         # Set up failure on OST0, the first stripe:
23972         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
23973         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
23974         # So this fail_val specifies OST0
23975         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
23976         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
23977
23978         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
23979                 error "parallel dio write with failure on first stripe succeeded"
23980         stack_trap "rm -f $DIR/$tfile"
23981         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23982
23983         # Place data in file for read
23984         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
23985                 error "parallel dio write failed"
23986
23987         # Fail read on OST0, first stripe
23988         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
23989         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
23990         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
23991                 error "parallel dio read with error on first stripe succeeded"
23992         rm -f $DIR/$tfile.2
23993         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
23994
23995         # Switch to testing on OST1, second stripe
23996         # Clear file contents, maintain striping
23997         echo > $DIR/$tfile
23998         # Set up failure on OST1, second stripe:
23999         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24000         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24001
24002         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24003                 error "parallel dio write with failure on first stripe succeeded"
24004         stack_trap "rm -f $DIR/$tfile"
24005         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24006
24007         # Place data in file for read
24008         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24009                 error "parallel dio write failed"
24010
24011         # Fail read on OST1, second stripe
24012         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24013         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24014         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24015                 error "parallel dio read with error on first stripe succeeded"
24016         rm -f $DIR/$tfile.2
24017         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24018 }
24019 run_test 398m "test RPC failures with parallel dio"
24020
24021 # Parallel submission of DIO should not cause problems for append, but it's
24022 # important to verify.
24023 test_398n() { #  LU-13798
24024         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24025
24026         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24027                 error "dd to create source file failed"
24028         stack_trap "rm -f $DIR/$tfile"
24029
24030         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24031                 error "parallel dio write with failure on second stripe succeeded"
24032         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24033         diff $DIR/$tfile $DIR/$tfile.1
24034         [[ $? == 0 ]] || error "data incorrect after append"
24035
24036 }
24037 run_test 398n "test append with parallel DIO"
24038
24039 test_fake_rw() {
24040         local read_write=$1
24041         if [ "$read_write" = "write" ]; then
24042                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24043         elif [ "$read_write" = "read" ]; then
24044                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24045         else
24046                 error "argument error"
24047         fi
24048
24049         # turn off debug for performance testing
24050         local saved_debug=$($LCTL get_param -n debug)
24051         $LCTL set_param debug=0
24052
24053         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24054
24055         # get ost1 size - $FSNAME-OST0000
24056         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24057         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24058         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24059
24060         if [ "$read_write" = "read" ]; then
24061                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24062         fi
24063
24064         local start_time=$(date +%s.%N)
24065         $dd_cmd bs=1M count=$blocks oflag=sync ||
24066                 error "real dd $read_write error"
24067         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24068
24069         if [ "$read_write" = "write" ]; then
24070                 rm -f $DIR/$tfile
24071         fi
24072
24073         # define OBD_FAIL_OST_FAKE_RW           0x238
24074         do_facet ost1 $LCTL set_param fail_loc=0x238
24075
24076         local start_time=$(date +%s.%N)
24077         $dd_cmd bs=1M count=$blocks oflag=sync ||
24078                 error "fake dd $read_write error"
24079         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24080
24081         if [ "$read_write" = "write" ]; then
24082                 # verify file size
24083                 cancel_lru_locks osc
24084                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24085                         error "$tfile size not $blocks MB"
24086         fi
24087         do_facet ost1 $LCTL set_param fail_loc=0
24088
24089         echo "fake $read_write $duration_fake vs. normal $read_write" \
24090                 "$duration in seconds"
24091         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24092                 error_not_in_vm "fake write is slower"
24093
24094         $LCTL set_param -n debug="$saved_debug"
24095         rm -f $DIR/$tfile
24096 }
24097 test_399a() { # LU-7655 for OST fake write
24098         remote_ost_nodsh && skip "remote OST with nodsh"
24099
24100         test_fake_rw write
24101 }
24102 run_test 399a "fake write should not be slower than normal write"
24103
24104 test_399b() { # LU-8726 for OST fake read
24105         remote_ost_nodsh && skip "remote OST with nodsh"
24106         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24107                 skip_env "ldiskfs only test"
24108         fi
24109
24110         test_fake_rw read
24111 }
24112 run_test 399b "fake read should not be slower than normal read"
24113
24114 test_400a() { # LU-1606, was conf-sanity test_74
24115         if ! which $CC > /dev/null 2>&1; then
24116                 skip_env "$CC is not installed"
24117         fi
24118
24119         local extra_flags=''
24120         local out=$TMP/$tfile
24121         local prefix=/usr/include/lustre
24122         local prog
24123
24124         # Oleg removes c files in his test rig so test if any c files exist
24125         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24126                 skip_env "Needed c test files are missing"
24127
24128         if ! [[ -d $prefix ]]; then
24129                 # Assume we're running in tree and fixup the include path.
24130                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24131                 extra_flags+=" -L$LUSTRE/utils/.lib"
24132         fi
24133
24134         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24135                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24136                         error "client api broken"
24137         done
24138         rm -f $out
24139 }
24140 run_test 400a "Lustre client api program can compile and link"
24141
24142 test_400b() { # LU-1606, LU-5011
24143         local header
24144         local out=$TMP/$tfile
24145         local prefix=/usr/include/linux/lustre
24146
24147         # We use a hard coded prefix so that this test will not fail
24148         # when run in tree. There are headers in lustre/include/lustre/
24149         # that are not packaged (like lustre_idl.h) and have more
24150         # complicated include dependencies (like config.h and lnet/types.h).
24151         # Since this test about correct packaging we just skip them when
24152         # they don't exist (see below) rather than try to fixup cppflags.
24153
24154         if ! which $CC > /dev/null 2>&1; then
24155                 skip_env "$CC is not installed"
24156         fi
24157
24158         for header in $prefix/*.h; do
24159                 if ! [[ -f "$header" ]]; then
24160                         continue
24161                 fi
24162
24163                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24164                         continue # lustre_ioctl.h is internal header
24165                 fi
24166
24167                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24168                         error "cannot compile '$header'"
24169         done
24170         rm -f $out
24171 }
24172 run_test 400b "packaged headers can be compiled"
24173
24174 test_401a() { #LU-7437
24175         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24176         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24177
24178         #count the number of parameters by "list_param -R"
24179         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24180         #count the number of parameters by listing proc files
24181         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24182         echo "proc_dirs='$proc_dirs'"
24183         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24184         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24185                       sort -u | wc -l)
24186
24187         [ $params -eq $procs ] ||
24188                 error "found $params parameters vs. $procs proc files"
24189
24190         # test the list_param -D option only returns directories
24191         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24192         #count the number of parameters by listing proc directories
24193         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24194                 sort -u | wc -l)
24195
24196         [ $params -eq $procs ] ||
24197                 error "found $params parameters vs. $procs proc files"
24198 }
24199 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24200
24201 test_401b() {
24202         # jobid_var may not allow arbitrary values, so use jobid_name
24203         # if available
24204         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24205                 local testname=jobid_name tmp='testing%p'
24206         else
24207                 local testname=jobid_var tmp=testing
24208         fi
24209
24210         local save=$($LCTL get_param -n $testname)
24211
24212         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24213                 error "no error returned when setting bad parameters"
24214
24215         local jobid_new=$($LCTL get_param -n foe $testname baz)
24216         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24217
24218         $LCTL set_param -n fog=bam $testname=$save bat=fog
24219         local jobid_old=$($LCTL get_param -n foe $testname bag)
24220         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24221 }
24222 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24223
24224 test_401c() {
24225         # jobid_var may not allow arbitrary values, so use jobid_name
24226         # if available
24227         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24228                 local testname=jobid_name
24229         else
24230                 local testname=jobid_var
24231         fi
24232
24233         local jobid_var_old=$($LCTL get_param -n $testname)
24234         local jobid_var_new
24235
24236         $LCTL set_param $testname= &&
24237                 error "no error returned for 'set_param a='"
24238
24239         jobid_var_new=$($LCTL get_param -n $testname)
24240         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24241                 error "$testname was changed by setting without value"
24242
24243         $LCTL set_param $testname &&
24244                 error "no error returned for 'set_param a'"
24245
24246         jobid_var_new=$($LCTL get_param -n $testname)
24247         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24248                 error "$testname was changed by setting without value"
24249 }
24250 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24251
24252 test_401d() {
24253         # jobid_var may not allow arbitrary values, so use jobid_name
24254         # if available
24255         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24256                 local testname=jobid_name new_value='foo=bar%p'
24257         else
24258                 local testname=jobid_var new_valuie=foo=bar
24259         fi
24260
24261         local jobid_var_old=$($LCTL get_param -n $testname)
24262         local jobid_var_new
24263
24264         $LCTL set_param $testname=$new_value ||
24265                 error "'set_param a=b' did not accept a value containing '='"
24266
24267         jobid_var_new=$($LCTL get_param -n $testname)
24268         [[ "$jobid_var_new" == "$new_value" ]] ||
24269                 error "'set_param a=b' failed on a value containing '='"
24270
24271         # Reset the $testname to test the other format
24272         $LCTL set_param $testname=$jobid_var_old
24273         jobid_var_new=$($LCTL get_param -n $testname)
24274         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24275                 error "failed to reset $testname"
24276
24277         $LCTL set_param $testname $new_value ||
24278                 error "'set_param a b' did not accept a value containing '='"
24279
24280         jobid_var_new=$($LCTL get_param -n $testname)
24281         [[ "$jobid_var_new" == "$new_value" ]] ||
24282                 error "'set_param a b' failed on a value containing '='"
24283
24284         $LCTL set_param $testname $jobid_var_old
24285         jobid_var_new=$($LCTL get_param -n $testname)
24286         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24287                 error "failed to reset $testname"
24288 }
24289 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24290
24291 test_401e() { # LU-14779
24292         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24293                 error "lctl list_param MGC* failed"
24294         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24295         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24296                 error "lctl get_param lru_size failed"
24297 }
24298 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24299
24300 test_402() {
24301         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24302         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24303                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24304         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24305                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24306                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24307         remote_mds_nodsh && skip "remote MDS with nodsh"
24308
24309         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24310 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24311         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24312         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24313                 echo "Touch failed - OK"
24314 }
24315 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24316
24317 test_403() {
24318         local file1=$DIR/$tfile.1
24319         local file2=$DIR/$tfile.2
24320         local tfile=$TMP/$tfile
24321
24322         rm -f $file1 $file2 $tfile
24323
24324         touch $file1
24325         ln $file1 $file2
24326
24327         # 30 sec OBD_TIMEOUT in ll_getattr()
24328         # right before populating st_nlink
24329         $LCTL set_param fail_loc=0x80001409
24330         stat -c %h $file1 > $tfile &
24331
24332         # create an alias, drop all locks and reclaim the dentry
24333         < $file2
24334         cancel_lru_locks mdc
24335         cancel_lru_locks osc
24336         sysctl -w vm.drop_caches=2
24337
24338         wait
24339
24340         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24341
24342         rm -f $tfile $file1 $file2
24343 }
24344 run_test 403 "i_nlink should not drop to zero due to aliasing"
24345
24346 test_404() { # LU-6601
24347         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24348                 skip "Need server version newer than 2.8.52"
24349         remote_mds_nodsh && skip "remote MDS with nodsh"
24350
24351         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24352                 awk '/osp .*-osc-MDT/ { print $4}')
24353
24354         local osp
24355         for osp in $mosps; do
24356                 echo "Deactivate: " $osp
24357                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24358                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24359                         awk -vp=$osp '$4 == p { print $2 }')
24360                 [ $stat = IN ] || {
24361                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24362                         error "deactivate error"
24363                 }
24364                 echo "Activate: " $osp
24365                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24366                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24367                         awk -vp=$osp '$4 == p { print $2 }')
24368                 [ $stat = UP ] || {
24369                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24370                         error "activate error"
24371                 }
24372         done
24373 }
24374 run_test 404 "validate manual {de}activated works properly for OSPs"
24375
24376 test_405() {
24377         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24378         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24379                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24380                         skip "Layout swap lock is not supported"
24381
24382         check_swap_layouts_support
24383         check_swap_layout_no_dom $DIR
24384
24385         test_mkdir $DIR/$tdir
24386         swap_lock_test -d $DIR/$tdir ||
24387                 error "One layout swap locked test failed"
24388 }
24389 run_test 405 "Various layout swap lock tests"
24390
24391 test_406() {
24392         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24393         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24394         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24396         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24397                 skip "Need MDS version at least 2.8.50"
24398
24399         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24400         local test_pool=$TESTNAME
24401
24402         pool_add $test_pool || error "pool_add failed"
24403         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24404                 error "pool_add_targets failed"
24405
24406         save_layout_restore_at_exit $MOUNT
24407
24408         # parent set default stripe count only, child will stripe from both
24409         # parent and fs default
24410         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24411                 error "setstripe $MOUNT failed"
24412         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24413         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24414         for i in $(seq 10); do
24415                 local f=$DIR/$tdir/$tfile.$i
24416                 touch $f || error "touch failed"
24417                 local count=$($LFS getstripe -c $f)
24418                 [ $count -eq $OSTCOUNT ] ||
24419                         error "$f stripe count $count != $OSTCOUNT"
24420                 local offset=$($LFS getstripe -i $f)
24421                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24422                 local size=$($LFS getstripe -S $f)
24423                 [ $size -eq $((def_stripe_size * 2)) ] ||
24424                         error "$f stripe size $size != $((def_stripe_size * 2))"
24425                 local pool=$($LFS getstripe -p $f)
24426                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24427         done
24428
24429         # change fs default striping, delete parent default striping, now child
24430         # will stripe from new fs default striping only
24431         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24432                 error "change $MOUNT default stripe failed"
24433         $LFS setstripe -c 0 $DIR/$tdir ||
24434                 error "delete $tdir default stripe failed"
24435         for i in $(seq 11 20); do
24436                 local f=$DIR/$tdir/$tfile.$i
24437                 touch $f || error "touch $f failed"
24438                 local count=$($LFS getstripe -c $f)
24439                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24440                 local offset=$($LFS getstripe -i $f)
24441                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24442                 local size=$($LFS getstripe -S $f)
24443                 [ $size -eq $def_stripe_size ] ||
24444                         error "$f stripe size $size != $def_stripe_size"
24445                 local pool=$($LFS getstripe -p $f)
24446                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24447         done
24448
24449         unlinkmany $DIR/$tdir/$tfile. 1 20
24450
24451         local f=$DIR/$tdir/$tfile
24452         pool_remove_all_targets $test_pool $f
24453         pool_remove $test_pool $f
24454 }
24455 run_test 406 "DNE support fs default striping"
24456
24457 test_407() {
24458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24459         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24460                 skip "Need MDS version at least 2.8.55"
24461         remote_mds_nodsh && skip "remote MDS with nodsh"
24462
24463         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24464                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24465         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24466                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24467         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24468
24469         #define OBD_FAIL_DT_TXN_STOP    0x2019
24470         for idx in $(seq $MDSCOUNT); do
24471                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24472         done
24473         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24474         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24475                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24476         true
24477 }
24478 run_test 407 "transaction fail should cause operation fail"
24479
24480 test_408() {
24481         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24482
24483         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24484         lctl set_param fail_loc=0x8000040a
24485         # let ll_prepare_partial_page() fail
24486         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24487
24488         rm -f $DIR/$tfile
24489
24490         # create at least 100 unused inodes so that
24491         # shrink_icache_memory(0) should not return 0
24492         touch $DIR/$tfile-{0..100}
24493         rm -f $DIR/$tfile-{0..100}
24494         sync
24495
24496         echo 2 > /proc/sys/vm/drop_caches
24497 }
24498 run_test 408 "drop_caches should not hang due to page leaks"
24499
24500 test_409()
24501 {
24502         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24503
24504         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24505         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24506         touch $DIR/$tdir/guard || error "(2) Fail to create"
24507
24508         local PREFIX=$(str_repeat 'A' 128)
24509         echo "Create 1K hard links start at $(date)"
24510         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24511                 error "(3) Fail to hard link"
24512
24513         echo "Links count should be right although linkEA overflow"
24514         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24515         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24516         [ $linkcount -eq 1001 ] ||
24517                 error "(5) Unexpected hard links count: $linkcount"
24518
24519         echo "List all links start at $(date)"
24520         ls -l $DIR/$tdir/foo > /dev/null ||
24521                 error "(6) Fail to list $DIR/$tdir/foo"
24522
24523         echo "Unlink hard links start at $(date)"
24524         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24525                 error "(7) Fail to unlink"
24526         echo "Unlink hard links finished at $(date)"
24527 }
24528 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24529
24530 test_410()
24531 {
24532         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24533                 skip "Need client version at least 2.9.59"
24534         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24535                 skip "Need MODULES build"
24536
24537         # Create a file, and stat it from the kernel
24538         local testfile=$DIR/$tfile
24539         touch $testfile
24540
24541         local run_id=$RANDOM
24542         local my_ino=$(stat --format "%i" $testfile)
24543
24544         # Try to insert the module. This will always fail as the
24545         # module is designed to not be inserted.
24546         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24547             &> /dev/null
24548
24549         # Anything but success is a test failure
24550         dmesg | grep -q \
24551             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24552             error "no inode match"
24553 }
24554 run_test 410 "Test inode number returned from kernel thread"
24555
24556 cleanup_test411_cgroup() {
24557         trap 0
24558         rmdir "$1"
24559 }
24560
24561 test_411() {
24562         local cg_basedir=/sys/fs/cgroup/memory
24563         # LU-9966
24564         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24565                 skip "no setup for cgroup"
24566
24567         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24568                 error "test file creation failed"
24569         cancel_lru_locks osc
24570
24571         # Create a very small memory cgroup to force a slab allocation error
24572         local cgdir=$cg_basedir/osc_slab_alloc
24573         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24574         trap "cleanup_test411_cgroup $cgdir" EXIT
24575         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24576         echo 1M > $cgdir/memory.limit_in_bytes
24577
24578         # Should not LBUG, just be killed by oom-killer
24579         # dd will return 0 even allocation failure in some environment.
24580         # So don't check return value
24581         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24582         cleanup_test411_cgroup $cgdir
24583
24584         return 0
24585 }
24586 run_test 411 "Slab allocation error with cgroup does not LBUG"
24587
24588 test_412() {
24589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24590         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24591                 skip "Need server version at least 2.10.55"
24592         fi
24593
24594         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24595                 error "mkdir failed"
24596         $LFS getdirstripe $DIR/$tdir
24597         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24598         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24599                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24600         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24601         [ $stripe_count -eq 2 ] ||
24602                 error "expect 2 get $stripe_count"
24603 }
24604 run_test 412 "mkdir on specific MDTs"
24605
24606 generate_uneven_mdts() {
24607         local threshold=$1
24608         local ffree
24609         local bavail
24610         local max
24611         local min
24612         local max_index
24613         local min_index
24614         local tmp
24615         local i
24616
24617         echo
24618         echo "Check for uneven MDTs: "
24619
24620         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24621         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24622         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24623
24624         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24625         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24626         max_index=0
24627         min_index=0
24628         for ((i = 1; i < ${#ffree[@]}; i++)); do
24629                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24630                 if [ $tmp -gt $max ]; then
24631                         max=$tmp
24632                         max_index=$i
24633                 fi
24634                 if [ $tmp -lt $min ]; then
24635                         min=$tmp
24636                         min_index=$i
24637                 fi
24638         done
24639
24640         # Check if we need to generate uneven MDTs
24641         local diff=$(((max - min) * 100 / min))
24642         local testdir=$DIR/$tdir-fillmdt
24643
24644         mkdir -p $testdir
24645
24646         i=0
24647         while (( diff < threshold )); do
24648                 # generate uneven MDTs, create till $threshold% diff
24649                 echo -n "weight diff=$diff% must be > $threshold% ..."
24650                 echo "Fill MDT$min_index with 100 files: loop $i"
24651                 testdir=$DIR/$tdir-fillmdt/$i
24652                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
24653                         error "mkdir $testdir failed"
24654                 $LFS setstripe -E 1M -L mdt $testdir ||
24655                         error "setstripe $testdir failed"
24656                 for F in f.{0..99}; do
24657                         dd if=/dev/zero of=$testdir/$F bs=1M count=1 > \
24658                                 /dev/null 2>&1 || error "dd $F failed"
24659                 done
24660
24661                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
24662                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
24663                 max=$(((${ffree[max_index]} >> 8) * \
24664                         (${bavail[max_index]} * bsize >> 16)))
24665                 min=$(((${ffree[min_index]} >> 8) * \
24666                         (${bavail[min_index]} * bsize >> 16)))
24667                 diff=$(((max - min) * 100 / min))
24668                 i=$((i + 1))
24669         done
24670
24671         echo "MDT filesfree available: ${ffree[@]}"
24672         echo "MDT blocks available: ${bavail[@]}"
24673         echo "weight diff=$diff%"
24674 }
24675
24676 test_qos_mkdir() {
24677         local mkdir_cmd=$1
24678         local stripe_count=$2
24679         local mdts=$(comma_list $(mdts_nodes))
24680
24681         local testdir
24682         local lmv_qos_prio_free
24683         local lmv_qos_threshold_rr
24684         local lmv_qos_maxage
24685         local lod_qos_prio_free
24686         local lod_qos_threshold_rr
24687         local lod_qos_maxage
24688         local count
24689         local i
24690
24691         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
24692         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
24693         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24694                 head -n1)
24695         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
24696         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24697         stack_trap "$LCTL set_param \
24698                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
24699         stack_trap "$LCTL set_param \
24700                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
24701         stack_trap "$LCTL set_param \
24702                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
24703
24704         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
24705                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
24706         lod_qos_prio_free=${lod_qos_prio_free%%%}
24707         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
24708                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
24709         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
24710         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24711                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24712         stack_trap "do_nodes $mdts $LCTL set_param \
24713                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
24714         stack_trap "do_nodes $mdts $LCTL set_param \
24715                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
24716         stack_trap "do_nodes $mdts $LCTL set_param \
24717                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
24718
24719         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24720         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
24721
24722         testdir=$DIR/$tdir-s$stripe_count/rr
24723
24724         local stripe_index=$($LFS getstripe -m $testdir)
24725         local test_mkdir_rr=true
24726
24727         echo "dirstripe: '$($LFS getdirstripe $testdir)'"
24728         getfattr -d -m dmv -e hex $testdir | grep dmv
24729         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
24730                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
24731                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
24732                         test_mkdir_rr=false
24733         fi
24734
24735         echo
24736         $test_mkdir_rr &&
24737                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
24738                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
24739
24740         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
24741         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
24742                 eval $mkdir_cmd $testdir/subdir$i ||
24743                         error "$mkdir_cmd subdir$i failed"
24744         done
24745
24746         for (( i = 0; i < $MDSCOUNT; i++ )); do
24747                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24748                 echo "$count directories created on MDT$i"
24749                 if $test_mkdir_rr; then
24750                         (( $count == 100 )) ||
24751                                 error "subdirs are not evenly distributed"
24752                 elif (( $i == $stripe_index )); then
24753                         (( $count == 100 * MDSCOUNT )) ||
24754                                 error "$count subdirs created on MDT$i"
24755                 else
24756                         (( $count == 0 )) ||
24757                                 error "$count subdirs created on MDT$i"
24758                 fi
24759
24760                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
24761                         count=$($LFS getdirstripe $testdir/* |
24762                                 grep -c -P "^\s+$i\t")
24763                         echo "$count stripes created on MDT$i"
24764                         # deviation should < 5% of average
24765                         (( $count >= 95 * stripe_count &&
24766                            $count <= 105 * stripe_count)) ||
24767                                 error "stripes are not evenly distributed"
24768                 fi
24769         done
24770
24771         echo
24772         echo "Check for uneven MDTs: "
24773
24774         local ffree
24775         local bavail
24776         local max
24777         local min
24778         local max_index
24779         local min_index
24780         local tmp
24781
24782         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24783         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24784         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24785
24786         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24787         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24788         max_index=0
24789         min_index=0
24790         for ((i = 1; i < ${#ffree[@]}; i++)); do
24791                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24792                 if [ $tmp -gt $max ]; then
24793                         max=$tmp
24794                         max_index=$i
24795                 fi
24796                 if [ $tmp -lt $min ]; then
24797                         min=$tmp
24798                         min_index=$i
24799                 fi
24800         done
24801
24802         (( ${ffree[min_index]} > 0 )) ||
24803                 skip "no free files in MDT$min_index"
24804         (( ${ffree[min_index]} < 100000000 )) ||
24805                 skip "too many free files in MDT$min_index"
24806
24807         echo "MDT filesfree available: ${ffree[@]}"
24808         echo "MDT blocks available: ${bavail[@]}"
24809         echo "weight diff=$(((max - min) * 100 / min))%"
24810         echo
24811         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
24812
24813         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
24814         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
24815         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
24816         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
24817         # decrease statfs age, so that it can be updated in time
24818         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
24819         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
24820
24821         sleep 1
24822
24823         testdir=$DIR/$tdir-s$stripe_count/qos
24824         local num=200
24825
24826         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
24827         for (( i = 0; i < num * MDSCOUNT; i++ )); do
24828                 eval $mkdir_cmd $testdir/subdir$i ||
24829                         error "$mkdir_cmd subdir$i failed"
24830         done
24831
24832         for (( i = 0; i < $MDSCOUNT; i++ )); do
24833                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
24834                 echo "$count directories created on MDT$i"
24835
24836                 if [ $stripe_count -gt 1 ]; then
24837                         count=$($LFS getdirstripe $testdir/* |
24838                                 grep -c -P "^\s+$i\t")
24839                         echo "$count stripes created on MDT$i"
24840                 fi
24841         done
24842
24843         max=$($LFS getdirstripe -i $testdir/* | grep -c "^$max_index$")
24844         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
24845
24846         # D-value should > 10% of averge
24847         (( max - min >= num / 10 )) ||
24848                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
24849
24850         # 5% for stripes
24851         if (( stripe_count > 1 )); then
24852                 max=$($LFS getdirstripe $testdir/* |
24853                       grep -c -P "^\s+$max_index\t")
24854                 min=$($LFS getdirstripe $testdir/* |
24855                         grep -c -P "^\s+$min_index\t")
24856                 (( max - min >= num * stripe_count / 20 )) ||
24857                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 20)) * $stripe_count"
24858         fi
24859 }
24860
24861 most_full_mdt() {
24862         local ffree
24863         local bavail
24864         local bsize
24865         local min
24866         local min_index
24867         local tmp
24868
24869         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
24870         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
24871         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
24872
24873         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
24874         min_index=0
24875         for ((i = 1; i < ${#ffree[@]}; i++)); do
24876                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
24877                 (( tmp < min )) && min=$tmp && min_index=$i
24878         done
24879
24880         echo -n $min_index
24881 }
24882
24883 test_413a() {
24884         [ $MDSCOUNT -lt 2 ] &&
24885                 skip "We need at least 2 MDTs for this test"
24886
24887         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24888                 skip "Need server version at least 2.12.52"
24889
24890         local stripe_count
24891
24892         generate_uneven_mdts 100
24893         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24894                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
24895                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
24896                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
24897                         error "mkdir failed"
24898                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
24899         done
24900 }
24901 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
24902
24903 test_413b() {
24904         [ $MDSCOUNT -lt 2 ] &&
24905                 skip "We need at least 2 MDTs for this test"
24906
24907         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
24908                 skip "Need server version at least 2.12.52"
24909
24910         local testdir
24911         local stripe_count
24912
24913         generate_uneven_mdts 100
24914         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
24915                 testdir=$DIR/$tdir-s$stripe_count
24916                 mkdir $testdir || error "mkdir $testdir failed"
24917                 mkdir $testdir/rr || error "mkdir rr failed"
24918                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
24919                         error "mkdir qos failed"
24920                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
24921                         $testdir/rr || error "setdirstripe rr failed"
24922                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
24923                         error "setdirstripe failed"
24924                 test_qos_mkdir "mkdir" $stripe_count
24925         done
24926 }
24927 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
24928
24929 test_413c() {
24930         (( $MDSCOUNT >= 2 )) ||
24931                 skip "We need at least 2 MDTs for this test"
24932
24933         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
24934                 skip "Need server version at least 2.14.51"
24935
24936         local testdir
24937         local inherit
24938         local inherit_rr
24939
24940         testdir=$DIR/${tdir}-s1
24941         mkdir $testdir || error "mkdir $testdir failed"
24942         mkdir $testdir/rr || error "mkdir rr failed"
24943         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
24944         # default max_inherit is -1, default max_inherit_rr is 0
24945         $LFS setdirstripe -D -c 1 $testdir/rr ||
24946                 error "setdirstripe rr failed"
24947         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
24948                 error "setdirstripe qos failed"
24949         test_qos_mkdir "mkdir" 1
24950
24951         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
24952         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
24953         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
24954         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
24955         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
24956
24957         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
24958         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
24959         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
24960         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
24961         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
24962         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
24963         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
24964                 error "level2 shouldn't have default LMV" || true
24965 }
24966 run_test 413c "mkdir with default LMV max inherit rr"
24967
24968 test_413d() {
24969         (( MDSCOUNT >= 2 )) ||
24970                 skip "We need at least 2 MDTs for this test"
24971
24972         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
24973                 skip "Need server version at least 2.14.51"
24974
24975         local lmv_qos_threshold_rr
24976
24977         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
24978                 head -n1)
24979         stack_trap "$LCTL set_param \
24980                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
24981
24982         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
24983         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24984         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
24985                 error "$tdir shouldn't have default LMV"
24986         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
24987                 error "mkdir sub failed"
24988
24989         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
24990
24991         (( count == 100 )) || error "$count subdirs on MDT0"
24992 }
24993 run_test 413d "inherit ROOT default LMV"
24994
24995 test_413z() {
24996         local pids=""
24997         local subdir
24998         local pid
24999
25000         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25001                 unlinkmany $subdir/f. 100 &
25002                 pids="$pids $!"
25003         done
25004
25005         for pid in $pids; do
25006                 wait $pid
25007         done
25008 }
25009 run_test 413z "413 test cleanup"
25010
25011 test_414() {
25012 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25013         $LCTL set_param fail_loc=0x80000521
25014         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25015         rm -f $DIR/$tfile
25016 }
25017 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25018
25019 test_415() {
25020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25021         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25022                 skip "Need server version at least 2.11.52"
25023
25024         # LU-11102
25025         local total
25026         local setattr_pid
25027         local start_time
25028         local end_time
25029         local duration
25030
25031         total=500
25032         # this test may be slow on ZFS
25033         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25034
25035         # though this test is designed for striped directory, let's test normal
25036         # directory too since lock is always saved as CoS lock.
25037         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25038         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25039
25040         (
25041                 while true; do
25042                         touch $DIR/$tdir
25043                 done
25044         ) &
25045         setattr_pid=$!
25046
25047         start_time=$(date +%s)
25048         for i in $(seq $total); do
25049                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25050                         > /dev/null
25051         done
25052         end_time=$(date +%s)
25053         duration=$((end_time - start_time))
25054
25055         kill -9 $setattr_pid
25056
25057         echo "rename $total files took $duration sec"
25058         [ $duration -lt 100 ] || error "rename took $duration sec"
25059 }
25060 run_test 415 "lock revoke is not missing"
25061
25062 test_416() {
25063         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25064                 skip "Need server version at least 2.11.55"
25065
25066         # define OBD_FAIL_OSD_TXN_START    0x19a
25067         do_facet mds1 lctl set_param fail_loc=0x19a
25068
25069         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25070
25071         true
25072 }
25073 run_test 416 "transaction start failure won't cause system hung"
25074
25075 cleanup_417() {
25076         trap 0
25077         do_nodes $(comma_list $(mdts_nodes)) \
25078                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25079         do_nodes $(comma_list $(mdts_nodes)) \
25080                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25081         do_nodes $(comma_list $(mdts_nodes)) \
25082                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25083 }
25084
25085 test_417() {
25086         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25087         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25088                 skip "Need MDS version at least 2.11.56"
25089
25090         trap cleanup_417 RETURN EXIT
25091
25092         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25093         do_nodes $(comma_list $(mdts_nodes)) \
25094                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25095         $LFS migrate -m 0 $DIR/$tdir.1 &&
25096                 error "migrate dir $tdir.1 should fail"
25097
25098         do_nodes $(comma_list $(mdts_nodes)) \
25099                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25100         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25101                 error "create remote dir $tdir.2 should fail"
25102
25103         do_nodes $(comma_list $(mdts_nodes)) \
25104                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25105         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25106                 error "create striped dir $tdir.3 should fail"
25107         true
25108 }
25109 run_test 417 "disable remote dir, striped dir and dir migration"
25110
25111 # Checks that the outputs of df [-i] and lfs df [-i] match
25112 #
25113 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25114 check_lfs_df() {
25115         local dir=$2
25116         local inodes
25117         local df_out
25118         local lfs_df_out
25119         local count
25120         local passed=false
25121
25122         # blocks or inodes
25123         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25124
25125         for count in {1..100}; do
25126                 cancel_lru_locks
25127                 sync; sleep 0.2
25128
25129                 # read the lines of interest
25130                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25131                         error "df $inodes $dir | tail -n +2 failed"
25132                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25133                         error "lfs df $inodes $dir | grep summary: failed"
25134
25135                 # skip first substrings of each output as they are different
25136                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25137                 # compare the two outputs
25138                 passed=true
25139                 for i in {1..5}; do
25140                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25141                 done
25142                 $passed && break
25143         done
25144
25145         if ! $passed; then
25146                 df -P $inodes $dir
25147                 echo
25148                 lfs df $inodes $dir
25149                 error "df and lfs df $1 output mismatch: "      \
25150                       "df ${inodes}: ${df_out[*]}, "            \
25151                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25152         fi
25153 }
25154
25155 test_418() {
25156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25157
25158         local dir=$DIR/$tdir
25159         local numfiles=$((RANDOM % 4096 + 2))
25160         local numblocks=$((RANDOM % 256 + 1))
25161
25162         wait_delete_completed
25163         test_mkdir $dir
25164
25165         # check block output
25166         check_lfs_df blocks $dir
25167         # check inode output
25168         check_lfs_df inodes $dir
25169
25170         # create a single file and retest
25171         echo "Creating a single file and testing"
25172         createmany -o $dir/$tfile- 1 &>/dev/null ||
25173                 error "creating 1 file in $dir failed"
25174         check_lfs_df blocks $dir
25175         check_lfs_df inodes $dir
25176
25177         # create a random number of files
25178         echo "Creating $((numfiles - 1)) files and testing"
25179         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25180                 error "creating $((numfiles - 1)) files in $dir failed"
25181
25182         # write a random number of blocks to the first test file
25183         echo "Writing $numblocks 4K blocks and testing"
25184         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25185                 count=$numblocks &>/dev/null ||
25186                 error "dd to $dir/${tfile}-0 failed"
25187
25188         # retest
25189         check_lfs_df blocks $dir
25190         check_lfs_df inodes $dir
25191
25192         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25193                 error "unlinking $numfiles files in $dir failed"
25194 }
25195 run_test 418 "df and lfs df outputs match"
25196
25197 test_419()
25198 {
25199         local dir=$DIR/$tdir
25200
25201         mkdir -p $dir
25202         touch $dir/file
25203
25204         cancel_lru_locks mdc
25205
25206         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25207         $LCTL set_param fail_loc=0x1410
25208         cat $dir/file
25209         $LCTL set_param fail_loc=0
25210         rm -rf $dir
25211 }
25212 run_test 419 "Verify open file by name doesn't crash kernel"
25213
25214 test_420()
25215 {
25216         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25217                 skip "Need MDS version at least 2.12.53"
25218
25219         local SAVE_UMASK=$(umask)
25220         local dir=$DIR/$tdir
25221         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25222
25223         mkdir -p $dir
25224         umask 0000
25225         mkdir -m03777 $dir/testdir
25226         ls -dn $dir/testdir
25227         # Need to remove trailing '.' when SELinux is enabled
25228         local dirperms=$(ls -dn $dir/testdir |
25229                          awk '{ sub(/\.$/, "", $1); print $1}')
25230         [ $dirperms == "drwxrwsrwt" ] ||
25231                 error "incorrect perms on $dir/testdir"
25232
25233         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25234                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25235         ls -n $dir/testdir/testfile
25236         local fileperms=$(ls -n $dir/testdir/testfile |
25237                           awk '{ sub(/\.$/, "", $1); print $1}')
25238         [ $fileperms == "-rwxr-xr-x" ] ||
25239                 error "incorrect perms on $dir/testdir/testfile"
25240
25241         umask $SAVE_UMASK
25242 }
25243 run_test 420 "clear SGID bit on non-directories for non-members"
25244
25245 test_421a() {
25246         local cnt
25247         local fid1
25248         local fid2
25249
25250         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25251                 skip "Need MDS version at least 2.12.54"
25252
25253         test_mkdir $DIR/$tdir
25254         createmany -o $DIR/$tdir/f 3
25255         cnt=$(ls -1 $DIR/$tdir | wc -l)
25256         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25257
25258         fid1=$(lfs path2fid $DIR/$tdir/f1)
25259         fid2=$(lfs path2fid $DIR/$tdir/f2)
25260         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25261
25262         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25263         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25264
25265         cnt=$(ls -1 $DIR/$tdir | wc -l)
25266         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25267
25268         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25269         createmany -o $DIR/$tdir/f 3
25270         cnt=$(ls -1 $DIR/$tdir | wc -l)
25271         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25272
25273         fid1=$(lfs path2fid $DIR/$tdir/f1)
25274         fid2=$(lfs path2fid $DIR/$tdir/f2)
25275         echo "remove using fsname $FSNAME"
25276         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25277
25278         cnt=$(ls -1 $DIR/$tdir | wc -l)
25279         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25280 }
25281 run_test 421a "simple rm by fid"
25282
25283 test_421b() {
25284         local cnt
25285         local FID1
25286         local FID2
25287
25288         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25289                 skip "Need MDS version at least 2.12.54"
25290
25291         test_mkdir $DIR/$tdir
25292         createmany -o $DIR/$tdir/f 3
25293         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25294         MULTIPID=$!
25295
25296         FID1=$(lfs path2fid $DIR/$tdir/f1)
25297         FID2=$(lfs path2fid $DIR/$tdir/f2)
25298         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25299
25300         kill -USR1 $MULTIPID
25301         wait
25302
25303         cnt=$(ls $DIR/$tdir | wc -l)
25304         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25305 }
25306 run_test 421b "rm by fid on open file"
25307
25308 test_421c() {
25309         local cnt
25310         local FIDS
25311
25312         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25313                 skip "Need MDS version at least 2.12.54"
25314
25315         test_mkdir $DIR/$tdir
25316         createmany -o $DIR/$tdir/f 3
25317         touch $DIR/$tdir/$tfile
25318         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25319         cnt=$(ls -1 $DIR/$tdir | wc -l)
25320         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25321
25322         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25323         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25324
25325         cnt=$(ls $DIR/$tdir | wc -l)
25326         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25327 }
25328 run_test 421c "rm by fid against hardlinked files"
25329
25330 test_421d() {
25331         local cnt
25332         local FIDS
25333
25334         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25335                 skip "Need MDS version at least 2.12.54"
25336
25337         test_mkdir $DIR/$tdir
25338         createmany -o $DIR/$tdir/f 4097
25339         cnt=$(ls -1 $DIR/$tdir | wc -l)
25340         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25341
25342         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25343         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25344
25345         cnt=$(ls $DIR/$tdir | wc -l)
25346         rm -rf $DIR/$tdir
25347         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25348 }
25349 run_test 421d "rmfid en masse"
25350
25351 test_421e() {
25352         local cnt
25353         local FID
25354
25355         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25356         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25357                 skip "Need MDS version at least 2.12.54"
25358
25359         mkdir -p $DIR/$tdir
25360         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25361         createmany -o $DIR/$tdir/striped_dir/f 512
25362         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25363         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25364
25365         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25366                 sed "s/[/][^:]*://g")
25367         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25368
25369         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25370         rm -rf $DIR/$tdir
25371         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25372 }
25373 run_test 421e "rmfid in DNE"
25374
25375 test_421f() {
25376         local cnt
25377         local FID
25378
25379         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25380                 skip "Need MDS version at least 2.12.54"
25381
25382         test_mkdir $DIR/$tdir
25383         touch $DIR/$tdir/f
25384         cnt=$(ls -1 $DIR/$tdir | wc -l)
25385         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25386
25387         FID=$(lfs path2fid $DIR/$tdir/f)
25388         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25389         # rmfid should fail
25390         cnt=$(ls -1 $DIR/$tdir | wc -l)
25391         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25392
25393         chmod a+rw $DIR/$tdir
25394         ls -la $DIR/$tdir
25395         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25396         # rmfid should fail
25397         cnt=$(ls -1 $DIR/$tdir | wc -l)
25398         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25399
25400         rm -f $DIR/$tdir/f
25401         $RUNAS touch $DIR/$tdir/f
25402         FID=$(lfs path2fid $DIR/$tdir/f)
25403         echo "rmfid as root"
25404         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25405         cnt=$(ls -1 $DIR/$tdir | wc -l)
25406         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25407
25408         rm -f $DIR/$tdir/f
25409         $RUNAS touch $DIR/$tdir/f
25410         cnt=$(ls -1 $DIR/$tdir | wc -l)
25411         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25412         FID=$(lfs path2fid $DIR/$tdir/f)
25413         # rmfid w/o user_fid2path mount option should fail
25414         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25415         cnt=$(ls -1 $DIR/$tdir | wc -l)
25416         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25417
25418         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25419         stack_trap "rmdir $tmpdir"
25420         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25421                 error "failed to mount client'"
25422         stack_trap "umount_client $tmpdir"
25423
25424         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25425         # rmfid should succeed
25426         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25427         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25428
25429         # rmfid shouldn't allow to remove files due to dir's permission
25430         chmod a+rwx $tmpdir/$tdir
25431         touch $tmpdir/$tdir/f
25432         ls -la $tmpdir/$tdir
25433         FID=$(lfs path2fid $tmpdir/$tdir/f)
25434         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25435         return 0
25436 }
25437 run_test 421f "rmfid checks permissions"
25438
25439 test_421g() {
25440         local cnt
25441         local FIDS
25442
25443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25444         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25445                 skip "Need MDS version at least 2.12.54"
25446
25447         mkdir -p $DIR/$tdir
25448         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25449         createmany -o $DIR/$tdir/striped_dir/f 512
25450         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25451         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25452
25453         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25454                 sed "s/[/][^:]*://g")
25455
25456         rm -f $DIR/$tdir/striped_dir/f1*
25457         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25458         removed=$((512 - cnt))
25459
25460         # few files have been just removed, so we expect
25461         # rmfid to fail on their fids
25462         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25463         [ $removed != $errors ] && error "$errors != $removed"
25464
25465         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25466         rm -rf $DIR/$tdir
25467         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25468 }
25469 run_test 421g "rmfid to return errors properly"
25470
25471 test_422() {
25472         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25473         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25474         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25475         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25476         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25477
25478         local amc=$(at_max_get client)
25479         local amo=$(at_max_get mds1)
25480         local timeout=`lctl get_param -n timeout`
25481
25482         at_max_set 0 client
25483         at_max_set 0 mds1
25484
25485 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25486         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25487                         fail_val=$(((2*timeout + 10)*1000))
25488         touch $DIR/$tdir/d3/file &
25489         sleep 2
25490 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25491         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25492                         fail_val=$((2*timeout + 5))
25493         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25494         local pid=$!
25495         sleep 1
25496         kill -9 $pid
25497         sleep $((2 * timeout))
25498         echo kill $pid
25499         kill -9 $pid
25500         lctl mark touch
25501         touch $DIR/$tdir/d2/file3
25502         touch $DIR/$tdir/d2/file4
25503         touch $DIR/$tdir/d2/file5
25504
25505         wait
25506         at_max_set $amc client
25507         at_max_set $amo mds1
25508
25509         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25510         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25511                 error "Watchdog is always throttled"
25512 }
25513 run_test 422 "kill a process with RPC in progress"
25514
25515 stat_test() {
25516     df -h $MOUNT &
25517     df -h $MOUNT &
25518     df -h $MOUNT &
25519     df -h $MOUNT &
25520     df -h $MOUNT &
25521     df -h $MOUNT &
25522 }
25523
25524 test_423() {
25525     local _stats
25526     # ensure statfs cache is expired
25527     sleep 2;
25528
25529     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25530     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25531
25532     return 0
25533 }
25534 run_test 423 "statfs should return a right data"
25535
25536 test_424() {
25537 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25538         $LCTL set_param fail_loc=0x80000522
25539         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25540         rm -f $DIR/$tfile
25541 }
25542 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25543
25544 test_425() {
25545         test_mkdir -c -1 $DIR/$tdir
25546         $LFS setstripe -c -1 $DIR/$tdir
25547
25548         lru_resize_disable "" 100
25549         stack_trap "lru_resize_enable" EXIT
25550
25551         sleep 5
25552
25553         for i in $(seq $((MDSCOUNT * 125))); do
25554                 local t=$DIR/$tdir/$tfile_$i
25555
25556                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25557                         error_noexit "Create file $t"
25558         done
25559         stack_trap "rm -rf $DIR/$tdir" EXIT
25560
25561         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25562                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25563                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25564
25565                 [ $lock_count -le $lru_size ] ||
25566                         error "osc lock count $lock_count > lru size $lru_size"
25567         done
25568
25569         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25570                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25571                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25572
25573                 [ $lock_count -le $lru_size ] ||
25574                         error "mdc lock count $lock_count > lru size $lru_size"
25575         done
25576 }
25577 run_test 425 "lock count should not exceed lru size"
25578
25579 test_426() {
25580         splice-test -r $DIR/$tfile
25581         splice-test -rd $DIR/$tfile
25582         splice-test $DIR/$tfile
25583         splice-test -d $DIR/$tfile
25584 }
25585 run_test 426 "splice test on Lustre"
25586
25587 test_427() {
25588         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25589         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25590                 skip "Need MDS version at least 2.12.4"
25591         local log
25592
25593         mkdir $DIR/$tdir
25594         mkdir $DIR/$tdir/1
25595         mkdir $DIR/$tdir/2
25596         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25597         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25598
25599         $LFS getdirstripe $DIR/$tdir/1/dir
25600
25601         #first setfattr for creating updatelog
25602         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
25603
25604 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
25605         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
25606         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
25607         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
25608
25609         sleep 2
25610         fail mds2
25611         wait_recovery_complete mds2 $((2*TIMEOUT))
25612
25613         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
25614         echo $log | grep "get update log failed" &&
25615                 error "update log corruption is detected" || true
25616 }
25617 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
25618
25619 test_428() {
25620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25621         local cache_limit=$CACHE_MAX
25622
25623         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
25624         $LCTL set_param -n llite.*.max_cached_mb=64
25625
25626         mkdir $DIR/$tdir
25627         $LFS setstripe -c 1 $DIR/$tdir
25628         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
25629         stack_trap "rm -f $DIR/$tdir/$tfile.*"
25630         #test write
25631         for f in $(seq 4); do
25632                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
25633         done
25634         wait
25635
25636         cancel_lru_locks osc
25637         # Test read
25638         for f in $(seq 4); do
25639                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
25640         done
25641         wait
25642 }
25643 run_test 428 "large block size IO should not hang"
25644
25645 test_429() { # LU-7915 / LU-10948
25646         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
25647         local testfile=$DIR/$tfile
25648         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
25649         local new_flag=1
25650         local first_rpc
25651         local second_rpc
25652         local third_rpc
25653
25654         $LCTL get_param $ll_opencache_threshold_count ||
25655                 skip "client does not have opencache parameter"
25656
25657         set_opencache $new_flag
25658         stack_trap "restore_opencache"
25659         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
25660                 error "enable opencache failed"
25661         touch $testfile
25662         # drop MDC DLM locks
25663         cancel_lru_locks mdc
25664         # clear MDC RPC stats counters
25665         $LCTL set_param $mdc_rpcstats=clear
25666
25667         # According to the current implementation, we need to run 3 times
25668         # open & close file to verify if opencache is enabled correctly.
25669         # 1st, RPCs are sent for lookup/open and open handle is released on
25670         #      close finally.
25671         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
25672         #      so open handle won't be released thereafter.
25673         # 3rd, No RPC is sent out.
25674         $MULTIOP $testfile oc || error "multiop failed"
25675         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25676         echo "1st: $first_rpc RPCs in flight"
25677
25678         $MULTIOP $testfile oc || error "multiop failed"
25679         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25680         echo "2nd: $second_rpc RPCs in flight"
25681
25682         $MULTIOP $testfile oc || error "multiop failed"
25683         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
25684         echo "3rd: $third_rpc RPCs in flight"
25685
25686         #verify no MDC RPC is sent
25687         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
25688 }
25689 run_test 429 "verify if opencache flag on client side does work"
25690
25691 lseek_test_430() {
25692         local offset
25693         local file=$1
25694
25695         # data at [200K, 400K)
25696         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
25697                 error "256K->512K dd fails"
25698         # data at [2M, 3M)
25699         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
25700                 error "2M->3M dd fails"
25701         # data at [4M, 5M)
25702         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
25703                 error "4M->5M dd fails"
25704         echo "Data at 256K...512K, 2M...3M and 4M...5M"
25705         # start at first component hole #1
25706         printf "Seeking hole from 1000 ... "
25707         offset=$(lseek_test -l 1000 $file)
25708         echo $offset
25709         [[ $offset == 1000 ]] || error "offset $offset != 1000"
25710         printf "Seeking data from 1000 ... "
25711         offset=$(lseek_test -d 1000 $file)
25712         echo $offset
25713         [[ $offset == 262144 ]] || error "offset $offset != 262144"
25714
25715         # start at first component data block
25716         printf "Seeking hole from 300000 ... "
25717         offset=$(lseek_test -l 300000 $file)
25718         echo $offset
25719         [[ $offset == 524288 ]] || error "offset $offset != 524288"
25720         printf "Seeking data from 300000 ... "
25721         offset=$(lseek_test -d 300000 $file)
25722         echo $offset
25723         [[ $offset == 300000 ]] || error "offset $offset != 300000"
25724
25725         # start at the first component but beyond end of object size
25726         printf "Seeking hole from 1000000 ... "
25727         offset=$(lseek_test -l 1000000 $file)
25728         echo $offset
25729         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25730         printf "Seeking data from 1000000 ... "
25731         offset=$(lseek_test -d 1000000 $file)
25732         echo $offset
25733         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25734
25735         # start at second component stripe 2 (empty file)
25736         printf "Seeking hole from 1500000 ... "
25737         offset=$(lseek_test -l 1500000 $file)
25738         echo $offset
25739         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
25740         printf "Seeking data from 1500000 ... "
25741         offset=$(lseek_test -d 1500000 $file)
25742         echo $offset
25743         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
25744
25745         # start at second component stripe 1 (all data)
25746         printf "Seeking hole from 3000000 ... "
25747         offset=$(lseek_test -l 3000000 $file)
25748         echo $offset
25749         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
25750         printf "Seeking data from 3000000 ... "
25751         offset=$(lseek_test -d 3000000 $file)
25752         echo $offset
25753         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
25754
25755         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
25756                 error "2nd dd fails"
25757         echo "Add data block at 640K...1280K"
25758
25759         # start at before new data block, in hole
25760         printf "Seeking hole from 600000 ... "
25761         offset=$(lseek_test -l 600000 $file)
25762         echo $offset
25763         [[ $offset == 600000 ]] || error "offset $offset != 600000"
25764         printf "Seeking data from 600000 ... "
25765         offset=$(lseek_test -d 600000 $file)
25766         echo $offset
25767         [[ $offset == 655360 ]] || error "offset $offset != 655360"
25768
25769         # start at the first component new data block
25770         printf "Seeking hole from 1000000 ... "
25771         offset=$(lseek_test -l 1000000 $file)
25772         echo $offset
25773         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25774         printf "Seeking data from 1000000 ... "
25775         offset=$(lseek_test -d 1000000 $file)
25776         echo $offset
25777         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25778
25779         # start at second component stripe 2, new data
25780         printf "Seeking hole from 1200000 ... "
25781         offset=$(lseek_test -l 1200000 $file)
25782         echo $offset
25783         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
25784         printf "Seeking data from 1200000 ... "
25785         offset=$(lseek_test -d 1200000 $file)
25786         echo $offset
25787         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
25788
25789         # start beyond file end
25790         printf "Using offset > filesize ... "
25791         lseek_test -l 4000000 $file && error "lseek should fail"
25792         printf "Using offset > filesize ... "
25793         lseek_test -d 4000000 $file && error "lseek should fail"
25794
25795         printf "Done\n\n"
25796 }
25797
25798 test_430a() {
25799         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
25800                 skip "MDT does not support SEEK_HOLE"
25801
25802         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25803                 skip "OST does not support SEEK_HOLE"
25804
25805         local file=$DIR/$tdir/$tfile
25806
25807         mkdir -p $DIR/$tdir
25808
25809         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
25810         # OST stripe #1 will have continuous data at [1M, 3M)
25811         # OST stripe #2 is empty
25812         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
25813         lseek_test_430 $file
25814         rm $file
25815         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
25816         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
25817         lseek_test_430 $file
25818         rm $file
25819         $LFS setstripe -c2 -S 512K $file
25820         echo "Two stripes, stripe size 512K"
25821         lseek_test_430 $file
25822         rm $file
25823         # FLR with stale mirror
25824         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
25825                        -N -c2 -S 1M $file
25826         echo "Mirrored file:"
25827         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
25828         echo "Plain 2 stripes 1M"
25829         lseek_test_430 $file
25830         rm $file
25831 }
25832 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
25833
25834 test_430b() {
25835         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25836                 skip "OST does not support SEEK_HOLE"
25837
25838         local offset
25839         local file=$DIR/$tdir/$tfile
25840
25841         mkdir -p $DIR/$tdir
25842         # Empty layout lseek should fail
25843         $MCREATE $file
25844         # seek from 0
25845         printf "Seeking hole from 0 ... "
25846         lseek_test -l 0 $file && error "lseek should fail"
25847         printf "Seeking data from 0 ... "
25848         lseek_test -d 0 $file && error "lseek should fail"
25849         rm $file
25850
25851         # 1M-hole file
25852         $LFS setstripe -E 1M -c2 -E eof $file
25853         $TRUNCATE $file 1048576
25854         printf "Seeking hole from 1000000 ... "
25855         offset=$(lseek_test -l 1000000 $file)
25856         echo $offset
25857         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
25858         printf "Seeking data from 1000000 ... "
25859         lseek_test -d 1000000 $file && error "lseek should fail"
25860         rm $file
25861
25862         # full component followed by non-inited one
25863         $LFS setstripe -E 1M -c2 -E eof $file
25864         dd if=/dev/urandom of=$file bs=1M count=1
25865         printf "Seeking hole from 1000000 ... "
25866         offset=$(lseek_test -l 1000000 $file)
25867         echo $offset
25868         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25869         printf "Seeking hole from 1048576 ... "
25870         lseek_test -l 1048576 $file && error "lseek should fail"
25871         # init second component and truncate back
25872         echo "123" >> $file
25873         $TRUNCATE $file 1048576
25874         printf "Seeking hole from 1000000 ... "
25875         offset=$(lseek_test -l 1000000 $file)
25876         echo $offset
25877         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
25878         printf "Seeking hole from 1048576 ... "
25879         lseek_test -l 1048576 $file && error "lseek should fail"
25880         # boundary checks for big values
25881         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
25882         offset=$(lseek_test -d 0 $file.10g)
25883         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
25884         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
25885         offset=$(lseek_test -d 0 $file.100g)
25886         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
25887         return 0
25888 }
25889 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
25890
25891 test_430c() {
25892         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
25893                 skip "OST does not support SEEK_HOLE"
25894
25895         local file=$DIR/$tdir/$tfile
25896         local start
25897
25898         mkdir -p $DIR/$tdir
25899         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
25900
25901         # cp version 8.33+ prefers lseek over fiemap
25902         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
25903                 start=$SECONDS
25904                 time cp $file /dev/null
25905                 (( SECONDS - start < 5 )) ||
25906                         error "cp: too long runtime $((SECONDS - start))"
25907
25908         fi
25909         # tar version 1.29+ supports SEEK_HOLE/DATA
25910         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
25911                 start=$SECONDS
25912                 time tar cS $file - | cat > /dev/null
25913                 (( SECONDS - start < 5 )) ||
25914                         error "tar: too long runtime $((SECONDS - start))"
25915         fi
25916 }
25917 run_test 430c "lseek: external tools check"
25918
25919 test_431() { # LU-14187
25920         local file=$DIR/$tdir/$tfile
25921
25922         mkdir -p $DIR/$tdir
25923         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
25924         dd if=/dev/urandom of=$file bs=4k count=1
25925         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
25926         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
25927         #define OBD_FAIL_OST_RESTART_IO 0x251
25928         do_facet ost1 "$LCTL set_param fail_loc=0x251"
25929         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
25930         cp $file $file.0
25931         cancel_lru_locks
25932         sync_all_data
25933         echo 3 > /proc/sys/vm/drop_caches
25934         diff  $file $file.0 || error "data diff"
25935 }
25936 run_test 431 "Restart transaction for IO"
25937
25938 cleanup_test_432() {
25939         do_facet mgs $LCTL nodemap_activate 0
25940         wait_nm_sync active
25941 }
25942
25943 test_432() {
25944         local tmpdir=$TMP/dir432
25945
25946         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
25947                 skip "Need MDS version at least 2.14.52"
25948
25949         stack_trap cleanup_test_432 EXIT
25950         mkdir $DIR/$tdir
25951         mkdir $tmpdir
25952
25953         do_facet mgs $LCTL nodemap_activate 1
25954         wait_nm_sync active
25955         do_facet mgs $LCTL nodemap_modify --name default \
25956                 --property admin --value 1
25957         do_facet mgs $LCTL nodemap_modify --name default \
25958                 --property trusted --value 1
25959         cancel_lru_locks mdc
25960         wait_nm_sync default admin_nodemap
25961         wait_nm_sync default trusted_nodemap
25962
25963         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
25964                grep -ci "Operation not permitted") -ne 0 ]; then
25965                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
25966         fi
25967 }
25968 run_test 432 "mv dir from outside Lustre"
25969
25970 prep_801() {
25971         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
25972         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
25973                 skip "Need server version at least 2.9.55"
25974
25975         start_full_debug_logging
25976 }
25977
25978 post_801() {
25979         stop_full_debug_logging
25980 }
25981
25982 barrier_stat() {
25983         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25984                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25985                            awk '/The barrier for/ { print $7 }')
25986                 echo $st
25987         else
25988                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
25989                 echo \'$st\'
25990         fi
25991 }
25992
25993 barrier_expired() {
25994         local expired
25995
25996         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
25997                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
25998                           awk '/will be expired/ { print $7 }')
25999         else
26000                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26001         fi
26002
26003         echo $expired
26004 }
26005
26006 test_801a() {
26007         prep_801
26008
26009         echo "Start barrier_freeze at: $(date)"
26010         #define OBD_FAIL_BARRIER_DELAY          0x2202
26011         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26012         # Do not reduce barrier time - See LU-11873
26013         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26014
26015         sleep 2
26016         local b_status=$(barrier_stat)
26017         echo "Got barrier status at: $(date)"
26018         [ "$b_status" = "'freezing_p1'" ] ||
26019                 error "(1) unexpected barrier status $b_status"
26020
26021         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26022         wait
26023         b_status=$(barrier_stat)
26024         [ "$b_status" = "'frozen'" ] ||
26025                 error "(2) unexpected barrier status $b_status"
26026
26027         local expired=$(barrier_expired)
26028         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26029         sleep $((expired + 3))
26030
26031         b_status=$(barrier_stat)
26032         [ "$b_status" = "'expired'" ] ||
26033                 error "(3) unexpected barrier status $b_status"
26034
26035         # Do not reduce barrier time - See LU-11873
26036         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26037                 error "(4) fail to freeze barrier"
26038
26039         b_status=$(barrier_stat)
26040         [ "$b_status" = "'frozen'" ] ||
26041                 error "(5) unexpected barrier status $b_status"
26042
26043         echo "Start barrier_thaw at: $(date)"
26044         #define OBD_FAIL_BARRIER_DELAY          0x2202
26045         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26046         do_facet mgs $LCTL barrier_thaw $FSNAME &
26047
26048         sleep 2
26049         b_status=$(barrier_stat)
26050         echo "Got barrier status at: $(date)"
26051         [ "$b_status" = "'thawing'" ] ||
26052                 error "(6) unexpected barrier status $b_status"
26053
26054         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26055         wait
26056         b_status=$(barrier_stat)
26057         [ "$b_status" = "'thawed'" ] ||
26058                 error "(7) unexpected barrier status $b_status"
26059
26060         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26061         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26062         do_facet mgs $LCTL barrier_freeze $FSNAME
26063
26064         b_status=$(barrier_stat)
26065         [ "$b_status" = "'failed'" ] ||
26066                 error "(8) unexpected barrier status $b_status"
26067
26068         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26069         do_facet mgs $LCTL barrier_thaw $FSNAME
26070
26071         post_801
26072 }
26073 run_test 801a "write barrier user interfaces and stat machine"
26074
26075 test_801b() {
26076         prep_801
26077
26078         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26079         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26080         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26081         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26082         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26083
26084         cancel_lru_locks mdc
26085
26086         # 180 seconds should be long enough
26087         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26088
26089         local b_status=$(barrier_stat)
26090         [ "$b_status" = "'frozen'" ] ||
26091                 error "(6) unexpected barrier status $b_status"
26092
26093         mkdir $DIR/$tdir/d0/d10 &
26094         mkdir_pid=$!
26095
26096         touch $DIR/$tdir/d1/f13 &
26097         touch_pid=$!
26098
26099         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26100         ln_pid=$!
26101
26102         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26103         mv_pid=$!
26104
26105         rm -f $DIR/$tdir/d4/f12 &
26106         rm_pid=$!
26107
26108         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26109
26110         # To guarantee taht the 'stat' is not blocked
26111         b_status=$(barrier_stat)
26112         [ "$b_status" = "'frozen'" ] ||
26113                 error "(8) unexpected barrier status $b_status"
26114
26115         # let above commands to run at background
26116         sleep 5
26117
26118         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26119         ps -p $touch_pid || error "(10) touch should be blocked"
26120         ps -p $ln_pid || error "(11) link should be blocked"
26121         ps -p $mv_pid || error "(12) rename should be blocked"
26122         ps -p $rm_pid || error "(13) unlink should be blocked"
26123
26124         b_status=$(barrier_stat)
26125         [ "$b_status" = "'frozen'" ] ||
26126                 error "(14) unexpected barrier status $b_status"
26127
26128         do_facet mgs $LCTL barrier_thaw $FSNAME
26129         b_status=$(barrier_stat)
26130         [ "$b_status" = "'thawed'" ] ||
26131                 error "(15) unexpected barrier status $b_status"
26132
26133         wait $mkdir_pid || error "(16) mkdir should succeed"
26134         wait $touch_pid || error "(17) touch should succeed"
26135         wait $ln_pid || error "(18) link should succeed"
26136         wait $mv_pid || error "(19) rename should succeed"
26137         wait $rm_pid || error "(20) unlink should succeed"
26138
26139         post_801
26140 }
26141 run_test 801b "modification will be blocked by write barrier"
26142
26143 test_801c() {
26144         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26145
26146         prep_801
26147
26148         stop mds2 || error "(1) Fail to stop mds2"
26149
26150         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26151
26152         local b_status=$(barrier_stat)
26153         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26154                 do_facet mgs $LCTL barrier_thaw $FSNAME
26155                 error "(2) unexpected barrier status $b_status"
26156         }
26157
26158         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26159                 error "(3) Fail to rescan barrier bitmap"
26160
26161         # Do not reduce barrier time - See LU-11873
26162         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26163
26164         b_status=$(barrier_stat)
26165         [ "$b_status" = "'frozen'" ] ||
26166                 error "(4) unexpected barrier status $b_status"
26167
26168         do_facet mgs $LCTL barrier_thaw $FSNAME
26169         b_status=$(barrier_stat)
26170         [ "$b_status" = "'thawed'" ] ||
26171                 error "(5) unexpected barrier status $b_status"
26172
26173         local devname=$(mdsdevname 2)
26174
26175         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26176
26177         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26178                 error "(7) Fail to rescan barrier bitmap"
26179
26180         post_801
26181 }
26182 run_test 801c "rescan barrier bitmap"
26183
26184 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26185 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26186 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26187 saved_MOUNT_OPTS=$MOUNT_OPTS
26188
26189 cleanup_802a() {
26190         trap 0
26191
26192         stopall
26193         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26194         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26195         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26196         MOUNT_OPTS=$saved_MOUNT_OPTS
26197         setupall
26198 }
26199
26200 test_802a() {
26201         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26202         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26203         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26204                 skip "Need server version at least 2.9.55"
26205
26206         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26207
26208         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26209
26210         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26211                 error "(2) Fail to copy"
26212
26213         trap cleanup_802a EXIT
26214
26215         # sync by force before remount as readonly
26216         sync; sync_all_data; sleep 3; sync_all_data
26217
26218         stopall
26219
26220         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26221         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26222         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26223
26224         echo "Mount the server as read only"
26225         setupall server_only || error "(3) Fail to start servers"
26226
26227         echo "Mount client without ro should fail"
26228         mount_client $MOUNT &&
26229                 error "(4) Mount client without 'ro' should fail"
26230
26231         echo "Mount client with ro should succeed"
26232         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26233         mount_client $MOUNT ||
26234                 error "(5) Mount client with 'ro' should succeed"
26235
26236         echo "Modify should be refused"
26237         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26238
26239         echo "Read should be allowed"
26240         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26241                 error "(7) Read should succeed under ro mode"
26242
26243         cleanup_802a
26244 }
26245 run_test 802a "simulate readonly device"
26246
26247 test_802b() {
26248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26249         remote_mds_nodsh && skip "remote MDS with nodsh"
26250
26251         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26252                 skip "readonly option not available"
26253
26254         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26255
26256         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26257                 error "(2) Fail to copy"
26258
26259         # write back all cached data before setting MDT to readonly
26260         cancel_lru_locks
26261         sync_all_data
26262
26263         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26264         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26265
26266         echo "Modify should be refused"
26267         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26268
26269         echo "Read should be allowed"
26270         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26271                 error "(7) Read should succeed under ro mode"
26272
26273         # disable readonly
26274         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26275 }
26276 run_test 802b "be able to set MDTs to readonly"
26277
26278 test_803a() {
26279         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26280         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26281                 skip "MDS needs to be newer than 2.10.54"
26282
26283         mkdir_on_mdt0 $DIR/$tdir
26284         # Create some objects on all MDTs to trigger related logs objects
26285         for idx in $(seq $MDSCOUNT); do
26286                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26287                         $DIR/$tdir/dir${idx} ||
26288                         error "Fail to create $DIR/$tdir/dir${idx}"
26289         done
26290
26291         sync; sleep 3
26292         wait_delete_completed # ensure old test cleanups are finished
26293         echo "before create:"
26294         $LFS df -i $MOUNT
26295         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26296
26297         for i in {1..10}; do
26298                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26299                         error "Fail to create $DIR/$tdir/foo$i"
26300         done
26301
26302         sync; sleep 3
26303         echo "after create:"
26304         $LFS df -i $MOUNT
26305         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26306
26307         # allow for an llog to be cleaned up during the test
26308         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26309                 error "before ($before_used) + 10 > after ($after_used)"
26310
26311         for i in {1..10}; do
26312                 rm -rf $DIR/$tdir/foo$i ||
26313                         error "Fail to remove $DIR/$tdir/foo$i"
26314         done
26315
26316         sleep 3 # avoid MDT return cached statfs
26317         wait_delete_completed
26318         echo "after unlink:"
26319         $LFS df -i $MOUNT
26320         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26321
26322         # allow for an llog to be created during the test
26323         [ $after_used -le $((before_used + 1)) ] ||
26324                 error "after ($after_used) > before ($before_used) + 1"
26325 }
26326 run_test 803a "verify agent object for remote object"
26327
26328 test_803b() {
26329         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26330         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26331                 skip "MDS needs to be newer than 2.13.56"
26332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26333
26334         for i in $(seq 0 $((MDSCOUNT - 1))); do
26335                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26336         done
26337
26338         local before=0
26339         local after=0
26340
26341         local tmp
26342
26343         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26344         for i in $(seq 0 $((MDSCOUNT - 1))); do
26345                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26346                         awk '/getattr/ { print $2 }')
26347                 before=$((before + tmp))
26348         done
26349         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26350         for i in $(seq 0 $((MDSCOUNT - 1))); do
26351                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26352                         awk '/getattr/ { print $2 }')
26353                 after=$((after + tmp))
26354         done
26355
26356         [ $before -eq $after ] || error "getattr count $before != $after"
26357 }
26358 run_test 803b "remote object can getattr from cache"
26359
26360 test_804() {
26361         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26362         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26363                 skip "MDS needs to be newer than 2.10.54"
26364         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26365
26366         mkdir -p $DIR/$tdir
26367         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26368                 error "Fail to create $DIR/$tdir/dir0"
26369
26370         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26371         local dev=$(mdsdevname 2)
26372
26373         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26374                 grep ${fid} || error "NOT found agent entry for dir0"
26375
26376         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26377                 error "Fail to create $DIR/$tdir/dir1"
26378
26379         touch $DIR/$tdir/dir1/foo0 ||
26380                 error "Fail to create $DIR/$tdir/dir1/foo0"
26381         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26382         local rc=0
26383
26384         for idx in $(seq $MDSCOUNT); do
26385                 dev=$(mdsdevname $idx)
26386                 do_facet mds${idx} \
26387                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26388                         grep ${fid} && rc=$idx
26389         done
26390
26391         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26392                 error "Fail to rename foo0 to foo1"
26393         if [ $rc -eq 0 ]; then
26394                 for idx in $(seq $MDSCOUNT); do
26395                         dev=$(mdsdevname $idx)
26396                         do_facet mds${idx} \
26397                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26398                         grep ${fid} && rc=$idx
26399                 done
26400         fi
26401
26402         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26403                 error "Fail to rename foo1 to foo2"
26404         if [ $rc -eq 0 ]; then
26405                 for idx in $(seq $MDSCOUNT); do
26406                         dev=$(mdsdevname $idx)
26407                         do_facet mds${idx} \
26408                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26409                         grep ${fid} && rc=$idx
26410                 done
26411         fi
26412
26413         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26414
26415         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26416                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26417         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26418                 error "Fail to rename foo2 to foo0"
26419         unlink $DIR/$tdir/dir1/foo0 ||
26420                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26421         rm -rf $DIR/$tdir/dir0 ||
26422                 error "Fail to rm $DIR/$tdir/dir0"
26423
26424         for idx in $(seq $MDSCOUNT); do
26425                 dev=$(mdsdevname $idx)
26426                 rc=0
26427
26428                 stop mds${idx}
26429                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26430                         rc=$?
26431                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26432                         error "mount mds$idx failed"
26433                 df $MOUNT > /dev/null 2>&1
26434
26435                 # e2fsck should not return error
26436                 [ $rc -eq 0 ] ||
26437                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26438         done
26439 }
26440 run_test 804 "verify agent entry for remote entry"
26441
26442 cleanup_805() {
26443         do_facet $SINGLEMDS zfs set quota=$old $fsset
26444         unlinkmany $DIR/$tdir/f- 1000000
26445         trap 0
26446 }
26447
26448 test_805() {
26449         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26450         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26451         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26452                 skip "netfree not implemented before 0.7"
26453         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26454                 skip "Need MDS version at least 2.10.57"
26455
26456         local fsset
26457         local freekb
26458         local usedkb
26459         local old
26460         local quota
26461         local pref="osd-zfs.$FSNAME-MDT0000."
26462
26463         # limit available space on MDS dataset to meet nospace issue
26464         # quickly. then ZFS 0.7.2 can use reserved space if asked
26465         # properly (using netfree flag in osd_declare_destroy()
26466         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26467         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26468                 gawk '{print $3}')
26469         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26470         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26471         let "usedkb=usedkb-freekb"
26472         let "freekb=freekb/2"
26473         if let "freekb > 5000"; then
26474                 let "freekb=5000"
26475         fi
26476         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26477         trap cleanup_805 EXIT
26478         mkdir_on_mdt0 $DIR/$tdir
26479         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26480                 error "Can't set PFL layout"
26481         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26482         rm -rf $DIR/$tdir || error "not able to remove"
26483         do_facet $SINGLEMDS zfs set quota=$old $fsset
26484         trap 0
26485 }
26486 run_test 805 "ZFS can remove from full fs"
26487
26488 # Size-on-MDS test
26489 check_lsom_data()
26490 {
26491         local file=$1
26492         local expect=$(stat -c %s $file)
26493
26494         check_lsom_size $1 $expect
26495
26496         local blocks=$($LFS getsom -b $file)
26497         expect=$(stat -c %b $file)
26498         [[ $blocks == $expect ]] ||
26499                 error "$file expected blocks: $expect, got: $blocks"
26500 }
26501
26502 check_lsom_size()
26503 {
26504         local size
26505         local expect=$2
26506
26507         cancel_lru_locks mdc
26508
26509         size=$($LFS getsom -s $1)
26510         [[ $size == $expect ]] ||
26511                 error "$file expected size: $expect, got: $size"
26512 }
26513
26514 test_806() {
26515         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26516                 skip "Need MDS version at least 2.11.52"
26517
26518         local bs=1048576
26519
26520         touch $DIR/$tfile || error "touch $tfile failed"
26521
26522         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26523         save_lustre_params client "llite.*.xattr_cache" > $save
26524         lctl set_param llite.*.xattr_cache=0
26525         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26526
26527         # single-threaded write
26528         echo "Test SOM for single-threaded write"
26529         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26530                 error "write $tfile failed"
26531         check_lsom_size $DIR/$tfile $bs
26532
26533         local num=32
26534         local size=$(($num * $bs))
26535         local offset=0
26536         local i
26537
26538         echo "Test SOM for single client multi-threaded($num) write"
26539         $TRUNCATE $DIR/$tfile 0
26540         for ((i = 0; i < $num; i++)); do
26541                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26542                 local pids[$i]=$!
26543                 offset=$((offset + $bs))
26544         done
26545         for (( i=0; i < $num; i++ )); do
26546                 wait ${pids[$i]}
26547         done
26548         check_lsom_size $DIR/$tfile $size
26549
26550         $TRUNCATE $DIR/$tfile 0
26551         for ((i = 0; i < $num; i++)); do
26552                 offset=$((offset - $bs))
26553                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26554                 local pids[$i]=$!
26555         done
26556         for (( i=0; i < $num; i++ )); do
26557                 wait ${pids[$i]}
26558         done
26559         check_lsom_size $DIR/$tfile $size
26560
26561         # multi-client writes
26562         num=$(get_node_count ${CLIENTS//,/ })
26563         size=$(($num * $bs))
26564         offset=0
26565         i=0
26566
26567         echo "Test SOM for multi-client ($num) writes"
26568         $TRUNCATE $DIR/$tfile 0
26569         for client in ${CLIENTS//,/ }; do
26570                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26571                 local pids[$i]=$!
26572                 i=$((i + 1))
26573                 offset=$((offset + $bs))
26574         done
26575         for (( i=0; i < $num; i++ )); do
26576                 wait ${pids[$i]}
26577         done
26578         check_lsom_size $DIR/$tfile $offset
26579
26580         i=0
26581         $TRUNCATE $DIR/$tfile 0
26582         for client in ${CLIENTS//,/ }; do
26583                 offset=$((offset - $bs))
26584                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26585                 local pids[$i]=$!
26586                 i=$((i + 1))
26587         done
26588         for (( i=0; i < $num; i++ )); do
26589                 wait ${pids[$i]}
26590         done
26591         check_lsom_size $DIR/$tfile $size
26592
26593         # verify truncate
26594         echo "Test SOM for truncate"
26595         $TRUNCATE $DIR/$tfile 1048576
26596         check_lsom_size $DIR/$tfile 1048576
26597         $TRUNCATE $DIR/$tfile 1234
26598         check_lsom_size $DIR/$tfile 1234
26599
26600         # verify SOM blocks count
26601         echo "Verify SOM block count"
26602         $TRUNCATE $DIR/$tfile 0
26603         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
26604                 error "failed to write file $tfile"
26605         check_lsom_data $DIR/$tfile
26606 }
26607 run_test 806 "Verify Lazy Size on MDS"
26608
26609 test_807() {
26610         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26611         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26612                 skip "Need MDS version at least 2.11.52"
26613
26614         # Registration step
26615         changelog_register || error "changelog_register failed"
26616         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
26617         changelog_users $SINGLEMDS | grep -q $cl_user ||
26618                 error "User $cl_user not found in changelog_users"
26619
26620         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26621         save_lustre_params client "llite.*.xattr_cache" > $save
26622         lctl set_param llite.*.xattr_cache=0
26623         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26624
26625         rm -rf $DIR/$tdir || error "rm $tdir failed"
26626         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26627         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
26628         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
26629         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
26630                 error "truncate $tdir/trunc failed"
26631
26632         local bs=1048576
26633         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
26634                 error "write $tfile failed"
26635
26636         # multi-client wirtes
26637         local num=$(get_node_count ${CLIENTS//,/ })
26638         local offset=0
26639         local i=0
26640
26641         echo "Test SOM for multi-client ($num) writes"
26642         touch $DIR/$tfile || error "touch $tfile failed"
26643         $TRUNCATE $DIR/$tfile 0
26644         for client in ${CLIENTS//,/ }; do
26645                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26646                 local pids[$i]=$!
26647                 i=$((i + 1))
26648                 offset=$((offset + $bs))
26649         done
26650         for (( i=0; i < $num; i++ )); do
26651                 wait ${pids[$i]}
26652         done
26653
26654         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
26655         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
26656         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
26657         check_lsom_data $DIR/$tdir/trunc
26658         check_lsom_data $DIR/$tdir/single_dd
26659         check_lsom_data $DIR/$tfile
26660
26661         rm -rf $DIR/$tdir
26662         # Deregistration step
26663         changelog_deregister || error "changelog_deregister failed"
26664 }
26665 run_test 807 "verify LSOM syncing tool"
26666
26667 check_som_nologged()
26668 {
26669         local lines=$($LFS changelog $FSNAME-MDT0000 |
26670                 grep 'x=trusted.som' | wc -l)
26671         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
26672 }
26673
26674 test_808() {
26675         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
26676                 skip "Need MDS version at least 2.11.55"
26677
26678         # Registration step
26679         changelog_register || error "changelog_register failed"
26680
26681         touch $DIR/$tfile || error "touch $tfile failed"
26682         check_som_nologged
26683
26684         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
26685                 error "write $tfile failed"
26686         check_som_nologged
26687
26688         $TRUNCATE $DIR/$tfile 1234
26689         check_som_nologged
26690
26691         $TRUNCATE $DIR/$tfile 1048576
26692         check_som_nologged
26693
26694         # Deregistration step
26695         changelog_deregister || error "changelog_deregister failed"
26696 }
26697 run_test 808 "Check trusted.som xattr not logged in Changelogs"
26698
26699 check_som_nodata()
26700 {
26701         $LFS getsom $1
26702         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
26703 }
26704
26705 test_809() {
26706         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
26707                 skip "Need MDS version at least 2.11.56"
26708
26709         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
26710                 error "failed to create DoM-only file $DIR/$tfile"
26711         touch $DIR/$tfile || error "touch $tfile failed"
26712         check_som_nodata $DIR/$tfile
26713
26714         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
26715                 error "write $tfile failed"
26716         check_som_nodata $DIR/$tfile
26717
26718         $TRUNCATE $DIR/$tfile 1234
26719         check_som_nodata $DIR/$tfile
26720
26721         $TRUNCATE $DIR/$tfile 4097
26722         check_som_nodata $DIR/$file
26723 }
26724 run_test 809 "Verify no SOM xattr store for DoM-only files"
26725
26726 test_810() {
26727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26728         $GSS && skip_env "could not run with gss"
26729         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
26730                 skip "OST < 2.12.58 doesn't align checksum"
26731
26732         set_checksums 1
26733         stack_trap "set_checksums $ORIG_CSUM" EXIT
26734         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
26735
26736         local csum
26737         local before
26738         local after
26739         for csum in $CKSUM_TYPES; do
26740                 #define OBD_FAIL_OSC_NO_GRANT   0x411
26741                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
26742                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
26743                         eval set -- $i
26744                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
26745                         before=$(md5sum $DIR/$tfile)
26746                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
26747                         after=$(md5sum $DIR/$tfile)
26748                         [ "$before" == "$after" ] ||
26749                                 error "$csum: $before != $after bs=$1 seek=$2"
26750                 done
26751         done
26752 }
26753 run_test 810 "partial page writes on ZFS (LU-11663)"
26754
26755 test_812a() {
26756         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26757                 skip "OST < 2.12.51 doesn't support this fail_loc"
26758
26759         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26760         # ensure ost1 is connected
26761         stat $DIR/$tfile >/dev/null || error "can't stat"
26762         wait_osc_import_state client ost1 FULL
26763         # no locks, no reqs to let the connection idle
26764         cancel_lru_locks osc
26765
26766         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26767 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26768         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26769         wait_osc_import_state client ost1 CONNECTING
26770         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26771
26772         stat $DIR/$tfile >/dev/null || error "can't stat file"
26773 }
26774 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
26775
26776 test_812b() { # LU-12378
26777         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
26778                 skip "OST < 2.12.51 doesn't support this fail_loc"
26779
26780         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
26781         # ensure ost1 is connected
26782         stat $DIR/$tfile >/dev/null || error "can't stat"
26783         wait_osc_import_state client ost1 FULL
26784         # no locks, no reqs to let the connection idle
26785         cancel_lru_locks osc
26786
26787         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
26788 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
26789         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
26790         wait_osc_import_state client ost1 CONNECTING
26791         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
26792
26793         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
26794         wait_osc_import_state client ost1 IDLE
26795 }
26796 run_test 812b "do not drop no resend request for idle connect"
26797
26798 test_812c() {
26799         local old
26800
26801         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
26802
26803         $LFS setstripe -c 1 -o 0 $DIR/$tfile
26804         $LFS getstripe $DIR/$tfile
26805         $LCTL set_param osc.*.idle_timeout=10
26806         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
26807         # ensure ost1 is connected
26808         stat $DIR/$tfile >/dev/null || error "can't stat"
26809         wait_osc_import_state client ost1 FULL
26810         # no locks, no reqs to let the connection idle
26811         cancel_lru_locks osc
26812
26813 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
26814         $LCTL set_param fail_loc=0x80000533
26815         sleep 15
26816         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
26817 }
26818 run_test 812c "idle import vs lock enqueue race"
26819
26820 test_813() {
26821         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
26822         [ -z "$file_heat_sav" ] && skip "no file heat support"
26823
26824         local readsample
26825         local writesample
26826         local readbyte
26827         local writebyte
26828         local readsample1
26829         local writesample1
26830         local readbyte1
26831         local writebyte1
26832
26833         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
26834         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
26835
26836         $LCTL set_param -n llite.*.file_heat=1
26837         echo "Turn on file heat"
26838         echo "Period second: $period_second, Decay percentage: $decay_pct"
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         local out=$($LFS heat_get $DIR/$tfile)
26849
26850         $LFS heat_get $DIR/$tfile
26851         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26852         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26853         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26854         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26855
26856         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
26857         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
26858         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
26859         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
26860
26861         sleep $((period_second + 3))
26862         echo "Sleep $((period_second + 3)) seconds..."
26863         # The recursion formula to calculate the heat of the file f is as
26864         # follow:
26865         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
26866         # Where Hi is the heat value in the period between time points i*I and
26867         # (i+1)*I; Ci is the access count in the period; the symbol P refers
26868         # to the weight of Ci.
26869         out=$($LFS heat_get $DIR/$tfile)
26870         $LFS heat_get $DIR/$tfile
26871         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26872         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26873         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26874         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26875
26876         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
26877                 error "read sample ($readsample) is wrong"
26878         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
26879                 error "write sample ($writesample) is wrong"
26880         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
26881                 error "read bytes ($readbyte) is wrong"
26882         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
26883                 error "write bytes ($writebyte) is wrong"
26884
26885         echo "QQQQ" > $DIR/$tfile
26886         echo "QQQQ" > $DIR/$tfile
26887         echo "QQQQ" > $DIR/$tfile
26888         cat $DIR/$tfile > /dev/null
26889         cat $DIR/$tfile > /dev/null
26890         cat $DIR/$tfile > /dev/null
26891         cat $DIR/$tfile > /dev/null
26892
26893         sleep $((period_second + 3))
26894         echo "Sleep $((period_second + 3)) seconds..."
26895
26896         out=$($LFS heat_get $DIR/$tfile)
26897         $LFS heat_get $DIR/$tfile
26898         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26899         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26900         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26901         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26902
26903         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
26904                 4 * $decay_pct) / 100") -eq 1 ] ||
26905                 error "read sample ($readsample1) is wrong"
26906         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
26907                 3 * $decay_pct) / 100") -eq 1 ] ||
26908                 error "write sample ($writesample1) is wrong"
26909         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
26910                 20 * $decay_pct) / 100") -eq 1 ] ||
26911                 error "read bytes ($readbyte1) is wrong"
26912         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
26913                 15 * $decay_pct) / 100") -eq 1 ] ||
26914                 error "write bytes ($writebyte1) is wrong"
26915
26916         echo "Turn off file heat for the file $DIR/$tfile"
26917         $LFS heat_set -o $DIR/$tfile
26918
26919         echo "QQQQ" > $DIR/$tfile
26920         echo "QQQQ" > $DIR/$tfile
26921         echo "QQQQ" > $DIR/$tfile
26922         cat $DIR/$tfile > /dev/null
26923         cat $DIR/$tfile > /dev/null
26924         cat $DIR/$tfile > /dev/null
26925         cat $DIR/$tfile > /dev/null
26926
26927         out=$($LFS heat_get $DIR/$tfile)
26928         $LFS heat_get $DIR/$tfile
26929         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26930         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26931         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26932         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26933
26934         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26935         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26936         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26937         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26938
26939         echo "Trun on file heat for the file $DIR/$tfile"
26940         $LFS heat_set -O $DIR/$tfile
26941
26942         echo "QQQQ" > $DIR/$tfile
26943         echo "QQQQ" > $DIR/$tfile
26944         echo "QQQQ" > $DIR/$tfile
26945         cat $DIR/$tfile > /dev/null
26946         cat $DIR/$tfile > /dev/null
26947         cat $DIR/$tfile > /dev/null
26948         cat $DIR/$tfile > /dev/null
26949
26950         out=$($LFS heat_get $DIR/$tfile)
26951         $LFS heat_get $DIR/$tfile
26952         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26953         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26954         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26955         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26956
26957         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
26958         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
26959         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
26960         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
26961
26962         $LFS heat_set -c $DIR/$tfile
26963         $LCTL set_param -n llite.*.file_heat=0
26964         echo "Turn off file heat support for the Lustre filesystem"
26965
26966         echo "QQQQ" > $DIR/$tfile
26967         echo "QQQQ" > $DIR/$tfile
26968         echo "QQQQ" > $DIR/$tfile
26969         cat $DIR/$tfile > /dev/null
26970         cat $DIR/$tfile > /dev/null
26971         cat $DIR/$tfile > /dev/null
26972         cat $DIR/$tfile > /dev/null
26973
26974         out=$($LFS heat_get $DIR/$tfile)
26975         $LFS heat_get $DIR/$tfile
26976         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
26977         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
26978         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
26979         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
26980
26981         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
26982         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
26983         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
26984         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
26985
26986         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
26987         rm -f $DIR/$tfile
26988 }
26989 run_test 813 "File heat verfication"
26990
26991 test_814()
26992 {
26993         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
26994         echo -n y >> $DIR/$tfile
26995         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
26996         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
26997 }
26998 run_test 814 "sparse cp works as expected (LU-12361)"
26999
27000 test_815()
27001 {
27002         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27003         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27004 }
27005 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27006
27007 test_816() {
27008         local ost1_imp=$(get_osc_import_name client ost1)
27009         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27010                          cut -d'.' -f2)
27011
27012         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27013         # ensure ost1 is connected
27014
27015         stat $DIR/$tfile >/dev/null || error "can't stat"
27016         wait_osc_import_state client ost1 FULL
27017         # no locks, no reqs to let the connection idle
27018         cancel_lru_locks osc
27019         lru_resize_disable osc
27020         local before
27021         local now
27022         before=$($LCTL get_param -n \
27023                  ldlm.namespaces.$imp_name.lru_size)
27024
27025         wait_osc_import_state client ost1 IDLE
27026         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27027         now=$($LCTL get_param -n \
27028               ldlm.namespaces.$imp_name.lru_size)
27029         [ $before == $now ] || error "lru_size changed $before != $now"
27030 }
27031 run_test 816 "do not reset lru_resize on idle reconnect"
27032
27033 cleanup_817() {
27034         umount $tmpdir
27035         exportfs -u localhost:$DIR/nfsexp
27036         rm -rf $DIR/nfsexp
27037 }
27038
27039 test_817() {
27040         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27041
27042         mkdir -p $DIR/nfsexp
27043         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27044                 error "failed to export nfs"
27045
27046         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27047         stack_trap cleanup_817 EXIT
27048
27049         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27050                 error "failed to mount nfs to $tmpdir"
27051
27052         cp /bin/true $tmpdir
27053         $DIR/nfsexp/true || error "failed to execute 'true' command"
27054 }
27055 run_test 817 "nfsd won't cache write lock for exec file"
27056
27057 test_818() {
27058         mkdir $DIR/$tdir
27059         $LFS setstripe -c1 -i0 $DIR/$tfile
27060         $LFS setstripe -c1 -i1 $DIR/$tfile
27061         stop $SINGLEMDS
27062         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27063         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27064         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27065                 error "start $SINGLEMDS failed"
27066         rm -rf $DIR/$tdir
27067 }
27068 run_test 818 "unlink with failed llog"
27069
27070 test_819a() {
27071         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27072         cancel_lru_locks osc
27073         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27074         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27075         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27076         rm -f $TDIR/$tfile
27077 }
27078 run_test 819a "too big niobuf in read"
27079
27080 test_819b() {
27081         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27082         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27083         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27084         cancel_lru_locks osc
27085         sleep 1
27086         rm -f $TDIR/$tfile
27087 }
27088 run_test 819b "too big niobuf in write"
27089
27090
27091 function test_820_start_ost() {
27092         sleep 5
27093
27094         for num in $(seq $OSTCOUNT); do
27095                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27096         done
27097 }
27098
27099 test_820() {
27100         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27101
27102         mkdir $DIR/$tdir
27103         umount_client $MOUNT || error "umount failed"
27104         for num in $(seq $OSTCOUNT); do
27105                 stop ost$num
27106         done
27107
27108         # mount client with no active OSTs
27109         # so that the client can't initialize max LOV EA size
27110         # from OSC notifications
27111         mount_client $MOUNT || error "mount failed"
27112         # delay OST starting to keep this 0 max EA size for a while
27113         test_820_start_ost &
27114
27115         # create a directory on MDS2
27116         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27117                 error "Failed to create directory"
27118         # open intent should update default EA size
27119         # see mdc_update_max_ea_from_body()
27120         # notice this is the very first RPC to MDS2
27121         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27122         ret=$?
27123         echo $out
27124         # With SSK, this situation can lead to -EPERM being returned.
27125         # In that case, simply retry.
27126         if [ $ret -ne 0 ] && $SHARED_KEY; then
27127                 if echo "$out" | grep -q "not permitted"; then
27128                         cp /etc/services $DIR/$tdir/mds2
27129                         ret=$?
27130                 fi
27131         fi
27132         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27133 }
27134 run_test 820 "update max EA from open intent"
27135
27136 test_822() {
27137         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27138
27139         save_lustre_params mds1 \
27140                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27141         do_facet $SINGLEMDS "$LCTL set_param -n \
27142                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27143         do_facet $SINGLEMDS "$LCTL set_param -n \
27144                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27145
27146         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27147         local maxage=$(do_facet mds1 $LCTL get_param -n \
27148                        osp.$FSNAME-OST0000*MDT0000.maxage)
27149         sleep $((maxage + 1))
27150
27151         #define OBD_FAIL_NET_ERROR_RPC          0x532
27152         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27153
27154         stack_trap "restore_lustre_params < $p; rm $p"
27155
27156         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27157                       osp.$FSNAME-OST0000*MDT0000.create_count")
27158         for i in $(seq 1 $count); do
27159                 touch $DIR/$tfile.${i} || error "touch failed"
27160         done
27161 }
27162 run_test 822 "test precreate failure"
27163
27164 #
27165 # tests that do cleanup/setup should be run at the end
27166 #
27167
27168 test_900() {
27169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27170         local ls
27171
27172         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27173         $LCTL set_param fail_loc=0x903
27174
27175         cancel_lru_locks MGC
27176
27177         FAIL_ON_ERROR=true cleanup
27178         FAIL_ON_ERROR=true setup
27179 }
27180 run_test 900 "umount should not race with any mgc requeue thread"
27181
27182 # LUS-6253/LU-11185
27183 test_901() {
27184         local oldc
27185         local newc
27186         local olds
27187         local news
27188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27189
27190         # some get_param have a bug to handle dot in param name
27191         cancel_lru_locks MGC
27192         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27193         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27194         umount_client $MOUNT || error "umount failed"
27195         mount_client $MOUNT || error "mount failed"
27196         cancel_lru_locks MGC
27197         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27198         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27199
27200         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27201         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27202
27203         return 0
27204 }
27205 run_test 901 "don't leak a mgc lock on client umount"
27206
27207 # LU-13377
27208 test_902() {
27209         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27210                 skip "client does not have LU-13377 fix"
27211         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27212         $LCTL set_param fail_loc=0x1415
27213         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27214         cancel_lru_locks osc
27215         rm -f $DIR/$tfile
27216 }
27217 run_test 902 "test short write doesn't hang lustre"
27218
27219 complete $SECONDS
27220 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27221 check_and_cleanup_lustre
27222 if [ "$I_MOUNTED" != "yes" ]; then
27223         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27224 fi
27225 exit_status