Whamcloud - gitweb
LU-15338 tests: check whole jobid in sanity 205a
[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
63         ALWAYS_EXCEPT+=" 45"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5              12     8   12  15   (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_0e() { # LU-13417
257         (( $MDSCOUNT > 1 )) ||
258                 skip "We need at least 2 MDTs for this test"
259
260         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
261                 skip "Need server version at least 2.14.51"
262
263         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
264         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
265
266         [ $default_lmv_count -eq 1 ] ||
267                 error "$MOUNT default stripe count $default_lmv_count"
268
269         [ $default_lmv_index -eq -1 ] ||
270                 error "$MOUNT default stripe index $default_lmv_index"
271
272         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
273         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
274
275         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
276         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
277
278         [ $mdt_index1 -eq $mdt_index2 ] &&
279                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
280
281         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
282 }
283 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718         local devname=$(mdsdevname $mds_index)
719
720         echo "stop and checking mds${mds_index}:"
721         # e2fsck should not return error
722         stop mds${mds_index}
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 local devname=$(mdsdevname $mdt_index)
743                 # e2fsck should not return error
744                 stop mds${mdt_index}
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170 test_24t() {
1171         test_mkdir $DIR/R16a
1172         test_mkdir $DIR/R16a/b
1173         test_mkdir $DIR/R16a/b/c
1174         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1175         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1176         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1177 }
1178 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1179
1180 test_24u() { # bug12192
1181         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1182         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1183 }
1184 run_test 24u "create stripe file"
1185
1186 simple_cleanup_common() {
1187         local createmany=$1
1188         local rc=0
1189
1190         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1191
1192         local start=$SECONDS
1193
1194         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1195         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1196         rc=$?
1197         wait_delete_completed
1198         echo "cleanup time $((SECONDS - start))"
1199         return $rc
1200 }
1201
1202 max_pages_per_rpc() {
1203         local mdtname="$(printf "MDT%04x" ${1:-0})"
1204         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1205 }
1206
1207 test_24v() {
1208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1209
1210         local nrfiles=${COUNT:-100000}
1211         local fname="$DIR/$tdir/$tfile"
1212
1213         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1214         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1215
1216         test_mkdir "$(dirname $fname)"
1217         # assume MDT0000 has the fewest inodes
1218         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1219         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1220         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1221
1222         stack_trap "simple_cleanup_common $nrfiles"
1223
1224         createmany -m "$fname" $nrfiles
1225
1226         cancel_lru_locks mdc
1227         lctl set_param mdc.*.stats clear
1228
1229         # was previously test_24D: LU-6101
1230         # readdir() returns correct number of entries after cursor reload
1231         local num_ls=$(ls $DIR/$tdir | wc -l)
1232         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1233         local num_all=$(ls -a $DIR/$tdir | wc -l)
1234         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1235                 [ $num_all -ne $((nrfiles + 2)) ]; then
1236                         error "Expected $nrfiles files, got $num_ls " \
1237                                 "($num_uniq unique $num_all .&..)"
1238         fi
1239         # LU-5 large readdir
1240         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1241         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1242         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1243         # take into account of overhead in lu_dirpage header and end mark in
1244         # each page, plus one in rpc_num calculation.
1245         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1246         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1247         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1248         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1249         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1250         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1251         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1252         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1253                 error "large readdir doesn't take effect: " \
1254                       "$mds_readpage should be about $rpc_max"
1255 }
1256 run_test 24v "list large directory (test hash collision, b=17560)"
1257
1258 test_24w() { # bug21506
1259         SZ1=234852
1260         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1261         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1262         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1263         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1264         [[ "$SZ1" -eq "$SZ2" ]] ||
1265                 error "Error reading at the end of the file $tfile"
1266 }
1267 run_test 24w "Reading a file larger than 4Gb"
1268
1269 test_24x() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1273                 skip "Need MDS version at least 2.7.56"
1274
1275         local MDTIDX=1
1276         local remote_dir=$DIR/$tdir/remote_dir
1277
1278         test_mkdir $DIR/$tdir
1279         $LFS mkdir -i $MDTIDX $remote_dir ||
1280                 error "create remote directory failed"
1281
1282         test_mkdir $DIR/$tdir/src_dir
1283         touch $DIR/$tdir/src_file
1284         test_mkdir $remote_dir/tgt_dir
1285         touch $remote_dir/tgt_file
1286
1287         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1288                 error "rename dir cross MDT failed!"
1289
1290         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1291                 error "rename file cross MDT failed!"
1292
1293         touch $DIR/$tdir/ln_file
1294         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1295                 error "ln file cross MDT failed"
1296
1297         rm -rf $DIR/$tdir || error "Can not delete directories"
1298 }
1299 run_test 24x "cross MDT rename/link"
1300
1301 test_24y() {
1302         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1304
1305         local remote_dir=$DIR/$tdir/remote_dir
1306         local mdtidx=1
1307
1308         test_mkdir $DIR/$tdir
1309         $LFS mkdir -i $mdtidx $remote_dir ||
1310                 error "create remote directory failed"
1311
1312         test_mkdir $remote_dir/src_dir
1313         touch $remote_dir/src_file
1314         test_mkdir $remote_dir/tgt_dir
1315         touch $remote_dir/tgt_file
1316
1317         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1318                 error "rename subdir in the same remote dir failed!"
1319
1320         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1321                 error "rename files in the same remote dir failed!"
1322
1323         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1324                 error "link files in the same remote dir failed!"
1325
1326         rm -rf $DIR/$tdir || error "Can not delete directories"
1327 }
1328 run_test 24y "rename/link on the same dir should succeed"
1329
1330 test_24z() {
1331         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1332         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1333                 skip "Need MDS version at least 2.12.51"
1334
1335         local index
1336
1337         for index in 0 1; do
1338                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1339                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1340         done
1341
1342         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1343
1344         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1345         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1346
1347         local mdts=$(comma_list $(mdts_nodes))
1348
1349         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1350         stack_trap "do_nodes $mdts $LCTL \
1351                 set_param mdt.*.enable_remote_rename=1" EXIT
1352
1353         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1354
1355         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1356         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1357 }
1358 run_test 24z "cross-MDT rename is done as cp"
1359
1360 test_24A() { # LU-3182
1361         local NFILES=5000
1362
1363         test_mkdir $DIR/$tdir
1364         stack_trap "simple_cleanup_common $NFILES"
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
1370         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372 }
1373 run_test 24A "readdir() returns correct number of entries."
1374
1375 test_24B() { # LU-4805
1376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1377
1378         local count
1379
1380         test_mkdir $DIR/$tdir
1381         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1382                 error "create striped dir failed"
1383
1384         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1385         [ $count -eq 2 ] || error "Expected 2, got $count"
1386
1387         touch $DIR/$tdir/striped_dir/a
1388
1389         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1390         [ $count -eq 3 ] || error "Expected 3, got $count"
1391
1392         touch $DIR/$tdir/striped_dir/.f
1393
1394         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1395         [ $count -eq 4 ] || error "Expected 4, got $count"
1396
1397         rm -rf $DIR/$tdir || error "Can not delete directories"
1398 }
1399 run_test 24B "readdir for striped dir return correct number of entries"
1400
1401 test_24C() {
1402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1403
1404         mkdir $DIR/$tdir
1405         mkdir $DIR/$tdir/d0
1406         mkdir $DIR/$tdir/d1
1407
1408         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1409                 error "create striped dir failed"
1410
1411         cd $DIR/$tdir/d0/striped_dir
1412
1413         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1414         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1415         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1416
1417         [ "$d0_ino" = "$parent_ino" ] ||
1418                 error ".. wrong, expect $d0_ino, get $parent_ino"
1419
1420         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1421                 error "mv striped dir failed"
1422
1423         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1424
1425         [ "$d1_ino" = "$parent_ino" ] ||
1426                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1427 }
1428 run_test 24C "check .. in striped dir"
1429
1430 test_24E() {
1431         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1433
1434         mkdir -p $DIR/$tdir
1435         mkdir $DIR/$tdir/src_dir
1436         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1437                 error "create remote source failed"
1438
1439         touch $DIR/$tdir/src_dir/src_child/a
1440
1441         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1442                 error "create remote target dir failed"
1443
1444         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1445                 error "create remote target child failed"
1446
1447         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "rename dir cross MDT failed!"
1449
1450         find $DIR/$tdir
1451
1452         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1453                 error "src_child still exists after rename"
1454
1455         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1456                 error "missing file(a) after rename"
1457
1458         rm -rf $DIR/$tdir || error "Can not delete directories"
1459 }
1460 run_test 24E "cross MDT rename/link"
1461
1462 test_24F () {
1463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1464
1465         local repeats=1000
1466         [ "$SLOW" = "no" ] && repeats=100
1467
1468         mkdir -p $DIR/$tdir
1469
1470         echo "$repeats repeats"
1471         for ((i = 0; i < repeats; i++)); do
1472                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1473                 touch $DIR/$tdir/test/a || error "touch fails"
1474                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1475                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1476         done
1477
1478         true
1479 }
1480 run_test 24F "hash order vs readdir (LU-11330)"
1481
1482 test_24G () {
1483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1484
1485         local ino1
1486         local ino2
1487
1488         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1489         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1490         touch $DIR/$tdir-0/f1 || error "touch f1"
1491         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1492         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1493         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1494         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1495         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1496 }
1497 run_test 24G "migrate symlink in rename"
1498
1499 test_25a() {
1500         echo '== symlink sanity ============================================='
1501
1502         test_mkdir $DIR/d25
1503         ln -s d25 $DIR/s25
1504         touch $DIR/s25/foo ||
1505                 error "File creation in symlinked directory failed"
1506 }
1507 run_test 25a "create file in symlinked directory ==============="
1508
1509 test_25b() {
1510         [ ! -d $DIR/d25 ] && test_25a
1511         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1512 }
1513 run_test 25b "lookup file in symlinked directory ==============="
1514
1515 test_26a() {
1516         test_mkdir $DIR/d26
1517         test_mkdir $DIR/d26/d26-2
1518         ln -s d26/d26-2 $DIR/s26
1519         touch $DIR/s26/foo || error "File creation failed"
1520 }
1521 run_test 26a "multiple component symlink ======================="
1522
1523 test_26b() {
1524         test_mkdir -p $DIR/$tdir/d26-2
1525         ln -s $tdir/d26-2/foo $DIR/s26-2
1526         touch $DIR/s26-2 || error "File creation failed"
1527 }
1528 run_test 26b "multiple component symlink at end of lookup ======"
1529
1530 test_26c() {
1531         test_mkdir $DIR/d26.2
1532         touch $DIR/d26.2/foo
1533         ln -s d26.2 $DIR/s26.2-1
1534         ln -s s26.2-1 $DIR/s26.2-2
1535         ln -s s26.2-2 $DIR/s26.2-3
1536         chmod 0666 $DIR/s26.2-3/foo
1537 }
1538 run_test 26c "chain of symlinks"
1539
1540 # recursive symlinks (bug 439)
1541 test_26d() {
1542         ln -s d26-3/foo $DIR/d26-3
1543 }
1544 run_test 26d "create multiple component recursive symlink"
1545
1546 test_26e() {
1547         [ ! -h $DIR/d26-3 ] && test_26d
1548         rm $DIR/d26-3
1549 }
1550 run_test 26e "unlink multiple component recursive symlink"
1551
1552 # recursive symlinks (bug 7022)
1553 test_26f() {
1554         test_mkdir $DIR/$tdir
1555         test_mkdir $DIR/$tdir/$tfile
1556         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1557         test_mkdir -p lndir/bar1
1558         test_mkdir $DIR/$tdir/$tfile/$tfile
1559         cd $tfile                || error "cd $tfile failed"
1560         ln -s .. dotdot          || error "ln dotdot failed"
1561         ln -s dotdot/lndir lndir || error "ln lndir failed"
1562         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1563         output=`ls $tfile/$tfile/lndir/bar1`
1564         [ "$output" = bar1 ] && error "unexpected output"
1565         rm -r $tfile             || error "rm $tfile failed"
1566         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1567 }
1568 run_test 26f "rm -r of a directory which has recursive symlink"
1569
1570 test_27a() {
1571         test_mkdir $DIR/$tdir
1572         $LFS getstripe $DIR/$tdir
1573         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1574         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1575         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1576 }
1577 run_test 27a "one stripe file"
1578
1579 test_27b() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1581
1582         test_mkdir $DIR/$tdir
1583         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1584         $LFS getstripe -c $DIR/$tdir/$tfile
1585         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1586                 error "two-stripe file doesn't have two stripes"
1587
1588         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1589 }
1590 run_test 27b "create and write to two stripe file"
1591
1592 # 27c family tests specific striping, setstripe -o
1593 test_27ca() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         test_mkdir -p $DIR/$tdir
1596         local osts="1"
1597
1598         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1599         $LFS getstripe -i $DIR/$tdir/$tfile
1600         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1601                 error "stripe not on specified OST"
1602
1603         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1604 }
1605 run_test 27ca "one stripe on specified OST"
1606
1607 test_27cb() {
1608         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1609         test_mkdir -p $DIR/$tdir
1610         local osts="1,0"
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27cb "two stripes on specified OSTs"
1624
1625 test_27cc() {
1626         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1627         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1628                 skip "server does not support overstriping"
1629
1630         test_mkdir -p $DIR/$tdir
1631         local osts="0,0"
1632         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1633         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1634         echo "$getstripe"
1635
1636         # Strip getstripe output to a space separated list of OSTs
1637         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1638                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1639         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1640                 error "stripes not on specified OSTs"
1641
1642         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1643 }
1644 run_test 27cc "two stripes on the same OST"
1645
1646 test_27cd() {
1647         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1648         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1649                 skip "server does not support overstriping"
1650         test_mkdir -p $DIR/$tdir
1651         local osts="0,1,1,0"
1652         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1653         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1654         echo "$getstripe"
1655
1656         # Strip getstripe output to a space separated list of OSTs
1657         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1658                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1659         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1660                 error "stripes not on specified OSTs"
1661
1662         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1663 }
1664 run_test 27cd "four stripes on two OSTs"
1665
1666 test_27ce() {
1667         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1668                 skip_env "too many osts, skipping"
1669         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1670                 skip "server does not support overstriping"
1671         # We do one more stripe than we have OSTs
1672         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1673                 skip_env "ea_inode feature disabled"
1674
1675         test_mkdir -p $DIR/$tdir
1676         local osts=""
1677         for i in $(seq 0 $OSTCOUNT);
1678         do
1679                 osts=$osts"0"
1680                 if [ $i -ne $OSTCOUNT ]; then
1681                         osts=$osts","
1682                 fi
1683         done
1684         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1685         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1686         echo "$getstripe"
1687
1688         # Strip getstripe output to a space separated list of OSTs
1689         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1690                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1691         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1692                 error "stripes not on specified OSTs"
1693
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1695 }
1696 run_test 27ce "more stripes than OSTs with -o"
1697
1698 test_27cf() {
1699         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1700         local pid=0
1701
1702         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1703         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1704         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1706                 error "failed to set $osp_proc=0"
1707
1708         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1709         pid=$!
1710         sleep 1
1711         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1712         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1713                 error "failed to set $osp_proc=1"
1714         wait $pid
1715         [[ $pid -ne 0 ]] ||
1716                 error "should return error due to $osp_proc=0"
1717 }
1718 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1719
1720 test_27d() {
1721         test_mkdir $DIR/$tdir
1722         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1723                 error "setstripe failed"
1724         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1725         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1726 }
1727 run_test 27d "create file with default settings"
1728
1729 test_27e() {
1730         # LU-5839 adds check for existed layout before setting it
1731         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1732                 skip "Need MDS version at least 2.7.56"
1733
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1736         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1737         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1738 }
1739 run_test 27e "setstripe existing file (should return error)"
1740
1741 test_27f() {
1742         test_mkdir $DIR/$tdir
1743         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1744                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1745         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1746                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1747         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1748         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1749 }
1750 run_test 27f "setstripe with bad stripe size (should return error)"
1751
1752 test_27g() {
1753         test_mkdir $DIR/$tdir
1754         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1755         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1756                 error "$DIR/$tdir/$tfile has object"
1757 }
1758 run_test 27g "$LFS getstripe with no objects"
1759
1760 test_27ga() {
1761         test_mkdir $DIR/$tdir
1762         touch $DIR/$tdir/$tfile || error "touch failed"
1763         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1764         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1765         local rc=$?
1766         (( rc == 2 )) || error "getstripe did not return ENOENT"
1767 }
1768 run_test 27ga "$LFS getstripe with missing file (should return error)"
1769
1770 test_27i() {
1771         test_mkdir $DIR/$tdir
1772         touch $DIR/$tdir/$tfile || error "touch failed"
1773         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1774                 error "missing objects"
1775 }
1776 run_test 27i "$LFS getstripe with some objects"
1777
1778 test_27j() {
1779         test_mkdir $DIR/$tdir
1780         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1781                 error "setstripe failed" || true
1782 }
1783 run_test 27j "setstripe with bad stripe offset (should return error)"
1784
1785 test_27k() { # bug 2844
1786         test_mkdir $DIR/$tdir
1787         local file=$DIR/$tdir/$tfile
1788         local ll_max_blksize=$((4 * 1024 * 1024))
1789         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1790         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1791         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1792         dd if=/dev/zero of=$file bs=4k count=1
1793         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1795 }
1796 run_test 27k "limit i_blksize for broken user apps"
1797
1798 test_27l() {
1799         mcreate $DIR/$tfile || error "creating file"
1800         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1801                 error "setstripe should have failed" || true
1802 }
1803 run_test 27l "check setstripe permissions (should return error)"
1804
1805 test_27m() {
1806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1807
1808         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1809                 skip_env "multiple clients -- skipping"
1810
1811         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1812                    head -n1)
1813         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1814                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1815         fi
1816         stack_trap simple_cleanup_common
1817         test_mkdir $DIR/$tdir
1818         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1819         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1820                 error "dd should fill OST0"
1821         i=2
1822         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1823                 i=$((i + 1))
1824                 [ $i -gt 256 ] && break
1825         done
1826         i=$((i + 1))
1827         touch $DIR/$tdir/$tfile.$i
1828         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1829             awk '{print $1}'| grep -w "0") ] &&
1830                 error "OST0 was full but new created file still use it"
1831         i=$((i + 1))
1832         touch $DIR/$tdir/$tfile.$i
1833         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1834             awk '{print $1}'| grep -w "0") ] &&
1835                 error "OST0 was full but new created file still use it" || true
1836 }
1837 run_test 27m "create file while OST0 was full"
1838
1839 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1840 # if the OST isn't full anymore.
1841 reset_enospc() {
1842         local ostidx=${1:-""}
1843         local delay
1844         local ready
1845         local get_prealloc
1846
1847         local list=$(comma_list $(osts_nodes))
1848         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1849
1850         do_nodes $list lctl set_param fail_loc=0
1851         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1852         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1853                 awk '{print $1 * 2;exit;}')
1854         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1855                         grep -v \"^0$\""
1856         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1857 }
1858
1859 test_27n() {
1860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1862         remote_mds_nodsh && skip "remote MDS with nodsh"
1863         remote_ost_nodsh && skip "remote OST with nodsh"
1864
1865         reset_enospc
1866         rm -f $DIR/$tdir/$tfile
1867         exhaust_precreations 0 0x80000215
1868         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1869         touch $DIR/$tdir/$tfile || error "touch failed"
1870         $LFS getstripe $DIR/$tdir/$tfile
1871         reset_enospc
1872 }
1873 run_test 27n "create file with some full OSTs"
1874
1875 test_27o() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_all_precreations 0x215
1884
1885         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1886
1887         reset_enospc
1888         rm -rf $DIR/$tdir/*
1889 }
1890 run_test 27o "create file with all full OSTs (should error)"
1891
1892 function create_and_checktime() {
1893         local fname=$1
1894         local loops=$2
1895         local i
1896
1897         for ((i=0; i < $loops; i++)); do
1898                 local start=$SECONDS
1899                 multiop $fname-$i Oc
1900                 ((SECONDS-start < TIMEOUT)) ||
1901                         error "creation took " $((SECONDS-$start)) && return 1
1902         done
1903 }
1904
1905 test_27oo() {
1906         local mdts=$(comma_list $(mdts_nodes))
1907
1908         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1909                 skip "Need MDS version at least 2.13.57"
1910
1911         local f0=$DIR/${tfile}-0
1912         local f1=$DIR/${tfile}-1
1913
1914         wait_delete_completed
1915
1916         # refill precreated objects
1917         $LFS setstripe -i0 -c1 $f0
1918
1919         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1920         # force QoS allocation policy
1921         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1922         stack_trap "do_nodes $mdts $LCTL set_param \
1923                 lov.*.qos_threshold_rr=$saved" EXIT
1924         sleep_maxage
1925
1926         # one OST is unavailable, but still have few objects preallocated
1927         stop ost1
1928         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1929                 rm -rf $f1 $DIR/$tdir*" EXIT
1930
1931         for ((i=0; i < 7; i++)); do
1932                 mkdir $DIR/$tdir$i || error "can't create dir"
1933                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1934                         error "can't set striping"
1935         done
1936         for ((i=0; i < 7; i++)); do
1937                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1938         done
1939         wait
1940 }
1941 run_test 27oo "don't let few threads to reserve too many objects"
1942
1943 test_27p() {
1944         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1946         remote_mds_nodsh && skip "remote MDS with nodsh"
1947         remote_ost_nodsh && skip "remote OST with nodsh"
1948
1949         reset_enospc
1950         rm -f $DIR/$tdir/$tfile
1951         test_mkdir $DIR/$tdir
1952
1953         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1954         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1955         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1956
1957         exhaust_precreations 0 0x80000215
1958         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1959         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1960         $LFS getstripe $DIR/$tdir/$tfile
1961
1962         reset_enospc
1963 }
1964 run_test 27p "append to a truncated file with some full OSTs"
1965
1966 test_27q() {
1967         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1969         remote_mds_nodsh && skip "remote MDS with nodsh"
1970         remote_ost_nodsh && skip "remote OST with nodsh"
1971
1972         reset_enospc
1973         rm -f $DIR/$tdir/$tfile
1974
1975         mkdir_on_mdt0 $DIR/$tdir
1976         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1977         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1978                 error "truncate $DIR/$tdir/$tfile failed"
1979         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1980
1981         exhaust_all_precreations 0x215
1982
1983         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1985
1986         reset_enospc
1987 }
1988 run_test 27q "append to truncated file with all OSTs full (should error)"
1989
1990 test_27r() {
1991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1993         remote_mds_nodsh && skip "remote MDS with nodsh"
1994         remote_ost_nodsh && skip "remote OST with nodsh"
1995
1996         reset_enospc
1997         rm -f $DIR/$tdir/$tfile
1998         exhaust_precreations 0 0x80000215
1999
2000         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2005
2006 test_27s() { # bug 10725
2007         test_mkdir $DIR/$tdir
2008         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2009         local stripe_count=0
2010         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2011         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2012                 error "stripe width >= 2^32 succeeded" || true
2013
2014 }
2015 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2016
2017 test_27t() { # bug 10864
2018         WDIR=$(pwd)
2019         WLFS=$(which lfs)
2020         cd $DIR
2021         touch $tfile
2022         $WLFS getstripe $tfile
2023         cd $WDIR
2024 }
2025 run_test 27t "check that utils parse path correctly"
2026
2027 test_27u() { # bug 4900
2028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2029         remote_mds_nodsh && skip "remote MDS with nodsh"
2030
2031         local index
2032         local list=$(comma_list $(mdts_nodes))
2033
2034 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2035         do_nodes $list $LCTL set_param fail_loc=0x139
2036         test_mkdir -p $DIR/$tdir
2037         stack_trap "simple_cleanup_common 1000"
2038         createmany -o $DIR/$tdir/$tfile 1000
2039         do_nodes $list $LCTL set_param fail_loc=0
2040
2041         TLOG=$TMP/$tfile.getstripe
2042         $LFS getstripe $DIR/$tdir > $TLOG
2043         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2044         [[ $OBJS -gt 0 ]] &&
2045                 error "$OBJS objects created on OST-0. See $TLOG" ||
2046                 rm -f $TLOG
2047 }
2048 run_test 27u "skip object creation on OSC w/o objects"
2049
2050 test_27v() { # bug 4900
2051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2053         remote_mds_nodsh && skip "remote MDS with nodsh"
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055
2056         exhaust_all_precreations 0x215
2057         reset_enospc
2058
2059         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2060
2061         touch $DIR/$tdir/$tfile
2062         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2063         # all except ost1
2064         for (( i=1; i < OSTCOUNT; i++ )); do
2065                 do_facet ost$i lctl set_param fail_loc=0x705
2066         done
2067         local START=`date +%s`
2068         createmany -o $DIR/$tdir/$tfile 32
2069
2070         local FINISH=`date +%s`
2071         local TIMEOUT=`lctl get_param -n timeout`
2072         local PROCESS=$((FINISH - START))
2073         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2074                error "$FINISH - $START >= $TIMEOUT / 2"
2075         sleep $((TIMEOUT / 2 - PROCESS))
2076         reset_enospc
2077 }
2078 run_test 27v "skip object creation on slow OST"
2079
2080 test_27w() { # bug 10997
2081         test_mkdir $DIR/$tdir
2082         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2083         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2084                 error "stripe size $size != 65536" || true
2085         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2086                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2087 }
2088 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2089
2090 test_27wa() {
2091         [[ $OSTCOUNT -lt 2 ]] &&
2092                 skip_env "skipping multiple stripe count/offset test"
2093
2094         test_mkdir $DIR/$tdir
2095         for i in $(seq 1 $OSTCOUNT); do
2096                 offset=$((i - 1))
2097                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2098                         error "setstripe -c $i -i $offset failed"
2099                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2100                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2101                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2102                 [ $index -ne $offset ] &&
2103                         error "stripe offset $index != $offset" || true
2104         done
2105 }
2106 run_test 27wa "check $LFS setstripe -c -i options"
2107
2108 test_27x() {
2109         remote_ost_nodsh && skip "remote OST with nodsh"
2110         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2112
2113         OFFSET=$(($OSTCOUNT - 1))
2114         OSTIDX=0
2115         local OST=$(ostname_from_index $OSTIDX)
2116
2117         test_mkdir $DIR/$tdir
2118         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2119         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2120         sleep_maxage
2121         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2122         for i in $(seq 0 $OFFSET); do
2123                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2124                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2125                 error "OST0 was degraded but new created file still use it"
2126         done
2127         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2128 }
2129 run_test 27x "create files while OST0 is degraded"
2130
2131 test_27y() {
2132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2133         remote_mds_nodsh && skip "remote MDS with nodsh"
2134         remote_ost_nodsh && skip "remote OST with nodsh"
2135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2136
2137         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2138         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_last_id)
2140         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2141                 osp.$mdtosc.prealloc_next_id)
2142         local fcount=$((last_id - next_id))
2143         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2144         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2145
2146         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2147                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2148         local OST_DEACTIVE_IDX=-1
2149         local OSC
2150         local OSTIDX
2151         local OST
2152
2153         for OSC in $MDS_OSCS; do
2154                 OST=$(osc_to_ost $OSC)
2155                 OSTIDX=$(index_from_ostuuid $OST)
2156                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2157                         OST_DEACTIVE_IDX=$OSTIDX
2158                 fi
2159                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2160                         echo $OSC "is Deactivated:"
2161                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2162                 fi
2163         done
2164
2165         OSTIDX=$(index_from_ostuuid $OST)
2166         test_mkdir $DIR/$tdir
2167         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2173                         echo $OST "is degraded:"
2174                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2175                                                 obdfilter.$OST.degraded=1
2176                 fi
2177         done
2178
2179         sleep_maxage
2180         createmany -o $DIR/$tdir/$tfile $fcount
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2186                         echo $OST "is recovered from degraded:"
2187                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2188                                                 obdfilter.$OST.degraded=0
2189                 else
2190                         do_facet $SINGLEMDS lctl --device %$OSC activate
2191                 fi
2192         done
2193
2194         # all osp devices get activated, hence -1 stripe count restored
2195         local stripe_count=0
2196
2197         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2198         # devices get activated.
2199         sleep_maxage
2200         $LFS setstripe -c -1 $DIR/$tfile
2201         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2202         rm -f $DIR/$tfile
2203         [ $stripe_count -ne $OSTCOUNT ] &&
2204                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2205         return 0
2206 }
2207 run_test 27y "create files while OST0 is degraded and the rest inactive"
2208
2209 check_seq_oid()
2210 {
2211         log "check file $1"
2212
2213         lmm_count=$($LFS getstripe -c $1)
2214         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2215         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2216
2217         local old_ifs="$IFS"
2218         IFS=$'[:]'
2219         fid=($($LFS path2fid $1))
2220         IFS="$old_ifs"
2221
2222         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2223         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2224
2225         # compare lmm_seq and lu_fid->f_seq
2226         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2227         # compare lmm_object_id and lu_fid->oid
2228         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2229
2230         # check the trusted.fid attribute of the OST objects of the file
2231         local have_obdidx=false
2232         local stripe_nr=0
2233         $LFS getstripe $1 | while read obdidx oid hex seq; do
2234                 # skip lines up to and including "obdidx"
2235                 [ -z "$obdidx" ] && break
2236                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2237                 $have_obdidx || continue
2238
2239                 local ost=$((obdidx + 1))
2240                 local dev=$(ostdevname $ost)
2241                 local oid_hex
2242
2243                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2244
2245                 seq=$(echo $seq | sed -e "s/^0x//g")
2246                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2247                         oid_hex=$(echo $oid)
2248                 else
2249                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2250                 fi
2251                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2252
2253                 local ff=""
2254                 #
2255                 # Don't unmount/remount the OSTs if we don't need to do that.
2256                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2257                 # update too, until that use mount/ll_decode_filter_fid/mount.
2258                 # Re-enable when debugfs will understand new filter_fid.
2259                 #
2260                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2261                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2262                                 $dev 2>/dev/null" | grep "parent=")
2263                 fi
2264                 if [ -z "$ff" ]; then
2265                         stop ost$ost
2266                         mount_fstype ost$ost
2267                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2268                                 $(facet_mntpt ost$ost)/$obj_file)
2269                         unmount_fstype ost$ost
2270                         start ost$ost $dev $OST_MOUNT_OPTS
2271                         clients_up
2272                 fi
2273
2274                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2275
2276                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2277
2278                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2279                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2280                 #
2281                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2282                 #       stripe_size=1048576 component_id=1 component_start=0 \
2283                 #       component_end=33554432
2284                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2285                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2286                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2287                 local ff_pstripe
2288                 if grep -q 'stripe=' <<<$ff; then
2289                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2290                 else
2291                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2292                         # into f_ver in this case.  See comment on ff_parent.
2293                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2294                 fi
2295
2296                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2297                 [ $ff_pseq = $lmm_seq ] ||
2298                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2299                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2300                 [ $ff_poid = $lmm_oid ] ||
2301                         error "FF parent OID $ff_poid != $lmm_oid"
2302                 (($ff_pstripe == $stripe_nr)) ||
2303                         error "FF stripe $ff_pstripe != $stripe_nr"
2304
2305                 stripe_nr=$((stripe_nr + 1))
2306                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2307                         continue
2308                 if grep -q 'stripe_count=' <<<$ff; then
2309                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2310                                             -e 's/ .*//' <<<$ff)
2311                         [ $lmm_count = $ff_scnt ] ||
2312                                 error "FF stripe count $lmm_count != $ff_scnt"
2313                 fi
2314         done
2315 }
2316
2317 test_27z() {
2318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2319         remote_ost_nodsh && skip "remote OST with nodsh"
2320
2321         test_mkdir $DIR/$tdir
2322         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2323                 { error "setstripe -c -1 failed"; return 1; }
2324         # We need to send a write to every object to get parent FID info set.
2325         # This _should_ also work for setattr, but does not currently.
2326         # touch $DIR/$tdir/$tfile-1 ||
2327         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2328                 { error "dd $tfile-1 failed"; return 2; }
2329         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2330                 { error "setstripe -c -1 failed"; return 3; }
2331         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2332                 { error "dd $tfile-2 failed"; return 4; }
2333
2334         # make sure write RPCs have been sent to OSTs
2335         sync; sleep 5; sync
2336
2337         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2338         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2339 }
2340 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2341
2342 test_27A() { # b=19102
2343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2344
2345         save_layout_restore_at_exit $MOUNT
2346         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2347         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2348                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2349         local default_size=$($LFS getstripe -S $MOUNT)
2350         local default_offset=$($LFS getstripe -i $MOUNT)
2351         local dsize=$(do_facet $SINGLEMDS \
2352                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2353         [ $default_size -eq $dsize ] ||
2354                 error "stripe size $default_size != $dsize"
2355         [ $default_offset -eq -1 ] ||
2356                 error "stripe offset $default_offset != -1"
2357 }
2358 run_test 27A "check filesystem-wide default LOV EA values"
2359
2360 test_27B() { # LU-2523
2361         test_mkdir $DIR/$tdir
2362         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2363         touch $DIR/$tdir/f0
2364         # open f1 with O_LOV_DELAY_CREATE
2365         # rename f0 onto f1
2366         # call setstripe ioctl on open file descriptor for f1
2367         # close
2368         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2369                 $DIR/$tdir/f0
2370
2371         rm -f $DIR/$tdir/f1
2372         # open f1 with O_LOV_DELAY_CREATE
2373         # unlink f1
2374         # call setstripe ioctl on open file descriptor for f1
2375         # close
2376         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2377
2378         # Allow multiop to fail in imitation of NFS's busted semantics.
2379         true
2380 }
2381 run_test 27B "call setstripe on open unlinked file/rename victim"
2382
2383 # 27C family tests full striping and overstriping
2384 test_27Ca() { #LU-2871
2385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2386
2387         declare -a ost_idx
2388         local index
2389         local found
2390         local i
2391         local j
2392
2393         test_mkdir $DIR/$tdir
2394         cd $DIR/$tdir
2395         for i in $(seq 0 $((OSTCOUNT - 1))); do
2396                 # set stripe across all OSTs starting from OST$i
2397                 $LFS setstripe -i $i -c -1 $tfile$i
2398                 # get striping information
2399                 ost_idx=($($LFS getstripe $tfile$i |
2400                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2401                 echo ${ost_idx[@]}
2402
2403                 # check the layout
2404                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2405                         error "${#ost_idx[@]} != $OSTCOUNT"
2406
2407                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2408                         found=0
2409                         for j in $(echo ${ost_idx[@]}); do
2410                                 if [ $index -eq $j ]; then
2411                                         found=1
2412                                         break
2413                                 fi
2414                         done
2415                         [ $found = 1 ] ||
2416                                 error "Can not find $index in ${ost_idx[@]}"
2417                 done
2418         done
2419 }
2420 run_test 27Ca "check full striping across all OSTs"
2421
2422 test_27Cb() {
2423         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2424                 skip "server does not support overstriping"
2425         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2426                 skip_env "too many osts, skipping"
2427
2428         test_mkdir -p $DIR/$tdir
2429         local setcount=$(($OSTCOUNT * 2))
2430         [ $setcount -lt 160 ] || large_xattr_enabled ||
2431                 skip_env "ea_inode feature disabled"
2432
2433         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2434                 error "setstripe failed"
2435
2436         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2437         [ $count -eq $setcount ] ||
2438                 error "stripe count $count, should be $setcount"
2439
2440         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2441                 error "overstriped should be set in pattern"
2442
2443         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2444                 error "dd failed"
2445 }
2446 run_test 27Cb "more stripes than OSTs with -C"
2447
2448 test_27Cc() {
2449         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2450                 skip "server does not support overstriping"
2451         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2452
2453         test_mkdir -p $DIR/$tdir
2454         local setcount=$(($OSTCOUNT - 1))
2455
2456         [ $setcount -lt 160 ] || large_xattr_enabled ||
2457                 skip_env "ea_inode feature disabled"
2458
2459         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2460                 error "setstripe failed"
2461
2462         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2463         [ $count -eq $setcount ] ||
2464                 error "stripe count $count, should be $setcount"
2465
2466         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2467                 error "overstriped should not be set in pattern"
2468
2469         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2470                 error "dd failed"
2471 }
2472 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2473
2474 test_27Cd() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2478         large_xattr_enabled || skip_env "ea_inode feature disabled"
2479
2480         test_mkdir -p $DIR/$tdir
2481         local setcount=$LOV_MAX_STRIPE_COUNT
2482
2483         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2484                 error "setstripe failed"
2485
2486         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2487         [ $count -eq $setcount ] ||
2488                 error "stripe count $count, should be $setcount"
2489
2490         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2491                 error "overstriped should be set in pattern"
2492
2493         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2494                 error "dd failed"
2495
2496         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2497 }
2498 run_test 27Cd "test maximum stripe count"
2499
2500 test_27Ce() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         test_mkdir -p $DIR/$tdir
2504
2505         pool_add $TESTNAME || error "Pool creation failed"
2506         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2507
2508         local setcount=8
2509
2510         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2518                 error "overstriped should be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522
2523         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2524 }
2525 run_test 27Ce "test pool with overstriping"
2526
2527 test_27Cf() {
2528         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2529                 skip "server does not support overstriping"
2530         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2531                 skip_env "too many osts, skipping"
2532
2533         test_mkdir -p $DIR/$tdir
2534
2535         local setcount=$(($OSTCOUNT * 2))
2536         [ $setcount -lt 160 ] || large_xattr_enabled ||
2537                 skip_env "ea_inode feature disabled"
2538
2539         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2540                 error "setstripe failed"
2541
2542         echo 1 > $DIR/$tdir/$tfile
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Cf "test default inheritance with overstriping"
2557
2558 test_27D() {
2559         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2560         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2561         remote_mds_nodsh && skip "remote MDS with nodsh"
2562
2563         local POOL=${POOL:-testpool}
2564         local first_ost=0
2565         local last_ost=$(($OSTCOUNT - 1))
2566         local ost_step=1
2567         local ost_list=$(seq $first_ost $ost_step $last_ost)
2568         local ost_range="$first_ost $last_ost $ost_step"
2569
2570         test_mkdir $DIR/$tdir
2571         pool_add $POOL || error "pool_add failed"
2572         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2573
2574         local skip27D
2575         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2576                 skip27D+="-s 29"
2577         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2578                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2579                         skip27D+=" -s 30,31"
2580         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2581           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2582                 skip27D+=" -s 32,33"
2583         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2584                 skip27D+=" -s 34"
2585         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2586                 error "llapi_layout_test failed"
2587
2588         destroy_test_pools || error "destroy test pools failed"
2589 }
2590 run_test 27D "validate llapi_layout API"
2591
2592 # Verify that default_easize is increased from its initial value after
2593 # accessing a widely striped file.
2594 test_27E() {
2595         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2596         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2597                 skip "client does not have LU-3338 fix"
2598
2599         # 72 bytes is the minimum space required to store striping
2600         # information for a file striped across one OST:
2601         # (sizeof(struct lov_user_md_v3) +
2602         #  sizeof(struct lov_user_ost_data_v1))
2603         local min_easize=72
2604         $LCTL set_param -n llite.*.default_easize $min_easize ||
2605                 error "lctl set_param failed"
2606         local easize=$($LCTL get_param -n llite.*.default_easize)
2607
2608         [ $easize -eq $min_easize ] ||
2609                 error "failed to set default_easize"
2610
2611         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2612                 error "setstripe failed"
2613         # In order to ensure stat() call actually talks to MDS we need to
2614         # do something drastic to this file to shake off all lock, e.g.
2615         # rename it (kills lookup lock forcing cache cleaning)
2616         mv $DIR/$tfile $DIR/${tfile}-1
2617         ls -l $DIR/${tfile}-1
2618         rm $DIR/${tfile}-1
2619
2620         easize=$($LCTL get_param -n llite.*.default_easize)
2621
2622         [ $easize -gt $min_easize ] ||
2623                 error "default_easize not updated"
2624 }
2625 run_test 27E "check that default extended attribute size properly increases"
2626
2627 test_27F() { # LU-5346/LU-7975
2628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2629         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2630         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2631                 skip "Need MDS version at least 2.8.51"
2632         remote_ost_nodsh && skip "remote OST with nodsh"
2633
2634         test_mkdir $DIR/$tdir
2635         rm -f $DIR/$tdir/f0
2636         $LFS setstripe -c 2 $DIR/$tdir
2637
2638         # stop all OSTs to reproduce situation for LU-7975 ticket
2639         for num in $(seq $OSTCOUNT); do
2640                 stop ost$num
2641         done
2642
2643         # open/create f0 with O_LOV_DELAY_CREATE
2644         # truncate f0 to a non-0 size
2645         # close
2646         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2647
2648         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2649         # open/write it again to force delayed layout creation
2650         cat /etc/hosts > $DIR/$tdir/f0 &
2651         catpid=$!
2652
2653         # restart OSTs
2654         for num in $(seq $OSTCOUNT); do
2655                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2656                         error "ost$num failed to start"
2657         done
2658
2659         wait $catpid || error "cat failed"
2660
2661         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2662         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2663                 error "wrong stripecount"
2664
2665 }
2666 run_test 27F "Client resend delayed layout creation with non-zero size"
2667
2668 test_27G() { #LU-10629
2669         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2670                 skip "Need MDS version at least 2.11.51"
2671         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2672         remote_mds_nodsh && skip "remote MDS with nodsh"
2673         local POOL=${POOL:-testpool}
2674         local ostrange="0 0 1"
2675
2676         test_mkdir $DIR/$tdir
2677         touch $DIR/$tdir/$tfile.nopool
2678         pool_add $POOL || error "pool_add failed"
2679         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2680         $LFS setstripe -p $POOL $DIR/$tdir
2681
2682         local pool=$($LFS getstripe -p $DIR/$tdir)
2683
2684         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2685         touch $DIR/$tdir/$tfile.default
2686         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2687         $LFS find $DIR/$tdir -type f --pool $POOL
2688         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2689         [[ "$found" == "2" ]] ||
2690                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2691
2692         $LFS setstripe -d $DIR/$tdir
2693
2694         pool=$($LFS getstripe -p -d $DIR/$tdir)
2695
2696         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2697 }
2698 run_test 27G "Clear OST pool from stripe"
2699
2700 test_27H() {
2701         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2702                 skip "Need MDS version newer than 2.11.54"
2703         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2704         test_mkdir $DIR/$tdir
2705         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2706         touch $DIR/$tdir/$tfile
2707         $LFS getstripe -c $DIR/$tdir/$tfile
2708         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2709                 error "two-stripe file doesn't have two stripes"
2710
2711         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2712         $LFS getstripe -y $DIR/$tdir/$tfile
2713         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2714              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2715                 error "expected l_ost_idx: [02]$ not matched"
2716
2717         # make sure ost list has been cleared
2718         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2719         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2720                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2721         touch $DIR/$tdir/f3
2722         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2723 }
2724 run_test 27H "Set specific OSTs stripe"
2725
2726 test_27I() {
2727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2729         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2730                 skip "Need MDS version newer than 2.12.52"
2731         local pool=$TESTNAME
2732         local ostrange="1 1 1"
2733
2734         save_layout_restore_at_exit $MOUNT
2735         $LFS setstripe -c 2 -i 0 $MOUNT
2736         pool_add $pool || error "pool_add failed"
2737         pool_add_targets $pool $ostrange ||
2738                 error "pool_add_targets failed"
2739         test_mkdir $DIR/$tdir
2740         $LFS setstripe -p $pool $DIR/$tdir
2741         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2742         $LFS getstripe $DIR/$tdir/$tfile
2743 }
2744 run_test 27I "check that root dir striping does not break parent dir one"
2745
2746 test_27J() {
2747         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2748                 skip "Need MDS version newer than 2.12.51"
2749
2750         test_mkdir $DIR/$tdir
2751         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2752         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2753
2754         # create foreign file (raw way)
2755         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2756                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2757
2758         ! $LFS setstripe --foreign --flags foo \
2759                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2760                         error "creating $tfile with '--flags foo' should fail"
2761
2762         ! $LFS setstripe --foreign --flags 0xffffffff \
2763                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2764                         error "creating $tfile w/ 0xffffffff flags should fail"
2765
2766         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2767                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2768
2769         # verify foreign file (raw way)
2770         parse_foreign_file -f $DIR/$tdir/$tfile |
2771                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2773         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2774                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2775         parse_foreign_file -f $DIR/$tdir/$tfile |
2776                 grep "lov_foreign_size: 73" ||
2777                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2778         parse_foreign_file -f $DIR/$tdir/$tfile |
2779                 grep "lov_foreign_type: 1" ||
2780                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2781         parse_foreign_file -f $DIR/$tdir/$tfile |
2782                 grep "lov_foreign_flags: 0x0000DA08" ||
2783                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2784         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2785                 grep "lov_foreign_value: 0x" |
2786                 sed -e 's/lov_foreign_value: 0x//')
2787         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2788         [[ $lov = ${lov2// /} ]] ||
2789                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2790
2791         # create foreign file (lfs + API)
2792         $LFS setstripe --foreign=none --flags 0xda08 \
2793                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2794                 error "$DIR/$tdir/${tfile}2: create failed"
2795
2796         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2797                 grep "lfm_magic:.*0x0BD70BD0" ||
2798                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2799         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2803                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2804         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2805                 grep "lfm_flags:.*0x0000DA08" ||
2806                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2807         $LFS getstripe $DIR/$tdir/${tfile}2 |
2808                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2809                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2810
2811         # modify striping should fail
2812         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2813                 error "$DIR/$tdir/$tfile: setstripe should fail"
2814         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2815                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2816
2817         # R/W should fail
2818         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2819         cat $DIR/$tdir/${tfile}2 &&
2820                 error "$DIR/$tdir/${tfile}2: read should fail"
2821         cat /etc/passwd > $DIR/$tdir/$tfile &&
2822                 error "$DIR/$tdir/$tfile: write should fail"
2823         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2824                 error "$DIR/$tdir/${tfile}2: write should fail"
2825
2826         # chmod should work
2827         chmod 222 $DIR/$tdir/$tfile ||
2828                 error "$DIR/$tdir/$tfile: chmod failed"
2829         chmod 222 $DIR/$tdir/${tfile}2 ||
2830                 error "$DIR/$tdir/${tfile}2: chmod failed"
2831
2832         # chown should work
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2834                 error "$DIR/$tdir/$tfile: chown failed"
2835         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: chown failed"
2837
2838         # rename should work
2839         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2840                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2841         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2842                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2843
2844         #remove foreign file
2845         rm $DIR/$tdir/${tfile}.new ||
2846                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2847         rm $DIR/$tdir/${tfile}2.new ||
2848                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2849 }
2850 run_test 27J "basic ops on file with foreign LOV"
2851
2852 test_27K() {
2853         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2854                 skip "Need MDS version newer than 2.12.49"
2855
2856         test_mkdir $DIR/$tdir
2857         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2858         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2859
2860         # create foreign dir (raw way)
2861         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2862                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2863
2864         ! $LFS setdirstripe --foreign --flags foo \
2865                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2866                         error "creating $tdir with '--flags foo' should fail"
2867
2868         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2869                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2870                         error "creating $tdir w/ 0xffffffff flags should fail"
2871
2872         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2873                 error "create_foreign_dir FAILED"
2874
2875         # verify foreign dir (raw way)
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2878                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2882                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2883         parse_foreign_dir -d $DIR/$tdir/$tdir |
2884                 grep "lmv_foreign_flags: 55813$" ||
2885                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2886         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2887                 grep "lmv_foreign_value: 0x" |
2888                 sed 's/lmv_foreign_value: 0x//')
2889         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2890                 sed 's/ //g')
2891         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2892
2893         # create foreign dir (lfs + API)
2894         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2895                 $DIR/$tdir/${tdir}2 ||
2896                 error "$DIR/$tdir/${tdir}2: create failed"
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         test_mkdir $DIR/$tdir
2965
2966         # Set default striping on directory
2967         local setcount=4
2968         local stripe_opt
2969
2970         # if we run against a 2.12 server which lacks overstring support
2971         # then the connect_flag will not report overstriping, even if client
2972         # is 2.14+
2973         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2974                 stripe_opt="-C $setcount"
2975         elif (( $OSTCOUNT >= $setcount )); then
2976                 stripe_opt="-c $setcount"
2977         else
2978                 skip "server does not support overstriping"
2979         fi
2980         $LFS setstripe $stripe_opt $DIR/$tdir
2981
2982         echo 1 > $DIR/$tdir/${tfile}.1
2983         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2984         [ $count -eq $setcount ] ||
2985                 error "(1) stripe count $count, should be $setcount"
2986
2987         # Capture existing append_stripe_count setting for restore
2988         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2989         local mdts=$(comma_list $(mdts_nodes))
2990         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2991
2992         local appendcount=$orig_count
2993         echo 1 >> $DIR/$tdir/${tfile}.2_append
2994         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2995         [ $count -eq $appendcount ] ||
2996                 error "(2)stripe count $count, should be $appendcount for append"
2997
2998         # Disable O_APPEND striping, verify it works
2999         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3000
3001         # Should now get the default striping, which is 4
3002         setcount=4
3003         echo 1 >> $DIR/$tdir/${tfile}.3_append
3004         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3005         [ $count -eq $setcount ] ||
3006                 error "(3) stripe count $count, should be $setcount"
3007
3008         # Try changing the stripe count for append files
3009         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3010
3011         # Append striping is now 2 (directory default is still 4)
3012         appendcount=2
3013         echo 1 >> $DIR/$tdir/${tfile}.4_append
3014         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3015         [ $count -eq $appendcount ] ||
3016                 error "(4) stripe count $count, should be $appendcount for append"
3017
3018         # Test append stripe count of -1
3019         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3020         appendcount=$OSTCOUNT
3021         echo 1 >> $DIR/$tdir/${tfile}.5
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3023         [ $count -eq $appendcount ] ||
3024                 error "(5) stripe count $count, should be $appendcount for append"
3025
3026         # Set append striping back to default of 1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3028
3029         # Try a new default striping, PFL + DOM
3030         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3031
3032         # Create normal DOM file, DOM returns stripe count == 0
3033         setcount=0
3034         touch $DIR/$tdir/${tfile}.6
3035         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3036         [ $count -eq $setcount ] ||
3037                 error "(6) stripe count $count, should be $setcount"
3038
3039         # Show
3040         appendcount=1
3041         echo 1 >> $DIR/$tdir/${tfile}.7_append
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3043         [ $count -eq $appendcount ] ||
3044                 error "(7) stripe count $count, should be $appendcount for append"
3045
3046         # Clean up DOM layout
3047         $LFS setstripe -d $DIR/$tdir
3048
3049         save_layout_restore_at_exit $MOUNT
3050         # Now test that append striping works when layout is from root
3051         $LFS setstripe -c 2 $MOUNT
3052         # Make a special directory for this
3053         mkdir $DIR/${tdir}/${tdir}.2
3054
3055         # Verify for normal file
3056         setcount=2
3057         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3058         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3059         [ $count -eq $setcount ] ||
3060                 error "(8) stripe count $count, should be $setcount"
3061
3062         appendcount=1
3063         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3064         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(9) stripe count $count, should be $appendcount for append"
3067
3068         # Now test O_APPEND striping with pools
3069         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3070         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3071
3072         # Create the pool
3073         pool_add $TESTNAME || error "pool creation failed"
3074         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3075
3076         echo 1 >> $DIR/$tdir/${tfile}.10_append
3077
3078         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3079         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3080
3081         # Check that count is still correct
3082         appendcount=1
3083         echo 1 >> $DIR/$tdir/${tfile}.11_append
3084         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3085         [ $count -eq $appendcount ] ||
3086                 error "(11) stripe count $count, should be $appendcount for append"
3087
3088         # Disable O_APPEND stripe count, verify pool works separately
3089         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3090
3091         echo 1 >> $DIR/$tdir/${tfile}.12_append
3092
3093         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3094         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3095
3096         # Remove pool setting, verify it's not applied
3097         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.13_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3102         [ "$pool" = "" ] || error "(13) pool found: $pool"
3103 }
3104 run_test 27M "test O_APPEND striping"
3105
3106 test_27N() {
3107         combined_mgs_mds && skip "needs separate MGS/MDT"
3108
3109         pool_add $TESTNAME || error "pool_add failed"
3110         do_facet mgs "$LCTL pool_list $FSNAME" |
3111                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3112                 error "lctl pool_list on MGS failed"
3113 }
3114 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3115
3116 clean_foreign_symlink() {
3117         trap 0
3118         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3119         for i in $DIR/$tdir/* ; do
3120                 $LFS unlink_foreign $i || true
3121         done
3122 }
3123
3124 test_27O() {
3125         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3126                 skip "Need MDS version newer than 2.12.51"
3127
3128         test_mkdir $DIR/$tdir
3129         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3130         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3131
3132         trap clean_foreign_symlink EXIT
3133
3134         # enable foreign_symlink behaviour
3135         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3136
3137         # foreign symlink LOV format is a partial path by default
3138
3139         # create foreign file (lfs + API)
3140         $LFS setstripe --foreign=symlink --flags 0xda05 \
3141                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3142                 error "$DIR/$tdir/${tfile}: create failed"
3143
3144         $LFS getstripe -v $DIR/$tdir/${tfile} |
3145                 grep "lfm_magic:.*0x0BD70BD0" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3148                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3149         $LFS getstripe -v $DIR/$tdir/${tfile} |
3150                 grep "lfm_flags:.*0x0000DA05" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3152         $LFS getstripe $DIR/$tdir/${tfile} |
3153                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3155
3156         # modify striping should fail
3157         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3158                 error "$DIR/$tdir/$tfile: setstripe should fail"
3159
3160         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3161         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3162         cat /etc/passwd > $DIR/$tdir/$tfile &&
3163                 error "$DIR/$tdir/$tfile: write should fail"
3164
3165         # rename should succeed
3166         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3167                 error "$DIR/$tdir/$tfile: rename has failed"
3168
3169         #remove foreign_symlink file should fail
3170         rm $DIR/$tdir/${tfile}.new &&
3171                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3172
3173         #test fake symlink
3174         mkdir /tmp/${uuid1} ||
3175                 error "/tmp/${uuid1}: mkdir has failed"
3176         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3177                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3178         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3179         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3180                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3181         #read should succeed now
3182         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3183                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3184         #write should succeed now
3185         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3187         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3189         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3190                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3191
3192         #check that getstripe still works
3193         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3195
3196         # chmod should still succeed
3197         chmod 644 $DIR/$tdir/${tfile}.new ||
3198                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3199
3200         # chown should still succeed
3201         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3203
3204         # rename should still succeed
3205         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3206                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3207
3208         #remove foreign_symlink file should still fail
3209         rm $DIR/$tdir/${tfile} &&
3210                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3211
3212         #use special ioctl() to unlink foreign_symlink file
3213         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3215
3216 }
3217 run_test 27O "basic ops on foreign file of symlink type"
3218
3219 test_27P() {
3220         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3221                 skip "Need MDS version newer than 2.12.49"
3222
3223         test_mkdir $DIR/$tdir
3224         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3225         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3226
3227         trap clean_foreign_symlink EXIT
3228
3229         # enable foreign_symlink behaviour
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3231
3232         # foreign symlink LMV format is a partial path by default
3233
3234         # create foreign dir (lfs + API)
3235         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3236                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3237                 error "$DIR/$tdir/${tdir}: create failed"
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 # createtest also checks that device nodes are created and
3377 # then visible correctly (#2091)
3378 test_28() { # bug 2091
3379         test_mkdir $DIR/d28
3380         $CREATETEST $DIR/d28/ct || error "createtest failed"
3381 }
3382 run_test 28 "create/mknod/mkdir with bad file types ============"
3383
3384 test_29() {
3385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3386
3387         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3388                 disable_opencache
3389                 stack_trap "restore_opencache"
3390         }
3391
3392         sync; sleep 1; sync # flush out any dirty pages from previous tests
3393         cancel_lru_locks
3394         test_mkdir $DIR/d29
3395         touch $DIR/d29/foo
3396         log 'first d29'
3397         ls -l $DIR/d29
3398
3399         declare -i LOCKCOUNTORIG=0
3400         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3401                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3402         done
3403         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3404
3405         declare -i LOCKUNUSEDCOUNTORIG=0
3406         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3407                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3408         done
3409
3410         log 'second d29'
3411         ls -l $DIR/d29
3412         log 'done'
3413
3414         declare -i LOCKCOUNTCURRENT=0
3415         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3416                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3417         done
3418
3419         declare -i LOCKUNUSEDCOUNTCURRENT=0
3420         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3421                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3422         done
3423
3424         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3425                 $LCTL set_param -n ldlm.dump_namespaces ""
3426                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3427                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3428                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3429                 return 2
3430         fi
3431         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3432                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3433                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3434                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3435                 return 3
3436         fi
3437 }
3438 run_test 29 "IT_GETATTR regression  ============================"
3439
3440 test_30a() { # was test_30
3441         cp $(which ls) $DIR || cp /bin/ls $DIR
3442         $DIR/ls / || error "Can't execute binary from lustre"
3443         rm $DIR/ls
3444 }
3445 run_test 30a "execute binary from Lustre (execve) =============="
3446
3447 test_30b() {
3448         cp `which ls` $DIR || cp /bin/ls $DIR
3449         chmod go+rx $DIR/ls
3450         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3451         rm $DIR/ls
3452 }
3453 run_test 30b "execute binary from Lustre as non-root ==========="
3454
3455 test_30c() { # b=22376
3456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3457
3458         cp $(which ls) $DIR || cp /bin/ls $DIR
3459         chmod a-rw $DIR/ls
3460         cancel_lru_locks mdc
3461         cancel_lru_locks osc
3462         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3463         rm -f $DIR/ls
3464 }
3465 run_test 30c "execute binary from Lustre without read perms ===="
3466
3467 test_30d() {
3468         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3469
3470         for i in {1..10}; do
3471                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3472                 local PID=$!
3473                 sleep 1
3474                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3475                 wait $PID || error "executing dd from Lustre failed"
3476                 rm -f $DIR/$tfile
3477         done
3478
3479         rm -f $DIR/dd
3480 }
3481 run_test 30d "execute binary from Lustre while clear locks"
3482
3483 test_31a() {
3484         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3485         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3486 }
3487 run_test 31a "open-unlink file =================================="
3488
3489 test_31b() {
3490         touch $DIR/f31 || error "touch $DIR/f31 failed"
3491         ln $DIR/f31 $DIR/f31b || error "ln failed"
3492         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3493         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3494 }
3495 run_test 31b "unlink file with multiple links while open ======="
3496
3497 test_31c() {
3498         touch $DIR/f31 || error "touch $DIR/f31 failed"
3499         ln $DIR/f31 $DIR/f31c || error "ln failed"
3500         multiop_bg_pause $DIR/f31 O_uc ||
3501                 error "multiop_bg_pause for $DIR/f31 failed"
3502         MULTIPID=$!
3503         $MULTIOP $DIR/f31c Ouc
3504         kill -USR1 $MULTIPID
3505         wait $MULTIPID
3506 }
3507 run_test 31c "open-unlink file with multiple links ============="
3508
3509 test_31d() {
3510         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3511         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3512 }
3513 run_test 31d "remove of open directory ========================="
3514
3515 test_31e() { # bug 2904
3516         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3517 }
3518 run_test 31e "remove of open non-empty directory ==============="
3519
3520 test_31f() { # bug 4554
3521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3522
3523         set -vx
3524         test_mkdir $DIR/d31f
3525         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3526         cp /etc/hosts $DIR/d31f
3527         ls -l $DIR/d31f
3528         $LFS getstripe $DIR/d31f/hosts
3529         multiop_bg_pause $DIR/d31f D_c || return 1
3530         MULTIPID=$!
3531
3532         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3533         test_mkdir $DIR/d31f
3534         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3535         cp /etc/hosts $DIR/d31f
3536         ls -l $DIR/d31f
3537         $LFS getstripe $DIR/d31f/hosts
3538         multiop_bg_pause $DIR/d31f D_c || return 1
3539         MULTIPID2=$!
3540
3541         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3542         wait $MULTIPID || error "first opendir $MULTIPID failed"
3543
3544         sleep 6
3545
3546         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3547         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3548         set +vx
3549 }
3550 run_test 31f "remove of open directory with open-unlink file ==="
3551
3552 test_31g() {
3553         echo "-- cross directory link --"
3554         test_mkdir -c1 $DIR/${tdir}ga
3555         test_mkdir -c1 $DIR/${tdir}gb
3556         touch $DIR/${tdir}ga/f
3557         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3558         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3559         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3560         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3561         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3562 }
3563 run_test 31g "cross directory link==============="
3564
3565 test_31h() {
3566         echo "-- cross directory link --"
3567         test_mkdir -c1 $DIR/${tdir}
3568         test_mkdir -c1 $DIR/${tdir}/dir
3569         touch $DIR/${tdir}/f
3570         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3571         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3572         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3573         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3574         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3575 }
3576 run_test 31h "cross directory link under child==============="
3577
3578 test_31i() {
3579         echo "-- cross directory link --"
3580         test_mkdir -c1 $DIR/$tdir
3581         test_mkdir -c1 $DIR/$tdir/dir
3582         touch $DIR/$tdir/dir/f
3583         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3584         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3585         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3586         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3587         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3588 }
3589 run_test 31i "cross directory link under parent==============="
3590
3591 test_31j() {
3592         test_mkdir -c1 -p $DIR/$tdir
3593         test_mkdir -c1 -p $DIR/$tdir/dir1
3594         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3595         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3596         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3597         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3598         return 0
3599 }
3600 run_test 31j "link for directory==============="
3601
3602 test_31k() {
3603         test_mkdir -c1 -p $DIR/$tdir
3604         touch $DIR/$tdir/s
3605         touch $DIR/$tdir/exist
3606         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3607         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3608         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3609         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3610         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3611         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3612         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3613         return 0
3614 }
3615 run_test 31k "link to file: the same, non-existing, dir==============="
3616
3617 test_31m() {
3618         mkdir $DIR/d31m
3619         touch $DIR/d31m/s
3620         mkdir $DIR/d31m2
3621         touch $DIR/d31m2/exist
3622         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3623         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3624         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3625         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3626         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3627         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3628         return 0
3629 }
3630 run_test 31m "link to file: the same, non-existing, dir==============="
3631
3632 test_31n() {
3633         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3634         nlink=$(stat --format=%h $DIR/$tfile)
3635         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3636         local fd=$(free_fd)
3637         local cmd="exec $fd<$DIR/$tfile"
3638         eval $cmd
3639         cmd="exec $fd<&-"
3640         trap "eval $cmd" EXIT
3641         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3642         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3643         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3644         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3645         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3646         eval $cmd
3647 }
3648 run_test 31n "check link count of unlinked file"
3649
3650 link_one() {
3651         local tempfile=$(mktemp $1_XXXXXX)
3652         mlink $tempfile $1 2> /dev/null &&
3653                 echo "$BASHPID: link $tempfile to $1 succeeded"
3654         munlink $tempfile
3655 }
3656
3657 test_31o() { # LU-2901
3658         test_mkdir $DIR/$tdir
3659         for LOOP in $(seq 100); do
3660                 rm -f $DIR/$tdir/$tfile*
3661                 for THREAD in $(seq 8); do
3662                         link_one $DIR/$tdir/$tfile.$LOOP &
3663                 done
3664                 wait
3665                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3666                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3667                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3668                         break || true
3669         done
3670 }
3671 run_test 31o "duplicate hard links with same filename"
3672
3673 test_31p() {
3674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3675
3676         test_mkdir $DIR/$tdir
3677         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3678         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3679
3680         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3681                 error "open unlink test1 failed"
3682         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3683                 error "open unlink test2 failed"
3684
3685         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3686                 error "test1 still exists"
3687         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3688                 error "test2 still exists"
3689 }
3690 run_test 31p "remove of open striped directory"
3691
3692 test_31q() {
3693         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3694
3695         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3696         index=$($LFS getdirstripe -i $DIR/$tdir)
3697         [ $index -eq 3 ] || error "first stripe index $index != 3"
3698         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3699         [ $index -eq 1 ] || error "second stripe index $index != 1"
3700
3701         # when "-c <stripe_count>" is set, the number of MDTs specified after
3702         # "-i" should equal to the stripe count
3703         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3704 }
3705 run_test 31q "create striped directory on specific MDTs"
3706
3707 #LU-14949
3708 test_31r() {
3709         touch $DIR/$tfile.target
3710         touch $DIR/$tfile.source
3711
3712         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3713         $LCTL set_param fail_loc=0x1419 fail_val=3
3714         cat $DIR/$tfile.target &
3715         CATPID=$!
3716
3717         # Guarantee open is waiting before we get here
3718         sleep 1
3719         mv $DIR/$tfile.source $DIR/$tfile.target
3720
3721         wait $CATPID
3722         RC=$?
3723         if [[ $RC -ne 0 ]]; then
3724                 error "open with cat failed, rc=$RC"
3725         fi
3726 }
3727 run_test 31r "open-rename(replace) race"
3728
3729 cleanup_test32_mount() {
3730         local rc=0
3731         trap 0
3732         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3733         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3734         losetup -d $loopdev || true
3735         rm -rf $DIR/$tdir
3736         return $rc
3737 }
3738
3739 test_32a() {
3740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3741
3742         echo "== more mountpoints and symlinks ================="
3743         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3744         trap cleanup_test32_mount EXIT
3745         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3746         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3747                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3748         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3749                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3750         cleanup_test32_mount
3751 }
3752 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3753
3754 test_32b() {
3755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3756
3757         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3758         trap cleanup_test32_mount EXIT
3759         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3760         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3761                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3762         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3763                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3764         cleanup_test32_mount
3765 }
3766 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3767
3768 test_32c() {
3769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3770
3771         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3772         trap cleanup_test32_mount EXIT
3773         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3774         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3775                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3776         test_mkdir -p $DIR/$tdir/d2/test_dir
3777         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3778                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3779         cleanup_test32_mount
3780 }
3781 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3782
3783 test_32d() {
3784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3785
3786         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3787         trap cleanup_test32_mount EXIT
3788         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3789         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3790                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3791         test_mkdir -p $DIR/$tdir/d2/test_dir
3792         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3793                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3794         cleanup_test32_mount
3795 }
3796 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3797
3798 test_32e() {
3799         rm -fr $DIR/$tdir
3800         test_mkdir -p $DIR/$tdir/tmp
3801         local tmp_dir=$DIR/$tdir/tmp
3802         ln -s $DIR/$tdir $tmp_dir/symlink11
3803         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3804         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3805         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3806 }
3807 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3808
3809 test_32f() {
3810         rm -fr $DIR/$tdir
3811         test_mkdir -p $DIR/$tdir/tmp
3812         local tmp_dir=$DIR/$tdir/tmp
3813         ln -s $DIR/$tdir $tmp_dir/symlink11
3814         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3815         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3816         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3817 }
3818 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3819
3820 test_32g() {
3821         local tmp_dir=$DIR/$tdir/tmp
3822         test_mkdir -p $tmp_dir
3823         test_mkdir $DIR/${tdir}2
3824         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3825         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3826         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3827         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3828         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3829         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3830 }
3831 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3832
3833 test_32h() {
3834         rm -fr $DIR/$tdir $DIR/${tdir}2
3835         tmp_dir=$DIR/$tdir/tmp
3836         test_mkdir -p $tmp_dir
3837         test_mkdir $DIR/${tdir}2
3838         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3839         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3840         ls $tmp_dir/symlink12 || error "listing symlink12"
3841         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3842 }
3843 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3844
3845 test_32i() {
3846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3847
3848         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3849         trap cleanup_test32_mount EXIT
3850         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3851         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3852                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3853         touch $DIR/$tdir/test_file
3854         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3855                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3856         cleanup_test32_mount
3857 }
3858 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3859
3860 test_32j() {
3861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3862
3863         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3864         trap cleanup_test32_mount EXIT
3865         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3866         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3867                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3868         touch $DIR/$tdir/test_file
3869         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3870                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3871         cleanup_test32_mount
3872 }
3873 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3874
3875 test_32k() {
3876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3877
3878         rm -fr $DIR/$tdir
3879         trap cleanup_test32_mount EXIT
3880         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3881         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3882                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3883         test_mkdir -p $DIR/$tdir/d2
3884         touch $DIR/$tdir/d2/test_file || error "touch failed"
3885         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3886                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3887         cleanup_test32_mount
3888 }
3889 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3890
3891 test_32l() {
3892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3893
3894         rm -fr $DIR/$tdir
3895         trap cleanup_test32_mount EXIT
3896         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3897         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3898                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3899         test_mkdir -p $DIR/$tdir/d2
3900         touch $DIR/$tdir/d2/test_file || error "touch failed"
3901         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3902                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3903         cleanup_test32_mount
3904 }
3905 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3906
3907 test_32m() {
3908         rm -fr $DIR/d32m
3909         test_mkdir -p $DIR/d32m/tmp
3910         TMP_DIR=$DIR/d32m/tmp
3911         ln -s $DIR $TMP_DIR/symlink11
3912         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3913         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3914                 error "symlink11 not a link"
3915         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3916                 error "symlink01 not a link"
3917 }
3918 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3919
3920 test_32n() {
3921         rm -fr $DIR/d32n
3922         test_mkdir -p $DIR/d32n/tmp
3923         TMP_DIR=$DIR/d32n/tmp
3924         ln -s $DIR $TMP_DIR/symlink11
3925         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3926         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3927         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3928 }
3929 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3930
3931 test_32o() {
3932         touch $DIR/$tfile
3933         test_mkdir -p $DIR/d32o/tmp
3934         TMP_DIR=$DIR/d32o/tmp
3935         ln -s $DIR/$tfile $TMP_DIR/symlink12
3936         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3937         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3938                 error "symlink12 not a link"
3939         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3940         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3941                 error "$DIR/d32o/tmp/symlink12 not file type"
3942         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3943                 error "$DIR/d32o/symlink02 not file type"
3944 }
3945 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3946
3947 test_32p() {
3948         log 32p_1
3949         rm -fr $DIR/d32p
3950         log 32p_2
3951         rm -f $DIR/$tfile
3952         log 32p_3
3953         touch $DIR/$tfile
3954         log 32p_4
3955         test_mkdir -p $DIR/d32p/tmp
3956         log 32p_5
3957         TMP_DIR=$DIR/d32p/tmp
3958         log 32p_6
3959         ln -s $DIR/$tfile $TMP_DIR/symlink12
3960         log 32p_7
3961         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3962         log 32p_8
3963         cat $DIR/d32p/tmp/symlink12 ||
3964                 error "Can't open $DIR/d32p/tmp/symlink12"
3965         log 32p_9
3966         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3967         log 32p_10
3968 }
3969 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3970
3971 test_32q() {
3972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3973
3974         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3975         trap cleanup_test32_mount EXIT
3976         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3977         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3978         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3979                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3980         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3981         cleanup_test32_mount
3982 }
3983 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3984
3985 test_32r() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3989         trap cleanup_test32_mount EXIT
3990         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3991         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3992         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3993                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3994         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3995         cleanup_test32_mount
3996 }
3997 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3998
3999 test_33aa() {
4000         rm -f $DIR/$tfile
4001         touch $DIR/$tfile
4002         chmod 444 $DIR/$tfile
4003         chown $RUNAS_ID $DIR/$tfile
4004         log 33_1
4005         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4006         log 33_2
4007 }
4008 run_test 33aa "write file with mode 444 (should return error)"
4009
4010 test_33a() {
4011         rm -fr $DIR/$tdir
4012         test_mkdir $DIR/$tdir
4013         chown $RUNAS_ID $DIR/$tdir
4014         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4015                 error "$RUNAS create $tdir/$tfile failed"
4016         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4017                 error "open RDWR" || true
4018 }
4019 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4020
4021 test_33b() {
4022         rm -fr $DIR/$tdir
4023         test_mkdir $DIR/$tdir
4024         chown $RUNAS_ID $DIR/$tdir
4025         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4026 }
4027 run_test 33b "test open file with malformed flags (No panic)"
4028
4029 test_33c() {
4030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4031         remote_ost_nodsh && skip "remote OST with nodsh"
4032
4033         local ostnum
4034         local ostname
4035         local write_bytes
4036         local all_zeros
4037
4038         all_zeros=true
4039         test_mkdir $DIR/$tdir
4040         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4041
4042         sync
4043         for ostnum in $(seq $OSTCOUNT); do
4044                 # test-framework's OST numbering is one-based, while Lustre's
4045                 # is zero-based
4046                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4047                 # check if at least some write_bytes stats are counted
4048                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4049                               obdfilter.$ostname.stats |
4050                               awk '/^write_bytes/ {print $7}' )
4051                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4052                 if (( ${write_bytes:-0} > 0 )); then
4053                         all_zeros=false
4054                         break
4055                 fi
4056         done
4057
4058         $all_zeros || return 0
4059
4060         # Write four bytes
4061         echo foo > $DIR/$tdir/bar
4062         # Really write them
4063         sync
4064
4065         # Total up write_bytes after writing.  We'd better find non-zeros.
4066         for ostnum in $(seq $OSTCOUNT); do
4067                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4068                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4069                               obdfilter/$ostname/stats |
4070                               awk '/^write_bytes/ {print $7}' )
4071                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4072                 if (( ${write_bytes:-0} > 0 )); then
4073                         all_zeros=false
4074                         break
4075                 fi
4076         done
4077
4078         if $all_zeros; then
4079                 for ostnum in $(seq $OSTCOUNT); do
4080                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4081                         echo "Check write_bytes is in obdfilter.*.stats:"
4082                         do_facet ost$ostnum lctl get_param -n \
4083                                 obdfilter.$ostname.stats
4084                 done
4085                 error "OST not keeping write_bytes stats (b=22312)"
4086         fi
4087 }
4088 run_test 33c "test write_bytes stats"
4089
4090 test_33d() {
4091         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4093
4094         local MDTIDX=1
4095         local remote_dir=$DIR/$tdir/remote_dir
4096
4097         test_mkdir $DIR/$tdir
4098         $LFS mkdir -i $MDTIDX $remote_dir ||
4099                 error "create remote directory failed"
4100
4101         touch $remote_dir/$tfile
4102         chmod 444 $remote_dir/$tfile
4103         chown $RUNAS_ID $remote_dir/$tfile
4104
4105         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4106
4107         chown $RUNAS_ID $remote_dir
4108         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4109                                         error "create" || true
4110         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4111                                     error "open RDWR" || true
4112         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4113 }
4114 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4115
4116 test_33e() {
4117         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4118
4119         mkdir $DIR/$tdir
4120
4121         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4122         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4123         mkdir $DIR/$tdir/local_dir
4124
4125         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4126         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4127         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4128
4129         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4130                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4131
4132         rmdir $DIR/$tdir/* || error "rmdir failed"
4133
4134         umask 777
4135         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4136         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4137         mkdir $DIR/$tdir/local_dir
4138
4139         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4140         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4141         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4142
4143         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4144                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4145
4146         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4147
4148         umask 000
4149         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4150         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4151         mkdir $DIR/$tdir/local_dir
4152
4153         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4154         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4155         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4156
4157         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4158                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4159 }
4160 run_test 33e "mkdir and striped directory should have same mode"
4161
4162 cleanup_33f() {
4163         trap 0
4164         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4165 }
4166
4167 test_33f() {
4168         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4169         remote_mds_nodsh && skip "remote MDS with nodsh"
4170
4171         mkdir $DIR/$tdir
4172         chmod go+rwx $DIR/$tdir
4173         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4174         trap cleanup_33f EXIT
4175
4176         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4177                 error "cannot create striped directory"
4178
4179         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4180                 error "cannot create files in striped directory"
4181
4182         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4183                 error "cannot remove files in striped directory"
4184
4185         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4186                 error "cannot remove striped directory"
4187
4188         cleanup_33f
4189 }
4190 run_test 33f "nonroot user can create, access, and remove a striped directory"
4191
4192 test_33g() {
4193         mkdir -p $DIR/$tdir/dir2
4194
4195         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4196         echo $err
4197         [[ $err =~ "exists" ]] || error "Not exists error"
4198 }
4199 run_test 33g "nonroot user create already existing root created file"
4200
4201 test_33h() {
4202         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4203         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4204                 skip "Need MDS version at least 2.13.50"
4205
4206         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4207                 error "mkdir $tdir failed"
4208         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4209
4210         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4211         local index2
4212
4213         for fname in $DIR/$tdir/$tfile.bak \
4214                      $DIR/$tdir/$tfile.SAV \
4215                      $DIR/$tdir/$tfile.orig \
4216                      $DIR/$tdir/$tfile~; do
4217                 touch $fname  || error "touch $fname failed"
4218                 index2=$($LFS getstripe -m $fname)
4219                 [ $index -eq $index2 ] ||
4220                         error "$fname MDT index mismatch $index != $index2"
4221         done
4222
4223         local failed=0
4224         for i in {1..250}; do
4225                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4226                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4227                         touch $fname  || error "touch $fname failed"
4228                         index2=$($LFS getstripe -m $fname)
4229                         if [[ $index != $index2 ]]; then
4230                                 failed=$((failed + 1))
4231                                 echo "$fname MDT index mismatch $index != $index2"
4232                         fi
4233                 done
4234         done
4235         echo "$failed MDT index mismatches"
4236         (( failed < 20 )) || error "MDT index mismatch $failed times"
4237
4238 }
4239 run_test 33h "temp file is located on the same MDT as target"
4240
4241 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4242 test_34a() {
4243         rm -f $DIR/f34
4244         $MCREATE $DIR/f34 || error "mcreate failed"
4245         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4246                 error "getstripe failed"
4247         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4248         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4249                 error "getstripe failed"
4250         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4251                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4252 }
4253 run_test 34a "truncate file that has not been opened ==========="
4254
4255 test_34b() {
4256         [ ! -f $DIR/f34 ] && test_34a
4257         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4258                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4259         $OPENFILE -f O_RDONLY $DIR/f34
4260         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4261                 error "getstripe failed"
4262         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4263                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4264 }
4265 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4266
4267 test_34c() {
4268         [ ! -f $DIR/f34 ] && test_34a
4269         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4270                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4271         $OPENFILE -f O_RDWR $DIR/f34
4272         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4273                 error "$LFS getstripe failed"
4274         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4275                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4276 }
4277 run_test 34c "O_RDWR opening file-with-size works =============="
4278
4279 test_34d() {
4280         [ ! -f $DIR/f34 ] && test_34a
4281         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4282                 error "dd failed"
4283         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4284                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4285         rm $DIR/f34
4286 }
4287 run_test 34d "write to sparse file ============================="
4288
4289 test_34e() {
4290         rm -f $DIR/f34e
4291         $MCREATE $DIR/f34e || error "mcreate failed"
4292         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4293         $CHECKSTAT -s 1000 $DIR/f34e ||
4294                 error "Size of $DIR/f34e not equal to 1000 bytes"
4295         $OPENFILE -f O_RDWR $DIR/f34e
4296         $CHECKSTAT -s 1000 $DIR/f34e ||
4297                 error "Size of $DIR/f34e not equal to 1000 bytes"
4298 }
4299 run_test 34e "create objects, some with size and some without =="
4300
4301 test_34f() { # bug 6242, 6243
4302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4303
4304         SIZE34F=48000
4305         rm -f $DIR/f34f
4306         $MCREATE $DIR/f34f || error "mcreate failed"
4307         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4308         dd if=$DIR/f34f of=$TMP/f34f
4309         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4310         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4311         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4312         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4313         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4314 }
4315 run_test 34f "read from a file with no objects until EOF ======="
4316
4317 test_34g() {
4318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4319
4320         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4321                 error "dd failed"
4322         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4323         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4324                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4325         cancel_lru_locks osc
4326         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4327                 error "wrong size after lock cancel"
4328
4329         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4330         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4331                 error "expanding truncate failed"
4332         cancel_lru_locks osc
4333         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4334                 error "wrong expanded size after lock cancel"
4335 }
4336 run_test 34g "truncate long file ==============================="
4337
4338 test_34h() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         local gid=10
4342         local sz=1000
4343
4344         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4345         sync # Flush the cache so that multiop below does not block on cache
4346              # flush when getting the group lock
4347         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4348         MULTIPID=$!
4349
4350         # Since just timed wait is not good enough, let's do a sync write
4351         # that way we are sure enough time for a roundtrip + processing
4352         # passed + 2 seconds of extra margin.
4353         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4354         rm $DIR/${tfile}-1
4355         sleep 2
4356
4357         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4358                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4359                 kill -9 $MULTIPID
4360         fi
4361         wait $MULTIPID
4362         local nsz=`stat -c %s $DIR/$tfile`
4363         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4364 }
4365 run_test 34h "ftruncate file under grouplock should not block"
4366
4367 test_35a() {
4368         cp /bin/sh $DIR/f35a
4369         chmod 444 $DIR/f35a
4370         chown $RUNAS_ID $DIR/f35a
4371         $RUNAS $DIR/f35a && error || true
4372         rm $DIR/f35a
4373 }
4374 run_test 35a "exec file with mode 444 (should return and not leak)"
4375
4376 test_36a() {
4377         rm -f $DIR/f36
4378         utime $DIR/f36 || error "utime failed for MDS"
4379 }
4380 run_test 36a "MDS utime check (mknod, utime)"
4381
4382 test_36b() {
4383         echo "" > $DIR/f36
4384         utime $DIR/f36 || error "utime failed for OST"
4385 }
4386 run_test 36b "OST utime check (open, utime)"
4387
4388 test_36c() {
4389         rm -f $DIR/d36/f36
4390         test_mkdir $DIR/d36
4391         chown $RUNAS_ID $DIR/d36
4392         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4393 }
4394 run_test 36c "non-root MDS utime check (mknod, utime)"
4395
4396 test_36d() {
4397         [ ! -d $DIR/d36 ] && test_36c
4398         echo "" > $DIR/d36/f36
4399         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4400 }
4401 run_test 36d "non-root OST utime check (open, utime)"
4402
4403 test_36e() {
4404         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4405
4406         test_mkdir $DIR/$tdir
4407         touch $DIR/$tdir/$tfile
4408         $RUNAS utime $DIR/$tdir/$tfile &&
4409                 error "utime worked, expected failure" || true
4410 }
4411 run_test 36e "utime on non-owned file (should return error)"
4412
4413 subr_36fh() {
4414         local fl="$1"
4415         local LANG_SAVE=$LANG
4416         local LC_LANG_SAVE=$LC_LANG
4417         export LANG=C LC_LANG=C # for date language
4418
4419         DATESTR="Dec 20  2000"
4420         test_mkdir $DIR/$tdir
4421         lctl set_param fail_loc=$fl
4422         date; date +%s
4423         cp /etc/hosts $DIR/$tdir/$tfile
4424         sync & # write RPC generated with "current" inode timestamp, but delayed
4425         sleep 1
4426         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4427         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4428         cancel_lru_locks $OSC
4429         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4430         date; date +%s
4431         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4432                 echo "BEFORE: $LS_BEFORE" && \
4433                 echo "AFTER : $LS_AFTER" && \
4434                 echo "WANT  : $DATESTR" && \
4435                 error "$DIR/$tdir/$tfile timestamps changed" || true
4436
4437         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4438 }
4439
4440 test_36f() {
4441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4442
4443         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4444         subr_36fh "0x80000214"
4445 }
4446 run_test 36f "utime on file racing with OST BRW write =========="
4447
4448 test_36g() {
4449         remote_ost_nodsh && skip "remote OST with nodsh"
4450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4451         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4452                 skip "Need MDS version at least 2.12.51"
4453
4454         local fmd_max_age
4455         local fmd
4456         local facet="ost1"
4457         local tgt="obdfilter"
4458
4459         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4460
4461         test_mkdir $DIR/$tdir
4462         fmd_max_age=$(do_facet $facet \
4463                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4464                 head -n 1")
4465
4466         echo "FMD max age: ${fmd_max_age}s"
4467         touch $DIR/$tdir/$tfile
4468         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4469                 gawk '{cnt=cnt+$1}  END{print cnt}')
4470         echo "FMD before: $fmd"
4471         [[ $fmd == 0 ]] &&
4472                 error "FMD wasn't create by touch"
4473         sleep $((fmd_max_age + 12))
4474         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4475                 gawk '{cnt=cnt+$1}  END{print cnt}')
4476         echo "FMD after: $fmd"
4477         [[ $fmd == 0 ]] ||
4478                 error "FMD wasn't expired by ping"
4479 }
4480 run_test 36g "FMD cache expiry ====================="
4481
4482 test_36h() {
4483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4484
4485         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4486         subr_36fh "0x80000227"
4487 }
4488 run_test 36h "utime on file racing with OST BRW write =========="
4489
4490 test_36i() {
4491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4492
4493         test_mkdir $DIR/$tdir
4494         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4495
4496         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4497         local new_mtime=$((mtime + 200))
4498
4499         #change Modify time of striped dir
4500         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4501                         error "change mtime failed"
4502
4503         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4504
4505         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4506 }
4507 run_test 36i "change mtime on striped directory"
4508
4509 # test_37 - duplicate with tests 32q 32r
4510
4511 test_38() {
4512         local file=$DIR/$tfile
4513         touch $file
4514         openfile -f O_DIRECTORY $file
4515         local RC=$?
4516         local ENOTDIR=20
4517         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4518         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4519 }
4520 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4521
4522 test_39a() { # was test_39
4523         touch $DIR/$tfile
4524         touch $DIR/${tfile}2
4525 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4526 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4527 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4528         sleep 2
4529         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4530         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4531                 echo "mtime"
4532                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4533                 echo "atime"
4534                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4535                 echo "ctime"
4536                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4537                 error "O_TRUNC didn't change timestamps"
4538         fi
4539 }
4540 run_test 39a "mtime changed on create"
4541
4542 test_39b() {
4543         test_mkdir -c1 $DIR/$tdir
4544         cp -p /etc/passwd $DIR/$tdir/fopen
4545         cp -p /etc/passwd $DIR/$tdir/flink
4546         cp -p /etc/passwd $DIR/$tdir/funlink
4547         cp -p /etc/passwd $DIR/$tdir/frename
4548         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4549
4550         sleep 1
4551         echo "aaaaaa" >> $DIR/$tdir/fopen
4552         echo "aaaaaa" >> $DIR/$tdir/flink
4553         echo "aaaaaa" >> $DIR/$tdir/funlink
4554         echo "aaaaaa" >> $DIR/$tdir/frename
4555
4556         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4557         local link_new=`stat -c %Y $DIR/$tdir/flink`
4558         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4559         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4560
4561         cat $DIR/$tdir/fopen > /dev/null
4562         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4563         rm -f $DIR/$tdir/funlink2
4564         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4565
4566         for (( i=0; i < 2; i++ )) ; do
4567                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4568                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4569                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4570                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4571
4572                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4573                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4574                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4575                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4576
4577                 cancel_lru_locks $OSC
4578                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4579         done
4580 }
4581 run_test 39b "mtime change on open, link, unlink, rename  ======"
4582
4583 # this should be set to past
4584 TEST_39_MTIME=`date -d "1 year ago" +%s`
4585
4586 # bug 11063
4587 test_39c() {
4588         touch $DIR1/$tfile
4589         sleep 2
4590         local mtime0=`stat -c %Y $DIR1/$tfile`
4591
4592         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4593         local mtime1=`stat -c %Y $DIR1/$tfile`
4594         [ "$mtime1" = $TEST_39_MTIME ] || \
4595                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4596
4597         local d1=`date +%s`
4598         echo hello >> $DIR1/$tfile
4599         local d2=`date +%s`
4600         local mtime2=`stat -c %Y $DIR1/$tfile`
4601         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4602                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4603
4604         mv $DIR1/$tfile $DIR1/$tfile-1
4605
4606         for (( i=0; i < 2; i++ )) ; do
4607                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4608                 [ "$mtime2" = "$mtime3" ] || \
4609                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4610
4611                 cancel_lru_locks $OSC
4612                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4613         done
4614 }
4615 run_test 39c "mtime change on rename ==========================="
4616
4617 # bug 21114
4618 test_39d() {
4619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4620
4621         touch $DIR1/$tfile
4622         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4623
4624         for (( i=0; i < 2; i++ )) ; do
4625                 local mtime=`stat -c %Y $DIR1/$tfile`
4626                 [ $mtime = $TEST_39_MTIME ] || \
4627                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4628
4629                 cancel_lru_locks $OSC
4630                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4631         done
4632 }
4633 run_test 39d "create, utime, stat =============================="
4634
4635 # bug 21114
4636 test_39e() {
4637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4638
4639         touch $DIR1/$tfile
4640         local mtime1=`stat -c %Y $DIR1/$tfile`
4641
4642         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4643
4644         for (( i=0; i < 2; i++ )) ; do
4645                 local mtime2=`stat -c %Y $DIR1/$tfile`
4646                 [ $mtime2 = $TEST_39_MTIME ] || \
4647                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4648
4649                 cancel_lru_locks $OSC
4650                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4651         done
4652 }
4653 run_test 39e "create, stat, utime, stat ========================"
4654
4655 # bug 21114
4656 test_39f() {
4657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4658
4659         touch $DIR1/$tfile
4660         mtime1=`stat -c %Y $DIR1/$tfile`
4661
4662         sleep 2
4663         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4664
4665         for (( i=0; i < 2; i++ )) ; do
4666                 local mtime2=`stat -c %Y $DIR1/$tfile`
4667                 [ $mtime2 = $TEST_39_MTIME ] || \
4668                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4669
4670                 cancel_lru_locks $OSC
4671                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4672         done
4673 }
4674 run_test 39f "create, stat, sleep, utime, stat ================="
4675
4676 # bug 11063
4677 test_39g() {
4678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4679
4680         echo hello >> $DIR1/$tfile
4681         local mtime1=`stat -c %Y $DIR1/$tfile`
4682
4683         sleep 2
4684         chmod o+r $DIR1/$tfile
4685
4686         for (( i=0; i < 2; i++ )) ; do
4687                 local mtime2=`stat -c %Y $DIR1/$tfile`
4688                 [ "$mtime1" = "$mtime2" ] || \
4689                         error "lost mtime: $mtime2, should be $mtime1"
4690
4691                 cancel_lru_locks $OSC
4692                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4693         done
4694 }
4695 run_test 39g "write, chmod, stat ==============================="
4696
4697 # bug 11063
4698 test_39h() {
4699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4700
4701         touch $DIR1/$tfile
4702         sleep 1
4703
4704         local d1=`date`
4705         echo hello >> $DIR1/$tfile
4706         local mtime1=`stat -c %Y $DIR1/$tfile`
4707
4708         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4709         local d2=`date`
4710         if [ "$d1" != "$d2" ]; then
4711                 echo "write and touch not within one second"
4712         else
4713                 for (( i=0; i < 2; i++ )) ; do
4714                         local mtime2=`stat -c %Y $DIR1/$tfile`
4715                         [ "$mtime2" = $TEST_39_MTIME ] || \
4716                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4717
4718                         cancel_lru_locks $OSC
4719                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4720                 done
4721         fi
4722 }
4723 run_test 39h "write, utime within one second, stat ============="
4724
4725 test_39i() {
4726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4727
4728         touch $DIR1/$tfile
4729         sleep 1
4730
4731         echo hello >> $DIR1/$tfile
4732         local mtime1=`stat -c %Y $DIR1/$tfile`
4733
4734         mv $DIR1/$tfile $DIR1/$tfile-1
4735
4736         for (( i=0; i < 2; i++ )) ; do
4737                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4738
4739                 [ "$mtime1" = "$mtime2" ] || \
4740                         error "lost mtime: $mtime2, should be $mtime1"
4741
4742                 cancel_lru_locks $OSC
4743                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4744         done
4745 }
4746 run_test 39i "write, rename, stat =============================="
4747
4748 test_39j() {
4749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4750
4751         start_full_debug_logging
4752         touch $DIR1/$tfile
4753         sleep 1
4754
4755         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4756         lctl set_param fail_loc=0x80000412
4757         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4758                 error "multiop failed"
4759         local multipid=$!
4760         local mtime1=`stat -c %Y $DIR1/$tfile`
4761
4762         mv $DIR1/$tfile $DIR1/$tfile-1
4763
4764         kill -USR1 $multipid
4765         wait $multipid || error "multiop close failed"
4766
4767         for (( i=0; i < 2; i++ )) ; do
4768                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4769                 [ "$mtime1" = "$mtime2" ] ||
4770                         error "mtime is lost on close: $mtime2, " \
4771                               "should be $mtime1"
4772
4773                 cancel_lru_locks
4774                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4775         done
4776         lctl set_param fail_loc=0
4777         stop_full_debug_logging
4778 }
4779 run_test 39j "write, rename, close, stat ======================="
4780
4781 test_39k() {
4782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4783
4784         touch $DIR1/$tfile
4785         sleep 1
4786
4787         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4788         local multipid=$!
4789         local mtime1=`stat -c %Y $DIR1/$tfile`
4790
4791         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4792
4793         kill -USR1 $multipid
4794         wait $multipid || error "multiop close failed"
4795
4796         for (( i=0; i < 2; i++ )) ; do
4797                 local mtime2=`stat -c %Y $DIR1/$tfile`
4798
4799                 [ "$mtime2" = $TEST_39_MTIME ] || \
4800                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4801
4802                 cancel_lru_locks
4803                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4804         done
4805 }
4806 run_test 39k "write, utime, close, stat ========================"
4807
4808 # this should be set to future
4809 TEST_39_ATIME=`date -d "1 year" +%s`
4810
4811 test_39l() {
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813         remote_mds_nodsh && skip "remote MDS with nodsh"
4814
4815         local atime_diff=$(do_facet $SINGLEMDS \
4816                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4817         rm -rf $DIR/$tdir
4818         mkdir_on_mdt0 $DIR/$tdir
4819
4820         # test setting directory atime to future
4821         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4822         local atime=$(stat -c %X $DIR/$tdir)
4823         [ "$atime" = $TEST_39_ATIME ] ||
4824                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4825
4826         # test setting directory atime from future to now
4827         local now=$(date +%s)
4828         touch -a -d @$now $DIR/$tdir
4829
4830         atime=$(stat -c %X $DIR/$tdir)
4831         [ "$atime" -eq "$now"  ] ||
4832                 error "atime is not updated from future: $atime, $now"
4833
4834         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4835         sleep 3
4836
4837         # test setting directory atime when now > dir atime + atime_diff
4838         local d1=$(date +%s)
4839         ls $DIR/$tdir
4840         local d2=$(date +%s)
4841         cancel_lru_locks mdc
4842         atime=$(stat -c %X $DIR/$tdir)
4843         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4844                 error "atime is not updated  : $atime, should be $d2"
4845
4846         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4847         sleep 3
4848
4849         # test not setting directory atime when now < dir atime + atime_diff
4850         ls $DIR/$tdir
4851         cancel_lru_locks mdc
4852         atime=$(stat -c %X $DIR/$tdir)
4853         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4854                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4855
4856         do_facet $SINGLEMDS \
4857                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4858 }
4859 run_test 39l "directory atime update ==========================="
4860
4861 test_39m() {
4862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4863
4864         touch $DIR1/$tfile
4865         sleep 2
4866         local far_past_mtime=$(date -d "May 29 1953" +%s)
4867         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4868
4869         touch -m -d @$far_past_mtime $DIR1/$tfile
4870         touch -a -d @$far_past_atime $DIR1/$tfile
4871
4872         for (( i=0; i < 2; i++ )) ; do
4873                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4874                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4875                         error "atime or mtime set incorrectly"
4876
4877                 cancel_lru_locks $OSC
4878                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4879         done
4880 }
4881 run_test 39m "test atime and mtime before 1970"
4882
4883 test_39n() { # LU-3832
4884         remote_mds_nodsh && skip "remote MDS with nodsh"
4885
4886         local atime_diff=$(do_facet $SINGLEMDS \
4887                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4888         local atime0
4889         local atime1
4890         local atime2
4891
4892         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4893
4894         rm -rf $DIR/$tfile
4895         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4896         atime0=$(stat -c %X $DIR/$tfile)
4897
4898         sleep 5
4899         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4900         atime1=$(stat -c %X $DIR/$tfile)
4901
4902         sleep 5
4903         cancel_lru_locks mdc
4904         cancel_lru_locks osc
4905         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4906         atime2=$(stat -c %X $DIR/$tfile)
4907
4908         do_facet $SINGLEMDS \
4909                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4910
4911         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4912         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4913 }
4914 run_test 39n "check that O_NOATIME is honored"
4915
4916 test_39o() {
4917         TESTDIR=$DIR/$tdir/$tfile
4918         [ -e $TESTDIR ] && rm -rf $TESTDIR
4919         mkdir -p $TESTDIR
4920         cd $TESTDIR
4921         links1=2
4922         ls
4923         mkdir a b
4924         ls
4925         links2=$(stat -c %h .)
4926         [ $(($links1 + 2)) != $links2 ] &&
4927                 error "wrong links count $(($links1 + 2)) != $links2"
4928         rmdir b
4929         links3=$(stat -c %h .)
4930         [ $(($links1 + 1)) != $links3 ] &&
4931                 error "wrong links count $links1 != $links3"
4932         return 0
4933 }
4934 run_test 39o "directory cached attributes updated after create"
4935
4936 test_39p() {
4937         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4938
4939         local MDTIDX=1
4940         TESTDIR=$DIR/$tdir/$tdir
4941         [ -e $TESTDIR ] && rm -rf $TESTDIR
4942         test_mkdir -p $TESTDIR
4943         cd $TESTDIR
4944         links1=2
4945         ls
4946         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4947         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4948         ls
4949         links2=$(stat -c %h .)
4950         [ $(($links1 + 2)) != $links2 ] &&
4951                 error "wrong links count $(($links1 + 2)) != $links2"
4952         rmdir remote_dir2
4953         links3=$(stat -c %h .)
4954         [ $(($links1 + 1)) != $links3 ] &&
4955                 error "wrong links count $links1 != $links3"
4956         return 0
4957 }
4958 run_test 39p "remote directory cached attributes updated after create ========"
4959
4960 test_39r() {
4961         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4962                 skip "no atime update on old OST"
4963         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4964                 skip_env "ldiskfs only test"
4965         fi
4966
4967         local saved_adiff
4968         saved_adiff=$(do_facet ost1 \
4969                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4970         stack_trap "do_facet ost1 \
4971                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4972
4973         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4974
4975         $LFS setstripe -i 0 $DIR/$tfile
4976         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4977                 error "can't write initial file"
4978         cancel_lru_locks osc
4979
4980         # exceed atime_diff and access file
4981         sleep 6
4982         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4983                 error "can't udpate atime"
4984
4985         local atime_cli=$(stat -c %X $DIR/$tfile)
4986         echo "client atime: $atime_cli"
4987         # allow atime update to be written to device
4988         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4989         sleep 5
4990
4991         local ostdev=$(ostdevname 1)
4992         local fid=($(lfs getstripe -y $DIR/$tfile |
4993                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4994         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4995         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4996
4997         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4998         local atime_ost=$(do_facet ost1 "$cmd" |&
4999                           awk -F'[: ]' '/atime:/ { print $4 }')
5000         (( atime_cli == atime_ost )) ||
5001                 error "atime on client $atime_cli != ost $atime_ost"
5002 }
5003 run_test 39r "lazy atime update on OST"
5004
5005 test_39q() { # LU-8041
5006         local testdir=$DIR/$tdir
5007         mkdir -p $testdir
5008         multiop_bg_pause $testdir D_c || error "multiop failed"
5009         local multipid=$!
5010         cancel_lru_locks mdc
5011         kill -USR1 $multipid
5012         local atime=$(stat -c %X $testdir)
5013         [ "$atime" -ne 0 ] || error "atime is zero"
5014 }
5015 run_test 39q "close won't zero out atime"
5016
5017 test_40() {
5018         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5019         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5020                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5021         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5022                 error "$tfile is not 4096 bytes in size"
5023 }
5024 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5025
5026 test_41() {
5027         # bug 1553
5028         small_write $DIR/f41 18
5029 }
5030 run_test 41 "test small file write + fstat ====================="
5031
5032 count_ost_writes() {
5033         lctl get_param -n ${OSC}.*.stats |
5034                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5035                         END { printf("%0.0f", writes) }'
5036 }
5037
5038 # decent default
5039 WRITEBACK_SAVE=500
5040 DIRTY_RATIO_SAVE=40
5041 MAX_DIRTY_RATIO=50
5042 BG_DIRTY_RATIO_SAVE=10
5043 MAX_BG_DIRTY_RATIO=25
5044
5045 start_writeback() {
5046         trap 0
5047         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5048         # dirty_ratio, dirty_background_ratio
5049         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5050                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5051                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5052                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5053         else
5054                 # if file not here, we are a 2.4 kernel
5055                 kill -CONT `pidof kupdated`
5056         fi
5057 }
5058
5059 stop_writeback() {
5060         # setup the trap first, so someone cannot exit the test at the
5061         # exact wrong time and mess up a machine
5062         trap start_writeback EXIT
5063         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5064         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5065                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5066                 sysctl -w vm.dirty_writeback_centisecs=0
5067                 sysctl -w vm.dirty_writeback_centisecs=0
5068                 # save and increase /proc/sys/vm/dirty_ratio
5069                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5070                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5071                 # save and increase /proc/sys/vm/dirty_background_ratio
5072                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5073                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5074         else
5075                 # if file not here, we are a 2.4 kernel
5076                 kill -STOP `pidof kupdated`
5077         fi
5078 }
5079
5080 # ensure that all stripes have some grant before we test client-side cache
5081 setup_test42() {
5082         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5083                 dd if=/dev/zero of=$i bs=4k count=1
5084                 rm $i
5085         done
5086 }
5087
5088 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5089 # file truncation, and file removal.
5090 test_42a() {
5091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5092
5093         setup_test42
5094         cancel_lru_locks $OSC
5095         stop_writeback
5096         sync; sleep 1; sync # just to be safe
5097         BEFOREWRITES=`count_ost_writes`
5098         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5099         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5100         AFTERWRITES=`count_ost_writes`
5101         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5102                 error "$BEFOREWRITES < $AFTERWRITES"
5103         start_writeback
5104 }
5105 run_test 42a "ensure that we don't flush on close"
5106
5107 test_42b() {
5108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5109
5110         setup_test42
5111         cancel_lru_locks $OSC
5112         stop_writeback
5113         sync
5114         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5115         BEFOREWRITES=$(count_ost_writes)
5116         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5117         AFTERWRITES=$(count_ost_writes)
5118         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5119                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5120         fi
5121         BEFOREWRITES=$(count_ost_writes)
5122         sync || error "sync: $?"
5123         AFTERWRITES=$(count_ost_writes)
5124         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5125                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5126         fi
5127         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5128         start_writeback
5129         return 0
5130 }
5131 run_test 42b "test destroy of file with cached dirty data ======"
5132
5133 # if these tests just want to test the effect of truncation,
5134 # they have to be very careful.  consider:
5135 # - the first open gets a {0,EOF}PR lock
5136 # - the first write conflicts and gets a {0, count-1}PW
5137 # - the rest of the writes are under {count,EOF}PW
5138 # - the open for truncate tries to match a {0,EOF}PR
5139 #   for the filesize and cancels the PWs.
5140 # any number of fixes (don't get {0,EOF} on open, match
5141 # composite locks, do smarter file size management) fix
5142 # this, but for now we want these tests to verify that
5143 # the cancellation with truncate intent works, so we
5144 # start the file with a full-file pw lock to match against
5145 # until the truncate.
5146 trunc_test() {
5147         test=$1
5148         file=$DIR/$test
5149         offset=$2
5150         cancel_lru_locks $OSC
5151         stop_writeback
5152         # prime the file with 0,EOF PW to match
5153         touch $file
5154         $TRUNCATE $file 0
5155         sync; sync
5156         # now the real test..
5157         dd if=/dev/zero of=$file bs=1024 count=100
5158         BEFOREWRITES=`count_ost_writes`
5159         $TRUNCATE $file $offset
5160         cancel_lru_locks $OSC
5161         AFTERWRITES=`count_ost_writes`
5162         start_writeback
5163 }
5164
5165 test_42c() {
5166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5167
5168         trunc_test 42c 1024
5169         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5170                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5171         rm $file
5172 }
5173 run_test 42c "test partial truncate of file with cached dirty data"
5174
5175 test_42d() {
5176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5177
5178         trunc_test 42d 0
5179         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5180                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5181         rm $file
5182 }
5183 run_test 42d "test complete truncate of file with cached dirty data"
5184
5185 test_42e() { # bug22074
5186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5187
5188         local TDIR=$DIR/${tdir}e
5189         local pages=16 # hardcoded 16 pages, don't change it.
5190         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5191         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5192         local max_dirty_mb
5193         local warmup_files
5194
5195         test_mkdir $DIR/${tdir}e
5196         $LFS setstripe -c 1 $TDIR
5197         createmany -o $TDIR/f $files
5198
5199         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5200
5201         # we assume that with $OSTCOUNT files, at least one of them will
5202         # be allocated on OST0.
5203         warmup_files=$((OSTCOUNT * max_dirty_mb))
5204         createmany -o $TDIR/w $warmup_files
5205
5206         # write a large amount of data into one file and sync, to get good
5207         # avail_grant number from OST.
5208         for ((i=0; i<$warmup_files; i++)); do
5209                 idx=$($LFS getstripe -i $TDIR/w$i)
5210                 [ $idx -ne 0 ] && continue
5211                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5212                 break
5213         done
5214         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5215         sync
5216         $LCTL get_param $proc_osc0/cur_dirty_bytes
5217         $LCTL get_param $proc_osc0/cur_grant_bytes
5218
5219         # create as much dirty pages as we can while not to trigger the actual
5220         # RPCs directly. but depends on the env, VFS may trigger flush during this
5221         # period, hopefully we are good.
5222         for ((i=0; i<$warmup_files; i++)); do
5223                 idx=$($LFS getstripe -i $TDIR/w$i)
5224                 [ $idx -ne 0 ] && continue
5225                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5226         done
5227         $LCTL get_param $proc_osc0/cur_dirty_bytes
5228         $LCTL get_param $proc_osc0/cur_grant_bytes
5229
5230         # perform the real test
5231         $LCTL set_param $proc_osc0/rpc_stats 0
5232         for ((;i<$files; i++)); do
5233                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5234                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5235         done
5236         sync
5237         $LCTL get_param $proc_osc0/rpc_stats
5238
5239         local percent=0
5240         local have_ppr=false
5241         $LCTL get_param $proc_osc0/rpc_stats |
5242                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5243                         # skip lines until we are at the RPC histogram data
5244                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5245                         $have_ppr || continue
5246
5247                         # we only want the percent stat for < 16 pages
5248                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5249
5250                         percent=$((percent + WPCT))
5251                         if [[ $percent -gt 15 ]]; then
5252                                 error "less than 16-pages write RPCs" \
5253                                       "$percent% > 15%"
5254                                 break
5255                         fi
5256                 done
5257         rm -rf $TDIR
5258 }
5259 run_test 42e "verify sub-RPC writes are not done synchronously"
5260
5261 test_43A() { # was test_43
5262         test_mkdir $DIR/$tdir
5263         cp -p /bin/ls $DIR/$tdir/$tfile
5264         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5265         pid=$!
5266         # give multiop a chance to open
5267         sleep 1
5268
5269         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5270         kill -USR1 $pid
5271         # Wait for multiop to exit
5272         wait $pid
5273 }
5274 run_test 43A "execution of file opened for write should return -ETXTBSY"
5275
5276 test_43a() {
5277         test_mkdir $DIR/$tdir
5278         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5279         $DIR/$tdir/sleep 60 &
5280         SLEEP_PID=$!
5281         # Make sure exec of $tdir/sleep wins race with truncate
5282         sleep 1
5283         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5284         kill $SLEEP_PID
5285 }
5286 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5287
5288 test_43b() {
5289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5290
5291         test_mkdir $DIR/$tdir
5292         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5293         $DIR/$tdir/sleep 60 &
5294         SLEEP_PID=$!
5295         # Make sure exec of $tdir/sleep wins race with truncate
5296         sleep 1
5297         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5298         kill $SLEEP_PID
5299 }
5300 run_test 43b "truncate of file being executed should return -ETXTBSY"
5301
5302 test_43c() {
5303         local testdir="$DIR/$tdir"
5304         test_mkdir $testdir
5305         cp $SHELL $testdir/
5306         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5307                 ( cd $testdir && md5sum -c )
5308 }
5309 run_test 43c "md5sum of copy into lustre"
5310
5311 test_44A() { # was test_44
5312         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5313
5314         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5315         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5316 }
5317 run_test 44A "zero length read from a sparse stripe"
5318
5319 test_44a() {
5320         local nstripe=$($LFS getstripe -c -d $DIR)
5321         [ -z "$nstripe" ] && skip "can't get stripe info"
5322         [[ $nstripe -gt $OSTCOUNT ]] &&
5323                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5324
5325         local stride=$($LFS getstripe -S -d $DIR)
5326         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5327                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5328         fi
5329
5330         OFFSETS="0 $((stride/2)) $((stride-1))"
5331         for offset in $OFFSETS; do
5332                 for i in $(seq 0 $((nstripe-1))); do
5333                         local GLOBALOFFSETS=""
5334                         # size in Bytes
5335                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5336                         local myfn=$DIR/d44a-$size
5337                         echo "--------writing $myfn at $size"
5338                         ll_sparseness_write $myfn $size ||
5339                                 error "ll_sparseness_write"
5340                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5341                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5342                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5343
5344                         for j in $(seq 0 $((nstripe-1))); do
5345                                 # size in Bytes
5346                                 size=$((((j + $nstripe )*$stride + $offset)))
5347                                 ll_sparseness_write $myfn $size ||
5348                                         error "ll_sparseness_write"
5349                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5350                         done
5351                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5352                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5353                         rm -f $myfn
5354                 done
5355         done
5356 }
5357 run_test 44a "test sparse pwrite ==============================="
5358
5359 dirty_osc_total() {
5360         tot=0
5361         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5362                 tot=$(($tot + $d))
5363         done
5364         echo $tot
5365 }
5366 do_dirty_record() {
5367         before=`dirty_osc_total`
5368         echo executing "\"$*\""
5369         eval $*
5370         after=`dirty_osc_total`
5371         echo before $before, after $after
5372 }
5373 test_45() {
5374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5375
5376         f="$DIR/f45"
5377         # Obtain grants from OST if it supports it
5378         echo blah > ${f}_grant
5379         stop_writeback
5380         sync
5381         do_dirty_record "echo blah > $f"
5382         [[ $before -eq $after ]] && error "write wasn't cached"
5383         do_dirty_record "> $f"
5384         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5385         do_dirty_record "echo blah > $f"
5386         [[ $before -eq $after ]] && error "write wasn't cached"
5387         do_dirty_record "sync"
5388         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5389         do_dirty_record "echo blah > $f"
5390         [[ $before -eq $after ]] && error "write wasn't cached"
5391         do_dirty_record "cancel_lru_locks osc"
5392         [[ $before -gt $after ]] ||
5393                 error "lock cancellation didn't lower dirty count"
5394         start_writeback
5395 }
5396 run_test 45 "osc io page accounting ============================"
5397
5398 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5399 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5400 # objects offset and an assert hit when an rpc was built with 1023's mapped
5401 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5402 test_46() {
5403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5404
5405         f="$DIR/f46"
5406         stop_writeback
5407         sync
5408         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5409         sync
5410         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5411         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5412         sync
5413         start_writeback
5414 }
5415 run_test 46 "dirtying a previously written page ================"
5416
5417 # test_47 is removed "Device nodes check" is moved to test_28
5418
5419 test_48a() { # bug 2399
5420         [ "$mds1_FSTYPE" = "zfs" ] &&
5421         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5422                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5423
5424         test_mkdir $DIR/$tdir
5425         cd $DIR/$tdir
5426         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5427         test_mkdir $DIR/$tdir
5428         touch foo || error "'touch foo' failed after recreating cwd"
5429         test_mkdir bar
5430         touch .foo || error "'touch .foo' failed after recreating cwd"
5431         test_mkdir .bar
5432         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5433         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5434         cd . || error "'cd .' failed after recreating cwd"
5435         mkdir . && error "'mkdir .' worked after recreating cwd"
5436         rmdir . && error "'rmdir .' worked after recreating cwd"
5437         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5438         cd .. || error "'cd ..' failed after recreating cwd"
5439 }
5440 run_test 48a "Access renamed working dir (should return errors)="
5441
5442 test_48b() { # bug 2399
5443         rm -rf $DIR/$tdir
5444         test_mkdir $DIR/$tdir
5445         cd $DIR/$tdir
5446         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5447         touch foo && error "'touch foo' worked after removing cwd"
5448         mkdir foo && error "'mkdir foo' worked after removing cwd"
5449         touch .foo && error "'touch .foo' worked after removing cwd"
5450         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5451         ls . > /dev/null && error "'ls .' worked after removing cwd"
5452         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5453         mkdir . && error "'mkdir .' worked after removing cwd"
5454         rmdir . && error "'rmdir .' worked after removing cwd"
5455         ln -s . foo && error "'ln -s .' worked after removing cwd"
5456         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5457 }
5458 run_test 48b "Access removed working dir (should return errors)="
5459
5460 test_48c() { # bug 2350
5461         #lctl set_param debug=-1
5462         #set -vx
5463         rm -rf $DIR/$tdir
5464         test_mkdir -p $DIR/$tdir/dir
5465         cd $DIR/$tdir/dir
5466         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5467         $TRACE touch foo && error "touch foo worked after removing cwd"
5468         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5469         touch .foo && error "touch .foo worked after removing cwd"
5470         mkdir .foo && error "mkdir .foo worked after removing cwd"
5471         $TRACE ls . && error "'ls .' worked after removing cwd"
5472         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5473         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5474         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5475         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5476         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5477 }
5478 run_test 48c "Access removed working subdir (should return errors)"
5479
5480 test_48d() { # bug 2350
5481         #lctl set_param debug=-1
5482         #set -vx
5483         rm -rf $DIR/$tdir
5484         test_mkdir -p $DIR/$tdir/dir
5485         cd $DIR/$tdir/dir
5486         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5487         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5488         $TRACE touch foo && error "'touch foo' worked after removing parent"
5489         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5490         touch .foo && error "'touch .foo' worked after removing parent"
5491         mkdir .foo && error "mkdir .foo worked after removing parent"
5492         $TRACE ls . && error "'ls .' worked after removing parent"
5493         $TRACE ls .. && error "'ls ..' worked after removing parent"
5494         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5495         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5496         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5497         true
5498 }
5499 run_test 48d "Access removed parent subdir (should return errors)"
5500
5501 test_48e() { # bug 4134
5502         #lctl set_param debug=-1
5503         #set -vx
5504         rm -rf $DIR/$tdir
5505         test_mkdir -p $DIR/$tdir/dir
5506         cd $DIR/$tdir/dir
5507         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5508         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5509         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5510         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5511         # On a buggy kernel addition of "touch foo" after cd .. will
5512         # produce kernel oops in lookup_hash_it
5513         touch ../foo && error "'cd ..' worked after recreate parent"
5514         cd $DIR
5515         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5516 }
5517 run_test 48e "Access to recreated parent subdir (should return errors)"
5518
5519 test_48f() {
5520         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5521                 skip "need MDS >= 2.13.55"
5522         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5523         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5524                 skip "needs different host for mdt1 mdt2"
5525         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5526
5527         $LFS mkdir -i0 $DIR/$tdir
5528         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5529
5530         for d in sub1 sub2 sub3; do
5531                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5532                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5533                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5534         done
5535
5536         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5537 }
5538 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5539
5540 test_49() { # LU-1030
5541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5542         remote_ost_nodsh && skip "remote OST with nodsh"
5543
5544         # get ost1 size - $FSNAME-OST0000
5545         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5546                 awk '{ print $4 }')
5547         # write 800M at maximum
5548         [[ $ost1_size -lt 2 ]] && ost1_size=2
5549         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5550
5551         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5552         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5553         local dd_pid=$!
5554
5555         # change max_pages_per_rpc while writing the file
5556         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5557         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5558         # loop until dd process exits
5559         while ps ax -opid | grep -wq $dd_pid; do
5560                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5561                 sleep $((RANDOM % 5 + 1))
5562         done
5563         # restore original max_pages_per_rpc
5564         $LCTL set_param $osc1_mppc=$orig_mppc
5565         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5566 }
5567 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5568
5569 test_50() {
5570         # bug 1485
5571         test_mkdir $DIR/$tdir
5572         cd $DIR/$tdir
5573         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5574 }
5575 run_test 50 "special situations: /proc symlinks  ==============="
5576
5577 test_51a() {    # was test_51
5578         # bug 1516 - create an empty entry right after ".." then split dir
5579         test_mkdir -c1 $DIR/$tdir
5580         touch $DIR/$tdir/foo
5581         $MCREATE $DIR/$tdir/bar
5582         rm $DIR/$tdir/foo
5583         createmany -m $DIR/$tdir/longfile 201
5584         FNUM=202
5585         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5586                 $MCREATE $DIR/$tdir/longfile$FNUM
5587                 FNUM=$(($FNUM + 1))
5588                 echo -n "+"
5589         done
5590         echo
5591         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5592 }
5593 run_test 51a "special situations: split htree with empty entry =="
5594
5595 cleanup_print_lfs_df () {
5596         trap 0
5597         $LFS df
5598         $LFS df -i
5599 }
5600
5601 test_51b() {
5602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5603
5604         local dir=$DIR/$tdir
5605         local nrdirs=$((65536 + 100))
5606
5607         # cleanup the directory
5608         rm -fr $dir
5609
5610         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5611
5612         $LFS df
5613         $LFS df -i
5614         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5615         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5616         [[ $numfree -lt $nrdirs ]] &&
5617                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5618
5619         # need to check free space for the directories as well
5620         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5621         numfree=$(( blkfree / $(fs_inode_ksize) ))
5622         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5623
5624         trap cleanup_print_lfs_df EXIT
5625
5626         # create files
5627         createmany -d $dir/d $nrdirs || {
5628                 unlinkmany $dir/d $nrdirs
5629                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5630         }
5631
5632         # really created :
5633         nrdirs=$(ls -U $dir | wc -l)
5634
5635         # unlink all but 100 subdirectories, then check it still works
5636         local left=100
5637         local delete=$((nrdirs - left))
5638
5639         $LFS df
5640         $LFS df -i
5641
5642         # for ldiskfs the nlink count should be 1, but this is OSD specific
5643         # and so this is listed for informational purposes only
5644         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5645         unlinkmany -d $dir/d $delete ||
5646                 error "unlink of first $delete subdirs failed"
5647
5648         echo "nlink between: $(stat -c %h $dir)"
5649         local found=$(ls -U $dir | wc -l)
5650         [ $found -ne $left ] &&
5651                 error "can't find subdirs: found only $found, expected $left"
5652
5653         unlinkmany -d $dir/d $delete $left ||
5654                 error "unlink of second $left subdirs failed"
5655         # regardless of whether the backing filesystem tracks nlink accurately
5656         # or not, the nlink count shouldn't be more than "." and ".." here
5657         local after=$(stat -c %h $dir)
5658         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5659                 echo "nlink after: $after"
5660
5661         cleanup_print_lfs_df
5662 }
5663 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5664
5665 test_51d() {
5666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5667         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5668         local qos_old
5669
5670         test_mkdir $DIR/$tdir
5671         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5672
5673         qos_old=$(do_facet mds1 \
5674                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5675         do_nodes $(comma_list $(mdts_nodes)) \
5676                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5677         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5678                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5679
5680         createmany -o $DIR/$tdir/t- 1000
5681         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5682         for ((n = 0; n < $OSTCOUNT; n++)); do
5683                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5684                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5685                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5686                             '($1 == '$n') { objs += 1 } \
5687                             END { printf("%0.0f", objs) }')
5688                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5689         done
5690         unlinkmany $DIR/$tdir/t- 1000
5691
5692         nlast=0
5693         for ((n = 0; n < $OSTCOUNT; n++)); do
5694                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5695                         { $LFS df && $LFS df -i &&
5696                         error "OST $n has fewer objects vs. OST $nlast" \
5697                               " (${objs[$n]} < ${objs[$nlast]}"; }
5698                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5699                         { $LFS df && $LFS df -i &&
5700                         error "OST $n has fewer objects vs. OST $nlast" \
5701                               " (${objs[$n]} < ${objs[$nlast]}"; }
5702
5703                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5704                         { $LFS df && $LFS df -i &&
5705                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5706                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5707                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5708                         { $LFS df && $LFS df -i &&
5709                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5710                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5711                 nlast=$n
5712         done
5713 }
5714 run_test 51d "check object distribution"
5715
5716 test_51e() {
5717         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5718                 skip_env "ldiskfs only test"
5719         fi
5720
5721         test_mkdir -c1 $DIR/$tdir
5722         test_mkdir -c1 $DIR/$tdir/d0
5723
5724         touch $DIR/$tdir/d0/foo
5725         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5726                 error "file exceed 65000 nlink limit!"
5727         unlinkmany $DIR/$tdir/d0/f- 65001
5728         return 0
5729 }
5730 run_test 51e "check file nlink limit"
5731
5732 test_51f() {
5733         test_mkdir $DIR/$tdir
5734
5735         local max=100000
5736         local ulimit_old=$(ulimit -n)
5737         local spare=20 # number of spare fd's for scripts/libraries, etc.
5738         local mdt=$($LFS getstripe -m $DIR/$tdir)
5739         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5740
5741         echo "MDT$mdt numfree=$numfree, max=$max"
5742         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5743         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5744                 while ! ulimit -n $((numfree + spare)); do
5745                         numfree=$((numfree * 3 / 4))
5746                 done
5747                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5748         else
5749                 echo "left ulimit at $ulimit_old"
5750         fi
5751
5752         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5753                 unlinkmany $DIR/$tdir/f $numfree
5754                 error "create+open $numfree files in $DIR/$tdir failed"
5755         }
5756         ulimit -n $ulimit_old
5757
5758         # if createmany exits at 120s there will be fewer than $numfree files
5759         unlinkmany $DIR/$tdir/f $numfree || true
5760 }
5761 run_test 51f "check many open files limit"
5762
5763 test_52a() {
5764         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5765         test_mkdir $DIR/$tdir
5766         touch $DIR/$tdir/foo
5767         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5768         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5769         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5770         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5771         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5772                                         error "link worked"
5773         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5774         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5775         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5776                                                      error "lsattr"
5777         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5778         cp -r $DIR/$tdir $TMP/
5779         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5780 }
5781 run_test 52a "append-only flag test (should return errors)"
5782
5783 test_52b() {
5784         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5785         test_mkdir $DIR/$tdir
5786         touch $DIR/$tdir/foo
5787         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5788         cat test > $DIR/$tdir/foo && error "cat test worked"
5789         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5790         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5791         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5792                                         error "link worked"
5793         echo foo >> $DIR/$tdir/foo && error "echo worked"
5794         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5795         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5796         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5797         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5798                                                         error "lsattr"
5799         chattr -i $DIR/$tdir/foo || error "chattr failed"
5800
5801         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5802 }
5803 run_test 52b "immutable flag test (should return errors) ======="
5804
5805 test_53() {
5806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5807         remote_mds_nodsh && skip "remote MDS with nodsh"
5808         remote_ost_nodsh && skip "remote OST with nodsh"
5809
5810         local param
5811         local param_seq
5812         local ostname
5813         local mds_last
5814         local mds_last_seq
5815         local ost_last
5816         local ost_last_seq
5817         local ost_last_id
5818         local ostnum
5819         local node
5820         local found=false
5821         local support_last_seq=true
5822
5823         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5824                 support_last_seq=false
5825
5826         # only test MDT0000
5827         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5828         local value
5829         for value in $(do_facet $SINGLEMDS \
5830                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5831                 param=$(echo ${value[0]} | cut -d "=" -f1)
5832                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5833
5834                 if $support_last_seq; then
5835                         param_seq=$(echo $param |
5836                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5837                         mds_last_seq=$(do_facet $SINGLEMDS \
5838                                        $LCTL get_param -n $param_seq)
5839                 fi
5840                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5841
5842                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5843                 node=$(facet_active_host ost$((ostnum+1)))
5844                 param="obdfilter.$ostname.last_id"
5845                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5846                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5847                         ost_last_id=$ost_last
5848
5849                         if $support_last_seq; then
5850                                 ost_last_id=$(echo $ost_last |
5851                                               awk -F':' '{print $2}' |
5852                                               sed -e "s/^0x//g")
5853                                 ost_last_seq=$(echo $ost_last |
5854                                                awk -F':' '{print $1}')
5855                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5856                         fi
5857
5858                         if [[ $ost_last_id != $mds_last ]]; then
5859                                 error "$ost_last_id != $mds_last"
5860                         else
5861                                 found=true
5862                                 break
5863                         fi
5864                 done
5865         done
5866         $found || error "can not match last_seq/last_id for $mdtosc"
5867         return 0
5868 }
5869 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5870
5871 test_54a() {
5872         perl -MSocket -e ';' || skip "no Socket perl module installed"
5873
5874         $SOCKETSERVER $DIR/socket ||
5875                 error "$SOCKETSERVER $DIR/socket failed: $?"
5876         $SOCKETCLIENT $DIR/socket ||
5877                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5878         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5879 }
5880 run_test 54a "unix domain socket test =========================="
5881
5882 test_54b() {
5883         f="$DIR/f54b"
5884         mknod $f c 1 3
5885         chmod 0666 $f
5886         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5887 }
5888 run_test 54b "char device works in lustre ======================"
5889
5890 find_loop_dev() {
5891         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5892         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5893         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5894
5895         for i in $(seq 3 7); do
5896                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5897                 LOOPDEV=$LOOPBASE$i
5898                 LOOPNUM=$i
5899                 break
5900         done
5901 }
5902
5903 cleanup_54c() {
5904         local rc=0
5905         loopdev="$DIR/loop54c"
5906
5907         trap 0
5908         $UMOUNT $DIR/$tdir || rc=$?
5909         losetup -d $loopdev || true
5910         losetup -d $LOOPDEV || true
5911         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5912         return $rc
5913 }
5914
5915 test_54c() {
5916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5917
5918         loopdev="$DIR/loop54c"
5919
5920         find_loop_dev
5921         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5922         trap cleanup_54c EXIT
5923         mknod $loopdev b 7 $LOOPNUM
5924         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5925         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5926         losetup $loopdev $DIR/$tfile ||
5927                 error "can't set up $loopdev for $DIR/$tfile"
5928         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5929         test_mkdir $DIR/$tdir
5930         mount -t ext2 $loopdev $DIR/$tdir ||
5931                 error "error mounting $loopdev on $DIR/$tdir"
5932         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5933                 error "dd write"
5934         df $DIR/$tdir
5935         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5936                 error "dd read"
5937         cleanup_54c
5938 }
5939 run_test 54c "block device works in lustre ====================="
5940
5941 test_54d() {
5942         f="$DIR/f54d"
5943         string="aaaaaa"
5944         mknod $f p
5945         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5946 }
5947 run_test 54d "fifo device works in lustre ======================"
5948
5949 test_54e() {
5950         f="$DIR/f54e"
5951         string="aaaaaa"
5952         cp -aL /dev/console $f
5953         echo $string > $f || error "echo $string to $f failed"
5954 }
5955 run_test 54e "console/tty device works in lustre ======================"
5956
5957 test_56a() {
5958         local numfiles=3
5959         local numdirs=2
5960         local dir=$DIR/$tdir
5961
5962         rm -rf $dir
5963         test_mkdir -p $dir/dir
5964         for i in $(seq $numfiles); do
5965                 touch $dir/file$i
5966                 touch $dir/dir/file$i
5967         done
5968
5969         local numcomp=$($LFS getstripe --component-count $dir)
5970
5971         [[ $numcomp == 0 ]] && numcomp=1
5972
5973         # test lfs getstripe with --recursive
5974         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5975
5976         [[ $filenum -eq $((numfiles * 2)) ]] ||
5977                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5978         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5979         [[ $filenum -eq $numfiles ]] ||
5980                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5981         echo "$LFS getstripe showed obdidx or l_ost_idx"
5982
5983         # test lfs getstripe with file instead of dir
5984         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5985         [[ $filenum -eq 1 ]] ||
5986                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5987         echo "$LFS getstripe file1 passed"
5988
5989         #test lfs getstripe with --verbose
5990         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5991         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5992                 error "$LFS getstripe --verbose $dir: "\
5993                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5994         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5995                 error "$LFS getstripe $dir: showed lmm_magic"
5996
5997         #test lfs getstripe with -v prints lmm_fid
5998         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5999         local countfids=$((numdirs + numfiles * numcomp))
6000         [[ $filenum -eq $countfids ]] ||
6001                 error "$LFS getstripe -v $dir: "\
6002                       "got $filenum want $countfids lmm_fid"
6003         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6004                 error "$LFS getstripe $dir: showed lmm_fid by default"
6005         echo "$LFS getstripe --verbose passed"
6006
6007         #check for FID information
6008         local fid1=$($LFS getstripe --fid $dir/file1)
6009         local fid2=$($LFS getstripe --verbose $dir/file1 |
6010                      awk '/lmm_fid: / { print $2; exit; }')
6011         local fid3=$($LFS path2fid $dir/file1)
6012
6013         [ "$fid1" != "$fid2" ] &&
6014                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6015         [ "$fid1" != "$fid3" ] &&
6016                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6017         echo "$LFS getstripe --fid passed"
6018
6019         #test lfs getstripe with --obd
6020         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6021                 error "$LFS getstripe --obd wrong_uuid: should return error"
6022
6023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6024
6025         local ostidx=1
6026         local obduuid=$(ostuuid_from_index $ostidx)
6027         local found=$($LFS getstripe -r --obd $obduuid $dir |
6028                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6029
6030         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6031         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6032                 ((filenum--))
6033         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6034                 ((filenum--))
6035
6036         [[ $found -eq $filenum ]] ||
6037                 error "$LFS getstripe --obd: found $found expect $filenum"
6038         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6039                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6040                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6041                 error "$LFS getstripe --obd: should not show file on other obd"
6042         echo "$LFS getstripe --obd passed"
6043 }
6044 run_test 56a "check $LFS getstripe"
6045
6046 test_56b() {
6047         local dir=$DIR/$tdir
6048         local numdirs=3
6049
6050         test_mkdir $dir
6051         for i in $(seq $numdirs); do
6052                 test_mkdir $dir/dir$i
6053         done
6054
6055         # test lfs getdirstripe default mode is non-recursion, which is
6056         # different from lfs getstripe
6057         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6058
6059         [[ $dircnt -eq 1 ]] ||
6060                 error "$LFS getdirstripe: found $dircnt, not 1"
6061         dircnt=$($LFS getdirstripe --recursive $dir |
6062                 grep -c lmv_stripe_count)
6063         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6064                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6065 }
6066 run_test 56b "check $LFS getdirstripe"
6067
6068 test_56c() {
6069         remote_ost_nodsh && skip "remote OST with nodsh"
6070
6071         local ost_idx=0
6072         local ost_name=$(ostname_from_index $ost_idx)
6073         local old_status=$(ost_dev_status $ost_idx)
6074         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6075
6076         [[ -z "$old_status" ]] ||
6077                 skip_env "OST $ost_name is in $old_status status"
6078
6079         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6080         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6081                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6082         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6083                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6084                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6085         fi
6086
6087         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6088                 error "$LFS df -v showing inactive devices"
6089         sleep_maxage
6090
6091         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6092
6093         [[ "$new_status" =~ "D" ]] ||
6094                 error "$ost_name status is '$new_status', missing 'D'"
6095         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6096                 [[ "$new_status" =~ "N" ]] ||
6097                         error "$ost_name status is '$new_status', missing 'N'"
6098         fi
6099         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6100                 [[ "$new_status" =~ "f" ]] ||
6101                         error "$ost_name status is '$new_status', missing 'f'"
6102         fi
6103
6104         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6105         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6106                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6107         [[ -z "$p" ]] && restore_lustre_params < $p || true
6108         sleep_maxage
6109
6110         new_status=$(ost_dev_status $ost_idx)
6111         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6112                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6113         # can't check 'f' as devices may actually be on flash
6114 }
6115 run_test 56c "check 'lfs df' showing device status"
6116
6117 test_56d() {
6118         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6119         local osts=$($LFS df -v $MOUNT | grep -c OST)
6120
6121         $LFS df $MOUNT
6122
6123         (( mdts == MDSCOUNT )) ||
6124                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6125         (( osts == OSTCOUNT )) ||
6126                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6127 }
6128 run_test 56d "'lfs df -v' prints only configured devices"
6129
6130 test_56e() {
6131         err_enoent=2 # No such file or directory
6132         err_eopnotsupp=95 # Operation not supported
6133
6134         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6135         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6136
6137         # Check for handling of path not exists
6138         output=$($LFS df $enoent_mnt 2>&1)
6139         ret=$?
6140
6141         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6142         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6143                 error "expect failure $err_enoent, not $ret"
6144
6145         # Check for handling of non-Lustre FS
6146         output=$($LFS df $notsup_mnt)
6147         ret=$?
6148
6149         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6150         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6151                 error "expect success $err_eopnotsupp, not $ret"
6152
6153         # Check for multiple LustreFS argument
6154         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6155         ret=$?
6156
6157         [[ $output -eq 3 && $ret -eq 0 ]] ||
6158                 error "expect success 3, not $output, rc = $ret"
6159
6160         # Check for correct non-Lustre FS handling among multiple
6161         # LustreFS argument
6162         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6163                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6164         ret=$?
6165
6166         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6167                 error "expect success 2, not $output, rc = $ret"
6168 }
6169 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6170
6171 NUMFILES=3
6172 NUMDIRS=3
6173 setup_56() {
6174         local local_tdir="$1"
6175         local local_numfiles="$2"
6176         local local_numdirs="$3"
6177         local dir_params="$4"
6178         local dir_stripe_params="$5"
6179
6180         if [ ! -d "$local_tdir" ] ; then
6181                 test_mkdir -p $dir_stripe_params $local_tdir
6182                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6183                 for i in $(seq $local_numfiles) ; do
6184                         touch $local_tdir/file$i
6185                 done
6186                 for i in $(seq $local_numdirs) ; do
6187                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6188                         for j in $(seq $local_numfiles) ; do
6189                                 touch $local_tdir/dir$i/file$j
6190                         done
6191                 done
6192         fi
6193 }
6194
6195 setup_56_special() {
6196         local local_tdir=$1
6197         local local_numfiles=$2
6198         local local_numdirs=$3
6199
6200         setup_56 $local_tdir $local_numfiles $local_numdirs
6201
6202         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6203                 for i in $(seq $local_numfiles) ; do
6204                         mknod $local_tdir/loop${i}b b 7 $i
6205                         mknod $local_tdir/null${i}c c 1 3
6206                         ln -s $local_tdir/file1 $local_tdir/link${i}
6207                 done
6208                 for i in $(seq $local_numdirs) ; do
6209                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6210                         mknod $local_tdir/dir$i/null${i}c c 1 3
6211                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6212                 done
6213         fi
6214 }
6215
6216 test_56g() {
6217         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6218         local expected=$(($NUMDIRS + 2))
6219
6220         setup_56 $dir $NUMFILES $NUMDIRS
6221
6222         # test lfs find with -name
6223         for i in $(seq $NUMFILES) ; do
6224                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6225
6226                 [ $nums -eq $expected ] ||
6227                         error "lfs find -name '*$i' $dir wrong: "\
6228                               "found $nums, expected $expected"
6229         done
6230 }
6231 run_test 56g "check lfs find -name"
6232
6233 test_56h() {
6234         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6235         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6236
6237         setup_56 $dir $NUMFILES $NUMDIRS
6238
6239         # test lfs find with ! -name
6240         for i in $(seq $NUMFILES) ; do
6241                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6242
6243                 [ $nums -eq $expected ] ||
6244                         error "lfs find ! -name '*$i' $dir wrong: "\
6245                               "found $nums, expected $expected"
6246         done
6247 }
6248 run_test 56h "check lfs find ! -name"
6249
6250 test_56i() {
6251         local dir=$DIR/$tdir
6252
6253         test_mkdir $dir
6254
6255         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6256         local out=$($cmd)
6257
6258         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6259 }
6260 run_test 56i "check 'lfs find -ost UUID' skips directories"
6261
6262 test_56j() {
6263         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6264
6265         setup_56_special $dir $NUMFILES $NUMDIRS
6266
6267         local expected=$((NUMDIRS + 1))
6268         local cmd="$LFS find -type d $dir"
6269         local nums=$($cmd | wc -l)
6270
6271         [ $nums -eq $expected ] ||
6272                 error "'$cmd' wrong: found $nums, expected $expected"
6273 }
6274 run_test 56j "check lfs find -type d"
6275
6276 test_56k() {
6277         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6278
6279         setup_56_special $dir $NUMFILES $NUMDIRS
6280
6281         local expected=$(((NUMDIRS + 1) * NUMFILES))
6282         local cmd="$LFS find -type f $dir"
6283         local nums=$($cmd | wc -l)
6284
6285         [ $nums -eq $expected ] ||
6286                 error "'$cmd' wrong: found $nums, expected $expected"
6287 }
6288 run_test 56k "check lfs find -type f"
6289
6290 test_56l() {
6291         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6292
6293         setup_56_special $dir $NUMFILES $NUMDIRS
6294
6295         local expected=$((NUMDIRS + NUMFILES))
6296         local cmd="$LFS find -type b $dir"
6297         local nums=$($cmd | wc -l)
6298
6299         [ $nums -eq $expected ] ||
6300                 error "'$cmd' wrong: found $nums, expected $expected"
6301 }
6302 run_test 56l "check lfs find -type b"
6303
6304 test_56m() {
6305         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6306
6307         setup_56_special $dir $NUMFILES $NUMDIRS
6308
6309         local expected=$((NUMDIRS + NUMFILES))
6310         local cmd="$LFS find -type c $dir"
6311         local nums=$($cmd | wc -l)
6312         [ $nums -eq $expected ] ||
6313                 error "'$cmd' wrong: found $nums, expected $expected"
6314 }
6315 run_test 56m "check lfs find -type c"
6316
6317 test_56n() {
6318         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6319         setup_56_special $dir $NUMFILES $NUMDIRS
6320
6321         local expected=$((NUMDIRS + NUMFILES))
6322         local cmd="$LFS find -type l $dir"
6323         local nums=$($cmd | wc -l)
6324
6325         [ $nums -eq $expected ] ||
6326                 error "'$cmd' wrong: found $nums, expected $expected"
6327 }
6328 run_test 56n "check lfs find -type l"
6329
6330 test_56o() {
6331         local dir=$DIR/$tdir
6332
6333         setup_56 $dir $NUMFILES $NUMDIRS
6334         utime $dir/file1 > /dev/null || error "utime (1)"
6335         utime $dir/file2 > /dev/null || error "utime (2)"
6336         utime $dir/dir1 > /dev/null || error "utime (3)"
6337         utime $dir/dir2 > /dev/null || error "utime (4)"
6338         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6339         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6340
6341         local expected=4
6342         local nums=$($LFS find -mtime +0 $dir | wc -l)
6343
6344         [ $nums -eq $expected ] ||
6345                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6346
6347         expected=12
6348         cmd="$LFS find -mtime 0 $dir"
6349         nums=$($cmd | wc -l)
6350         [ $nums -eq $expected ] ||
6351                 error "'$cmd' wrong: found $nums, expected $expected"
6352 }
6353 run_test 56o "check lfs find -mtime for old files"
6354
6355 test_56ob() {
6356         local dir=$DIR/$tdir
6357         local expected=1
6358         local count=0
6359
6360         # just to make sure there is something that won't be found
6361         test_mkdir $dir
6362         touch $dir/$tfile.now
6363
6364         for age in year week day hour min; do
6365                 count=$((count + 1))
6366
6367                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6368                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6369                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6370
6371                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6372                 local nums=$($cmd | wc -l)
6373                 [ $nums -eq $expected ] ||
6374                         error "'$cmd' wrong: found $nums, expected $expected"
6375
6376                 cmd="$LFS find $dir -atime $count${age:0:1}"
6377                 nums=$($cmd | wc -l)
6378                 [ $nums -eq $expected ] ||
6379                         error "'$cmd' wrong: found $nums, expected $expected"
6380         done
6381
6382         sleep 2
6383         cmd="$LFS find $dir -ctime +1s -type f"
6384         nums=$($cmd | wc -l)
6385         (( $nums == $count * 2 + 1)) ||
6386                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6387 }
6388 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6389
6390 test_newerXY_base() {
6391         local x=$1
6392         local y=$2
6393         local dir=$DIR/$tdir
6394         local ref
6395         local negref
6396
6397         if [ $y == "t" ]; then
6398                 if [ $x == "b" ]; then
6399                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6400                 else
6401                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6402                 fi
6403         else
6404                 ref=$DIR/$tfile.newer.$x$y
6405                 touch $ref || error "touch $ref failed"
6406         fi
6407
6408         echo "before = $ref"
6409         sleep 2
6410         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6411         sleep 2
6412         if [ $y == "t" ]; then
6413                 if [ $x == "b" ]; then
6414                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6415                 else
6416                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6417                 fi
6418         else
6419                 negref=$DIR/$tfile.negnewer.$x$y
6420                 touch $negref || error "touch $negref failed"
6421         fi
6422
6423         echo "after = $negref"
6424         local cmd="$LFS find $dir -newer$x$y $ref"
6425         local nums=$(eval $cmd | wc -l)
6426         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6427
6428         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6429                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6430
6431         cmd="$LFS find $dir ! -newer$x$y $negref"
6432         nums=$(eval $cmd | wc -l)
6433         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6434                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6435
6436         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6437         nums=$(eval $cmd | wc -l)
6438         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6439                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6440
6441         rm -rf $DIR/*
6442 }
6443
6444 test_56oc() {
6445         test_newerXY_base "a" "a"
6446         test_newerXY_base "a" "m"
6447         test_newerXY_base "a" "c"
6448         test_newerXY_base "m" "a"
6449         test_newerXY_base "m" "m"
6450         test_newerXY_base "m" "c"
6451         test_newerXY_base "c" "a"
6452         test_newerXY_base "c" "m"
6453         test_newerXY_base "c" "c"
6454
6455         [[ -n "$sles_version" ]] &&
6456                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6457
6458         test_newerXY_base "a" "t"
6459         test_newerXY_base "m" "t"
6460         test_newerXY_base "c" "t"
6461
6462         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6463            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6464                 ! btime_supported && echo "btime unsupported" && return 0
6465
6466         test_newerXY_base "b" "b"
6467         test_newerXY_base "b" "t"
6468 }
6469 run_test 56oc "check lfs find -newerXY work"
6470
6471 btime_supported() {
6472         local dir=$DIR/$tdir
6473         local rc
6474
6475         mkdir -p $dir
6476         touch $dir/$tfile
6477         $LFS find $dir -btime -1d -type f
6478         rc=$?
6479         rm -rf $dir
6480         return $rc
6481 }
6482
6483 test_56od() {
6484         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6485                 ! btime_supported && skip "btime unsupported on MDS"
6486
6487         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6488                 ! btime_supported && skip "btime unsupported on clients"
6489
6490         local dir=$DIR/$tdir
6491         local ref=$DIR/$tfile.ref
6492         local negref=$DIR/$tfile.negref
6493
6494         mkdir $dir || error "mkdir $dir failed"
6495         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6496         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6497         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6498         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6499         touch $ref || error "touch $ref failed"
6500         # sleep 3 seconds at least
6501         sleep 3
6502
6503         local before=$(do_facet mds1 date +%s)
6504         local skew=$(($(date +%s) - before + 1))
6505
6506         if (( skew < 0 && skew > -5 )); then
6507                 sleep $((0 - skew + 1))
6508                 skew=0
6509         fi
6510
6511         # Set the dir stripe params to limit files all on MDT0,
6512         # otherwise we need to calc the max clock skew between
6513         # the client and MDTs.
6514         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6515         sleep 2
6516         touch $negref || error "touch $negref failed"
6517
6518         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6519         local nums=$($cmd | wc -l)
6520         local expected=$(((NUMFILES + 1) * NUMDIRS))
6521
6522         [ $nums -eq $expected ] ||
6523                 error "'$cmd' wrong: found $nums, expected $expected"
6524
6525         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6526         nums=$($cmd | wc -l)
6527         expected=$((NUMFILES + 1))
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530
6531         [ $skew -lt 0 ] && return
6532
6533         local after=$(do_facet mds1 date +%s)
6534         local age=$((after - before + 1 + skew))
6535
6536         cmd="$LFS find $dir -btime -${age}s -type f"
6537         nums=$($cmd | wc -l)
6538         expected=$(((NUMFILES + 1) * NUMDIRS))
6539
6540         echo "Clock skew between client and server: $skew, age:$age"
6541         [ $nums -eq $expected ] ||
6542                 error "'$cmd' wrong: found $nums, expected $expected"
6543
6544         expected=$(($NUMDIRS + 1))
6545         cmd="$LFS find $dir -btime -${age}s -type d"
6546         nums=$($cmd | wc -l)
6547         [ $nums -eq $expected ] ||
6548                 error "'$cmd' wrong: found $nums, expected $expected"
6549         rm -f $ref $negref || error "Failed to remove $ref $negref"
6550 }
6551 run_test 56od "check lfs find -btime with units"
6552
6553 test_56p() {
6554         [ $RUNAS_ID -eq $UID ] &&
6555                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6556
6557         local dir=$DIR/$tdir
6558
6559         setup_56 $dir $NUMFILES $NUMDIRS
6560         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6561
6562         local expected=$NUMFILES
6563         local cmd="$LFS find -uid $RUNAS_ID $dir"
6564         local nums=$($cmd | wc -l)
6565
6566         [ $nums -eq $expected ] ||
6567                 error "'$cmd' wrong: found $nums, expected $expected"
6568
6569         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6570         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6571         nums=$($cmd | wc -l)
6572         [ $nums -eq $expected ] ||
6573                 error "'$cmd' wrong: found $nums, expected $expected"
6574 }
6575 run_test 56p "check lfs find -uid and ! -uid"
6576
6577 test_56q() {
6578         [ $RUNAS_ID -eq $UID ] &&
6579                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6580
6581         local dir=$DIR/$tdir
6582
6583         setup_56 $dir $NUMFILES $NUMDIRS
6584         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6585
6586         local expected=$NUMFILES
6587         local cmd="$LFS find -gid $RUNAS_GID $dir"
6588         local nums=$($cmd | wc -l)
6589
6590         [ $nums -eq $expected ] ||
6591                 error "'$cmd' wrong: found $nums, expected $expected"
6592
6593         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6594         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6595         nums=$($cmd | wc -l)
6596         [ $nums -eq $expected ] ||
6597                 error "'$cmd' wrong: found $nums, expected $expected"
6598 }
6599 run_test 56q "check lfs find -gid and ! -gid"
6600
6601 test_56r() {
6602         local dir=$DIR/$tdir
6603
6604         setup_56 $dir $NUMFILES $NUMDIRS
6605
6606         local expected=12
6607         local cmd="$LFS find -size 0 -type f -lazy $dir"
6608         local nums=$($cmd | wc -l)
6609
6610         [ $nums -eq $expected ] ||
6611                 error "'$cmd' wrong: found $nums, expected $expected"
6612         cmd="$LFS find -size 0 -type f $dir"
6613         nums=$($cmd | wc -l)
6614         [ $nums -eq $expected ] ||
6615                 error "'$cmd' wrong: found $nums, expected $expected"
6616
6617         expected=0
6618         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6619         nums=$($cmd | wc -l)
6620         [ $nums -eq $expected ] ||
6621                 error "'$cmd' wrong: found $nums, expected $expected"
6622         cmd="$LFS find ! -size 0 -type f $dir"
6623         nums=$($cmd | wc -l)
6624         [ $nums -eq $expected ] ||
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626
6627         echo "test" > $dir/$tfile
6628         echo "test2" > $dir/$tfile.2 && sync
6629         expected=1
6630         cmd="$LFS find -size 5 -type f -lazy $dir"
6631         nums=$($cmd | wc -l)
6632         [ $nums -eq $expected ] ||
6633                 error "'$cmd' wrong: found $nums, expected $expected"
6634         cmd="$LFS find -size 5 -type f $dir"
6635         nums=$($cmd | wc -l)
6636         [ $nums -eq $expected ] ||
6637                 error "'$cmd' wrong: found $nums, expected $expected"
6638
6639         expected=1
6640         cmd="$LFS find -size +5 -type f -lazy $dir"
6641         nums=$($cmd | wc -l)
6642         [ $nums -eq $expected ] ||
6643                 error "'$cmd' wrong: found $nums, expected $expected"
6644         cmd="$LFS find -size +5 -type f $dir"
6645         nums=$($cmd | wc -l)
6646         [ $nums -eq $expected ] ||
6647                 error "'$cmd' wrong: found $nums, expected $expected"
6648
6649         expected=2
6650         cmd="$LFS find -size +0 -type f -lazy $dir"
6651         nums=$($cmd | wc -l)
6652         [ $nums -eq $expected ] ||
6653                 error "'$cmd' wrong: found $nums, expected $expected"
6654         cmd="$LFS find -size +0 -type f $dir"
6655         nums=$($cmd | wc -l)
6656         [ $nums -eq $expected ] ||
6657                 error "'$cmd' wrong: found $nums, expected $expected"
6658
6659         expected=2
6660         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6661         nums=$($cmd | wc -l)
6662         [ $nums -eq $expected ] ||
6663                 error "'$cmd' wrong: found $nums, expected $expected"
6664         cmd="$LFS find ! -size -5 -type f $dir"
6665         nums=$($cmd | wc -l)
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668
6669         expected=12
6670         cmd="$LFS find -size -5 -type f -lazy $dir"
6671         nums=$($cmd | wc -l)
6672         [ $nums -eq $expected ] ||
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674         cmd="$LFS find -size -5 -type f $dir"
6675         nums=$($cmd | wc -l)
6676         [ $nums -eq $expected ] ||
6677                 error "'$cmd' wrong: found $nums, expected $expected"
6678 }
6679 run_test 56r "check lfs find -size works"
6680
6681 test_56ra_sub() {
6682         local expected=$1
6683         local glimpses=$2
6684         local cmd="$3"
6685
6686         cancel_lru_locks $OSC
6687
6688         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6689         local nums=$($cmd | wc -l)
6690
6691         [ $nums -eq $expected ] ||
6692                 error "'$cmd' wrong: found $nums, expected $expected"
6693
6694         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6695
6696         if (( rpcs_before + glimpses != rpcs_after )); then
6697                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6698                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6699
6700                 if [[ $glimpses == 0 ]]; then
6701                         error "'$cmd' should not send glimpse RPCs to OST"
6702                 else
6703                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6704                 fi
6705         fi
6706 }
6707
6708 test_56ra() {
6709         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6710                 skip "MDS < 2.12.58 doesn't return LSOM data"
6711         local dir=$DIR/$tdir
6712         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6713
6714         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6715
6716         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6717         $LCTL set_param -n llite.*.statahead_agl=0
6718         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6719
6720         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6721         # open and close all files to ensure LSOM is updated
6722         cancel_lru_locks $OSC
6723         find $dir -type f | xargs cat > /dev/null
6724
6725         #   expect_found  glimpse_rpcs  command_to_run
6726         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6727         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6728         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6729         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6730
6731         echo "test" > $dir/$tfile
6732         echo "test2" > $dir/$tfile.2 && sync
6733         cancel_lru_locks $OSC
6734         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6735
6736         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6737         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6738         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6739         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6740
6741         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6742         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6743         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6744         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6745         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6746         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6747 }
6748 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6749
6750 test_56rb() {
6751         local dir=$DIR/$tdir
6752         local tmp=$TMP/$tfile.log
6753         local mdt_idx;
6754
6755         test_mkdir -p $dir || error "failed to mkdir $dir"
6756         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6757                 error "failed to setstripe $dir/$tfile"
6758         mdt_idx=$($LFS getdirstripe -i $dir)
6759         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6760
6761         stack_trap "rm -f $tmp" EXIT
6762         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6763         ! grep -q obd_uuid $tmp ||
6764                 error "failed to find --size +100K --ost 0 $dir"
6765         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6766         ! grep -q obd_uuid $tmp ||
6767                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6768 }
6769 run_test 56rb "check lfs find --size --ost/--mdt works"
6770
6771 test_56rc() {
6772         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6773         local dir=$DIR/$tdir
6774         local found
6775
6776         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6777         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6778         (( $MDSCOUNT > 2 )) &&
6779                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6780         mkdir $dir/$tdir-{1..10}
6781         touch $dir/$tfile-{1..10}
6782
6783         found=$($LFS find $dir --mdt-count 2 | wc -l)
6784         expect=11
6785         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6786
6787         found=$($LFS find $dir -T +1 | wc -l)
6788         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6789         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6790
6791         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6792         expect=11
6793         (( $found == $expect )) || error "found $found all_char, expect $expect"
6794
6795         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6796         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6797         (( $found == $expect )) || error "found $found all_char, expect $expect"
6798 }
6799 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6800
6801 test_56s() { # LU-611 #LU-9369
6802         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6803
6804         local dir=$DIR/$tdir
6805         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6806
6807         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6808         for i in $(seq $NUMDIRS); do
6809                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6810         done
6811
6812         local expected=$NUMDIRS
6813         local cmd="$LFS find -c $OSTCOUNT $dir"
6814         local nums=$($cmd | wc -l)
6815
6816         [ $nums -eq $expected ] || {
6817                 $LFS getstripe -R $dir
6818                 error "'$cmd' wrong: found $nums, expected $expected"
6819         }
6820
6821         expected=$((NUMDIRS + onestripe))
6822         cmd="$LFS find -stripe-count +0 -type f $dir"
6823         nums=$($cmd | wc -l)
6824         [ $nums -eq $expected ] || {
6825                 $LFS getstripe -R $dir
6826                 error "'$cmd' wrong: found $nums, expected $expected"
6827         }
6828
6829         expected=$onestripe
6830         cmd="$LFS find -stripe-count 1 -type f $dir"
6831         nums=$($cmd | wc -l)
6832         [ $nums -eq $expected ] || {
6833                 $LFS getstripe -R $dir
6834                 error "'$cmd' wrong: found $nums, expected $expected"
6835         }
6836
6837         cmd="$LFS find -stripe-count -2 -type f $dir"
6838         nums=$($cmd | wc -l)
6839         [ $nums -eq $expected ] || {
6840                 $LFS getstripe -R $dir
6841                 error "'$cmd' wrong: found $nums, expected $expected"
6842         }
6843
6844         expected=0
6845         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6846         nums=$($cmd | wc -l)
6847         [ $nums -eq $expected ] || {
6848                 $LFS getstripe -R $dir
6849                 error "'$cmd' wrong: found $nums, expected $expected"
6850         }
6851 }
6852 run_test 56s "check lfs find -stripe-count works"
6853
6854 test_56t() { # LU-611 #LU-9369
6855         local dir=$DIR/$tdir
6856
6857         setup_56 $dir 0 $NUMDIRS
6858         for i in $(seq $NUMDIRS); do
6859                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6860         done
6861
6862         local expected=$NUMDIRS
6863         local cmd="$LFS find -S 8M $dir"
6864         local nums=$($cmd | wc -l)
6865
6866         [ $nums -eq $expected ] || {
6867                 $LFS getstripe -R $dir
6868                 error "'$cmd' wrong: found $nums, expected $expected"
6869         }
6870         rm -rf $dir
6871
6872         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6873
6874         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6875
6876         expected=$(((NUMDIRS + 1) * NUMFILES))
6877         cmd="$LFS find -stripe-size 512k -type f $dir"
6878         nums=$($cmd | wc -l)
6879         [ $nums -eq $expected ] ||
6880                 error "'$cmd' wrong: found $nums, expected $expected"
6881
6882         cmd="$LFS find -stripe-size +320k -type f $dir"
6883         nums=$($cmd | wc -l)
6884         [ $nums -eq $expected ] ||
6885                 error "'$cmd' wrong: found $nums, expected $expected"
6886
6887         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6888         cmd="$LFS find -stripe-size +200k -type f $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892
6893         cmd="$LFS find -stripe-size -640k -type f $dir"
6894         nums=$($cmd | wc -l)
6895         [ $nums -eq $expected ] ||
6896                 error "'$cmd' wrong: found $nums, expected $expected"
6897
6898         expected=4
6899         cmd="$LFS find -stripe-size 256k -type f $dir"
6900         nums=$($cmd | wc -l)
6901         [ $nums -eq $expected ] ||
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903
6904         cmd="$LFS find -stripe-size -320k -type f $dir"
6905         nums=$($cmd | wc -l)
6906         [ $nums -eq $expected ] ||
6907                 error "'$cmd' wrong: found $nums, expected $expected"
6908
6909         expected=0
6910         cmd="$LFS find -stripe-size 1024k -type f $dir"
6911         nums=$($cmd | wc -l)
6912         [ $nums -eq $expected ] ||
6913                 error "'$cmd' wrong: found $nums, expected $expected"
6914 }
6915 run_test 56t "check lfs find -stripe-size works"
6916
6917 test_56u() { # LU-611
6918         local dir=$DIR/$tdir
6919
6920         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6921
6922         if [[ $OSTCOUNT -gt 1 ]]; then
6923                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6924                 onestripe=4
6925         else
6926                 onestripe=0
6927         fi
6928
6929         local expected=$(((NUMDIRS + 1) * NUMFILES))
6930         local cmd="$LFS find -stripe-index 0 -type f $dir"
6931         local nums=$($cmd | wc -l)
6932
6933         [ $nums -eq $expected ] ||
6934                 error "'$cmd' wrong: found $nums, expected $expected"
6935
6936         expected=$onestripe
6937         cmd="$LFS find -stripe-index 1 -type f $dir"
6938         nums=$($cmd | wc -l)
6939         [ $nums -eq $expected ] ||
6940                 error "'$cmd' wrong: found $nums, expected $expected"
6941
6942         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6943         nums=$($cmd | wc -l)
6944         [ $nums -eq $expected ] ||
6945                 error "'$cmd' wrong: found $nums, expected $expected"
6946
6947         expected=0
6948         # This should produce an error and not return any files
6949         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6950         nums=$($cmd 2>/dev/null | wc -l)
6951         [ $nums -eq $expected ] ||
6952                 error "'$cmd' wrong: found $nums, expected $expected"
6953
6954         if [[ $OSTCOUNT -gt 1 ]]; then
6955                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6956                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6957                 nums=$($cmd | wc -l)
6958                 [ $nums -eq $expected ] ||
6959                         error "'$cmd' wrong: found $nums, expected $expected"
6960         fi
6961 }
6962 run_test 56u "check lfs find -stripe-index works"
6963
6964 test_56v() {
6965         local mdt_idx=0
6966         local dir=$DIR/$tdir
6967
6968         setup_56 $dir $NUMFILES $NUMDIRS
6969
6970         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6971         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6972
6973         for file in $($LFS find -m $UUID $dir); do
6974                 file_midx=$($LFS getstripe -m $file)
6975                 [ $file_midx -eq $mdt_idx ] ||
6976                         error "lfs find -m $UUID != getstripe -m $file_midx"
6977         done
6978 }
6979 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6980
6981 test_56w() {
6982         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6984
6985         local dir=$DIR/$tdir
6986
6987         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6988
6989         local stripe_size=$($LFS getstripe -S -d $dir) ||
6990                 error "$LFS getstripe -S -d $dir failed"
6991         stripe_size=${stripe_size%% *}
6992
6993         local file_size=$((stripe_size * OSTCOUNT))
6994         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6995         local required_space=$((file_num * file_size))
6996         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6997                            head -n1)
6998         [[ $free_space -le $((required_space / 1024)) ]] &&
6999                 skip_env "need $required_space, have $free_space kbytes"
7000
7001         local dd_bs=65536
7002         local dd_count=$((file_size / dd_bs))
7003
7004         # write data into the files
7005         local i
7006         local j
7007         local file
7008
7009         for i in $(seq $NUMFILES); do
7010                 file=$dir/file$i
7011                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7012                         error "write data into $file failed"
7013         done
7014         for i in $(seq $NUMDIRS); do
7015                 for j in $(seq $NUMFILES); do
7016                         file=$dir/dir$i/file$j
7017                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7018                                 error "write data into $file failed"
7019                 done
7020         done
7021
7022         # $LFS_MIGRATE will fail if hard link migration is unsupported
7023         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7024                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7025                         error "creating links to $dir/dir1/file1 failed"
7026         fi
7027
7028         local expected=-1
7029
7030         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7031
7032         # lfs_migrate file
7033         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7034
7035         echo "$cmd"
7036         eval $cmd || error "$cmd failed"
7037
7038         check_stripe_count $dir/file1 $expected
7039
7040         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7041         then
7042                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7043                 # OST 1 if it is on OST 0. This file is small enough to
7044                 # be on only one stripe.
7045                 file=$dir/migr_1_ost
7046                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7047                         error "write data into $file failed"
7048                 local obdidx=$($LFS getstripe -i $file)
7049                 local oldmd5=$(md5sum $file)
7050                 local newobdidx=0
7051
7052                 [[ $obdidx -eq 0 ]] && newobdidx=1
7053                 cmd="$LFS migrate -i $newobdidx $file"
7054                 echo $cmd
7055                 eval $cmd || error "$cmd failed"
7056
7057                 local realobdix=$($LFS getstripe -i $file)
7058                 local newmd5=$(md5sum $file)
7059
7060                 [[ $newobdidx -ne $realobdix ]] &&
7061                         error "new OST is different (was=$obdidx, "\
7062                               "wanted=$newobdidx, got=$realobdix)"
7063                 [[ "$oldmd5" != "$newmd5" ]] &&
7064                         error "md5sum differ: $oldmd5, $newmd5"
7065         fi
7066
7067         # lfs_migrate dir
7068         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7069         echo "$cmd"
7070         eval $cmd || error "$cmd failed"
7071
7072         for j in $(seq $NUMFILES); do
7073                 check_stripe_count $dir/dir1/file$j $expected
7074         done
7075
7076         # lfs_migrate works with lfs find
7077         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7078              $LFS_MIGRATE -y -c $expected"
7079         echo "$cmd"
7080         eval $cmd || error "$cmd failed"
7081
7082         for i in $(seq 2 $NUMFILES); do
7083                 check_stripe_count $dir/file$i $expected
7084         done
7085         for i in $(seq 2 $NUMDIRS); do
7086                 for j in $(seq $NUMFILES); do
7087                 check_stripe_count $dir/dir$i/file$j $expected
7088                 done
7089         done
7090 }
7091 run_test 56w "check lfs_migrate -c stripe_count works"
7092
7093 test_56wb() {
7094         local file1=$DIR/$tdir/file1
7095         local create_pool=false
7096         local initial_pool=$($LFS getstripe -p $DIR)
7097         local pool_list=()
7098         local pool=""
7099
7100         echo -n "Creating test dir..."
7101         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7102         echo "done."
7103
7104         echo -n "Creating test file..."
7105         touch $file1 || error "cannot create file"
7106         echo "done."
7107
7108         echo -n "Detecting existing pools..."
7109         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7110
7111         if [ ${#pool_list[@]} -gt 0 ]; then
7112                 echo "${pool_list[@]}"
7113                 for thispool in "${pool_list[@]}"; do
7114                         if [[ -z "$initial_pool" ||
7115                               "$initial_pool" != "$thispool" ]]; then
7116                                 pool="$thispool"
7117                                 echo "Using existing pool '$pool'"
7118                                 break
7119                         fi
7120                 done
7121         else
7122                 echo "none detected."
7123         fi
7124         if [ -z "$pool" ]; then
7125                 pool=${POOL:-testpool}
7126                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7127                 echo -n "Creating pool '$pool'..."
7128                 create_pool=true
7129                 pool_add $pool &> /dev/null ||
7130                         error "pool_add failed"
7131                 echo "done."
7132
7133                 echo -n "Adding target to pool..."
7134                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7135                         error "pool_add_targets failed"
7136                 echo "done."
7137         fi
7138
7139         echo -n "Setting pool using -p option..."
7140         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7141                 error "migrate failed rc = $?"
7142         echo "done."
7143
7144         echo -n "Verifying test file is in pool after migrating..."
7145         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7146                 error "file was not migrated to pool $pool"
7147         echo "done."
7148
7149         echo -n "Removing test file from pool '$pool'..."
7150         # "lfs migrate $file" won't remove the file from the pool
7151         # until some striping information is changed.
7152         $LFS migrate -c 1 $file1 &> /dev/null ||
7153                 error "cannot remove from pool"
7154         [ "$($LFS getstripe -p $file1)" ] &&
7155                 error "pool still set"
7156         echo "done."
7157
7158         echo -n "Setting pool using --pool option..."
7159         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7160                 error "migrate failed rc = $?"
7161         echo "done."
7162
7163         # Clean up
7164         rm -f $file1
7165         if $create_pool; then
7166                 destroy_test_pools 2> /dev/null ||
7167                         error "destroy test pools failed"
7168         fi
7169 }
7170 run_test 56wb "check lfs_migrate pool support"
7171
7172 test_56wc() {
7173         local file1="$DIR/$tdir/file1"
7174         local parent_ssize
7175         local parent_scount
7176         local cur_ssize
7177         local cur_scount
7178         local orig_ssize
7179
7180         echo -n "Creating test dir..."
7181         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7182         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7183                 error "cannot set stripe by '-S 1M -c 1'"
7184         echo "done"
7185
7186         echo -n "Setting initial stripe for test file..."
7187         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7188                 error "cannot set stripe"
7189         cur_ssize=$($LFS getstripe -S "$file1")
7190         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7191         echo "done."
7192
7193         # File currently set to -S 512K -c 1
7194
7195         # Ensure -c and -S options are rejected when -R is set
7196         echo -n "Verifying incompatible options are detected..."
7197         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7198                 error "incompatible -c and -R options not detected"
7199         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7200                 error "incompatible -S and -R options not detected"
7201         echo "done."
7202
7203         # Ensure unrecognized options are passed through to 'lfs migrate'
7204         echo -n "Verifying -S option is passed through to lfs migrate..."
7205         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7206                 error "migration failed"
7207         cur_ssize=$($LFS getstripe -S "$file1")
7208         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7209         echo "done."
7210
7211         # File currently set to -S 1M -c 1
7212
7213         # Ensure long options are supported
7214         echo -n "Verifying long options supported..."
7215         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7216                 error "long option without argument not supported"
7217         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7218                 error "long option with argument not supported"
7219         cur_ssize=$($LFS getstripe -S "$file1")
7220         [ $cur_ssize -eq 524288 ] ||
7221                 error "migrate --stripe-size $cur_ssize != 524288"
7222         echo "done."
7223
7224         # File currently set to -S 512K -c 1
7225
7226         if [ "$OSTCOUNT" -gt 1 ]; then
7227                 echo -n "Verifying explicit stripe count can be set..."
7228                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7229                         error "migrate failed"
7230                 cur_scount=$($LFS getstripe -c "$file1")
7231                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7232                 echo "done."
7233         fi
7234
7235         # File currently set to -S 512K -c 1 or -S 512K -c 2
7236
7237         # Ensure parent striping is used if -R is set, and no stripe
7238         # count or size is specified
7239         echo -n "Setting stripe for parent directory..."
7240         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7241                 error "cannot set stripe '-S 2M -c 1'"
7242         echo "done."
7243
7244         echo -n "Verifying restripe option uses parent stripe settings..."
7245         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7246         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7247         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7248                 error "migrate failed"
7249         cur_ssize=$($LFS getstripe -S "$file1")
7250         [ $cur_ssize -eq $parent_ssize ] ||
7251                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7252         cur_scount=$($LFS getstripe -c "$file1")
7253         [ $cur_scount -eq $parent_scount ] ||
7254                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7255         echo "done."
7256
7257         # File currently set to -S 1M -c 1
7258
7259         # Ensure striping is preserved if -R is not set, and no stripe
7260         # count or size is specified
7261         echo -n "Verifying striping size preserved when not specified..."
7262         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7263         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7264                 error "cannot set stripe on parent directory"
7265         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7266                 error "migrate failed"
7267         cur_ssize=$($LFS getstripe -S "$file1")
7268         [ $cur_ssize -eq $orig_ssize ] ||
7269                 error "migrate by default $cur_ssize != $orig_ssize"
7270         echo "done."
7271
7272         # Ensure file name properly detected when final option has no argument
7273         echo -n "Verifying file name properly detected..."
7274         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7275                 error "file name interpreted as option argument"
7276         echo "done."
7277
7278         # Clean up
7279         rm -f "$file1"
7280 }
7281 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7282
7283 test_56wd() {
7284         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7285
7286         local file1=$DIR/$tdir/file1
7287
7288         echo -n "Creating test dir..."
7289         test_mkdir $DIR/$tdir || error "cannot create dir"
7290         echo "done."
7291
7292         echo -n "Creating test file..."
7293         touch $file1
7294         echo "done."
7295
7296         # Ensure 'lfs migrate' will fail by using a non-existent option,
7297         # and make sure rsync is not called to recover
7298         echo -n "Make sure --no-rsync option works..."
7299         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7300                 grep -q 'refusing to fall back to rsync' ||
7301                 error "rsync was called with --no-rsync set"
7302         echo "done."
7303
7304         # Ensure rsync is called without trying 'lfs migrate' first
7305         echo -n "Make sure --rsync option works..."
7306         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7307                 grep -q 'falling back to rsync' &&
7308                 error "lfs migrate was called with --rsync set"
7309         echo "done."
7310
7311         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7312         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7313                 grep -q 'at the same time' ||
7314                 error "--rsync and --no-rsync accepted concurrently"
7315         echo "done."
7316
7317         # Clean up
7318         rm -f $file1
7319 }
7320 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7321
7322 test_56we() {
7323         local td=$DIR/$tdir
7324         local tf=$td/$tfile
7325
7326         test_mkdir $td || error "cannot create $td"
7327         touch $tf || error "cannot touch $tf"
7328
7329         echo -n "Make sure --non-direct|-D works..."
7330         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7331                 grep -q "lfs migrate --non-direct" ||
7332                 error "--non-direct option cannot work correctly"
7333         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7334                 grep -q "lfs migrate -D" ||
7335                 error "-D option cannot work correctly"
7336         echo "done."
7337 }
7338 run_test 56we "check lfs_migrate --non-direct|-D support"
7339
7340 test_56x() {
7341         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7342         check_swap_layouts_support
7343
7344         local dir=$DIR/$tdir
7345         local ref1=/etc/passwd
7346         local file1=$dir/file1
7347
7348         test_mkdir $dir || error "creating dir $dir"
7349         $LFS setstripe -c 2 $file1
7350         cp $ref1 $file1
7351         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7352         stripe=$($LFS getstripe -c $file1)
7353         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7354         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7355
7356         # clean up
7357         rm -f $file1
7358 }
7359 run_test 56x "lfs migration support"
7360
7361 test_56xa() {
7362         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7363         check_swap_layouts_support
7364
7365         local dir=$DIR/$tdir/$testnum
7366
7367         test_mkdir -p $dir
7368
7369         local ref1=/etc/passwd
7370         local file1=$dir/file1
7371
7372         $LFS setstripe -c 2 $file1
7373         cp $ref1 $file1
7374         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7375
7376         local stripe=$($LFS getstripe -c $file1)
7377
7378         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7379         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7380
7381         # clean up
7382         rm -f $file1
7383 }
7384 run_test 56xa "lfs migration --block support"
7385
7386 check_migrate_links() {
7387         local dir="$1"
7388         local file1="$dir/file1"
7389         local begin="$2"
7390         local count="$3"
7391         local runas="$4"
7392         local total_count=$(($begin + $count - 1))
7393         local symlink_count=10
7394         local uniq_count=10
7395
7396         if [ ! -f "$file1" ]; then
7397                 echo -n "creating initial file..."
7398                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7399                         error "cannot setstripe initial file"
7400                 echo "done"
7401
7402                 echo -n "creating symlinks..."
7403                 for s in $(seq 1 $symlink_count); do
7404                         ln -s "$file1" "$dir/slink$s" ||
7405                                 error "cannot create symlinks"
7406                 done
7407                 echo "done"
7408
7409                 echo -n "creating nonlinked files..."
7410                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7411                         error "cannot create nonlinked files"
7412                 echo "done"
7413         fi
7414
7415         # create hard links
7416         if [ ! -f "$dir/file$total_count" ]; then
7417                 echo -n "creating hard links $begin:$total_count..."
7418                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7419                         /dev/null || error "cannot create hard links"
7420                 echo "done"
7421         fi
7422
7423         echo -n "checking number of hard links listed in xattrs..."
7424         local fid=$($LFS getstripe -F "$file1")
7425         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7426
7427         echo "${#paths[*]}"
7428         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7429                         skip "hard link list has unexpected size, skipping test"
7430         fi
7431         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7432                         error "link names should exceed xattrs size"
7433         fi
7434
7435         echo -n "migrating files..."
7436         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7437         local rc=$?
7438         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7439         echo "done"
7440
7441         # make sure all links have been properly migrated
7442         echo -n "verifying files..."
7443         fid=$($LFS getstripe -F "$file1") ||
7444                 error "cannot get fid for file $file1"
7445         for i in $(seq 2 $total_count); do
7446                 local fid2=$($LFS getstripe -F $dir/file$i)
7447
7448                 [ "$fid2" == "$fid" ] ||
7449                         error "migrated hard link has mismatched FID"
7450         done
7451
7452         # make sure hard links were properly detected, and migration was
7453         # performed only once for the entire link set; nonlinked files should
7454         # also be migrated
7455         local actual=$(grep -c 'done' <<< "$migrate_out")
7456         local expected=$(($uniq_count + 1))
7457
7458         [ "$actual" -eq  "$expected" ] ||
7459                 error "hard links individually migrated ($actual != $expected)"
7460
7461         # make sure the correct number of hard links are present
7462         local hardlinks=$(stat -c '%h' "$file1")
7463
7464         [ $hardlinks -eq $total_count ] ||
7465                 error "num hard links $hardlinks != $total_count"
7466         echo "done"
7467
7468         return 0
7469 }
7470
7471 test_56xb() {
7472         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7473                 skip "Need MDS version at least 2.10.55"
7474
7475         local dir="$DIR/$tdir"
7476
7477         test_mkdir "$dir" || error "cannot create dir $dir"
7478
7479         echo "testing lfs migrate mode when all links fit within xattrs"
7480         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7481
7482         echo "testing rsync mode when all links fit within xattrs"
7483         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7484
7485         echo "testing lfs migrate mode when all links do not fit within xattrs"
7486         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7487
7488         echo "testing rsync mode when all links do not fit within xattrs"
7489         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7490
7491         chown -R $RUNAS_ID $dir
7492         echo "testing non-root lfs migrate mode when not all links are in xattr"
7493         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7494
7495         # clean up
7496         rm -rf $dir
7497 }
7498 run_test 56xb "lfs migration hard link support"
7499
7500 test_56xc() {
7501         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7502
7503         local dir="$DIR/$tdir"
7504
7505         test_mkdir "$dir" || error "cannot create dir $dir"
7506
7507         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7508         echo -n "Setting initial stripe for 20MB test file..."
7509         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7510                 error "cannot setstripe 20MB file"
7511         echo "done"
7512         echo -n "Sizing 20MB test file..."
7513         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7514         echo "done"
7515         echo -n "Verifying small file autostripe count is 1..."
7516         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7517                 error "cannot migrate 20MB file"
7518         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7519                 error "cannot get stripe for $dir/20mb"
7520         [ $stripe_count -eq 1 ] ||
7521                 error "unexpected stripe count $stripe_count for 20MB file"
7522         rm -f "$dir/20mb"
7523         echo "done"
7524
7525         # Test 2: File is small enough to fit within the available space on
7526         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7527         # have at least an additional 1KB for each desired stripe for test 3
7528         echo -n "Setting stripe for 1GB test file..."
7529         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7530         echo "done"
7531         echo -n "Sizing 1GB test file..."
7532         # File size is 1GB + 3KB
7533         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7534         echo "done"
7535
7536         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7537         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7538         if (( avail > 524288 * OSTCOUNT )); then
7539                 echo -n "Migrating 1GB file..."
7540                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7541                         error "cannot migrate 1GB file"
7542                 echo "done"
7543                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7544                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7545                         error "cannot getstripe for 1GB file"
7546                 [ $stripe_count -eq 2 ] ||
7547                         error "unexpected stripe count $stripe_count != 2"
7548                 echo "done"
7549         fi
7550
7551         # Test 3: File is too large to fit within the available space on
7552         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7553         if [ $OSTCOUNT -ge 3 ]; then
7554                 # The required available space is calculated as
7555                 # file size (1GB + 3KB) / OST count (3).
7556                 local kb_per_ost=349526
7557
7558                 echo -n "Migrating 1GB file with limit..."
7559                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7560                         error "cannot migrate 1GB file with limit"
7561                 echo "done"
7562
7563                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7564                 echo -n "Verifying 1GB autostripe count with limited space..."
7565                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7566                         error "unexpected stripe count $stripe_count (min 3)"
7567                 echo "done"
7568         fi
7569
7570         # clean up
7571         rm -rf $dir
7572 }
7573 run_test 56xc "lfs migration autostripe"
7574
7575 test_56xd() {
7576         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7577
7578         local dir=$DIR/$tdir
7579         local f_mgrt=$dir/$tfile.mgrt
7580         local f_yaml=$dir/$tfile.yaml
7581         local f_copy=$dir/$tfile.copy
7582         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7583         local layout_copy="-c 2 -S 2M -i 1"
7584         local yamlfile=$dir/yamlfile
7585         local layout_before;
7586         local layout_after;
7587
7588         test_mkdir "$dir" || error "cannot create dir $dir"
7589         $LFS setstripe $layout_yaml $f_yaml ||
7590                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7591         $LFS getstripe --yaml $f_yaml > $yamlfile
7592         $LFS setstripe $layout_copy $f_copy ||
7593                 error "cannot setstripe $f_copy with layout $layout_copy"
7594         touch $f_mgrt
7595         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7596
7597         # 1. test option --yaml
7598         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7599                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7600         layout_before=$(get_layout_param $f_yaml)
7601         layout_after=$(get_layout_param $f_mgrt)
7602         [ "$layout_after" == "$layout_before" ] ||
7603                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7604
7605         # 2. test option --copy
7606         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7607                 error "cannot migrate $f_mgrt with --copy $f_copy"
7608         layout_before=$(get_layout_param $f_copy)
7609         layout_after=$(get_layout_param $f_mgrt)
7610         [ "$layout_after" == "$layout_before" ] ||
7611                 error "lfs_migrate --copy: $layout_after != $layout_before"
7612 }
7613 run_test 56xd "check lfs_migrate --yaml and --copy support"
7614
7615 test_56xe() {
7616         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7617
7618         local dir=$DIR/$tdir
7619         local f_comp=$dir/$tfile
7620         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7621         local layout_before=""
7622         local layout_after=""
7623
7624         test_mkdir "$dir" || error "cannot create dir $dir"
7625         $LFS setstripe $layout $f_comp ||
7626                 error "cannot setstripe $f_comp with layout $layout"
7627         layout_before=$(get_layout_param $f_comp)
7628         dd if=/dev/zero of=$f_comp bs=1M count=4
7629
7630         # 1. migrate a comp layout file by lfs_migrate
7631         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7632         layout_after=$(get_layout_param $f_comp)
7633         [ "$layout_before" == "$layout_after" ] ||
7634                 error "lfs_migrate: $layout_before != $layout_after"
7635
7636         # 2. migrate a comp layout file by lfs migrate
7637         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7638         layout_after=$(get_layout_param $f_comp)
7639         [ "$layout_before" == "$layout_after" ] ||
7640                 error "lfs migrate: $layout_before != $layout_after"
7641 }
7642 run_test 56xe "migrate a composite layout file"
7643
7644 test_56xf() {
7645         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7646
7647         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7648                 skip "Need server version at least 2.13.53"
7649
7650         local dir=$DIR/$tdir
7651         local f_comp=$dir/$tfile
7652         local layout="-E 1M -c1 -E -1 -c2"
7653         local fid_before=""
7654         local fid_after=""
7655
7656         test_mkdir "$dir" || error "cannot create dir $dir"
7657         $LFS setstripe $layout $f_comp ||
7658                 error "cannot setstripe $f_comp with layout $layout"
7659         fid_before=$($LFS getstripe --fid $f_comp)
7660         dd if=/dev/zero of=$f_comp bs=1M count=4
7661
7662         # 1. migrate a comp layout file to a comp layout
7663         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7664         fid_after=$($LFS getstripe --fid $f_comp)
7665         [ "$fid_before" == "$fid_after" ] ||
7666                 error "comp-to-comp migrate: $fid_before != $fid_after"
7667
7668         # 2. migrate a comp layout file to a plain layout
7669         $LFS migrate -c2 $f_comp ||
7670                 error "cannot migrate $f_comp by lfs migrate"
7671         fid_after=$($LFS getstripe --fid $f_comp)
7672         [ "$fid_before" == "$fid_after" ] ||
7673                 error "comp-to-plain migrate: $fid_before != $fid_after"
7674
7675         # 3. migrate a plain layout file to a comp layout
7676         $LFS migrate $layout $f_comp ||
7677                 error "cannot migrate $f_comp by lfs migrate"
7678         fid_after=$($LFS getstripe --fid $f_comp)
7679         [ "$fid_before" == "$fid_after" ] ||
7680                 error "plain-to-comp migrate: $fid_before != $fid_after"
7681 }
7682 run_test 56xf "FID is not lost during migration of a composite layout file"
7683
7684 check_file_ost_range() {
7685         local file="$1"
7686         shift
7687         local range="$*"
7688         local -a file_range
7689         local idx
7690
7691         file_range=($($LFS getstripe -y "$file" |
7692                 awk '/l_ost_idx:/ { print $NF }'))
7693
7694         if [[ "${#file_range[@]}" = 0 ]]; then
7695                 echo "No osts found for $file"
7696                 return 1
7697         fi
7698
7699         for idx in "${file_range[@]}"; do
7700                 [[ " $range " =~ " $idx " ]] ||
7701                         return 1
7702         done
7703
7704         return 0
7705 }
7706
7707 sub_test_56xg() {
7708         local stripe_opt="$1"
7709         local pool="$2"
7710         shift 2
7711         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7712
7713         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7714                 error "Fail to migrate $tfile on $pool"
7715         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7716                 error "$tfile is not in pool $pool"
7717         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7718                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7719 }
7720
7721 test_56xg() {
7722         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7723         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7724         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7725                 skip "Need MDS version newer than 2.14.52"
7726
7727         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7728         local -a pool_ranges=("0 0" "1 1" "0 1")
7729
7730         # init pools
7731         for i in "${!pool_names[@]}"; do
7732                 pool_add ${pool_names[$i]} ||
7733                         error "pool_add failed (pool: ${pool_names[$i]})"
7734                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7735                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7736         done
7737
7738         # init the file to migrate
7739         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7740                 error "Unable to create $tfile on OST1"
7741         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7742                 error "Unable to write on $tfile"
7743
7744         echo "1. migrate $tfile on pool ${pool_names[0]}"
7745         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7746
7747         echo "2. migrate $tfile on pool ${pool_names[2]}"
7748         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7749
7750         echo "3. migrate $tfile on pool ${pool_names[1]}"
7751         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7752
7753         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7754         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7755         echo
7756
7757         # Clean pools
7758         destroy_test_pools ||
7759                 error "pool_destroy failed"
7760 }
7761 run_test 56xg "lfs migrate pool support"
7762
7763 test_56y() {
7764         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7765                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7766
7767         local res=""
7768         local dir=$DIR/$tdir
7769         local f1=$dir/file1
7770         local f2=$dir/file2
7771
7772         test_mkdir -p $dir || error "creating dir $dir"
7773         touch $f1 || error "creating std file $f1"
7774         $MULTIOP $f2 H2c || error "creating released file $f2"
7775
7776         # a directory can be raid0, so ask only for files
7777         res=$($LFS find $dir -L raid0 -type f | wc -l)
7778         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7779
7780         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7781         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7782
7783         # only files can be released, so no need to force file search
7784         res=$($LFS find $dir -L released)
7785         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7786
7787         res=$($LFS find $dir -type f \! -L released)
7788         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7789 }
7790 run_test 56y "lfs find -L raid0|released"
7791
7792 test_56z() { # LU-4824
7793         # This checks to make sure 'lfs find' continues after errors
7794         # There are two classes of errors that should be caught:
7795         # - If multiple paths are provided, all should be searched even if one
7796         #   errors out
7797         # - If errors are encountered during the search, it should not terminate
7798         #   early
7799         local dir=$DIR/$tdir
7800         local i
7801
7802         test_mkdir $dir
7803         for i in d{0..9}; do
7804                 test_mkdir $dir/$i
7805                 touch $dir/$i/$tfile
7806         done
7807         $LFS find $DIR/non_existent_dir $dir &&
7808                 error "$LFS find did not return an error"
7809         # Make a directory unsearchable. This should NOT be the last entry in
7810         # directory order.  Arbitrarily pick the 6th entry
7811         chmod 700 $($LFS find $dir -type d | sed '6!d')
7812
7813         $RUNAS $LFS find $DIR/non_existent $dir
7814         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7815
7816         # The user should be able to see 10 directories and 9 files
7817         (( count == 19 )) ||
7818                 error "$LFS find found $count != 19 entries after error"
7819 }
7820 run_test 56z "lfs find should continue after an error"
7821
7822 test_56aa() { # LU-5937
7823         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7824
7825         local dir=$DIR/$tdir
7826
7827         mkdir $dir
7828         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7829
7830         createmany -o $dir/striped_dir/${tfile}- 1024
7831         local dirs=$($LFS find --size +8k $dir/)
7832
7833         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7834 }
7835 run_test 56aa "lfs find --size under striped dir"
7836
7837 test_56ab() { # LU-10705
7838         test_mkdir $DIR/$tdir
7839         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7840         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7841         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7842         # Flush writes to ensure valid blocks.  Need to be more thorough for
7843         # ZFS, since blocks are not allocated/returned to client immediately.
7844         sync_all_data
7845         wait_zfs_commit ost1 2
7846         cancel_lru_locks osc
7847         ls -ls $DIR/$tdir
7848
7849         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7850
7851         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7852
7853         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7854         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7855
7856         rm -f $DIR/$tdir/$tfile.[123]
7857 }
7858 run_test 56ab "lfs find --blocks"
7859
7860 # LU-11188
7861 test_56aca() {
7862         local dir="$DIR/$tdir"
7863         local perms=(001 002 003 004 005 006 007
7864                      010 020 030 040 050 060 070
7865                      100 200 300 400 500 600 700
7866                      111 222 333 444 555 666 777)
7867         local perm_minus=(8 8 4 8 4 4 2
7868                           8 8 4 8 4 4 2
7869                           8 8 4 8 4 4 2
7870                           4 4 2 4 2 2 1)
7871         local perm_slash=(8  8 12  8 12 12 14
7872                           8  8 12  8 12 12 14
7873                           8  8 12  8 12 12 14
7874                          16 16 24 16 24 24 28)
7875
7876         test_mkdir "$dir"
7877         for perm in ${perms[*]}; do
7878                 touch "$dir/$tfile.$perm"
7879                 chmod $perm "$dir/$tfile.$perm"
7880         done
7881
7882         for ((i = 0; i < ${#perms[*]}; i++)); do
7883                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7884                 (( $num == 1 )) ||
7885                         error "lfs find -perm ${perms[i]}:"\
7886                               "$num != 1"
7887
7888                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7889                 (( $num == ${perm_minus[i]} )) ||
7890                         error "lfs find -perm -${perms[i]}:"\
7891                               "$num != ${perm_minus[i]}"
7892
7893                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7894                 (( $num == ${perm_slash[i]} )) ||
7895                         error "lfs find -perm /${perms[i]}:"\
7896                               "$num != ${perm_slash[i]}"
7897         done
7898 }
7899 run_test 56aca "check lfs find -perm with octal representation"
7900
7901 test_56acb() {
7902         local dir=$DIR/$tdir
7903         # p is the permission of write and execute for user, group and other
7904         # without the umask. It is used to test +wx.
7905         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7906         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7907         local symbolic=(+t  a+t u+t g+t o+t
7908                         g+s u+s o+s +s o+sr
7909                         o=r,ug+o,u+w
7910                         u+ g+ o+ a+ ugo+
7911                         u- g- o- a- ugo-
7912                         u= g= o= a= ugo=
7913                         o=r,ug+o,u+w u=r,a+u,u+w
7914                         g=r,ugo=g,u+w u+x,+X +X
7915                         u+x,u+X u+X u+x,g+X o+r,+X
7916                         u+x,go+X +wx +rwx)
7917
7918         test_mkdir $dir
7919         for perm in ${perms[*]}; do
7920                 touch "$dir/$tfile.$perm"
7921                 chmod $perm "$dir/$tfile.$perm"
7922         done
7923
7924         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7925                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7926
7927                 (( $num == 1 )) ||
7928                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7929         done
7930 }
7931 run_test 56acb "check lfs find -perm with symbolic representation"
7932
7933 test_56acc() {
7934         local dir=$DIR/$tdir
7935         local tests="17777 787 789 abcd
7936                 ug=uu ug=a ug=gu uo=ou urw
7937                 u+xg+x a=r,u+x,"
7938
7939         test_mkdir $dir
7940         for err in $tests; do
7941                 if $LFS find $dir -perm $err 2>/dev/null; then
7942                         error "lfs find -perm $err: parsing should have failed"
7943                 fi
7944         done
7945 }
7946 run_test 56acc "check parsing error for lfs find -perm"
7947
7948 test_56ba() {
7949         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7950                 skip "Need MDS version at least 2.10.50"
7951
7952         # Create composite files with one component
7953         local dir=$DIR/$tdir
7954
7955         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7956         # Create composite files with three components
7957         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7958         # Create non-composite files
7959         createmany -o $dir/${tfile}- 10
7960
7961         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7962
7963         [[ $nfiles == 10 ]] ||
7964                 error "lfs find -E 1M found $nfiles != 10 files"
7965
7966         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7967         [[ $nfiles == 25 ]] ||
7968                 error "lfs find ! -E 1M found $nfiles != 25 files"
7969
7970         # All files have a component that starts at 0
7971         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7972         [[ $nfiles == 35 ]] ||
7973                 error "lfs find --component-start 0 - $nfiles != 35 files"
7974
7975         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7976         [[ $nfiles == 15 ]] ||
7977                 error "lfs find --component-start 2M - $nfiles != 15 files"
7978
7979         # All files created here have a componenet that does not starts at 2M
7980         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7981         [[ $nfiles == 35 ]] ||
7982                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7983
7984         # Find files with a specified number of components
7985         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7986         [[ $nfiles == 15 ]] ||
7987                 error "lfs find --component-count 3 - $nfiles != 15 files"
7988
7989         # Remember non-composite files have a component count of zero
7990         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7991         [[ $nfiles == 10 ]] ||
7992                 error "lfs find --component-count 0 - $nfiles != 10 files"
7993
7994         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7995         [[ $nfiles == 20 ]] ||
7996                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7997
7998         # All files have a flag called "init"
7999         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8000         [[ $nfiles == 35 ]] ||
8001                 error "lfs find --component-flags init - $nfiles != 35 files"
8002
8003         # Multi-component files will have a component not initialized
8004         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8005         [[ $nfiles == 15 ]] ||
8006                 error "lfs find !--component-flags init - $nfiles != 15 files"
8007
8008         rm -rf $dir
8009
8010 }
8011 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8012
8013 test_56ca() {
8014         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8015                 skip "Need MDS version at least 2.10.57"
8016
8017         local td=$DIR/$tdir
8018         local tf=$td/$tfile
8019         local dir
8020         local nfiles
8021         local cmd
8022         local i
8023         local j
8024
8025         # create mirrored directories and mirrored files
8026         mkdir $td || error "mkdir $td failed"
8027         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8028         createmany -o $tf- 10 || error "create $tf- failed"
8029
8030         for i in $(seq 2); do
8031                 dir=$td/dir$i
8032                 mkdir $dir || error "mkdir $dir failed"
8033                 $LFS mirror create -N$((3 + i)) $dir ||
8034                         error "create mirrored dir $dir failed"
8035                 createmany -o $dir/$tfile- 10 ||
8036                         error "create $dir/$tfile- failed"
8037         done
8038
8039         # change the states of some mirrored files
8040         echo foo > $tf-6
8041         for i in $(seq 2); do
8042                 dir=$td/dir$i
8043                 for j in $(seq 4 9); do
8044                         echo foo > $dir/$tfile-$j
8045                 done
8046         done
8047
8048         # find mirrored files with specific mirror count
8049         cmd="$LFS find --mirror-count 3 --type f $td"
8050         nfiles=$($cmd | wc -l)
8051         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8052
8053         cmd="$LFS find ! --mirror-count 3 --type f $td"
8054         nfiles=$($cmd | wc -l)
8055         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8056
8057         cmd="$LFS find --mirror-count +2 --type f $td"
8058         nfiles=$($cmd | wc -l)
8059         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8060
8061         cmd="$LFS find --mirror-count -6 --type f $td"
8062         nfiles=$($cmd | wc -l)
8063         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8064
8065         # find mirrored files with specific file state
8066         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8067         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8068
8069         cmd="$LFS find --mirror-state=ro --type f $td"
8070         nfiles=$($cmd | wc -l)
8071         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8072
8073         cmd="$LFS find ! --mirror-state=ro --type f $td"
8074         nfiles=$($cmd | wc -l)
8075         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8076
8077         cmd="$LFS find --mirror-state=wp --type f $td"
8078         nfiles=$($cmd | wc -l)
8079         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8080
8081         cmd="$LFS find ! --mirror-state=sp --type f $td"
8082         nfiles=$($cmd | wc -l)
8083         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8084 }
8085 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8086
8087 test_56da() { # LU-14179
8088         local path=$DIR/$tdir
8089
8090         test_mkdir $path
8091         cd $path
8092
8093         local longdir=$(str_repeat 'a' 255)
8094
8095         for i in {1..15}; do
8096                 path=$path/$longdir
8097                 test_mkdir $longdir
8098                 cd $longdir
8099         done
8100
8101         local len=${#path}
8102         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8103
8104         test_mkdir $lastdir
8105         cd $lastdir
8106         # PATH_MAX-1
8107         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8108
8109         # NAME_MAX
8110         touch $(str_repeat 'f' 255)
8111
8112         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8113                 error "lfs find reported an error"
8114
8115         rm -rf $DIR/$tdir
8116 }
8117 run_test 56da "test lfs find with long paths"
8118
8119 test_57a() {
8120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8121         # note test will not do anything if MDS is not local
8122         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8123                 skip_env "ldiskfs only test"
8124         fi
8125         remote_mds_nodsh && skip "remote MDS with nodsh"
8126
8127         local MNTDEV="osd*.*MDT*.mntdev"
8128         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8129         [ -z "$DEV" ] && error "can't access $MNTDEV"
8130         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8131                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8132                         error "can't access $DEV"
8133                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8134                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8135                 rm $TMP/t57a.dump
8136         done
8137 }
8138 run_test 57a "verify MDS filesystem created with large inodes =="
8139
8140 test_57b() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8143                 skip_env "ldiskfs only test"
8144         fi
8145         remote_mds_nodsh && skip "remote MDS with nodsh"
8146
8147         local dir=$DIR/$tdir
8148         local filecount=100
8149         local file1=$dir/f1
8150         local fileN=$dir/f$filecount
8151
8152         rm -rf $dir || error "removing $dir"
8153         test_mkdir -c1 $dir
8154         local mdtidx=$($LFS getstripe -m $dir)
8155         local mdtname=MDT$(printf %04x $mdtidx)
8156         local facet=mds$((mdtidx + 1))
8157
8158         echo "mcreating $filecount files"
8159         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8160
8161         # verify that files do not have EAs yet
8162         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8163                 error "$file1 has an EA"
8164         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8165                 error "$fileN has an EA"
8166
8167         sync
8168         sleep 1
8169         df $dir  #make sure we get new statfs data
8170         local mdsfree=$(do_facet $facet \
8171                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8172         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8173         local file
8174
8175         echo "opening files to create objects/EAs"
8176         for file in $(seq -f $dir/f%g 1 $filecount); do
8177                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8178                         error "opening $file"
8179         done
8180
8181         # verify that files have EAs now
8182         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8183         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8184
8185         sleep 1  #make sure we get new statfs data
8186         df $dir
8187         local mdsfree2=$(do_facet $facet \
8188                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8189         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8190
8191         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8192                 if [ "$mdsfree" != "$mdsfree2" ]; then
8193                         error "MDC before $mdcfree != after $mdcfree2"
8194                 else
8195                         echo "MDC before $mdcfree != after $mdcfree2"
8196                         echo "unable to confirm if MDS has large inodes"
8197                 fi
8198         fi
8199         rm -rf $dir
8200 }
8201 run_test 57b "default LOV EAs are stored inside large inodes ==="
8202
8203 test_58() {
8204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8205         [ -z "$(which wiretest 2>/dev/null)" ] &&
8206                         skip_env "could not find wiretest"
8207
8208         wiretest
8209 }
8210 run_test 58 "verify cross-platform wire constants =============="
8211
8212 test_59() {
8213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8214
8215         echo "touch 130 files"
8216         createmany -o $DIR/f59- 130
8217         echo "rm 130 files"
8218         unlinkmany $DIR/f59- 130
8219         sync
8220         # wait for commitment of removal
8221         wait_delete_completed
8222 }
8223 run_test 59 "verify cancellation of llog records async ========="
8224
8225 TEST60_HEAD="test_60 run $RANDOM"
8226 test_60a() {
8227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8228         remote_mgs_nodsh && skip "remote MGS with nodsh"
8229         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8230                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8231                         skip_env "missing subtest run-llog.sh"
8232
8233         log "$TEST60_HEAD - from kernel mode"
8234         do_facet mgs "$LCTL dk > /dev/null"
8235         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8236         do_facet mgs $LCTL dk > $TMP/$tfile
8237
8238         # LU-6388: test llog_reader
8239         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8240         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8241         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8242                         skip_env "missing llog_reader"
8243         local fstype=$(facet_fstype mgs)
8244         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8245                 skip_env "Only for ldiskfs or zfs type mgs"
8246
8247         local mntpt=$(facet_mntpt mgs)
8248         local mgsdev=$(mgsdevname 1)
8249         local fid_list
8250         local fid
8251         local rec_list
8252         local rec
8253         local rec_type
8254         local obj_file
8255         local path
8256         local seq
8257         local oid
8258         local pass=true
8259
8260         #get fid and record list
8261         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8262                 tail -n 4))
8263         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8264                 tail -n 4))
8265         #remount mgs as ldiskfs or zfs type
8266         stop mgs || error "stop mgs failed"
8267         mount_fstype mgs || error "remount mgs failed"
8268         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8269                 fid=${fid_list[i]}
8270                 rec=${rec_list[i]}
8271                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8272                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8273                 oid=$((16#$oid))
8274
8275                 case $fstype in
8276                         ldiskfs )
8277                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8278                         zfs )
8279                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8280                 esac
8281                 echo "obj_file is $obj_file"
8282                 do_facet mgs $llog_reader $obj_file
8283
8284                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8285                         awk '{ print $3 }' | sed -e "s/^type=//g")
8286                 if [ $rec_type != $rec ]; then
8287                         echo "FAILED test_60a wrong record type $rec_type," \
8288                               "should be $rec"
8289                         pass=false
8290                         break
8291                 fi
8292
8293                 #check obj path if record type is LLOG_LOGID_MAGIC
8294                 if [ "$rec" == "1064553b" ]; then
8295                         path=$(do_facet mgs $llog_reader $obj_file |
8296                                 grep "path=" | awk '{ print $NF }' |
8297                                 sed -e "s/^path=//g")
8298                         if [ $obj_file != $mntpt/$path ]; then
8299                                 echo "FAILED test_60a wrong obj path" \
8300                                       "$montpt/$path, should be $obj_file"
8301                                 pass=false
8302                                 break
8303                         fi
8304                 fi
8305         done
8306         rm -f $TMP/$tfile
8307         #restart mgs before "error", otherwise it will block the next test
8308         stop mgs || error "stop mgs failed"
8309         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8310         $pass || error "test failed, see FAILED test_60a messages for specifics"
8311 }
8312 run_test 60a "llog_test run from kernel module and test llog_reader"
8313
8314 test_60b() { # bug 6411
8315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8316
8317         dmesg > $DIR/$tfile
8318         LLOG_COUNT=$(do_facet mgs dmesg |
8319                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8320                           /llog_[a-z]*.c:[0-9]/ {
8321                                 if (marker)
8322                                         from_marker++
8323                                 from_begin++
8324                           }
8325                           END {
8326                                 if (marker)
8327                                         print from_marker
8328                                 else
8329                                         print from_begin
8330                           }")
8331
8332         [[ $LLOG_COUNT -gt 120 ]] &&
8333                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8334 }
8335 run_test 60b "limit repeated messages from CERROR/CWARN"
8336
8337 test_60c() {
8338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8339
8340         echo "create 5000 files"
8341         createmany -o $DIR/f60c- 5000
8342 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8343         lctl set_param fail_loc=0x80000137
8344         unlinkmany $DIR/f60c- 5000
8345         lctl set_param fail_loc=0
8346 }
8347 run_test 60c "unlink file when mds full"
8348
8349 test_60d() {
8350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8351
8352         SAVEPRINTK=$(lctl get_param -n printk)
8353         # verify "lctl mark" is even working"
8354         MESSAGE="test message ID $RANDOM $$"
8355         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8356         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8357
8358         lctl set_param printk=0 || error "set lnet.printk failed"
8359         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8360         MESSAGE="new test message ID $RANDOM $$"
8361         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8362         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8363         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8364
8365         lctl set_param -n printk="$SAVEPRINTK"
8366 }
8367 run_test 60d "test printk console message masking"
8368
8369 test_60e() {
8370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8371         remote_mds_nodsh && skip "remote MDS with nodsh"
8372
8373         touch $DIR/$tfile
8374 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8375         do_facet mds1 lctl set_param fail_loc=0x15b
8376         rm $DIR/$tfile
8377 }
8378 run_test 60e "no space while new llog is being created"
8379
8380 test_60f() {
8381         local old_path=$($LCTL get_param -n debug_path)
8382
8383         stack_trap "$LCTL set_param debug_path=$old_path"
8384         stack_trap "rm -f $TMP/$tfile*"
8385         rm -f $TMP/$tfile* 2> /dev/null
8386         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8387         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8388         test_mkdir $DIR/$tdir
8389         # retry in case the open is cached and not released
8390         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8391                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8392                 sleep 0.1
8393         done
8394         ls $TMP/$tfile*
8395         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8396 }
8397 run_test 60f "change debug_path works"
8398
8399 test_60g() {
8400         local pid
8401         local i
8402
8403         test_mkdir -c $MDSCOUNT $DIR/$tdir
8404
8405         (
8406                 local index=0
8407                 while true; do
8408                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8409                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8410                                 2>/dev/null
8411                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8412                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8413                         index=$((index + 1))
8414                 done
8415         ) &
8416
8417         pid=$!
8418
8419         for i in {0..100}; do
8420                 # define OBD_FAIL_OSD_TXN_START    0x19a
8421                 local index=$((i % MDSCOUNT + 1))
8422
8423                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8424                         > /dev/null
8425                 sleep 0.01
8426         done
8427
8428         kill -9 $pid
8429
8430         for i in $(seq $MDSCOUNT); do
8431                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8432         done
8433
8434         mkdir $DIR/$tdir/new || error "mkdir failed"
8435         rmdir $DIR/$tdir/new || error "rmdir failed"
8436
8437         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8438                 -t namespace
8439         for i in $(seq $MDSCOUNT); do
8440                 wait_update_facet mds$i "$LCTL get_param -n \
8441                         mdd.$(facet_svc mds$i).lfsck_namespace |
8442                         awk '/^status/ { print \\\$2 }'" "completed"
8443         done
8444
8445         ls -R $DIR/$tdir || error "ls failed"
8446         rm -rf $DIR/$tdir || error "rmdir failed"
8447 }
8448 run_test 60g "transaction abort won't cause MDT hung"
8449
8450 test_60h() {
8451         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8452                 skip "Need MDS version at least 2.12.52"
8453         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8454
8455         local f
8456
8457         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8458         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8459         for fail_loc in 0x80000188 0x80000189; do
8460                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8461                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8462                         error "mkdir $dir-$fail_loc failed"
8463                 for i in {0..10}; do
8464                         # create may fail on missing stripe
8465                         echo $i > $DIR/$tdir-$fail_loc/$i
8466                 done
8467                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8468                         error "getdirstripe $tdir-$fail_loc failed"
8469                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8470                         error "migrate $tdir-$fail_loc failed"
8471                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8472                         error "getdirstripe $tdir-$fail_loc failed"
8473                 pushd $DIR/$tdir-$fail_loc
8474                 for f in *; do
8475                         echo $f | cmp $f - || error "$f data mismatch"
8476                 done
8477                 popd
8478                 rm -rf $DIR/$tdir-$fail_loc
8479         done
8480 }
8481 run_test 60h "striped directory with missing stripes can be accessed"
8482
8483 function t60i_load() {
8484         mkdir $DIR/$tdir
8485         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8486         $LCTL set_param fail_loc=0x131c fail_val=1
8487         for ((i=0; i<5000; i++)); do
8488                 touch $DIR/$tdir/f$i
8489         done
8490 }
8491
8492 test_60i() {
8493         changelog_register || error "changelog_register failed"
8494         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8495         changelog_users $SINGLEMDS | grep -q $cl_user ||
8496                 error "User $cl_user not found in changelog_users"
8497         changelog_chmask "ALL"
8498         t60i_load &
8499         local PID=$!
8500         for((i=0; i<100; i++)); do
8501                 changelog_dump >/dev/null ||
8502                         error "can't read changelog"
8503         done
8504         kill $PID
8505         wait $PID
8506         changelog_deregister || error "changelog_deregister failed"
8507         $LCTL set_param fail_loc=0
8508 }
8509 run_test 60i "llog: new record vs reader race"
8510
8511 test_61a() {
8512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8513
8514         f="$DIR/f61"
8515         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8516         cancel_lru_locks osc
8517         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8518         sync
8519 }
8520 run_test 61a "mmap() writes don't make sync hang ================"
8521
8522 test_61b() {
8523         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8524 }
8525 run_test 61b "mmap() of unstriped file is successful"
8526
8527 # bug 2330 - insufficient obd_match error checking causes LBUG
8528 test_62() {
8529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8530
8531         f="$DIR/f62"
8532         echo foo > $f
8533         cancel_lru_locks osc
8534         lctl set_param fail_loc=0x405
8535         cat $f && error "cat succeeded, expect -EIO"
8536         lctl set_param fail_loc=0
8537 }
8538 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8539 # match every page all of the time.
8540 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8541
8542 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8543 # Though this test is irrelevant anymore, it helped to reveal some
8544 # other grant bugs (LU-4482), let's keep it.
8545 test_63a() {   # was test_63
8546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8547
8548         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8549
8550         for i in `seq 10` ; do
8551                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8552                 sleep 5
8553                 kill $!
8554                 sleep 1
8555         done
8556
8557         rm -f $DIR/f63 || true
8558 }
8559 run_test 63a "Verify oig_wait interruption does not crash ======="
8560
8561 # bug 2248 - async write errors didn't return to application on sync
8562 # bug 3677 - async write errors left page locked
8563 test_63b() {
8564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8565
8566         debugsave
8567         lctl set_param debug=-1
8568
8569         # ensure we have a grant to do async writes
8570         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8571         rm $DIR/$tfile
8572
8573         sync    # sync lest earlier test intercept the fail_loc
8574
8575         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8576         lctl set_param fail_loc=0x80000406
8577         $MULTIOP $DIR/$tfile Owy && \
8578                 error "sync didn't return ENOMEM"
8579         sync; sleep 2; sync     # do a real sync this time to flush page
8580         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8581                 error "locked page left in cache after async error" || true
8582         debugrestore
8583 }
8584 run_test 63b "async write errors should be returned to fsync ==="
8585
8586 test_64a () {
8587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8588
8589         lfs df $DIR
8590         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8591 }
8592 run_test 64a "verify filter grant calculations (in kernel) ====="
8593
8594 test_64b () {
8595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8596
8597         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8598 }
8599 run_test 64b "check out-of-space detection on client"
8600
8601 test_64c() {
8602         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8603 }
8604 run_test 64c "verify grant shrink"
8605
8606 import_param() {
8607         local tgt=$1
8608         local param=$2
8609
8610         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8611 }
8612
8613 # this does exactly what osc_request.c:osc_announce_cached() does in
8614 # order to calculate max amount of grants to ask from server
8615 want_grant() {
8616         local tgt=$1
8617
8618         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8619         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8620
8621         ((rpc_in_flight++));
8622         nrpages=$((nrpages * rpc_in_flight))
8623
8624         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8625
8626         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8627
8628         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8629         local undirty=$((nrpages * PAGE_SIZE))
8630
8631         local max_extent_pages
8632         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8633         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8634         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8635         local grant_extent_tax
8636         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8637
8638         undirty=$((undirty + nrextents * grant_extent_tax))
8639
8640         echo $undirty
8641 }
8642
8643 # this is size of unit for grant allocation. It should be equal to
8644 # what tgt_grant.c:tgt_grant_chunk() calculates
8645 grant_chunk() {
8646         local tgt=$1
8647         local max_brw_size
8648         local grant_extent_tax
8649
8650         max_brw_size=$(import_param $tgt max_brw_size)
8651
8652         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8653
8654         echo $(((max_brw_size + grant_extent_tax) * 2))
8655 }
8656
8657 test_64d() {
8658         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8659                 skip "OST < 2.10.55 doesn't limit grants enough"
8660
8661         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8662
8663         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8664                 skip "no grant_param connect flag"
8665
8666         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8667
8668         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8669         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8670
8671
8672         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8673         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8674
8675         $LFS setstripe $DIR/$tfile -i 0 -c 1
8676         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8677         ddpid=$!
8678
8679         while kill -0 $ddpid; do
8680                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8681
8682                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8683                         kill $ddpid
8684                         error "cur_grant $cur_grant > $max_cur_granted"
8685                 fi
8686
8687                 sleep 1
8688         done
8689 }
8690 run_test 64d "check grant limit exceed"
8691
8692 check_grants() {
8693         local tgt=$1
8694         local expected=$2
8695         local msg=$3
8696         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8697
8698         ((cur_grants == expected)) ||
8699                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8700 }
8701
8702 round_up_p2() {
8703         echo $((($1 + $2 - 1) & ~($2 - 1)))
8704 }
8705
8706 test_64e() {
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8709                 skip "Need OSS version at least 2.11.56"
8710
8711         # Remount client to reset grant
8712         remount_client $MOUNT || error "failed to remount client"
8713         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8714
8715         local init_grants=$(import_param $osc_tgt initial_grant)
8716
8717         check_grants $osc_tgt $init_grants "init grants"
8718
8719         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8720         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8721         local gbs=$(import_param $osc_tgt grant_block_size)
8722
8723         # write random number of bytes from max_brw_size / 4 to max_brw_size
8724         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8725         # align for direct io
8726         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8727         # round to grant consumption unit
8728         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8729
8730         local grants=$((wb_round_up + extent_tax))
8731
8732         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8733
8734         # define OBD_FAIL_TGT_NO_GRANT 0x725
8735         # make the server not grant more back
8736         do_facet ost1 $LCTL set_param fail_loc=0x725
8737         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8738
8739         do_facet ost1 $LCTL set_param fail_loc=0
8740
8741         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8742
8743         rm -f $DIR/$tfile || error "rm failed"
8744
8745         # Remount client to reset grant
8746         remount_client $MOUNT || error "failed to remount client"
8747         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8748
8749         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8750
8751         # define OBD_FAIL_TGT_NO_GRANT 0x725
8752         # make the server not grant more back
8753         do_facet ost1 $LCTL set_param fail_loc=0x725
8754         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8755         do_facet ost1 $LCTL set_param fail_loc=0
8756
8757         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8758 }
8759 run_test 64e "check grant consumption (no grant allocation)"
8760
8761 test_64f() {
8762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8763
8764         # Remount client to reset grant
8765         remount_client $MOUNT || error "failed to remount client"
8766         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8767
8768         local init_grants=$(import_param $osc_tgt initial_grant)
8769         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8770         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8771         local gbs=$(import_param $osc_tgt grant_block_size)
8772         local chunk=$(grant_chunk $osc_tgt)
8773
8774         # write random number of bytes from max_brw_size / 4 to max_brw_size
8775         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8776         # align for direct io
8777         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8778         # round to grant consumption unit
8779         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8780
8781         local grants=$((wb_round_up + extent_tax))
8782
8783         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8784         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8785                 error "error writing to $DIR/$tfile"
8786
8787         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8788                 "direct io with grant allocation"
8789
8790         rm -f $DIR/$tfile || error "rm failed"
8791
8792         # Remount client to reset grant
8793         remount_client $MOUNT || error "failed to remount client"
8794         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8795
8796         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8797
8798         local cmd="oO_WRONLY:w${write_bytes}_yc"
8799
8800         $MULTIOP $DIR/$tfile $cmd &
8801         MULTIPID=$!
8802         sleep 1
8803
8804         check_grants $osc_tgt $((init_grants - grants)) \
8805                 "buffered io, not write rpc"
8806
8807         kill -USR1 $MULTIPID
8808         wait
8809
8810         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8811                 "buffered io, one RPC"
8812 }
8813 run_test 64f "check grant consumption (with grant allocation)"
8814
8815 test_64g() {
8816         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8817         #       skip "Need MDS version at least 2.14.54"
8818
8819         local mdts=$(comma_list $(mdts_nodes))
8820
8821         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8822                         tr '\n' ' ')
8823         stack_trap "$LCTL set_param $old"
8824
8825         # generate dirty pages and increase dirty granted on MDT
8826         stack_trap "rm -f $DIR/$tfile-*"
8827         for (( i = 0; i < 10; i++)); do
8828                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8829                         error "can't set stripe"
8830                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8831                         error "can't dd"
8832                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8833                         $LFS getstripe $DIR/$tfile-$i
8834                         error "not DoM file"
8835                 }
8836         done
8837
8838         # flush dirty pages
8839         sync
8840
8841         # wait until grant shrink reset grant dirty on MDTs
8842         for ((i = 0; i < 120; i++)); do
8843                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8844                         awk '{sum=sum+$1} END {print sum}')
8845                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8846                 echo "$grant_dirty grants, $vm_dirty pages"
8847                 (( grant_dirty + vm_dirty == 0 )) && break
8848                 (( i == 3 )) && sync &&
8849                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8850                 sleep 1
8851         done
8852
8853         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8854                 awk '{sum=sum+$1} END {print sum}')
8855         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8856 }
8857 run_test 64g "grant shrink on MDT"
8858
8859 test_64h() {
8860         local instance=$($LFS getname -i $DIR)
8861         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8862         local num_exps=$(do_facet ost1 \
8863             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8864         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8865         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8866         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8867
8868         # 10MiB is for file to be written, max_brw_size * 16 *
8869         # num_exps is space reserve so that tgt_grant_shrink() decided
8870         # to not shrink
8871         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8872         (( avail * 1024 < expect )) &&
8873                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8874
8875         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8876         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8877         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8878         $LCTL set_param osc.*OST0000*.grant_shrink=1
8879         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8880
8881         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8882         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8883
8884         # drop cache so that coming read would do rpc
8885         cancel_lru_locks osc
8886
8887         # shrink interval is set to 10, pause for 7 seconds so that
8888         # grant thread did not wake up yet but coming read entered
8889         # shrink mode for rpc (osc_should_shrink_grant())
8890         sleep 7
8891
8892         declare -a cur_grant_bytes
8893         declare -a tot_granted
8894         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8895         tot_granted[0]=$(do_facet ost1 \
8896             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8897
8898         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8899
8900         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8901         tot_granted[1]=$(do_facet ost1 \
8902             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8903
8904         # grant change should be equal on both sides
8905         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8906                 tot_granted[0] - tot_granted[1])) ||
8907                 error "grant change mismatch, "                                \
8908                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8909                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8910 }
8911 run_test 64h "grant shrink on read"
8912
8913 test_64i() {
8914         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8915                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8916
8917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8918         remote_ost_nodsh && skip "remote OSTs with nodsh"
8919
8920         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8921
8922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8923
8924         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8925         local instance=$($LFS getname -i $DIR)
8926
8927         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8928         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8929
8930         # shrink grants and simulate rpc loss
8931         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8932         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8933         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8934
8935         fail ost1
8936
8937         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8938
8939         local testid=$(echo $TESTNAME | tr '_' ' ')
8940
8941         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8942                 grep "GRANT, real grant" &&
8943                 error "client has more grants then it owns" || true
8944 }
8945 run_test 64i "shrink on reconnect"
8946
8947 # bug 1414 - set/get directories' stripe info
8948 test_65a() {
8949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8950
8951         test_mkdir $DIR/$tdir
8952         touch $DIR/$tdir/f1
8953         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8954 }
8955 run_test 65a "directory with no stripe info"
8956
8957 test_65b() {
8958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8959
8960         test_mkdir $DIR/$tdir
8961         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8962
8963         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8964                                                 error "setstripe"
8965         touch $DIR/$tdir/f2
8966         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8967 }
8968 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8969
8970 test_65c() {
8971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8972         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8973
8974         test_mkdir $DIR/$tdir
8975         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8976
8977         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8978                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8979         touch $DIR/$tdir/f3
8980         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8981 }
8982 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8983
8984 test_65d() {
8985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8986
8987         test_mkdir $DIR/$tdir
8988         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8989         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8990
8991         if [[ $STRIPECOUNT -le 0 ]]; then
8992                 sc=1
8993         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8994                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8995                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8996         else
8997                 sc=$(($STRIPECOUNT - 1))
8998         fi
8999         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9000         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9001         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9002                 error "lverify failed"
9003 }
9004 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9005
9006 test_65e() {
9007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9008
9009         test_mkdir $DIR/$tdir
9010
9011         $LFS setstripe $DIR/$tdir || error "setstripe"
9012         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9013                                         error "no stripe info failed"
9014         touch $DIR/$tdir/f6
9015         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9016 }
9017 run_test 65e "directory setstripe defaults"
9018
9019 test_65f() {
9020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9021
9022         test_mkdir $DIR/${tdir}f
9023         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9024                 error "setstripe succeeded" || true
9025 }
9026 run_test 65f "dir setstripe permission (should return error) ==="
9027
9028 test_65g() {
9029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9030
9031         test_mkdir $DIR/$tdir
9032         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9033
9034         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9035                 error "setstripe -S failed"
9036         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9037         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9038                 error "delete default stripe failed"
9039 }
9040 run_test 65g "directory setstripe -d"
9041
9042 test_65h() {
9043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9044
9045         test_mkdir $DIR/$tdir
9046         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9047
9048         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9049                 error "setstripe -S failed"
9050         test_mkdir $DIR/$tdir/dd1
9051         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9052                 error "stripe info inherit failed"
9053 }
9054 run_test 65h "directory stripe info inherit ===================="
9055
9056 test_65i() {
9057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9058
9059         save_layout_restore_at_exit $MOUNT
9060
9061         # bug6367: set non-default striping on root directory
9062         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9063
9064         # bug12836: getstripe on -1 default directory striping
9065         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9066
9067         # bug12836: getstripe -v on -1 default directory striping
9068         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9069
9070         # bug12836: new find on -1 default directory striping
9071         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9072 }
9073 run_test 65i "various tests to set root directory striping"
9074
9075 test_65j() { # bug6367
9076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9077
9078         sync; sleep 1
9079
9080         # if we aren't already remounting for each test, do so for this test
9081         if [ "$I_MOUNTED" = "yes" ]; then
9082                 cleanup || error "failed to unmount"
9083                 setup
9084         fi
9085
9086         save_layout_restore_at_exit $MOUNT
9087
9088         $LFS setstripe -d $MOUNT || error "setstripe failed"
9089 }
9090 run_test 65j "set default striping on root directory (bug 6367)="
9091
9092 cleanup_65k() {
9093         rm -rf $DIR/$tdir
9094         wait_delete_completed
9095         do_facet $SINGLEMDS "lctl set_param -n \
9096                 osp.$ost*MDT0000.max_create_count=$max_count"
9097         do_facet $SINGLEMDS "lctl set_param -n \
9098                 osp.$ost*MDT0000.create_count=$count"
9099         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9100         echo $INACTIVE_OSC "is Activate"
9101
9102         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9103 }
9104
9105 test_65k() { # bug11679
9106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9107         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9108         remote_mds_nodsh && skip "remote MDS with nodsh"
9109
9110         local disable_precreate=true
9111         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9112                 disable_precreate=false
9113
9114         echo "Check OST status: "
9115         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9116                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9117
9118         for OSC in $MDS_OSCS; do
9119                 echo $OSC "is active"
9120                 do_facet $SINGLEMDS lctl --device %$OSC activate
9121         done
9122
9123         for INACTIVE_OSC in $MDS_OSCS; do
9124                 local ost=$(osc_to_ost $INACTIVE_OSC)
9125                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9126                                lov.*md*.target_obd |
9127                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9128
9129                 mkdir -p $DIR/$tdir
9130                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9131                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9132
9133                 echo "Deactivate: " $INACTIVE_OSC
9134                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9135
9136                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9137                               osp.$ost*MDT0000.create_count")
9138                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9139                                   osp.$ost*MDT0000.max_create_count")
9140                 $disable_precreate &&
9141                         do_facet $SINGLEMDS "lctl set_param -n \
9142                                 osp.$ost*MDT0000.max_create_count=0"
9143
9144                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9145                         [ -f $DIR/$tdir/$idx ] && continue
9146                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9147                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9148                                 { cleanup_65k;
9149                                   error "setstripe $idx should succeed"; }
9150                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9151                 done
9152                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9153                 rmdir $DIR/$tdir
9154
9155                 do_facet $SINGLEMDS "lctl set_param -n \
9156                         osp.$ost*MDT0000.max_create_count=$max_count"
9157                 do_facet $SINGLEMDS "lctl set_param -n \
9158                         osp.$ost*MDT0000.create_count=$count"
9159                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9160                 echo $INACTIVE_OSC "is Activate"
9161
9162                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9163         done
9164 }
9165 run_test 65k "validate manual striping works properly with deactivated OSCs"
9166
9167 test_65l() { # bug 12836
9168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9169
9170         test_mkdir -p $DIR/$tdir/test_dir
9171         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9172         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9173 }
9174 run_test 65l "lfs find on -1 stripe dir ========================"
9175
9176 test_65m() {
9177         local layout=$(save_layout $MOUNT)
9178         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9179                 restore_layout $MOUNT $layout
9180                 error "setstripe should fail by non-root users"
9181         }
9182         true
9183 }
9184 run_test 65m "normal user can't set filesystem default stripe"
9185
9186 test_65n() {
9187         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9188         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9189                 skip "Need MDS version at least 2.12.50"
9190         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9191
9192         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9193         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9194         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9195
9196         save_layout_restore_at_exit $MOUNT
9197
9198         # new subdirectory under root directory should not inherit
9199         # the default layout from root
9200         local dir1=$MOUNT/$tdir-1
9201         mkdir $dir1 || error "mkdir $dir1 failed"
9202         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9203                 error "$dir1 shouldn't have LOV EA"
9204
9205         # delete the default layout on root directory
9206         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9207
9208         local dir2=$MOUNT/$tdir-2
9209         mkdir $dir2 || error "mkdir $dir2 failed"
9210         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9211                 error "$dir2 shouldn't have LOV EA"
9212
9213         # set a new striping pattern on root directory
9214         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9215         local new_def_stripe_size=$((def_stripe_size * 2))
9216         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9217                 error "set stripe size on $MOUNT failed"
9218
9219         # new file created in $dir2 should inherit the new stripe size from
9220         # the filesystem default
9221         local file2=$dir2/$tfile-2
9222         touch $file2 || error "touch $file2 failed"
9223
9224         local file2_stripe_size=$($LFS getstripe -S $file2)
9225         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9226         {
9227                 echo "file2_stripe_size: '$file2_stripe_size'"
9228                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9229                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9230         }
9231
9232         local dir3=$MOUNT/$tdir-3
9233         mkdir $dir3 || error "mkdir $dir3 failed"
9234         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9235         # the root layout, which is the actual default layout that will be used
9236         # when new files are created in $dir3.
9237         local dir3_layout=$(get_layout_param $dir3)
9238         local root_dir_layout=$(get_layout_param $MOUNT)
9239         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9240         {
9241                 echo "dir3_layout: '$dir3_layout'"
9242                 echo "root_dir_layout: '$root_dir_layout'"
9243                 error "$dir3 should show the default layout from $MOUNT"
9244         }
9245
9246         # set OST pool on root directory
9247         local pool=$TESTNAME
9248         pool_add $pool || error "add $pool failed"
9249         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9250                 error "add targets to $pool failed"
9251
9252         $LFS setstripe -p $pool $MOUNT ||
9253                 error "set OST pool on $MOUNT failed"
9254
9255         # new file created in $dir3 should inherit the pool from
9256         # the filesystem default
9257         local file3=$dir3/$tfile-3
9258         touch $file3 || error "touch $file3 failed"
9259
9260         local file3_pool=$($LFS getstripe -p $file3)
9261         [[ "$file3_pool" = "$pool" ]] ||
9262                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9263
9264         local dir4=$MOUNT/$tdir-4
9265         mkdir $dir4 || error "mkdir $dir4 failed"
9266         local dir4_layout=$(get_layout_param $dir4)
9267         root_dir_layout=$(get_layout_param $MOUNT)
9268         echo "$LFS getstripe -d $dir4"
9269         $LFS getstripe -d $dir4
9270         echo "$LFS getstripe -d $MOUNT"
9271         $LFS getstripe -d $MOUNT
9272         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9273         {
9274                 echo "dir4_layout: '$dir4_layout'"
9275                 echo "root_dir_layout: '$root_dir_layout'"
9276                 error "$dir4 should show the default layout from $MOUNT"
9277         }
9278
9279         # new file created in $dir4 should inherit the pool from
9280         # the filesystem default
9281         local file4=$dir4/$tfile-4
9282         touch $file4 || error "touch $file4 failed"
9283
9284         local file4_pool=$($LFS getstripe -p $file4)
9285         [[ "$file4_pool" = "$pool" ]] ||
9286                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9287
9288         # new subdirectory under non-root directory should inherit
9289         # the default layout from its parent directory
9290         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9291                 error "set directory layout on $dir4 failed"
9292
9293         local dir5=$dir4/$tdir-5
9294         mkdir $dir5 || error "mkdir $dir5 failed"
9295
9296         dir4_layout=$(get_layout_param $dir4)
9297         local dir5_layout=$(get_layout_param $dir5)
9298         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9299         {
9300                 echo "dir4_layout: '$dir4_layout'"
9301                 echo "dir5_layout: '$dir5_layout'"
9302                 error "$dir5 should inherit the default layout from $dir4"
9303         }
9304
9305         # though subdir under ROOT doesn't inherit default layout, but
9306         # its sub dir/file should be created with default layout.
9307         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9308         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9309                 skip "Need MDS version at least 2.12.59"
9310
9311         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9312         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9313         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9314
9315         if [ $default_lmv_hash == "none" ]; then
9316                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9317         else
9318                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9319                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9320         fi
9321
9322         $LFS setdirstripe -D -c 2 $MOUNT ||
9323                 error "setdirstripe -D -c 2 failed"
9324         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9325         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9326         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9327 }
9328 run_test 65n "don't inherit default layout from root for new subdirectories"
9329
9330 # bug 2543 - update blocks count on client
9331 test_66() {
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333
9334         COUNT=${COUNT:-8}
9335         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9336         sync; sync_all_data; sync; sync_all_data
9337         cancel_lru_locks osc
9338         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9339         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9340 }
9341 run_test 66 "update inode blocks count on client ==============="
9342
9343 meminfo() {
9344         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9345 }
9346
9347 swap_used() {
9348         swapon -s | awk '($1 == "'$1'") { print $4 }'
9349 }
9350
9351 # bug5265, obdfilter oa2dentry return -ENOENT
9352 # #define OBD_FAIL_SRV_ENOENT 0x217
9353 test_69() {
9354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9355         remote_ost_nodsh && skip "remote OST with nodsh"
9356
9357         f="$DIR/$tfile"
9358         $LFS setstripe -c 1 -i 0 $f
9359
9360         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9361
9362         do_facet ost1 lctl set_param fail_loc=0x217
9363         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9364         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9365
9366         do_facet ost1 lctl set_param fail_loc=0
9367         $DIRECTIO write $f 0 2 || error "write error"
9368
9369         cancel_lru_locks osc
9370         $DIRECTIO read $f 0 1 || error "read error"
9371
9372         do_facet ost1 lctl set_param fail_loc=0x217
9373         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9374
9375         do_facet ost1 lctl set_param fail_loc=0
9376         rm -f $f
9377 }
9378 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9379
9380 test_71() {
9381         test_mkdir $DIR/$tdir
9382         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9383         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9384 }
9385 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9386
9387 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9389         [ "$RUNAS_ID" = "$UID" ] &&
9390                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9391         # Check that testing environment is properly set up. Skip if not
9392         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9393                 skip_env "User $RUNAS_ID does not exist - skipping"
9394
9395         touch $DIR/$tfile
9396         chmod 777 $DIR/$tfile
9397         chmod ug+s $DIR/$tfile
9398         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9399                 error "$RUNAS dd $DIR/$tfile failed"
9400         # See if we are still setuid/sgid
9401         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9402                 error "S/gid is not dropped on write"
9403         # Now test that MDS is updated too
9404         cancel_lru_locks mdc
9405         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9406                 error "S/gid is not dropped on MDS"
9407         rm -f $DIR/$tfile
9408 }
9409 run_test 72a "Test that remove suid works properly (bug5695) ===="
9410
9411 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9412         local perm
9413
9414         [ "$RUNAS_ID" = "$UID" ] &&
9415                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9416         [ "$RUNAS_ID" -eq 0 ] &&
9417                 skip_env "RUNAS_ID = 0 -- skipping"
9418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9419         # Check that testing environment is properly set up. Skip if not
9420         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9421                 skip_env "User $RUNAS_ID does not exist - skipping"
9422
9423         touch $DIR/${tfile}-f{g,u}
9424         test_mkdir $DIR/${tfile}-dg
9425         test_mkdir $DIR/${tfile}-du
9426         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9427         chmod g+s $DIR/${tfile}-{f,d}g
9428         chmod u+s $DIR/${tfile}-{f,d}u
9429         for perm in 777 2777 4777; do
9430                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9431                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9432                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9433                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9434         done
9435         true
9436 }
9437 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9438
9439 # bug 3462 - multiple simultaneous MDC requests
9440 test_73() {
9441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9442
9443         test_mkdir $DIR/d73-1
9444         test_mkdir $DIR/d73-2
9445         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9446         pid1=$!
9447
9448         lctl set_param fail_loc=0x80000129
9449         $MULTIOP $DIR/d73-1/f73-2 Oc &
9450         sleep 1
9451         lctl set_param fail_loc=0
9452
9453         $MULTIOP $DIR/d73-2/f73-3 Oc &
9454         pid3=$!
9455
9456         kill -USR1 $pid1
9457         wait $pid1 || return 1
9458
9459         sleep 25
9460
9461         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9462         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9463         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9464
9465         rm -rf $DIR/d73-*
9466 }
9467 run_test 73 "multiple MDC requests (should not deadlock)"
9468
9469 test_74a() { # bug 6149, 6184
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471
9472         touch $DIR/f74a
9473         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9474         #
9475         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9476         # will spin in a tight reconnection loop
9477         $LCTL set_param fail_loc=0x8000030e
9478         # get any lock that won't be difficult - lookup works.
9479         ls $DIR/f74a
9480         $LCTL set_param fail_loc=0
9481         rm -f $DIR/f74a
9482         true
9483 }
9484 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9485
9486 test_74b() { # bug 13310
9487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9488
9489         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9490         #
9491         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9492         # will spin in a tight reconnection loop
9493         $LCTL set_param fail_loc=0x8000030e
9494         # get a "difficult" lock
9495         touch $DIR/f74b
9496         $LCTL set_param fail_loc=0
9497         rm -f $DIR/f74b
9498         true
9499 }
9500 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9501
9502 test_74c() {
9503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9504
9505         #define OBD_FAIL_LDLM_NEW_LOCK
9506         $LCTL set_param fail_loc=0x319
9507         touch $DIR/$tfile && error "touch successful"
9508         $LCTL set_param fail_loc=0
9509         true
9510 }
9511 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9512
9513 slab_lic=/sys/kernel/slab/lustre_inode_cache
9514 num_objects() {
9515         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9516         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9517                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9518 }
9519
9520 test_76a() { # Now for b=20433, added originally in b=1443
9521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9522
9523         cancel_lru_locks osc
9524         # there may be some slab objects cached per core
9525         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9526         local before=$(num_objects)
9527         local count=$((512 * cpus))
9528         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9529         local margin=$((count / 10))
9530         if [[ -f $slab_lic/aliases ]]; then
9531                 local aliases=$(cat $slab_lic/aliases)
9532                 (( aliases > 0 )) && margin=$((margin * aliases))
9533         fi
9534
9535         echo "before slab objects: $before"
9536         for i in $(seq $count); do
9537                 touch $DIR/$tfile
9538                 rm -f $DIR/$tfile
9539         done
9540         cancel_lru_locks osc
9541         local after=$(num_objects)
9542         echo "created: $count, after slab objects: $after"
9543         # shared slab counts are not very accurate, allow significant margin
9544         # the main goal is that the cache growth is not permanently > $count
9545         while (( after > before + margin )); do
9546                 sleep 1
9547                 after=$(num_objects)
9548                 wait=$((wait + 1))
9549                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9550                 if (( wait > 60 )); then
9551                         error "inode slab grew from $before+$margin to $after"
9552                 fi
9553         done
9554 }
9555 run_test 76a "confirm clients recycle inodes properly ===="
9556
9557 test_76b() {
9558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9559         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9560
9561         local count=512
9562         local before=$(num_objects)
9563
9564         for i in $(seq $count); do
9565                 mkdir $DIR/$tdir
9566                 rmdir $DIR/$tdir
9567         done
9568
9569         local after=$(num_objects)
9570         local wait=0
9571
9572         while (( after > before )); do
9573                 sleep 1
9574                 after=$(num_objects)
9575                 wait=$((wait + 1))
9576                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9577                 if (( wait > 60 )); then
9578                         error "inode slab grew from $before to $after"
9579                 fi
9580         done
9581
9582         echo "slab objects before: $before, after: $after"
9583 }
9584 run_test 76b "confirm clients recycle directory inodes properly ===="
9585
9586 export ORIG_CSUM=""
9587 set_checksums()
9588 {
9589         # Note: in sptlrpc modes which enable its own bulk checksum, the
9590         # original crc32_le bulk checksum will be automatically disabled,
9591         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9592         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9593         # In this case set_checksums() will not be no-op, because sptlrpc
9594         # bulk checksum will be enabled all through the test.
9595
9596         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9597         lctl set_param -n osc.*.checksums $1
9598         return 0
9599 }
9600
9601 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9602                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9603 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9604                              tr -d [] | head -n1)}
9605 set_checksum_type()
9606 {
9607         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9608         rc=$?
9609         log "set checksum type to $1, rc = $rc"
9610         return $rc
9611 }
9612
9613 get_osc_checksum_type()
9614 {
9615         # arugment 1: OST name, like OST0000
9616         ost=$1
9617         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9618                         sed 's/.*\[\(.*\)\].*/\1/g')
9619         rc=$?
9620         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9621         echo $checksum_type
9622 }
9623
9624 F77_TMP=$TMP/f77-temp
9625 F77SZ=8
9626 setup_f77() {
9627         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9628                 error "error writing to $F77_TMP"
9629 }
9630
9631 test_77a() { # bug 10889
9632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9633         $GSS && skip_env "could not run with gss"
9634
9635         [ ! -f $F77_TMP ] && setup_f77
9636         set_checksums 1
9637         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9638         set_checksums 0
9639         rm -f $DIR/$tfile
9640 }
9641 run_test 77a "normal checksum read/write operation"
9642
9643 test_77b() { # bug 10889
9644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9645         $GSS && skip_env "could not run with gss"
9646
9647         [ ! -f $F77_TMP ] && setup_f77
9648         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9649         $LCTL set_param fail_loc=0x80000409
9650         set_checksums 1
9651
9652         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9653                 error "dd error: $?"
9654         $LCTL set_param fail_loc=0
9655
9656         for algo in $CKSUM_TYPES; do
9657                 cancel_lru_locks osc
9658                 set_checksum_type $algo
9659                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9660                 $LCTL set_param fail_loc=0x80000408
9661                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9662                 $LCTL set_param fail_loc=0
9663         done
9664         set_checksums 0
9665         set_checksum_type $ORIG_CSUM_TYPE
9666         rm -f $DIR/$tfile
9667 }
9668 run_test 77b "checksum error on client write, read"
9669
9670 cleanup_77c() {
9671         trap 0
9672         set_checksums 0
9673         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9674         $check_ost &&
9675                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9676         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9677         $check_ost && [ -n "$ost_file_prefix" ] &&
9678                 do_facet ost1 rm -f ${ost_file_prefix}\*
9679 }
9680
9681 test_77c() {
9682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9683         $GSS && skip_env "could not run with gss"
9684         remote_ost_nodsh && skip "remote OST with nodsh"
9685
9686         local bad1
9687         local osc_file_prefix
9688         local osc_file
9689         local check_ost=false
9690         local ost_file_prefix
9691         local ost_file
9692         local orig_cksum
9693         local dump_cksum
9694         local fid
9695
9696         # ensure corruption will occur on first OSS/OST
9697         $LFS setstripe -i 0 $DIR/$tfile
9698
9699         [ ! -f $F77_TMP ] && setup_f77
9700         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9701                 error "dd write error: $?"
9702         fid=$($LFS path2fid $DIR/$tfile)
9703
9704         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9705         then
9706                 check_ost=true
9707                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9708                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9709         else
9710                 echo "OSS do not support bulk pages dump upon error"
9711         fi
9712
9713         osc_file_prefix=$($LCTL get_param -n debug_path)
9714         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9715
9716         trap cleanup_77c EXIT
9717
9718         set_checksums 1
9719         # enable bulk pages dump upon error on Client
9720         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9721         # enable bulk pages dump upon error on OSS
9722         $check_ost &&
9723                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9724
9725         # flush Client cache to allow next read to reach OSS
9726         cancel_lru_locks osc
9727
9728         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9729         $LCTL set_param fail_loc=0x80000408
9730         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9731         $LCTL set_param fail_loc=0
9732
9733         rm -f $DIR/$tfile
9734
9735         # check cksum dump on Client
9736         osc_file=$(ls ${osc_file_prefix}*)
9737         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9738         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9739         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9740         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9741         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9742                      cksum)
9743         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9744         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9745                 error "dump content does not match on Client"
9746
9747         $check_ost || skip "No need to check cksum dump on OSS"
9748
9749         # check cksum dump on OSS
9750         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9751         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9752         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9753         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9754         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9755                 error "dump content does not match on OSS"
9756
9757         cleanup_77c
9758 }
9759 run_test 77c "checksum error on client read with debug"
9760
9761 test_77d() { # bug 10889
9762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9763         $GSS && skip_env "could not run with gss"
9764
9765         stack_trap "rm -f $DIR/$tfile"
9766         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9767         $LCTL set_param fail_loc=0x80000409
9768         set_checksums 1
9769         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9770                 error "direct write: rc=$?"
9771         $LCTL set_param fail_loc=0
9772         set_checksums 0
9773
9774         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9775         $LCTL set_param fail_loc=0x80000408
9776         set_checksums 1
9777         cancel_lru_locks osc
9778         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9779                 error "direct read: rc=$?"
9780         $LCTL set_param fail_loc=0
9781         set_checksums 0
9782 }
9783 run_test 77d "checksum error on OST direct write, read"
9784
9785 test_77f() { # bug 10889
9786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9787         $GSS && skip_env "could not run with gss"
9788
9789         set_checksums 1
9790         stack_trap "rm -f $DIR/$tfile"
9791         for algo in $CKSUM_TYPES; do
9792                 cancel_lru_locks osc
9793                 set_checksum_type $algo
9794                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9795                 $LCTL set_param fail_loc=0x409
9796                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9797                         error "direct write succeeded"
9798                 $LCTL set_param fail_loc=0
9799         done
9800         set_checksum_type $ORIG_CSUM_TYPE
9801         set_checksums 0
9802 }
9803 run_test 77f "repeat checksum error on write (expect error)"
9804
9805 test_77g() { # bug 10889
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807         $GSS && skip_env "could not run with gss"
9808         remote_ost_nodsh && skip "remote OST with nodsh"
9809
9810         [ ! -f $F77_TMP ] && setup_f77
9811
9812         local file=$DIR/$tfile
9813         stack_trap "rm -f $file" EXIT
9814
9815         $LFS setstripe -c 1 -i 0 $file
9816         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9817         do_facet ost1 lctl set_param fail_loc=0x8000021a
9818         set_checksums 1
9819         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9820                 error "write error: rc=$?"
9821         do_facet ost1 lctl set_param fail_loc=0
9822         set_checksums 0
9823
9824         cancel_lru_locks osc
9825         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9826         do_facet ost1 lctl set_param fail_loc=0x8000021b
9827         set_checksums 1
9828         cmp $F77_TMP $file || error "file compare failed"
9829         do_facet ost1 lctl set_param fail_loc=0
9830         set_checksums 0
9831 }
9832 run_test 77g "checksum error on OST write, read"
9833
9834 test_77k() { # LU-10906
9835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9836         $GSS && skip_env "could not run with gss"
9837
9838         local cksum_param="osc.$FSNAME*.checksums"
9839         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9840         local checksum
9841         local i
9842
9843         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9844         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9845         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9846
9847         for i in 0 1; do
9848                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9849                         error "failed to set checksum=$i on MGS"
9850                 wait_update $HOSTNAME "$get_checksum" $i
9851                 #remount
9852                 echo "remount client, checksum should be $i"
9853                 remount_client $MOUNT || error "failed to remount client"
9854                 checksum=$(eval $get_checksum)
9855                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9856         done
9857         # remove persistent param to avoid races with checksum mountopt below
9858         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9859                 error "failed to delete checksum on MGS"
9860
9861         for opt in "checksum" "nochecksum"; do
9862                 #remount with mount option
9863                 echo "remount client with option $opt, checksum should be $i"
9864                 umount_client $MOUNT || error "failed to umount client"
9865                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9866                         error "failed to mount client with option '$opt'"
9867                 checksum=$(eval $get_checksum)
9868                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9869                 i=$((i - 1))
9870         done
9871
9872         remount_client $MOUNT || error "failed to remount client"
9873 }
9874 run_test 77k "enable/disable checksum correctly"
9875
9876 test_77l() {
9877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9878         $GSS && skip_env "could not run with gss"
9879
9880         set_checksums 1
9881         stack_trap "set_checksums $ORIG_CSUM" EXIT
9882         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9883
9884         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9885
9886         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9887         for algo in $CKSUM_TYPES; do
9888                 set_checksum_type $algo || error "fail to set checksum type $algo"
9889                 osc_algo=$(get_osc_checksum_type OST0000)
9890                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9891
9892                 # no locks, no reqs to let the connection idle
9893                 cancel_lru_locks osc
9894                 lru_resize_disable osc
9895                 wait_osc_import_state client ost1 IDLE
9896
9897                 # ensure ost1 is connected
9898                 stat $DIR/$tfile >/dev/null || error "can't stat"
9899                 wait_osc_import_state client ost1 FULL
9900
9901                 osc_algo=$(get_osc_checksum_type OST0000)
9902                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9903         done
9904         return 0
9905 }
9906 run_test 77l "preferred checksum type is remembered after reconnected"
9907
9908 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9909 rm -f $F77_TMP
9910 unset F77_TMP
9911
9912 test_77m() {
9913         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9914                 skip "Need at least version 2.14.52"
9915         local param=checksum_speed
9916
9917         $LCTL get_param $param || error "reading $param failed"
9918
9919         csum_speeds=$($LCTL get_param -n $param)
9920
9921         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9922                 error "known checksum types are missing"
9923 }
9924 run_test 77m "Verify checksum_speed is correctly read"
9925
9926 check_filefrag_77n() {
9927         local nr_ext=0
9928         local starts=()
9929         local ends=()
9930
9931         while read extidx a b start end rest; do
9932                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9933                         nr_ext=$(( $nr_ext + 1 ))
9934                         starts+=( ${start%..} )
9935                         ends+=( ${end%:} )
9936                 fi
9937         done < <( filefrag -sv $1 )
9938
9939         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9940         return 1
9941 }
9942
9943 test_77n() {
9944         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9945
9946         touch $DIR/$tfile
9947         $TRUNCATE $DIR/$tfile 0
9948         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9949         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9950         check_filefrag_77n $DIR/$tfile ||
9951                 skip "$tfile blocks not contiguous around hole"
9952
9953         set_checksums 1
9954         stack_trap "set_checksums $ORIG_CSUM" EXIT
9955         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9956         stack_trap "rm -f $DIR/$tfile"
9957
9958         for algo in $CKSUM_TYPES; do
9959                 if [[ "$algo" =~ ^t10 ]]; then
9960                         set_checksum_type $algo ||
9961                                 error "fail to set checksum type $algo"
9962                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9963                                 error "fail to read $tfile with $algo"
9964                 fi
9965         done
9966         rm -f $DIR/$tfile
9967         return 0
9968 }
9969 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9970
9971 test_77o() {
9972         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
9973                 skip "Need at least version 2.14.54"
9974         local ofd=obdfilter
9975         local mdt=mdt
9976
9977         # print OST checksum_type
9978         echo "$ofd.$FSNAME-*.checksum_type:"
9979         do_nodes $(comma_list $(osts_nodes)) \
9980                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
9981
9982         # print MDT checksum_type
9983         echo "$mdt.$FSNAME-*.checksum_type:"
9984         do_nodes $(comma_list $(mdts_nodes)) \
9985                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
9986
9987         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
9988                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
9989
9990         (( $o_count == $OSTCOUNT )) ||
9991                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
9992
9993         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
9994                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
9995
9996         (( $m_count == $MDSCOUNT )) ||
9997                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
9998 }
9999 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10000
10001 cleanup_test_78() {
10002         trap 0
10003         rm -f $DIR/$tfile
10004 }
10005
10006 test_78() { # bug 10901
10007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10008         remote_ost || skip_env "local OST"
10009
10010         NSEQ=5
10011         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10012         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10013         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10014         echo "MemTotal: $MEMTOTAL"
10015
10016         # reserve 256MB of memory for the kernel and other running processes,
10017         # and then take 1/2 of the remaining memory for the read/write buffers.
10018         if [ $MEMTOTAL -gt 512 ] ;then
10019                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10020         else
10021                 # for those poor memory-starved high-end clusters...
10022                 MEMTOTAL=$((MEMTOTAL / 2))
10023         fi
10024         echo "Mem to use for directio: $MEMTOTAL"
10025
10026         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10027         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10028         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10029         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10030                 head -n1)
10031         echo "Smallest OST: $SMALLESTOST"
10032         [[ $SMALLESTOST -lt 10240 ]] &&
10033                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10034
10035         trap cleanup_test_78 EXIT
10036
10037         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10038                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10039
10040         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10041         echo "File size: $F78SIZE"
10042         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10043         for i in $(seq 1 $NSEQ); do
10044                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10045                 echo directIO rdwr round $i of $NSEQ
10046                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10047         done
10048
10049         cleanup_test_78
10050 }
10051 run_test 78 "handle large O_DIRECT writes correctly ============"
10052
10053 test_79() { # bug 12743
10054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10055
10056         wait_delete_completed
10057
10058         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10059         BKFREE=$(calc_osc_kbytes kbytesfree)
10060         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10061
10062         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10063         DFTOTAL=`echo $STRING | cut -d, -f1`
10064         DFUSED=`echo $STRING  | cut -d, -f2`
10065         DFAVAIL=`echo $STRING | cut -d, -f3`
10066         DFFREE=$(($DFTOTAL - $DFUSED))
10067
10068         ALLOWANCE=$((64 * $OSTCOUNT))
10069
10070         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10071            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10072                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10073         fi
10074         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10075            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10076                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10077         fi
10078         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10079            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10080                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10081         fi
10082 }
10083 run_test 79 "df report consistency check ======================="
10084
10085 test_80() { # bug 10718
10086         remote_ost_nodsh && skip "remote OST with nodsh"
10087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10088
10089         # relax strong synchronous semantics for slow backends like ZFS
10090         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10091                 local soc="obdfilter.*.sync_lock_cancel"
10092                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10093
10094                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10095                 if [ -z "$save" ]; then
10096                         soc="obdfilter.*.sync_on_lock_cancel"
10097                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10098                 fi
10099
10100                 if [ "$save" != "never" ]; then
10101                         local hosts=$(comma_list $(osts_nodes))
10102
10103                         do_nodes $hosts $LCTL set_param $soc=never
10104                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10105                 fi
10106         fi
10107
10108         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10109         sync; sleep 1; sync
10110         local before=$(date +%s)
10111         cancel_lru_locks osc
10112         local after=$(date +%s)
10113         local diff=$((after - before))
10114         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10115
10116         rm -f $DIR/$tfile
10117 }
10118 run_test 80 "Page eviction is equally fast at high offsets too"
10119
10120 test_81a() { # LU-456
10121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10122         remote_ost_nodsh && skip "remote OST with nodsh"
10123
10124         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10125         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10126         do_facet ost1 lctl set_param fail_loc=0x80000228
10127
10128         # write should trigger a retry and success
10129         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10130         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10131         RC=$?
10132         if [ $RC -ne 0 ] ; then
10133                 error "write should success, but failed for $RC"
10134         fi
10135 }
10136 run_test 81a "OST should retry write when get -ENOSPC ==============="
10137
10138 test_81b() { # LU-456
10139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10140         remote_ost_nodsh && skip "remote OST with nodsh"
10141
10142         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10143         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10144         do_facet ost1 lctl set_param fail_loc=0x228
10145
10146         # write should retry several times and return -ENOSPC finally
10147         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10148         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10149         RC=$?
10150         ENOSPC=28
10151         if [ $RC -ne $ENOSPC ] ; then
10152                 error "dd should fail for -ENOSPC, but succeed."
10153         fi
10154 }
10155 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10156
10157 test_99() {
10158         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10159
10160         test_mkdir $DIR/$tdir.cvsroot
10161         chown $RUNAS_ID $DIR/$tdir.cvsroot
10162
10163         cd $TMP
10164         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10165
10166         cd /etc/init.d
10167         # some versions of cvs import exit(1) when asked to import links or
10168         # files they can't read.  ignore those files.
10169         local toignore=$(find . -type l -printf '-I %f\n' -o \
10170                          ! -perm /4 -printf '-I %f\n')
10171         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10172                 $tdir.reposname vtag rtag
10173
10174         cd $DIR
10175         test_mkdir $DIR/$tdir.reposname
10176         chown $RUNAS_ID $DIR/$tdir.reposname
10177         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10178
10179         cd $DIR/$tdir.reposname
10180         $RUNAS touch foo99
10181         $RUNAS cvs add -m 'addmsg' foo99
10182         $RUNAS cvs update
10183         $RUNAS cvs commit -m 'nomsg' foo99
10184         rm -fr $DIR/$tdir.cvsroot
10185 }
10186 run_test 99 "cvs strange file/directory operations"
10187
10188 test_100() {
10189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10190         [[ "$NETTYPE" =~ tcp ]] ||
10191                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10192         remote_ost_nodsh && skip "remote OST with nodsh"
10193         remote_mds_nodsh && skip "remote MDS with nodsh"
10194         remote_servers ||
10195                 skip "useless for local single node setup"
10196
10197         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10198                 [ "$PROT" != "tcp" ] && continue
10199                 RPORT=$(echo $REMOTE | cut -d: -f2)
10200                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10201
10202                 rc=0
10203                 LPORT=`echo $LOCAL | cut -d: -f2`
10204                 if [ $LPORT -ge 1024 ]; then
10205                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10206                         netstat -tna
10207                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10208                 fi
10209         done
10210         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10211 }
10212 run_test 100 "check local port using privileged port ==========="
10213
10214 function get_named_value()
10215 {
10216     local tag=$1
10217
10218     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10219 }
10220
10221 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10222                    awk '/^max_cached_mb/ { print $2 }')
10223
10224 cleanup_101a() {
10225         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10226         trap 0
10227 }
10228
10229 test_101a() {
10230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10231
10232         local s
10233         local discard
10234         local nreads=10000
10235         local cache_limit=32
10236
10237         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10238         trap cleanup_101a EXIT
10239         $LCTL set_param -n llite.*.read_ahead_stats=0
10240         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10241
10242         #
10243         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10244         #
10245         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10246         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10247
10248         discard=0
10249         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10250                    get_named_value 'read.but.discarded'); do
10251                         discard=$(($discard + $s))
10252         done
10253         cleanup_101a
10254
10255         $LCTL get_param osc.*-osc*.rpc_stats
10256         $LCTL get_param llite.*.read_ahead_stats
10257
10258         # Discard is generally zero, but sometimes a few random reads line up
10259         # and trigger larger readahead, which is wasted & leads to discards.
10260         if [[ $(($discard)) -gt $nreads ]]; then
10261                 error "too many ($discard) discarded pages"
10262         fi
10263         rm -f $DIR/$tfile || true
10264 }
10265 run_test 101a "check read-ahead for random reads"
10266
10267 setup_test101bc() {
10268         test_mkdir $DIR/$tdir
10269         local ssize=$1
10270         local FILE_LENGTH=$2
10271         STRIPE_OFFSET=0
10272
10273         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10274
10275         local list=$(comma_list $(osts_nodes))
10276         set_osd_param $list '' read_cache_enable 0
10277         set_osd_param $list '' writethrough_cache_enable 0
10278
10279         trap cleanup_test101bc EXIT
10280         # prepare the read-ahead file
10281         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10282
10283         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10284                                 count=$FILE_SIZE_MB 2> /dev/null
10285
10286 }
10287
10288 cleanup_test101bc() {
10289         trap 0
10290         rm -rf $DIR/$tdir
10291         rm -f $DIR/$tfile
10292
10293         local list=$(comma_list $(osts_nodes))
10294         set_osd_param $list '' read_cache_enable 1
10295         set_osd_param $list '' writethrough_cache_enable 1
10296 }
10297
10298 calc_total() {
10299         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10300 }
10301
10302 ra_check_101() {
10303         local READ_SIZE=$1
10304         local STRIPE_SIZE=$2
10305         local FILE_LENGTH=$3
10306         local RA_INC=1048576
10307         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10308         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10309                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10310         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10311                   get_named_value 'read.but.discarded' | calc_total)
10312         if [[ $DISCARD -gt $discard_limit ]]; then
10313                 $LCTL get_param llite.*.read_ahead_stats
10314                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10315         else
10316                 echo "Read-ahead success for size ${READ_SIZE}"
10317         fi
10318 }
10319
10320 test_101b() {
10321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10322         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10323
10324         local STRIPE_SIZE=1048576
10325         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10326
10327         if [ $SLOW == "yes" ]; then
10328                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10329         else
10330                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10331         fi
10332
10333         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10334
10335         # prepare the read-ahead file
10336         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10337         cancel_lru_locks osc
10338         for BIDX in 2 4 8 16 32 64 128 256
10339         do
10340                 local BSIZE=$((BIDX*4096))
10341                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10342                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10343                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10344                 $LCTL set_param -n llite.*.read_ahead_stats=0
10345                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10346                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10347                 cancel_lru_locks osc
10348                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10349         done
10350         cleanup_test101bc
10351         true
10352 }
10353 run_test 101b "check stride-io mode read-ahead ================="
10354
10355 test_101c() {
10356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10357
10358         local STRIPE_SIZE=1048576
10359         local FILE_LENGTH=$((STRIPE_SIZE*100))
10360         local nreads=10000
10361         local rsize=65536
10362         local osc_rpc_stats
10363
10364         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10365
10366         cancel_lru_locks osc
10367         $LCTL set_param osc.*.rpc_stats=0
10368         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10369         $LCTL get_param osc.*.rpc_stats
10370         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10371                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10372                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10373                 local size
10374
10375                 if [ $lines -le 20 ]; then
10376                         echo "continue debug"
10377                         continue
10378                 fi
10379                 for size in 1 2 4 8; do
10380                         local rpc=$(echo "$stats" |
10381                                     awk '($1 == "'$size':") {print $2; exit; }')
10382                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10383                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10384                 done
10385                 echo "$osc_rpc_stats check passed!"
10386         done
10387         cleanup_test101bc
10388         true
10389 }
10390 run_test 101c "check stripe_size aligned read-ahead"
10391
10392 test_101d() {
10393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10394
10395         local file=$DIR/$tfile
10396         local sz_MB=${FILESIZE_101d:-80}
10397         local ra_MB=${READAHEAD_MB:-40}
10398
10399         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10400         [ $free_MB -lt $sz_MB ] &&
10401                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10402
10403         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10404         $LFS setstripe -c -1 $file || error "setstripe failed"
10405
10406         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10407         echo Cancel LRU locks on lustre client to flush the client cache
10408         cancel_lru_locks osc
10409
10410         echo Disable read-ahead
10411         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10412         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10413         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10414         $LCTL get_param -n llite.*.max_read_ahead_mb
10415
10416         echo "Reading the test file $file with read-ahead disabled"
10417         local sz_KB=$((sz_MB * 1024 / 4))
10418         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10419         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10420         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10421                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10422
10423         echo "Cancel LRU locks on lustre client to flush the client cache"
10424         cancel_lru_locks osc
10425         echo Enable read-ahead with ${ra_MB}MB
10426         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10427
10428         echo "Reading the test file $file with read-ahead enabled"
10429         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10430                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10431
10432         echo "read-ahead disabled time read $raOFF"
10433         echo "read-ahead enabled time read $raON"
10434
10435         rm -f $file
10436         wait_delete_completed
10437
10438         # use awk for this check instead of bash because it handles decimals
10439         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10440                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10441 }
10442 run_test 101d "file read with and without read-ahead enabled"
10443
10444 test_101e() {
10445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10446
10447         local file=$DIR/$tfile
10448         local size_KB=500  #KB
10449         local count=100
10450         local bsize=1024
10451
10452         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10453         local need_KB=$((count * size_KB))
10454         [[ $free_KB -le $need_KB ]] &&
10455                 skip_env "Need free space $need_KB, have $free_KB"
10456
10457         echo "Creating $count ${size_KB}K test files"
10458         for ((i = 0; i < $count; i++)); do
10459                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10460         done
10461
10462         echo "Cancel LRU locks on lustre client to flush the client cache"
10463         cancel_lru_locks $OSC
10464
10465         echo "Reset readahead stats"
10466         $LCTL set_param -n llite.*.read_ahead_stats=0
10467
10468         for ((i = 0; i < $count; i++)); do
10469                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10470         done
10471
10472         $LCTL get_param llite.*.max_cached_mb
10473         $LCTL get_param llite.*.read_ahead_stats
10474         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10475                      get_named_value 'misses' | calc_total)
10476
10477         for ((i = 0; i < $count; i++)); do
10478                 rm -rf $file.$i 2>/dev/null
10479         done
10480
10481         #10000 means 20% reads are missing in readahead
10482         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10483 }
10484 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10485
10486 test_101f() {
10487         which iozone || skip_env "no iozone installed"
10488
10489         local old_debug=$($LCTL get_param debug)
10490         old_debug=${old_debug#*=}
10491         $LCTL set_param debug="reada mmap"
10492
10493         # create a test file
10494         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10495
10496         echo Cancel LRU locks on lustre client to flush the client cache
10497         cancel_lru_locks osc
10498
10499         echo Reset readahead stats
10500         $LCTL set_param -n llite.*.read_ahead_stats=0
10501
10502         echo mmap read the file with small block size
10503         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10504                 > /dev/null 2>&1
10505
10506         echo checking missing pages
10507         $LCTL get_param llite.*.read_ahead_stats
10508         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10509                         get_named_value 'misses' | calc_total)
10510
10511         $LCTL set_param debug="$old_debug"
10512         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10513         rm -f $DIR/$tfile
10514 }
10515 run_test 101f "check mmap read performance"
10516
10517 test_101g_brw_size_test() {
10518         local mb=$1
10519         local pages=$((mb * 1048576 / PAGE_SIZE))
10520         local file=$DIR/$tfile
10521
10522         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10523                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10524         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10525                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10526                         return 2
10527         done
10528
10529         stack_trap "rm -f $file" EXIT
10530         $LCTL set_param -n osc.*.rpc_stats=0
10531
10532         # 10 RPCs should be enough for the test
10533         local count=10
10534         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10535                 { error "dd write ${mb} MB blocks failed"; return 3; }
10536         cancel_lru_locks osc
10537         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10538                 { error "dd write ${mb} MB blocks failed"; return 4; }
10539
10540         # calculate number of full-sized read and write RPCs
10541         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10542                 sed -n '/pages per rpc/,/^$/p' |
10543                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10544                 END { print reads,writes }'))
10545         # allow one extra full-sized read RPC for async readahead
10546         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10547                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10548         [[ ${rpcs[1]} == $count ]] ||
10549                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10550 }
10551
10552 test_101g() {
10553         remote_ost_nodsh && skip "remote OST with nodsh"
10554
10555         local rpcs
10556         local osts=$(get_facets OST)
10557         local list=$(comma_list $(osts_nodes))
10558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10559         local brw_size="obdfilter.*.brw_size"
10560
10561         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10562
10563         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10564
10565         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10566                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10567                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10568            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10569                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10570                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10571
10572                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10573                         suffix="M"
10574
10575                 if [[ $orig_mb -lt 16 ]]; then
10576                         save_lustre_params $osts "$brw_size" > $p
10577                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10578                                 error "set 16MB RPC size failed"
10579
10580                         echo "remount client to enable new RPC size"
10581                         remount_client $MOUNT || error "remount_client failed"
10582                 fi
10583
10584                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10585                 # should be able to set brw_size=12, but no rpc_stats for that
10586                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10587         fi
10588
10589         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10590
10591         if [[ $orig_mb -lt 16 ]]; then
10592                 restore_lustre_params < $p
10593                 remount_client $MOUNT || error "remount_client restore failed"
10594         fi
10595
10596         rm -f $p $DIR/$tfile
10597 }
10598 run_test 101g "Big bulk(4/16 MiB) readahead"
10599
10600 test_101h() {
10601         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10602
10603         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10604                 error "dd 70M file failed"
10605         echo Cancel LRU locks on lustre client to flush the client cache
10606         cancel_lru_locks osc
10607
10608         echo "Reset readahead stats"
10609         $LCTL set_param -n llite.*.read_ahead_stats 0
10610
10611         echo "Read 10M of data but cross 64M bundary"
10612         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10613         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10614                      get_named_value 'misses' | calc_total)
10615         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10616         rm -f $p $DIR/$tfile
10617 }
10618 run_test 101h "Readahead should cover current read window"
10619
10620 test_101i() {
10621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10622                 error "dd 10M file failed"
10623
10624         local max_per_file_mb=$($LCTL get_param -n \
10625                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10626         cancel_lru_locks osc
10627         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10628         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10629                 error "set max_read_ahead_per_file_mb to 1 failed"
10630
10631         echo "Reset readahead stats"
10632         $LCTL set_param llite.*.read_ahead_stats=0
10633
10634         dd if=$DIR/$tfile of=/dev/null bs=2M
10635
10636         $LCTL get_param llite.*.read_ahead_stats
10637         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10638                      awk '/misses/ { print $2 }')
10639         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10640         rm -f $DIR/$tfile
10641 }
10642 run_test 101i "allow current readahead to exceed reservation"
10643
10644 test_101j() {
10645         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10646                 error "setstripe $DIR/$tfile failed"
10647         local file_size=$((1048576 * 16))
10648         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10649         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10650
10651         echo Disable read-ahead
10652         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10653
10654         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10655         for blk in $PAGE_SIZE 1048576 $file_size; do
10656                 cancel_lru_locks osc
10657                 echo "Reset readahead stats"
10658                 $LCTL set_param -n llite.*.read_ahead_stats=0
10659                 local count=$(($file_size / $blk))
10660                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10661                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10662                              get_named_value 'failed.to.fast.read' | calc_total)
10663                 $LCTL get_param -n llite.*.read_ahead_stats
10664                 [ $miss -eq $count ] || error "expected $count got $miss"
10665         done
10666
10667         rm -f $p $DIR/$tfile
10668 }
10669 run_test 101j "A complete read block should be submitted when no RA"
10670
10671 setup_test102() {
10672         test_mkdir $DIR/$tdir
10673         chown $RUNAS_ID $DIR/$tdir
10674         STRIPE_SIZE=65536
10675         STRIPE_OFFSET=1
10676         STRIPE_COUNT=$OSTCOUNT
10677         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10678
10679         trap cleanup_test102 EXIT
10680         cd $DIR
10681         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10682         cd $DIR/$tdir
10683         for num in 1 2 3 4; do
10684                 for count in $(seq 1 $STRIPE_COUNT); do
10685                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10686                                 local size=`expr $STRIPE_SIZE \* $num`
10687                                 local file=file"$num-$idx-$count"
10688                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10689                         done
10690                 done
10691         done
10692
10693         cd $DIR
10694         $1 tar cf $TMP/f102.tar $tdir --xattrs
10695 }
10696
10697 cleanup_test102() {
10698         trap 0
10699         rm -f $TMP/f102.tar
10700         rm -rf $DIR/d0.sanity/d102
10701 }
10702
10703 test_102a() {
10704         [ "$UID" != 0 ] && skip "must run as root"
10705         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10706                 skip_env "must have user_xattr"
10707
10708         [ -z "$(which setfattr 2>/dev/null)" ] &&
10709                 skip_env "could not find setfattr"
10710
10711         local testfile=$DIR/$tfile
10712
10713         touch $testfile
10714         echo "set/get xattr..."
10715         setfattr -n trusted.name1 -v value1 $testfile ||
10716                 error "setfattr -n trusted.name1=value1 $testfile failed"
10717         getfattr -n trusted.name1 $testfile 2> /dev/null |
10718           grep "trusted.name1=.value1" ||
10719                 error "$testfile missing trusted.name1=value1"
10720
10721         setfattr -n user.author1 -v author1 $testfile ||
10722                 error "setfattr -n user.author1=author1 $testfile failed"
10723         getfattr -n user.author1 $testfile 2> /dev/null |
10724           grep "user.author1=.author1" ||
10725                 error "$testfile missing trusted.author1=author1"
10726
10727         echo "listxattr..."
10728         setfattr -n trusted.name2 -v value2 $testfile ||
10729                 error "$testfile unable to set trusted.name2"
10730         setfattr -n trusted.name3 -v value3 $testfile ||
10731                 error "$testfile unable to set trusted.name3"
10732         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10733             grep "trusted.name" | wc -l) -eq 3 ] ||
10734                 error "$testfile missing 3 trusted.name xattrs"
10735
10736         setfattr -n user.author2 -v author2 $testfile ||
10737                 error "$testfile unable to set user.author2"
10738         setfattr -n user.author3 -v author3 $testfile ||
10739                 error "$testfile unable to set user.author3"
10740         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10741             grep "user.author" | wc -l) -eq 3 ] ||
10742                 error "$testfile missing 3 user.author xattrs"
10743
10744         echo "remove xattr..."
10745         setfattr -x trusted.name1 $testfile ||
10746                 error "$testfile error deleting trusted.name1"
10747         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10748                 error "$testfile did not delete trusted.name1 xattr"
10749
10750         setfattr -x user.author1 $testfile ||
10751                 error "$testfile error deleting user.author1"
10752         echo "set lustre special xattr ..."
10753         $LFS setstripe -c1 $testfile
10754         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10755                 awk -F "=" '/trusted.lov/ { print $2 }' )
10756         setfattr -n "trusted.lov" -v $lovea $testfile ||
10757                 error "$testfile doesn't ignore setting trusted.lov again"
10758         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10759                 error "$testfile allow setting invalid trusted.lov"
10760         rm -f $testfile
10761 }
10762 run_test 102a "user xattr test =================================="
10763
10764 check_102b_layout() {
10765         local layout="$*"
10766         local testfile=$DIR/$tfile
10767
10768         echo "test layout '$layout'"
10769         $LFS setstripe $layout $testfile || error "setstripe failed"
10770         $LFS getstripe -y $testfile
10771
10772         echo "get/set/list trusted.lov xattr ..." # b=10930
10773         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10774         [[ "$value" =~ "trusted.lov" ]] ||
10775                 error "can't get trusted.lov from $testfile"
10776         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10777                 error "getstripe failed"
10778
10779         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10780
10781         value=$(cut -d= -f2 <<<$value)
10782         # LU-13168: truncated xattr should fail if short lov_user_md header
10783         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10784                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10785         for len in $lens; do
10786                 echo "setfattr $len $testfile.2"
10787                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10788                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10789         done
10790         local stripe_size=$($LFS getstripe -S $testfile.2)
10791         local stripe_count=$($LFS getstripe -c $testfile.2)
10792         [[ $stripe_size -eq 65536 ]] ||
10793                 error "stripe size $stripe_size != 65536"
10794         [[ $stripe_count -eq $stripe_count_orig ]] ||
10795                 error "stripe count $stripe_count != $stripe_count_orig"
10796         rm $testfile $testfile.2
10797 }
10798
10799 test_102b() {
10800         [ -z "$(which setfattr 2>/dev/null)" ] &&
10801                 skip_env "could not find setfattr"
10802         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10803
10804         # check plain layout
10805         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10806
10807         # and also check composite layout
10808         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10809
10810 }
10811 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10812
10813 test_102c() {
10814         [ -z "$(which setfattr 2>/dev/null)" ] &&
10815                 skip_env "could not find setfattr"
10816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10817
10818         # b10930: get/set/list lustre.lov xattr
10819         echo "get/set/list lustre.lov xattr ..."
10820         test_mkdir $DIR/$tdir
10821         chown $RUNAS_ID $DIR/$tdir
10822         local testfile=$DIR/$tdir/$tfile
10823         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10824                 error "setstripe failed"
10825         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10826                 error "getstripe failed"
10827         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10828         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10829
10830         local testfile2=${testfile}2
10831         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10832                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10833
10834         $RUNAS $MCREATE $testfile2
10835         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10836         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10837         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10838         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10839         [ $stripe_count -eq $STRIPECOUNT ] ||
10840                 error "stripe count $stripe_count != $STRIPECOUNT"
10841 }
10842 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10843
10844 compare_stripe_info1() {
10845         local stripe_index_all_zero=true
10846
10847         for num in 1 2 3 4; do
10848                 for count in $(seq 1 $STRIPE_COUNT); do
10849                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10850                                 local size=$((STRIPE_SIZE * num))
10851                                 local file=file"$num-$offset-$count"
10852                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10853                                 [[ $stripe_size -ne $size ]] &&
10854                                     error "$file: size $stripe_size != $size"
10855                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10856                                 # allow fewer stripes to be created, ORI-601
10857                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10858                                     error "$file: count $stripe_count != $count"
10859                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10860                                 [[ $stripe_index -ne 0 ]] &&
10861                                         stripe_index_all_zero=false
10862                         done
10863                 done
10864         done
10865         $stripe_index_all_zero &&
10866                 error "all files are being extracted starting from OST index 0"
10867         return 0
10868 }
10869
10870 have_xattrs_include() {
10871         tar --help | grep -q xattrs-include &&
10872                 echo --xattrs-include="lustre.*"
10873 }
10874
10875 test_102d() {
10876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10877         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10878
10879         XINC=$(have_xattrs_include)
10880         setup_test102
10881         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10882         cd $DIR/$tdir/$tdir
10883         compare_stripe_info1
10884 }
10885 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10886
10887 test_102f() {
10888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10890
10891         XINC=$(have_xattrs_include)
10892         setup_test102
10893         test_mkdir $DIR/$tdir.restore
10894         cd $DIR
10895         tar cf - --xattrs $tdir | tar xf - \
10896                 -C $DIR/$tdir.restore --xattrs $XINC
10897         cd $DIR/$tdir.restore/$tdir
10898         compare_stripe_info1
10899 }
10900 run_test 102f "tar copy files, not keep osts"
10901
10902 grow_xattr() {
10903         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10904                 skip "must have user_xattr"
10905         [ -z "$(which setfattr 2>/dev/null)" ] &&
10906                 skip_env "could not find setfattr"
10907         [ -z "$(which getfattr 2>/dev/null)" ] &&
10908                 skip_env "could not find getfattr"
10909
10910         local xsize=${1:-1024}  # in bytes
10911         local file=$DIR/$tfile
10912         local value="$(generate_string $xsize)"
10913         local xbig=trusted.big
10914         local toobig=$2
10915
10916         touch $file
10917         log "save $xbig on $file"
10918         if [ -z "$toobig" ]
10919         then
10920                 setfattr -n $xbig -v $value $file ||
10921                         error "saving $xbig on $file failed"
10922         else
10923                 setfattr -n $xbig -v $value $file &&
10924                         error "saving $xbig on $file succeeded"
10925                 return 0
10926         fi
10927
10928         local orig=$(get_xattr_value $xbig $file)
10929         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10930
10931         local xsml=trusted.sml
10932         log "save $xsml on $file"
10933         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10934
10935         local new=$(get_xattr_value $xbig $file)
10936         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10937
10938         log "grow $xsml on $file"
10939         setfattr -n $xsml -v "$value" $file ||
10940                 error "growing $xsml on $file failed"
10941
10942         new=$(get_xattr_value $xbig $file)
10943         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10944         log "$xbig still valid after growing $xsml"
10945
10946         rm -f $file
10947 }
10948
10949 test_102h() { # bug 15777
10950         grow_xattr 1024
10951 }
10952 run_test 102h "grow xattr from inside inode to external block"
10953
10954 test_102ha() {
10955         large_xattr_enabled || skip_env "ea_inode feature disabled"
10956
10957         echo "setting xattr of max xattr size: $(max_xattr_size)"
10958         grow_xattr $(max_xattr_size)
10959
10960         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10961         echo "This should fail:"
10962         grow_xattr $(($(max_xattr_size) + 10)) 1
10963 }
10964 run_test 102ha "grow xattr from inside inode to external inode"
10965
10966 test_102i() { # bug 17038
10967         [ -z "$(which getfattr 2>/dev/null)" ] &&
10968                 skip "could not find getfattr"
10969
10970         touch $DIR/$tfile
10971         ln -s $DIR/$tfile $DIR/${tfile}link
10972         getfattr -n trusted.lov $DIR/$tfile ||
10973                 error "lgetxattr on $DIR/$tfile failed"
10974         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10975                 grep -i "no such attr" ||
10976                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10977         rm -f $DIR/$tfile $DIR/${tfile}link
10978 }
10979 run_test 102i "lgetxattr test on symbolic link ============"
10980
10981 test_102j() {
10982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10984
10985         XINC=$(have_xattrs_include)
10986         setup_test102 "$RUNAS"
10987         chown $RUNAS_ID $DIR/$tdir
10988         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10989         cd $DIR/$tdir/$tdir
10990         compare_stripe_info1 "$RUNAS"
10991 }
10992 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10993
10994 test_102k() {
10995         [ -z "$(which setfattr 2>/dev/null)" ] &&
10996                 skip "could not find setfattr"
10997
10998         touch $DIR/$tfile
10999         # b22187 just check that does not crash for regular file.
11000         setfattr -n trusted.lov $DIR/$tfile
11001         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11002         local test_kdir=$DIR/$tdir
11003         test_mkdir $test_kdir
11004         local default_size=$($LFS getstripe -S $test_kdir)
11005         local default_count=$($LFS getstripe -c $test_kdir)
11006         local default_offset=$($LFS getstripe -i $test_kdir)
11007         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11008                 error 'dir setstripe failed'
11009         setfattr -n trusted.lov $test_kdir
11010         local stripe_size=$($LFS getstripe -S $test_kdir)
11011         local stripe_count=$($LFS getstripe -c $test_kdir)
11012         local stripe_offset=$($LFS getstripe -i $test_kdir)
11013         [ $stripe_size -eq $default_size ] ||
11014                 error "stripe size $stripe_size != $default_size"
11015         [ $stripe_count -eq $default_count ] ||
11016                 error "stripe count $stripe_count != $default_count"
11017         [ $stripe_offset -eq $default_offset ] ||
11018                 error "stripe offset $stripe_offset != $default_offset"
11019         rm -rf $DIR/$tfile $test_kdir
11020 }
11021 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11022
11023 test_102l() {
11024         [ -z "$(which getfattr 2>/dev/null)" ] &&
11025                 skip "could not find getfattr"
11026
11027         # LU-532 trusted. xattr is invisible to non-root
11028         local testfile=$DIR/$tfile
11029
11030         touch $testfile
11031
11032         echo "listxattr as user..."
11033         chown $RUNAS_ID $testfile
11034         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11035             grep -q "trusted" &&
11036                 error "$testfile trusted xattrs are user visible"
11037
11038         return 0;
11039 }
11040 run_test 102l "listxattr size test =================================="
11041
11042 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11043         local path=$DIR/$tfile
11044         touch $path
11045
11046         listxattr_size_check $path || error "listattr_size_check $path failed"
11047 }
11048 run_test 102m "Ensure listxattr fails on small bufffer ========"
11049
11050 cleanup_test102
11051
11052 getxattr() { # getxattr path name
11053         # Return the base64 encoding of the value of xattr name on path.
11054         local path=$1
11055         local name=$2
11056
11057         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11058         # file: $path
11059         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11060         #
11061         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11062
11063         getfattr --absolute-names --encoding=base64 --name=$name $path |
11064                 awk -F= -v name=$name '$1 == name {
11065                         print substr($0, index($0, "=") + 1);
11066         }'
11067 }
11068
11069 test_102n() { # LU-4101 mdt: protect internal xattrs
11070         [ -z "$(which setfattr 2>/dev/null)" ] &&
11071                 skip "could not find setfattr"
11072         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11073         then
11074                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11075         fi
11076
11077         local file0=$DIR/$tfile.0
11078         local file1=$DIR/$tfile.1
11079         local xattr0=$TMP/$tfile.0
11080         local xattr1=$TMP/$tfile.1
11081         local namelist="lov lma lmv link fid version som hsm"
11082         local name
11083         local value
11084
11085         rm -rf $file0 $file1 $xattr0 $xattr1
11086         touch $file0 $file1
11087
11088         # Get 'before' xattrs of $file1.
11089         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11090
11091         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11092                 namelist+=" lfsck_namespace"
11093         for name in $namelist; do
11094                 # Try to copy xattr from $file0 to $file1.
11095                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11096
11097                 setfattr --name=trusted.$name --value="$value" $file1 ||
11098                         error "setxattr 'trusted.$name' failed"
11099
11100                 # Try to set a garbage xattr.
11101                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11102
11103                 if [[ x$name == "xlov" ]]; then
11104                         setfattr --name=trusted.lov --value="$value" $file1 &&
11105                         error "setxattr invalid 'trusted.lov' success"
11106                 else
11107                         setfattr --name=trusted.$name --value="$value" $file1 ||
11108                                 error "setxattr invalid 'trusted.$name' failed"
11109                 fi
11110
11111                 # Try to remove the xattr from $file1. We don't care if this
11112                 # appears to succeed or fail, we just don't want there to be
11113                 # any changes or crashes.
11114                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11115         done
11116
11117         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11118         then
11119                 name="lfsck_ns"
11120                 # Try to copy xattr from $file0 to $file1.
11121                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11122
11123                 setfattr --name=trusted.$name --value="$value" $file1 ||
11124                         error "setxattr 'trusted.$name' failed"
11125
11126                 # Try to set a garbage xattr.
11127                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11128
11129                 setfattr --name=trusted.$name --value="$value" $file1 ||
11130                         error "setxattr 'trusted.$name' failed"
11131
11132                 # Try to remove the xattr from $file1. We don't care if this
11133                 # appears to succeed or fail, we just don't want there to be
11134                 # any changes or crashes.
11135                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11136         fi
11137
11138         # Get 'after' xattrs of file1.
11139         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11140
11141         if ! diff $xattr0 $xattr1; then
11142                 error "before and after xattrs of '$file1' differ"
11143         fi
11144
11145         rm -rf $file0 $file1 $xattr0 $xattr1
11146
11147         return 0
11148 }
11149 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11150
11151 test_102p() { # LU-4703 setxattr did not check ownership
11152         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11153                 skip "MDS needs to be at least 2.5.56"
11154
11155         local testfile=$DIR/$tfile
11156
11157         touch $testfile
11158
11159         echo "setfacl as user..."
11160         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11161         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11162
11163         echo "setfattr as user..."
11164         setfacl -m "u:$RUNAS_ID:---" $testfile
11165         $RUNAS setfattr -x system.posix_acl_access $testfile
11166         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11167 }
11168 run_test 102p "check setxattr(2) correctly fails without permission"
11169
11170 test_102q() {
11171         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11172                 skip "MDS needs to be at least 2.6.92"
11173
11174         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11175 }
11176 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11177
11178 test_102r() {
11179         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11180                 skip "MDS needs to be at least 2.6.93"
11181
11182         touch $DIR/$tfile || error "touch"
11183         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11184         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11185         rm $DIR/$tfile || error "rm"
11186
11187         #normal directory
11188         mkdir -p $DIR/$tdir || error "mkdir"
11189         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11190         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11191         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11192                 error "$testfile error deleting user.author1"
11193         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11194                 grep "user.$(basename $tdir)" &&
11195                 error "$tdir did not delete user.$(basename $tdir)"
11196         rmdir $DIR/$tdir || error "rmdir"
11197
11198         #striped directory
11199         test_mkdir $DIR/$tdir
11200         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11201         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11202         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11203                 error "$testfile error deleting user.author1"
11204         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11205                 grep "user.$(basename $tdir)" &&
11206                 error "$tdir did not delete user.$(basename $tdir)"
11207         rmdir $DIR/$tdir || error "rm striped dir"
11208 }
11209 run_test 102r "set EAs with empty values"
11210
11211 test_102s() {
11212         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11213                 skip "MDS needs to be at least 2.11.52"
11214
11215         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11216
11217         save_lustre_params client "llite.*.xattr_cache" > $save
11218
11219         for cache in 0 1; do
11220                 lctl set_param llite.*.xattr_cache=$cache
11221
11222                 rm -f $DIR/$tfile
11223                 touch $DIR/$tfile || error "touch"
11224                 for prefix in lustre security system trusted user; do
11225                         # Note getxattr() may fail with 'Operation not
11226                         # supported' or 'No such attribute' depending
11227                         # on prefix and cache.
11228                         getfattr -n $prefix.n102s $DIR/$tfile &&
11229                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11230                 done
11231         done
11232
11233         restore_lustre_params < $save
11234 }
11235 run_test 102s "getting nonexistent xattrs should fail"
11236
11237 test_102t() {
11238         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11239                 skip "MDS needs to be at least 2.11.52"
11240
11241         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11242
11243         save_lustre_params client "llite.*.xattr_cache" > $save
11244
11245         for cache in 0 1; do
11246                 lctl set_param llite.*.xattr_cache=$cache
11247
11248                 for buf_size in 0 256; do
11249                         rm -f $DIR/$tfile
11250                         touch $DIR/$tfile || error "touch"
11251                         setfattr -n user.multiop $DIR/$tfile
11252                         $MULTIOP $DIR/$tfile oa$buf_size ||
11253                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11254                 done
11255         done
11256
11257         restore_lustre_params < $save
11258 }
11259 run_test 102t "zero length xattr values handled correctly"
11260
11261 run_acl_subtest()
11262 {
11263     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11264     return $?
11265 }
11266
11267 test_103a() {
11268         [ "$UID" != 0 ] && skip "must run as root"
11269         $GSS && skip_env "could not run under gss"
11270         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11271                 skip_env "must have acl enabled"
11272         [ -z "$(which setfacl 2>/dev/null)" ] &&
11273                 skip_env "could not find setfacl"
11274         remote_mds_nodsh && skip "remote MDS with nodsh"
11275
11276         gpasswd -a daemon bin                           # LU-5641
11277         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11278
11279         declare -a identity_old
11280
11281         for num in $(seq $MDSCOUNT); do
11282                 switch_identity $num true || identity_old[$num]=$?
11283         done
11284
11285         SAVE_UMASK=$(umask)
11286         umask 0022
11287         mkdir -p $DIR/$tdir
11288         cd $DIR/$tdir
11289
11290         echo "performing cp ..."
11291         run_acl_subtest cp || error "run_acl_subtest cp failed"
11292         echo "performing getfacl-noacl..."
11293         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11294         echo "performing misc..."
11295         run_acl_subtest misc || error  "misc test failed"
11296         echo "performing permissions..."
11297         run_acl_subtest permissions || error "permissions failed"
11298         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11299         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11300                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11301                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11302         then
11303                 echo "performing permissions xattr..."
11304                 run_acl_subtest permissions_xattr ||
11305                         error "permissions_xattr failed"
11306         fi
11307         echo "performing setfacl..."
11308         run_acl_subtest setfacl || error  "setfacl test failed"
11309
11310         # inheritance test got from HP
11311         echo "performing inheritance..."
11312         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11313         chmod +x make-tree || error "chmod +x failed"
11314         run_acl_subtest inheritance || error "inheritance test failed"
11315         rm -f make-tree
11316
11317         echo "LU-974 ignore umask when acl is enabled..."
11318         run_acl_subtest 974 || error "LU-974 umask test failed"
11319         if [ $MDSCOUNT -ge 2 ]; then
11320                 run_acl_subtest 974_remote ||
11321                         error "LU-974 umask test failed under remote dir"
11322         fi
11323
11324         echo "LU-2561 newly created file is same size as directory..."
11325         if [ "$mds1_FSTYPE" != "zfs" ]; then
11326                 run_acl_subtest 2561 || error "LU-2561 test failed"
11327         else
11328                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11329         fi
11330
11331         run_acl_subtest 4924 || error "LU-4924 test failed"
11332
11333         cd $SAVE_PWD
11334         umask $SAVE_UMASK
11335
11336         for num in $(seq $MDSCOUNT); do
11337                 if [ "${identity_old[$num]}" = 1 ]; then
11338                         switch_identity $num false || identity_old[$num]=$?
11339                 fi
11340         done
11341 }
11342 run_test 103a "acl test"
11343
11344 test_103b() {
11345         declare -a pids
11346         local U
11347
11348         for U in {0..511}; do
11349                 {
11350                 local O=$(printf "%04o" $U)
11351
11352                 umask $(printf "%04o" $((511 ^ $O)))
11353                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11354                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11355
11356                 (( $S == ($O & 0666) )) ||
11357                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11358
11359                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11360                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11361                 (( $S == ($O & 0666) )) ||
11362                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11363
11364                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11365                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11366                 (( $S == ($O & 0666) )) ||
11367                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11368                 rm -f $DIR/$tfile.[smp]$0
11369                 } &
11370                 local pid=$!
11371
11372                 # limit the concurrently running threads to 64. LU-11878
11373                 local idx=$((U % 64))
11374                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11375                 pids[idx]=$pid
11376         done
11377         wait
11378 }
11379 run_test 103b "umask lfs setstripe"
11380
11381 test_103c() {
11382         mkdir -p $DIR/$tdir
11383         cp -rp $DIR/$tdir $DIR/$tdir.bak
11384
11385         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11386                 error "$DIR/$tdir shouldn't contain default ACL"
11387         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11388                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11389         true
11390 }
11391 run_test 103c "'cp -rp' won't set empty acl"
11392
11393 test_103e() {
11394         local numacl
11395         local fileacl
11396         local saved_debug=$($LCTL get_param -n debug)
11397
11398         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11399                 skip "MDS needs to be at least 2.14.0"
11400
11401         large_xattr_enabled || skip_env "ea_inode feature disabled"
11402
11403         mkdir -p $DIR/$tdir
11404         # add big LOV EA to cause reply buffer overflow earlier
11405         $LFS setstripe -C 1000 $DIR/$tdir
11406         lctl set_param mdc.*-mdc*.stats=clear
11407
11408         $LCTL set_param debug=0
11409         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11410         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11411
11412         # add a large number of default ACLs (expect 8000+ for 2.13+)
11413         for U in {2..7000}; do
11414                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11415                         error "Able to add just $U default ACLs"
11416         done
11417         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11418         echo "$numacl default ACLs created"
11419
11420         stat $DIR/$tdir || error "Cannot stat directory"
11421         # check file creation
11422         touch $DIR/$tdir/$tfile ||
11423                 error "failed to create $tfile with $numacl default ACLs"
11424         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11425         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11426         echo "$fileacl ACLs were inherited"
11427         (( $fileacl == $numacl )) ||
11428                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11429         # check that new ACLs creation adds new ACLs to inherited ACLs
11430         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11431                 error "Cannot set new ACL"
11432         numacl=$((numacl + 1))
11433         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11434         (( $fileacl == $numacl )) ||
11435                 error "failed to add new ACL: $fileacl != $numacl as expected"
11436         # adds more ACLs to a file to reach their maximum at 8000+
11437         numacl=0
11438         for U in {20000..25000}; do
11439                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11440                 numacl=$((numacl + 1))
11441         done
11442         echo "Added $numacl more ACLs to the file"
11443         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11444         echo "Total $fileacl ACLs in file"
11445         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11446         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11447         rmdir $DIR/$tdir || error "Cannot remove directory"
11448 }
11449 run_test 103e "inheritance of big amount of default ACLs"
11450
11451 test_103f() {
11452         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11453                 skip "MDS needs to be at least 2.14.51"
11454
11455         large_xattr_enabled || skip_env "ea_inode feature disabled"
11456
11457         # enable changelog to consume more internal MDD buffers
11458         changelog_register
11459
11460         mkdir -p $DIR/$tdir
11461         # add big LOV EA
11462         $LFS setstripe -C 1000 $DIR/$tdir
11463         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11464         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11465         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11466         rmdir $DIR/$tdir || error "Cannot remove directory"
11467 }
11468 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11469
11470 test_104a() {
11471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11472
11473         touch $DIR/$tfile
11474         lfs df || error "lfs df failed"
11475         lfs df -ih || error "lfs df -ih failed"
11476         lfs df -h $DIR || error "lfs df -h $DIR failed"
11477         lfs df -i $DIR || error "lfs df -i $DIR failed"
11478         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11479         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11480
11481         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11482         lctl --device %$OSC deactivate
11483         lfs df || error "lfs df with deactivated OSC failed"
11484         lctl --device %$OSC activate
11485         # wait the osc back to normal
11486         wait_osc_import_ready client ost
11487
11488         lfs df || error "lfs df with reactivated OSC failed"
11489         rm -f $DIR/$tfile
11490 }
11491 run_test 104a "lfs df [-ih] [path] test ========================="
11492
11493 test_104b() {
11494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11495         [ $RUNAS_ID -eq $UID ] &&
11496                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11497
11498         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11499                         grep "Permission denied" | wc -l)))
11500         if [ $denied_cnt -ne 0 ]; then
11501                 error "lfs check servers test failed"
11502         fi
11503 }
11504 run_test 104b "$RUNAS lfs check servers test ===================="
11505
11506 #
11507 # Verify $1 is within range of $2.
11508 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11509 # $1 is <= 2% of $2. Else Fail.
11510 #
11511 value_in_range() {
11512         # Strip all units (M, G, T)
11513         actual=$(echo $1 | tr -d A-Z)
11514         expect=$(echo $2 | tr -d A-Z)
11515
11516         expect_lo=$(($expect * 98 / 100)) # 2% below
11517         expect_hi=$(($expect * 102 / 100)) # 2% above
11518
11519         # permit 2% drift above and below
11520         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11521 }
11522
11523 test_104c() {
11524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11525         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11526
11527         local ost_param="osd-zfs.$FSNAME-OST0000."
11528         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11529         local ofacets=$(get_facets OST)
11530         local mfacets=$(get_facets MDS)
11531         local saved_ost_blocks=
11532         local saved_mdt_blocks=
11533
11534         echo "Before recordsize change"
11535         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11536         df=($(df -h | grep "/mnt/lustre"$))
11537
11538         # For checking.
11539         echo "lfs output : ${lfs_df[*]}"
11540         echo "df  output : ${df[*]}"
11541
11542         for facet in ${ofacets//,/ }; do
11543                 if [ -z $saved_ost_blocks ]; then
11544                         saved_ost_blocks=$(do_facet $facet \
11545                                 lctl get_param -n $ost_param.blocksize)
11546                         echo "OST Blocksize: $saved_ost_blocks"
11547                 fi
11548                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11549                 do_facet $facet zfs set recordsize=32768 $ost
11550         done
11551
11552         # BS too small. Sufficient for functional testing.
11553         for facet in ${mfacets//,/ }; do
11554                 if [ -z $saved_mdt_blocks ]; then
11555                         saved_mdt_blocks=$(do_facet $facet \
11556                                 lctl get_param -n $mdt_param.blocksize)
11557                         echo "MDT Blocksize: $saved_mdt_blocks"
11558                 fi
11559                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11560                 do_facet $facet zfs set recordsize=32768 $mdt
11561         done
11562
11563         # Give new values chance to reflect change
11564         sleep 2
11565
11566         echo "After recordsize change"
11567         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11568         df_after=($(df -h | grep "/mnt/lustre"$))
11569
11570         # For checking.
11571         echo "lfs output : ${lfs_df_after[*]}"
11572         echo "df  output : ${df_after[*]}"
11573
11574         # Verify lfs df
11575         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11576                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11577         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11578                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11579         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11580                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11581
11582         # Verify df
11583         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11584                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11585         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11586                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11587         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11588                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11589
11590         # Restore MDT recordize back to original
11591         for facet in ${mfacets//,/ }; do
11592                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11593                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11594         done
11595
11596         # Restore OST recordize back to original
11597         for facet in ${ofacets//,/ }; do
11598                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11599                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11600         done
11601
11602         return 0
11603 }
11604 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11605
11606 test_105a() {
11607         # doesn't work on 2.4 kernels
11608         touch $DIR/$tfile
11609         if $(flock_is_enabled); then
11610                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11611         else
11612                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11613         fi
11614         rm -f $DIR/$tfile
11615 }
11616 run_test 105a "flock when mounted without -o flock test ========"
11617
11618 test_105b() {
11619         touch $DIR/$tfile
11620         if $(flock_is_enabled); then
11621                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11622         else
11623                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11624         fi
11625         rm -f $DIR/$tfile
11626 }
11627 run_test 105b "fcntl when mounted without -o flock test ========"
11628
11629 test_105c() {
11630         touch $DIR/$tfile
11631         if $(flock_is_enabled); then
11632                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11633         else
11634                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11635         fi
11636         rm -f $DIR/$tfile
11637 }
11638 run_test 105c "lockf when mounted without -o flock test"
11639
11640 test_105d() { # bug 15924
11641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11642
11643         test_mkdir $DIR/$tdir
11644         flock_is_enabled || skip_env "mount w/o flock enabled"
11645         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11646         $LCTL set_param fail_loc=0x80000315
11647         flocks_test 2 $DIR/$tdir
11648 }
11649 run_test 105d "flock race (should not freeze) ========"
11650
11651 test_105e() { # bug 22660 && 22040
11652         flock_is_enabled || skip_env "mount w/o flock enabled"
11653
11654         touch $DIR/$tfile
11655         flocks_test 3 $DIR/$tfile
11656 }
11657 run_test 105e "Two conflicting flocks from same process"
11658
11659 test_106() { #bug 10921
11660         test_mkdir $DIR/$tdir
11661         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11662         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11663 }
11664 run_test 106 "attempt exec of dir followed by chown of that dir"
11665
11666 test_107() {
11667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11668
11669         CDIR=`pwd`
11670         local file=core
11671
11672         cd $DIR
11673         rm -f $file
11674
11675         local save_pattern=$(sysctl -n kernel.core_pattern)
11676         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11677         sysctl -w kernel.core_pattern=$file
11678         sysctl -w kernel.core_uses_pid=0
11679
11680         ulimit -c unlimited
11681         sleep 60 &
11682         SLEEPPID=$!
11683
11684         sleep 1
11685
11686         kill -s 11 $SLEEPPID
11687         wait $SLEEPPID
11688         if [ -e $file ]; then
11689                 size=`stat -c%s $file`
11690                 [ $size -eq 0 ] && error "Fail to create core file $file"
11691         else
11692                 error "Fail to create core file $file"
11693         fi
11694         rm -f $file
11695         sysctl -w kernel.core_pattern=$save_pattern
11696         sysctl -w kernel.core_uses_pid=$save_uses_pid
11697         cd $CDIR
11698 }
11699 run_test 107 "Coredump on SIG"
11700
11701 test_110() {
11702         test_mkdir $DIR/$tdir
11703         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11704         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11705                 error "mkdir with 256 char should fail, but did not"
11706         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11707                 error "create with 255 char failed"
11708         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11709                 error "create with 256 char should fail, but did not"
11710
11711         ls -l $DIR/$tdir
11712         rm -rf $DIR/$tdir
11713 }
11714 run_test 110 "filename length checking"
11715
11716 #
11717 # Purpose: To verify dynamic thread (OSS) creation.
11718 #
11719 test_115() {
11720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11721         remote_ost_nodsh && skip "remote OST with nodsh"
11722
11723         # Lustre does not stop service threads once they are started.
11724         # Reset number of running threads to default.
11725         stopall
11726         setupall
11727
11728         local OSTIO_pre
11729         local save_params="$TMP/sanity-$TESTNAME.parameters"
11730
11731         # Get ll_ost_io count before I/O
11732         OSTIO_pre=$(do_facet ost1 \
11733                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11734         # Exit if lustre is not running (ll_ost_io not running).
11735         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11736
11737         echo "Starting with $OSTIO_pre threads"
11738         local thread_max=$((OSTIO_pre * 2))
11739         local rpc_in_flight=$((thread_max * 2))
11740         # Number of I/O Process proposed to be started.
11741         local nfiles
11742         local facets=$(get_facets OST)
11743
11744         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11745         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11746
11747         # Set in_flight to $rpc_in_flight
11748         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11749                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11750         nfiles=${rpc_in_flight}
11751         # Set ost thread_max to $thread_max
11752         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11753
11754         # 5 Minutes should be sufficient for max number of OSS
11755         # threads(thread_max) to be created.
11756         local timeout=300
11757
11758         # Start I/O.
11759         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11760         test_mkdir $DIR/$tdir
11761         for i in $(seq $nfiles); do
11762                 local file=$DIR/$tdir/${tfile}-$i
11763                 $LFS setstripe -c -1 -i 0 $file
11764                 ($WTL $file $timeout)&
11765         done
11766
11767         # I/O Started - Wait for thread_started to reach thread_max or report
11768         # error if thread_started is more than thread_max.
11769         echo "Waiting for thread_started to reach thread_max"
11770         local thread_started=0
11771         local end_time=$((SECONDS + timeout))
11772
11773         while [ $SECONDS -le $end_time ] ; do
11774                 echo -n "."
11775                 # Get ost i/o thread_started count.
11776                 thread_started=$(do_facet ost1 \
11777                         "$LCTL get_param \
11778                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11779                 # Break out if thread_started is equal/greater than thread_max
11780                 if [[ $thread_started -ge $thread_max ]]; then
11781                         echo ll_ost_io thread_started $thread_started, \
11782                                 equal/greater than thread_max $thread_max
11783                         break
11784                 fi
11785                 sleep 1
11786         done
11787
11788         # Cleanup - We have the numbers, Kill i/o jobs if running.
11789         jobcount=($(jobs -p))
11790         for i in $(seq 0 $((${#jobcount[@]}-1)))
11791         do
11792                 kill -9 ${jobcount[$i]}
11793                 if [ $? -ne 0 ] ; then
11794                         echo Warning: \
11795                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11796                 fi
11797         done
11798
11799         # Cleanup files left by WTL binary.
11800         for i in $(seq $nfiles); do
11801                 local file=$DIR/$tdir/${tfile}-$i
11802                 rm -rf $file
11803                 if [ $? -ne 0 ] ; then
11804                         echo "Warning: Failed to delete file $file"
11805                 fi
11806         done
11807
11808         restore_lustre_params <$save_params
11809         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11810
11811         # Error out if no new thread has started or Thread started is greater
11812         # than thread max.
11813         if [[ $thread_started -le $OSTIO_pre ||
11814                         $thread_started -gt $thread_max ]]; then
11815                 error "ll_ost_io: thread_started $thread_started" \
11816                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11817                       "No new thread started or thread started greater " \
11818                       "than thread_max."
11819         fi
11820 }
11821 run_test 115 "verify dynamic thread creation===================="
11822
11823 free_min_max () {
11824         wait_delete_completed
11825         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11826         echo "OST kbytes available: ${AVAIL[@]}"
11827         MAXV=${AVAIL[0]}
11828         MAXI=0
11829         MINV=${AVAIL[0]}
11830         MINI=0
11831         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11832                 #echo OST $i: ${AVAIL[i]}kb
11833                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11834                         MAXV=${AVAIL[i]}
11835                         MAXI=$i
11836                 fi
11837                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11838                         MINV=${AVAIL[i]}
11839                         MINI=$i
11840                 fi
11841         done
11842         echo "Min free space: OST $MINI: $MINV"
11843         echo "Max free space: OST $MAXI: $MAXV"
11844 }
11845
11846 test_116a() { # was previously test_116()
11847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11848         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11849         remote_mds_nodsh && skip "remote MDS with nodsh"
11850
11851         echo -n "Free space priority "
11852         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11853                 head -n1
11854         declare -a AVAIL
11855         free_min_max
11856
11857         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11858         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11859         stack_trap simple_cleanup_common
11860
11861         # Check if we need to generate uneven OSTs
11862         test_mkdir -p $DIR/$tdir/OST${MINI}
11863         local FILL=$((MINV / 4))
11864         local DIFF=$((MAXV - MINV))
11865         local DIFF2=$((DIFF * 100 / MINV))
11866
11867         local threshold=$(do_facet $SINGLEMDS \
11868                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11869         threshold=${threshold%%%}
11870         echo -n "Check for uneven OSTs: "
11871         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11872
11873         if [[ $DIFF2 -gt $threshold ]]; then
11874                 echo "ok"
11875                 echo "Don't need to fill OST$MINI"
11876         else
11877                 # generate uneven OSTs. Write 2% over the QOS threshold value
11878                 echo "no"
11879                 DIFF=$((threshold - DIFF2 + 2))
11880                 DIFF2=$((MINV * DIFF / 100))
11881                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11882                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11883                         error "setstripe failed"
11884                 DIFF=$((DIFF2 / 2048))
11885                 i=0
11886                 while [ $i -lt $DIFF ]; do
11887                         i=$((i + 1))
11888                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11889                                 bs=2M count=1 2>/dev/null
11890                         echo -n .
11891                 done
11892                 echo .
11893                 sync
11894                 sleep_maxage
11895                 free_min_max
11896         fi
11897
11898         DIFF=$((MAXV - MINV))
11899         DIFF2=$((DIFF * 100 / MINV))
11900         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11901         if [ $DIFF2 -gt $threshold ]; then
11902                 echo "ok"
11903         else
11904                 skip "QOS imbalance criteria not met"
11905         fi
11906
11907         MINI1=$MINI
11908         MINV1=$MINV
11909         MAXI1=$MAXI
11910         MAXV1=$MAXV
11911
11912         # now fill using QOS
11913         $LFS setstripe -c 1 $DIR/$tdir
11914         FILL=$((FILL / 200))
11915         if [ $FILL -gt 600 ]; then
11916                 FILL=600
11917         fi
11918         echo "writing $FILL files to QOS-assigned OSTs"
11919         i=0
11920         while [ $i -lt $FILL ]; do
11921                 i=$((i + 1))
11922                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11923                         count=1 2>/dev/null
11924                 echo -n .
11925         done
11926         echo "wrote $i 200k files"
11927         sync
11928         sleep_maxage
11929
11930         echo "Note: free space may not be updated, so measurements might be off"
11931         free_min_max
11932         DIFF2=$((MAXV - MINV))
11933         echo "free space delta: orig $DIFF final $DIFF2"
11934         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11935         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11936         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11937         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11938         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11939         if [[ $DIFF -gt 0 ]]; then
11940                 FILL=$((DIFF2 * 100 / DIFF - 100))
11941                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11942         fi
11943
11944         # Figure out which files were written where
11945         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11946                awk '/'$MINI1': / {print $2; exit}')
11947         echo $UUID
11948         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11949         echo "$MINC files created on smaller OST $MINI1"
11950         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11951                awk '/'$MAXI1': / {print $2; exit}')
11952         echo $UUID
11953         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11954         echo "$MAXC files created on larger OST $MAXI1"
11955         if [[ $MINC -gt 0 ]]; then
11956                 FILL=$((MAXC * 100 / MINC - 100))
11957                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11958         fi
11959         [[ $MAXC -gt $MINC ]] ||
11960                 error_ignore LU-9 "stripe QOS didn't balance free space"
11961 }
11962 run_test 116a "stripe QOS: free space balance ==================="
11963
11964 test_116b() { # LU-2093
11965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11966         remote_mds_nodsh && skip "remote MDS with nodsh"
11967
11968 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11969         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11970                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11971         [ -z "$old_rr" ] && skip "no QOS"
11972         do_facet $SINGLEMDS lctl set_param \
11973                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11974         mkdir -p $DIR/$tdir
11975         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11976         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11977         do_facet $SINGLEMDS lctl set_param fail_loc=0
11978         rm -rf $DIR/$tdir
11979         do_facet $SINGLEMDS lctl set_param \
11980                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11981 }
11982 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11983
11984 test_117() # bug 10891
11985 {
11986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11987
11988         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11989         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11990         lctl set_param fail_loc=0x21e
11991         > $DIR/$tfile || error "truncate failed"
11992         lctl set_param fail_loc=0
11993         echo "Truncate succeeded."
11994         rm -f $DIR/$tfile
11995 }
11996 run_test 117 "verify osd extend =========="
11997
11998 NO_SLOW_RESENDCOUNT=4
11999 export OLD_RESENDCOUNT=""
12000 set_resend_count () {
12001         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12002         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12003         lctl set_param -n $PROC_RESENDCOUNT $1
12004         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12005 }
12006
12007 # for reduce test_118* time (b=14842)
12008 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12009
12010 # Reset async IO behavior after error case
12011 reset_async() {
12012         FILE=$DIR/reset_async
12013
12014         # Ensure all OSCs are cleared
12015         $LFS setstripe -c -1 $FILE
12016         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12017         sync
12018         rm $FILE
12019 }
12020
12021 test_118a() #bug 11710
12022 {
12023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12024
12025         reset_async
12026
12027         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12028         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12029         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12030
12031         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12032                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12033                 return 1;
12034         fi
12035         rm -f $DIR/$tfile
12036 }
12037 run_test 118a "verify O_SYNC works =========="
12038
12039 test_118b()
12040 {
12041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12042         remote_ost_nodsh && skip "remote OST with nodsh"
12043
12044         reset_async
12045
12046         #define OBD_FAIL_SRV_ENOENT 0x217
12047         set_nodes_failloc "$(osts_nodes)" 0x217
12048         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12049         RC=$?
12050         set_nodes_failloc "$(osts_nodes)" 0
12051         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12052         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12053                     grep -c writeback)
12054
12055         if [[ $RC -eq 0 ]]; then
12056                 error "Must return error due to dropped pages, rc=$RC"
12057                 return 1;
12058         fi
12059
12060         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12061                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12062                 return 1;
12063         fi
12064
12065         echo "Dirty pages not leaked on ENOENT"
12066
12067         # Due to the above error the OSC will issue all RPCs syncronously
12068         # until a subsequent RPC completes successfully without error.
12069         $MULTIOP $DIR/$tfile Ow4096yc
12070         rm -f $DIR/$tfile
12071
12072         return 0
12073 }
12074 run_test 118b "Reclaim dirty pages on fatal error =========="
12075
12076 test_118c()
12077 {
12078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12079
12080         # for 118c, restore the original resend count, LU-1940
12081         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12082                                 set_resend_count $OLD_RESENDCOUNT
12083         remote_ost_nodsh && skip "remote OST with nodsh"
12084
12085         reset_async
12086
12087         #define OBD_FAIL_OST_EROFS               0x216
12088         set_nodes_failloc "$(osts_nodes)" 0x216
12089
12090         # multiop should block due to fsync until pages are written
12091         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12092         MULTIPID=$!
12093         sleep 1
12094
12095         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12096                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12097         fi
12098
12099         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12100                     grep -c writeback)
12101         if [[ $WRITEBACK -eq 0 ]]; then
12102                 error "No page in writeback, writeback=$WRITEBACK"
12103         fi
12104
12105         set_nodes_failloc "$(osts_nodes)" 0
12106         wait $MULTIPID
12107         RC=$?
12108         if [[ $RC -ne 0 ]]; then
12109                 error "Multiop fsync failed, rc=$RC"
12110         fi
12111
12112         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12113         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12114                     grep -c writeback)
12115         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12116                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12117         fi
12118
12119         rm -f $DIR/$tfile
12120         echo "Dirty pages flushed via fsync on EROFS"
12121         return 0
12122 }
12123 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12124
12125 # continue to use small resend count to reduce test_118* time (b=14842)
12126 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12127
12128 test_118d()
12129 {
12130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12131         remote_ost_nodsh && skip "remote OST with nodsh"
12132
12133         reset_async
12134
12135         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12136         set_nodes_failloc "$(osts_nodes)" 0x214
12137         # multiop should block due to fsync until pages are written
12138         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12139         MULTIPID=$!
12140         sleep 1
12141
12142         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12143                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12144         fi
12145
12146         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12147                     grep -c writeback)
12148         if [[ $WRITEBACK -eq 0 ]]; then
12149                 error "No page in writeback, writeback=$WRITEBACK"
12150         fi
12151
12152         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12153         set_nodes_failloc "$(osts_nodes)" 0
12154
12155         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12156         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12157                     grep -c writeback)
12158         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12159                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12160         fi
12161
12162         rm -f $DIR/$tfile
12163         echo "Dirty pages gaurenteed flushed via fsync"
12164         return 0
12165 }
12166 run_test 118d "Fsync validation inject a delay of the bulk =========="
12167
12168 test_118f() {
12169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12170
12171         reset_async
12172
12173         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12174         lctl set_param fail_loc=0x8000040a
12175
12176         # Should simulate EINVAL error which is fatal
12177         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12178         RC=$?
12179         if [[ $RC -eq 0 ]]; then
12180                 error "Must return error due to dropped pages, rc=$RC"
12181         fi
12182
12183         lctl set_param fail_loc=0x0
12184
12185         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12186         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12187         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12188                     grep -c writeback)
12189         if [[ $LOCKED -ne 0 ]]; then
12190                 error "Locked pages remain in cache, locked=$LOCKED"
12191         fi
12192
12193         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12194                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12195         fi
12196
12197         rm -f $DIR/$tfile
12198         echo "No pages locked after fsync"
12199
12200         reset_async
12201         return 0
12202 }
12203 run_test 118f "Simulate unrecoverable OSC side error =========="
12204
12205 test_118g() {
12206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12207
12208         reset_async
12209
12210         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12211         lctl set_param fail_loc=0x406
12212
12213         # simulate local -ENOMEM
12214         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12215         RC=$?
12216
12217         lctl set_param fail_loc=0
12218         if [[ $RC -eq 0 ]]; then
12219                 error "Must return error due to dropped pages, rc=$RC"
12220         fi
12221
12222         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12223         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12224         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12225                         grep -c writeback)
12226         if [[ $LOCKED -ne 0 ]]; then
12227                 error "Locked pages remain in cache, locked=$LOCKED"
12228         fi
12229
12230         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12231                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12232         fi
12233
12234         rm -f $DIR/$tfile
12235         echo "No pages locked after fsync"
12236
12237         reset_async
12238         return 0
12239 }
12240 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12241
12242 test_118h() {
12243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12244         remote_ost_nodsh && skip "remote OST with nodsh"
12245
12246         reset_async
12247
12248         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12249         set_nodes_failloc "$(osts_nodes)" 0x20e
12250         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12251         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12252         RC=$?
12253
12254         set_nodes_failloc "$(osts_nodes)" 0
12255         if [[ $RC -eq 0 ]]; then
12256                 error "Must return error due to dropped pages, rc=$RC"
12257         fi
12258
12259         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12260         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12261         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12262                     grep -c writeback)
12263         if [[ $LOCKED -ne 0 ]]; then
12264                 error "Locked pages remain in cache, locked=$LOCKED"
12265         fi
12266
12267         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12268                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12269         fi
12270
12271         rm -f $DIR/$tfile
12272         echo "No pages locked after fsync"
12273
12274         return 0
12275 }
12276 run_test 118h "Verify timeout in handling recoverables errors  =========="
12277
12278 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12279
12280 test_118i() {
12281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12282         remote_ost_nodsh && skip "remote OST with nodsh"
12283
12284         reset_async
12285
12286         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12287         set_nodes_failloc "$(osts_nodes)" 0x20e
12288
12289         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12290         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12291         PID=$!
12292         sleep 5
12293         set_nodes_failloc "$(osts_nodes)" 0
12294
12295         wait $PID
12296         RC=$?
12297         if [[ $RC -ne 0 ]]; then
12298                 error "got error, but should be not, rc=$RC"
12299         fi
12300
12301         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12302         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12303         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12304         if [[ $LOCKED -ne 0 ]]; then
12305                 error "Locked pages remain in cache, locked=$LOCKED"
12306         fi
12307
12308         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12309                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12310         fi
12311
12312         rm -f $DIR/$tfile
12313         echo "No pages locked after fsync"
12314
12315         return 0
12316 }
12317 run_test 118i "Fix error before timeout in recoverable error  =========="
12318
12319 [ "$SLOW" = "no" ] && set_resend_count 4
12320
12321 test_118j() {
12322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12323         remote_ost_nodsh && skip "remote OST with nodsh"
12324
12325         reset_async
12326
12327         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12328         set_nodes_failloc "$(osts_nodes)" 0x220
12329
12330         # return -EIO from OST
12331         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12332         RC=$?
12333         set_nodes_failloc "$(osts_nodes)" 0x0
12334         if [[ $RC -eq 0 ]]; then
12335                 error "Must return error due to dropped pages, rc=$RC"
12336         fi
12337
12338         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12339         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12340         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12341         if [[ $LOCKED -ne 0 ]]; then
12342                 error "Locked pages remain in cache, locked=$LOCKED"
12343         fi
12344
12345         # in recoverable error on OST we want resend and stay until it finished
12346         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12347                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12348         fi
12349
12350         rm -f $DIR/$tfile
12351         echo "No pages locked after fsync"
12352
12353         return 0
12354 }
12355 run_test 118j "Simulate unrecoverable OST side error =========="
12356
12357 test_118k()
12358 {
12359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12360         remote_ost_nodsh && skip "remote OSTs with nodsh"
12361
12362         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12363         set_nodes_failloc "$(osts_nodes)" 0x20e
12364         test_mkdir $DIR/$tdir
12365
12366         for ((i=0;i<10;i++)); do
12367                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12368                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12369                 SLEEPPID=$!
12370                 sleep 0.500s
12371                 kill $SLEEPPID
12372                 wait $SLEEPPID
12373         done
12374
12375         set_nodes_failloc "$(osts_nodes)" 0
12376         rm -rf $DIR/$tdir
12377 }
12378 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12379
12380 test_118l() # LU-646
12381 {
12382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12383
12384         test_mkdir $DIR/$tdir
12385         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12386         rm -rf $DIR/$tdir
12387 }
12388 run_test 118l "fsync dir"
12389
12390 test_118m() # LU-3066
12391 {
12392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12393
12394         test_mkdir $DIR/$tdir
12395         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12396         rm -rf $DIR/$tdir
12397 }
12398 run_test 118m "fdatasync dir ========="
12399
12400 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12401
12402 test_118n()
12403 {
12404         local begin
12405         local end
12406
12407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12408         remote_ost_nodsh && skip "remote OSTs with nodsh"
12409
12410         # Sleep to avoid a cached response.
12411         #define OBD_STATFS_CACHE_SECONDS 1
12412         sleep 2
12413
12414         # Inject a 10 second delay in the OST_STATFS handler.
12415         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12416         set_nodes_failloc "$(osts_nodes)" 0x242
12417
12418         begin=$SECONDS
12419         stat --file-system $MOUNT > /dev/null
12420         end=$SECONDS
12421
12422         set_nodes_failloc "$(osts_nodes)" 0
12423
12424         if ((end - begin > 20)); then
12425             error "statfs took $((end - begin)) seconds, expected 10"
12426         fi
12427 }
12428 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12429
12430 test_119a() # bug 11737
12431 {
12432         BSIZE=$((512 * 1024))
12433         directio write $DIR/$tfile 0 1 $BSIZE
12434         # We ask to read two blocks, which is more than a file size.
12435         # directio will indicate an error when requested and actual
12436         # sizes aren't equeal (a normal situation in this case) and
12437         # print actual read amount.
12438         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12439         if [ "$NOB" != "$BSIZE" ]; then
12440                 error "read $NOB bytes instead of $BSIZE"
12441         fi
12442         rm -f $DIR/$tfile
12443 }
12444 run_test 119a "Short directIO read must return actual read amount"
12445
12446 test_119b() # bug 11737
12447 {
12448         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12449
12450         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12451         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12452         sync
12453         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12454                 error "direct read failed"
12455         rm -f $DIR/$tfile
12456 }
12457 run_test 119b "Sparse directIO read must return actual read amount"
12458
12459 test_119c() # bug 13099
12460 {
12461         BSIZE=1048576
12462         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12463         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 119c "Testing for direct read hitting hole"
12467
12468 test_119d() # bug 15950
12469 {
12470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12471
12472         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12473         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12474         BSIZE=1048576
12475         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12476         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12477         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12478         lctl set_param fail_loc=0x40d
12479         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12480         pid_dio=$!
12481         sleep 1
12482         cat $DIR/$tfile > /dev/null &
12483         lctl set_param fail_loc=0
12484         pid_reads=$!
12485         wait $pid_dio
12486         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12487         sleep 2
12488         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12489         error "the read rpcs have not completed in 2s"
12490         rm -f $DIR/$tfile
12491         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12492 }
12493 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12494
12495 test_120a() {
12496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12497         remote_mds_nodsh && skip "remote MDS with nodsh"
12498         test_mkdir -i0 -c1 $DIR/$tdir
12499         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12500                 skip_env "no early lock cancel on server"
12501
12502         lru_resize_disable mdc
12503         lru_resize_disable osc
12504         cancel_lru_locks mdc
12505         # asynchronous object destroy at MDT could cause bl ast to client
12506         cancel_lru_locks osc
12507
12508         stat $DIR/$tdir > /dev/null
12509         can1=$(do_facet mds1 \
12510                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12511                awk '/ldlm_cancel/ {print $2}')
12512         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12513                awk '/ldlm_bl_callback/ {print $2}')
12514         test_mkdir -i0 -c1 $DIR/$tdir/d1
12515         can2=$(do_facet mds1 \
12516                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12517                awk '/ldlm_cancel/ {print $2}')
12518         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12519                awk '/ldlm_bl_callback/ {print $2}')
12520         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12521         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12522         lru_resize_enable mdc
12523         lru_resize_enable osc
12524 }
12525 run_test 120a "Early Lock Cancel: mkdir test"
12526
12527 test_120b() {
12528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12529         remote_mds_nodsh && skip "remote MDS with nodsh"
12530         test_mkdir $DIR/$tdir
12531         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12532                 skip_env "no early lock cancel on server"
12533
12534         lru_resize_disable mdc
12535         lru_resize_disable osc
12536         cancel_lru_locks mdc
12537         stat $DIR/$tdir > /dev/null
12538         can1=$(do_facet $SINGLEMDS \
12539                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12540                awk '/ldlm_cancel/ {print $2}')
12541         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12542                awk '/ldlm_bl_callback/ {print $2}')
12543         touch $DIR/$tdir/f1
12544         can2=$(do_facet $SINGLEMDS \
12545                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12546                awk '/ldlm_cancel/ {print $2}')
12547         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12548                awk '/ldlm_bl_callback/ {print $2}')
12549         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12550         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12551         lru_resize_enable mdc
12552         lru_resize_enable osc
12553 }
12554 run_test 120b "Early Lock Cancel: create test"
12555
12556 test_120c() {
12557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12558         remote_mds_nodsh && skip "remote MDS with nodsh"
12559         test_mkdir -i0 -c1 $DIR/$tdir
12560         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12561                 skip "no early lock cancel on server"
12562
12563         lru_resize_disable mdc
12564         lru_resize_disable osc
12565         test_mkdir -i0 -c1 $DIR/$tdir/d1
12566         test_mkdir -i0 -c1 $DIR/$tdir/d2
12567         touch $DIR/$tdir/d1/f1
12568         cancel_lru_locks mdc
12569         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12570         can1=$(do_facet mds1 \
12571                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12572                awk '/ldlm_cancel/ {print $2}')
12573         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12574                awk '/ldlm_bl_callback/ {print $2}')
12575         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12576         can2=$(do_facet mds1 \
12577                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12578                awk '/ldlm_cancel/ {print $2}')
12579         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12580                awk '/ldlm_bl_callback/ {print $2}')
12581         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12582         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12583         lru_resize_enable mdc
12584         lru_resize_enable osc
12585 }
12586 run_test 120c "Early Lock Cancel: link test"
12587
12588 test_120d() {
12589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12590         remote_mds_nodsh && skip "remote MDS with nodsh"
12591         test_mkdir -i0 -c1 $DIR/$tdir
12592         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12593                 skip_env "no early lock cancel on server"
12594
12595         lru_resize_disable mdc
12596         lru_resize_disable osc
12597         touch $DIR/$tdir
12598         cancel_lru_locks mdc
12599         stat $DIR/$tdir > /dev/null
12600         can1=$(do_facet mds1 \
12601                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12602                awk '/ldlm_cancel/ {print $2}')
12603         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12604                awk '/ldlm_bl_callback/ {print $2}')
12605         chmod a+x $DIR/$tdir
12606         can2=$(do_facet mds1 \
12607                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12608                awk '/ldlm_cancel/ {print $2}')
12609         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12610                awk '/ldlm_bl_callback/ {print $2}')
12611         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12612         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12613         lru_resize_enable mdc
12614         lru_resize_enable osc
12615 }
12616 run_test 120d "Early Lock Cancel: setattr test"
12617
12618 test_120e() {
12619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12620         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12621                 skip_env "no early lock cancel on server"
12622         remote_mds_nodsh && skip "remote MDS with nodsh"
12623
12624         local dlmtrace_set=false
12625
12626         test_mkdir -i0 -c1 $DIR/$tdir
12627         lru_resize_disable mdc
12628         lru_resize_disable osc
12629         ! $LCTL get_param debug | grep -q dlmtrace &&
12630                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12631         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12632         cancel_lru_locks mdc
12633         cancel_lru_locks osc
12634         dd if=$DIR/$tdir/f1 of=/dev/null
12635         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12636         # XXX client can not do early lock cancel of OST lock
12637         # during unlink (LU-4206), so cancel osc lock now.
12638         sleep 2
12639         cancel_lru_locks osc
12640         can1=$(do_facet mds1 \
12641                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12642                awk '/ldlm_cancel/ {print $2}')
12643         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12644                awk '/ldlm_bl_callback/ {print $2}')
12645         unlink $DIR/$tdir/f1
12646         sleep 5
12647         can2=$(do_facet mds1 \
12648                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12649                awk '/ldlm_cancel/ {print $2}')
12650         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12651                awk '/ldlm_bl_callback/ {print $2}')
12652         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12653                 $LCTL dk $TMP/cancel.debug.txt
12654         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12655                 $LCTL dk $TMP/blocking.debug.txt
12656         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12657         lru_resize_enable mdc
12658         lru_resize_enable osc
12659 }
12660 run_test 120e "Early Lock Cancel: unlink test"
12661
12662 test_120f() {
12663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12664         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12665                 skip_env "no early lock cancel on server"
12666         remote_mds_nodsh && skip "remote MDS with nodsh"
12667
12668         test_mkdir -i0 -c1 $DIR/$tdir
12669         lru_resize_disable mdc
12670         lru_resize_disable osc
12671         test_mkdir -i0 -c1 $DIR/$tdir/d1
12672         test_mkdir -i0 -c1 $DIR/$tdir/d2
12673         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12674         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12675         cancel_lru_locks mdc
12676         cancel_lru_locks osc
12677         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12678         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12679         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12680         # XXX client can not do early lock cancel of OST lock
12681         # during rename (LU-4206), so cancel osc lock now.
12682         sleep 2
12683         cancel_lru_locks osc
12684         can1=$(do_facet mds1 \
12685                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12686                awk '/ldlm_cancel/ {print $2}')
12687         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12688                awk '/ldlm_bl_callback/ {print $2}')
12689         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12690         sleep 5
12691         can2=$(do_facet mds1 \
12692                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12693                awk '/ldlm_cancel/ {print $2}')
12694         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12695                awk '/ldlm_bl_callback/ {print $2}')
12696         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12697         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12698         lru_resize_enable mdc
12699         lru_resize_enable osc
12700 }
12701 run_test 120f "Early Lock Cancel: rename test"
12702
12703 test_120g() {
12704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12705         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12706                 skip_env "no early lock cancel on server"
12707         remote_mds_nodsh && skip "remote MDS with nodsh"
12708
12709         lru_resize_disable mdc
12710         lru_resize_disable osc
12711         count=10000
12712         echo create $count files
12713         test_mkdir $DIR/$tdir
12714         cancel_lru_locks mdc
12715         cancel_lru_locks osc
12716         t0=$(date +%s)
12717
12718         can0=$(do_facet $SINGLEMDS \
12719                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12720                awk '/ldlm_cancel/ {print $2}')
12721         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12722                awk '/ldlm_bl_callback/ {print $2}')
12723         createmany -o $DIR/$tdir/f $count
12724         sync
12725         can1=$(do_facet $SINGLEMDS \
12726                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12727                awk '/ldlm_cancel/ {print $2}')
12728         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12729                awk '/ldlm_bl_callback/ {print $2}')
12730         t1=$(date +%s)
12731         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12732         echo rm $count files
12733         rm -r $DIR/$tdir
12734         sync
12735         can2=$(do_facet $SINGLEMDS \
12736                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12737                awk '/ldlm_cancel/ {print $2}')
12738         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12739                awk '/ldlm_bl_callback/ {print $2}')
12740         t2=$(date +%s)
12741         echo total: $count removes in $((t2-t1))
12742         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12743         sleep 2
12744         # wait for commitment of removal
12745         lru_resize_enable mdc
12746         lru_resize_enable osc
12747 }
12748 run_test 120g "Early Lock Cancel: performance test"
12749
12750 test_121() { #bug #10589
12751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12752
12753         rm -rf $DIR/$tfile
12754         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12755 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12756         lctl set_param fail_loc=0x310
12757         cancel_lru_locks osc > /dev/null
12758         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12759         lctl set_param fail_loc=0
12760         [[ $reads -eq $writes ]] ||
12761                 error "read $reads blocks, must be $writes blocks"
12762 }
12763 run_test 121 "read cancel race ========="
12764
12765 test_123a_base() { # was test 123, statahead(bug 11401)
12766         local lsx="$1"
12767
12768         SLOWOK=0
12769         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12770                 log "testing UP system. Performance may be lower than expected."
12771                 SLOWOK=1
12772         fi
12773
12774         rm -rf $DIR/$tdir
12775         test_mkdir $DIR/$tdir
12776         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12777         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12778         MULT=10
12779         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12780                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12781
12782                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12783                 lctl set_param -n llite.*.statahead_max 0
12784                 lctl get_param llite.*.statahead_max
12785                 cancel_lru_locks mdc
12786                 cancel_lru_locks osc
12787                 stime=$(date +%s)
12788                 time $lsx $DIR/$tdir | wc -l
12789                 etime=$(date +%s)
12790                 delta=$((etime - stime))
12791                 log "$lsx $i files without statahead: $delta sec"
12792                 lctl set_param llite.*.statahead_max=$max
12793
12794                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12795                         grep "statahead wrong:" | awk '{print $3}')
12796                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12797                 cancel_lru_locks mdc
12798                 cancel_lru_locks osc
12799                 stime=$(date +%s)
12800                 time $lsx $DIR/$tdir | wc -l
12801                 etime=$(date +%s)
12802                 delta_sa=$((etime - stime))
12803                 log "$lsx $i files with statahead: $delta_sa sec"
12804                 lctl get_param -n llite.*.statahead_stats
12805                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12806                         grep "statahead wrong:" | awk '{print $3}')
12807
12808                 [[ $swrong -lt $ewrong ]] &&
12809                         log "statahead was stopped, maybe too many locks held!"
12810                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12811
12812                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12813                         max=$(lctl get_param -n llite.*.statahead_max |
12814                                 head -n 1)
12815                         lctl set_param -n llite.*.statahead_max 0
12816                         lctl get_param llite.*.statahead_max
12817                         cancel_lru_locks mdc
12818                         cancel_lru_locks osc
12819                         stime=$(date +%s)
12820                         time $lsx $DIR/$tdir | wc -l
12821                         etime=$(date +%s)
12822                         delta=$((etime - stime))
12823                         log "$lsx $i files again without statahead: $delta sec"
12824                         lctl set_param llite.*.statahead_max=$max
12825                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12826                                 if [  $SLOWOK -eq 0 ]; then
12827                                         error "$lsx $i files is slower with statahead!"
12828                                 else
12829                                         log "$lsx $i files is slower with statahead!"
12830                                 fi
12831                                 break
12832                         fi
12833                 fi
12834
12835                 [ $delta -gt 20 ] && break
12836                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12837                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12838         done
12839         log "$lsx done"
12840
12841         stime=$(date +%s)
12842         rm -r $DIR/$tdir
12843         sync
12844         etime=$(date +%s)
12845         delta=$((etime - stime))
12846         log "rm -r $DIR/$tdir/: $delta seconds"
12847         log "rm done"
12848         lctl get_param -n llite.*.statahead_stats
12849 }
12850
12851 test_123aa() {
12852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12853
12854         test_123a_base "ls -l"
12855 }
12856 run_test 123aa "verify statahead work"
12857
12858 test_123ab() {
12859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12860
12861         statx_supported || skip_env "Test must be statx() syscall supported"
12862
12863         test_123a_base "$STATX -l"
12864 }
12865 run_test 123ab "verify statahead work by using statx"
12866
12867 test_123ac() {
12868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12869
12870         statx_supported || skip_env "Test must be statx() syscall supported"
12871
12872         local rpcs_before
12873         local rpcs_after
12874         local agl_before
12875         local agl_after
12876
12877         cancel_lru_locks $OSC
12878         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12879         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12880                 awk '/agl.total:/ {print $3}')
12881         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12882         test_123a_base "$STATX --cached=always -D"
12883         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12884                 awk '/agl.total:/ {print $3}')
12885         [ $agl_before -eq $agl_after ] ||
12886                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12887         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12888         [ $rpcs_after -eq $rpcs_before ] ||
12889                 error "$STATX should not send glimpse RPCs to $OSC"
12890 }
12891 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12892
12893 test_123b () { # statahead(bug 15027)
12894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12895
12896         test_mkdir $DIR/$tdir
12897         createmany -o $DIR/$tdir/$tfile-%d 1000
12898
12899         cancel_lru_locks mdc
12900         cancel_lru_locks osc
12901
12902 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12903         lctl set_param fail_loc=0x80000803
12904         ls -lR $DIR/$tdir > /dev/null
12905         log "ls done"
12906         lctl set_param fail_loc=0x0
12907         lctl get_param -n llite.*.statahead_stats
12908         rm -r $DIR/$tdir
12909         sync
12910
12911 }
12912 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12913
12914 test_123c() {
12915         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12916
12917         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12918         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12919         touch $DIR/$tdir.1/{1..3}
12920         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12921
12922         remount_client $MOUNT
12923
12924         $MULTIOP $DIR/$tdir.0 Q
12925
12926         # let statahead to complete
12927         ls -l $DIR/$tdir.0 > /dev/null
12928
12929         testid=$(echo $TESTNAME | tr '_' ' ')
12930         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12931                 error "statahead warning" || true
12932 }
12933 run_test 123c "Can not initialize inode warning on DNE statahead"
12934
12935 test_124a() {
12936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12937         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12938                 skip_env "no lru resize on server"
12939
12940         local NR=2000
12941
12942         test_mkdir $DIR/$tdir
12943
12944         log "create $NR files at $DIR/$tdir"
12945         createmany -o $DIR/$tdir/f $NR ||
12946                 error "failed to create $NR files in $DIR/$tdir"
12947
12948         cancel_lru_locks mdc
12949         ls -l $DIR/$tdir > /dev/null
12950
12951         local NSDIR=""
12952         local LRU_SIZE=0
12953         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12954                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12955                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12956                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12957                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12958                         log "NSDIR=$NSDIR"
12959                         log "NS=$(basename $NSDIR)"
12960                         break
12961                 fi
12962         done
12963
12964         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12965                 skip "Not enough cached locks created!"
12966         fi
12967         log "LRU=$LRU_SIZE"
12968
12969         local SLEEP=30
12970
12971         # We know that lru resize allows one client to hold $LIMIT locks
12972         # for 10h. After that locks begin to be killed by client.
12973         local MAX_HRS=10
12974         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12975         log "LIMIT=$LIMIT"
12976         if [ $LIMIT -lt $LRU_SIZE ]; then
12977                 skip "Limit is too small $LIMIT"
12978         fi
12979
12980         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12981         # killing locks. Some time was spent for creating locks. This means
12982         # that up to the moment of sleep finish we must have killed some of
12983         # them (10-100 locks). This depends on how fast ther were created.
12984         # Many of them were touched in almost the same moment and thus will
12985         # be killed in groups.
12986         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12987
12988         # Use $LRU_SIZE_B here to take into account real number of locks
12989         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12990         local LRU_SIZE_B=$LRU_SIZE
12991         log "LVF=$LVF"
12992         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12993         log "OLD_LVF=$OLD_LVF"
12994         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12995
12996         # Let's make sure that we really have some margin. Client checks
12997         # cached locks every 10 sec.
12998         SLEEP=$((SLEEP+20))
12999         log "Sleep ${SLEEP} sec"
13000         local SEC=0
13001         while ((SEC<$SLEEP)); do
13002                 echo -n "..."
13003                 sleep 5
13004                 SEC=$((SEC+5))
13005                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13006                 echo -n "$LRU_SIZE"
13007         done
13008         echo ""
13009         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13010         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13011
13012         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13013                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13014                 unlinkmany $DIR/$tdir/f $NR
13015                 return
13016         }
13017
13018         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13019         log "unlink $NR files at $DIR/$tdir"
13020         unlinkmany $DIR/$tdir/f $NR
13021 }
13022 run_test 124a "lru resize ======================================="
13023
13024 get_max_pool_limit()
13025 {
13026         local limit=$($LCTL get_param \
13027                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13028         local max=0
13029         for l in $limit; do
13030                 if [[ $l -gt $max ]]; then
13031                         max=$l
13032                 fi
13033         done
13034         echo $max
13035 }
13036
13037 test_124b() {
13038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13039         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13040                 skip_env "no lru resize on server"
13041
13042         LIMIT=$(get_max_pool_limit)
13043
13044         NR=$(($(default_lru_size)*20))
13045         if [[ $NR -gt $LIMIT ]]; then
13046                 log "Limit lock number by $LIMIT locks"
13047                 NR=$LIMIT
13048         fi
13049
13050         IFree=$(mdsrate_inodes_available)
13051         if [ $IFree -lt $NR ]; then
13052                 log "Limit lock number by $IFree inodes"
13053                 NR=$IFree
13054         fi
13055
13056         lru_resize_disable mdc
13057         test_mkdir -p $DIR/$tdir/disable_lru_resize
13058
13059         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13060         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13061         cancel_lru_locks mdc
13062         stime=`date +%s`
13063         PID=""
13064         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13065         PID="$PID $!"
13066         sleep 2
13067         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13068         PID="$PID $!"
13069         sleep 2
13070         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13071         PID="$PID $!"
13072         wait $PID
13073         etime=`date +%s`
13074         nolruresize_delta=$((etime-stime))
13075         log "ls -la time: $nolruresize_delta seconds"
13076         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13077         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13078
13079         lru_resize_enable mdc
13080         test_mkdir -p $DIR/$tdir/enable_lru_resize
13081
13082         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13083         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13084         cancel_lru_locks mdc
13085         stime=`date +%s`
13086         PID=""
13087         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13088         PID="$PID $!"
13089         sleep 2
13090         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13091         PID="$PID $!"
13092         sleep 2
13093         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13094         PID="$PID $!"
13095         wait $PID
13096         etime=`date +%s`
13097         lruresize_delta=$((etime-stime))
13098         log "ls -la time: $lruresize_delta seconds"
13099         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13100
13101         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13102                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13103         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13104                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13105         else
13106                 log "lru resize performs the same with no lru resize"
13107         fi
13108         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13109 }
13110 run_test 124b "lru resize (performance test) ======================="
13111
13112 test_124c() {
13113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13114         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13115                 skip_env "no lru resize on server"
13116
13117         # cache ununsed locks on client
13118         local nr=100
13119         cancel_lru_locks mdc
13120         test_mkdir $DIR/$tdir
13121         createmany -o $DIR/$tdir/f $nr ||
13122                 error "failed to create $nr files in $DIR/$tdir"
13123         ls -l $DIR/$tdir > /dev/null
13124
13125         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13126         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13127         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13128         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13129         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13130
13131         # set lru_max_age to 1 sec
13132         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13133         echo "sleep $((recalc_p * 2)) seconds..."
13134         sleep $((recalc_p * 2))
13135
13136         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13137         # restore lru_max_age
13138         $LCTL set_param -n $nsdir.lru_max_age $max_age
13139         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13140         unlinkmany $DIR/$tdir/f $nr
13141 }
13142 run_test 124c "LRUR cancel very aged locks"
13143
13144 test_124d() {
13145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13146         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13147                 skip_env "no lru resize on server"
13148
13149         # cache ununsed locks on client
13150         local nr=100
13151
13152         lru_resize_disable mdc
13153         stack_trap "lru_resize_enable mdc" EXIT
13154
13155         cancel_lru_locks mdc
13156
13157         # asynchronous object destroy at MDT could cause bl ast to client
13158         test_mkdir $DIR/$tdir
13159         createmany -o $DIR/$tdir/f $nr ||
13160                 error "failed to create $nr files in $DIR/$tdir"
13161         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13162
13163         ls -l $DIR/$tdir > /dev/null
13164
13165         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13166         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13167         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13168         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13169
13170         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13171
13172         # set lru_max_age to 1 sec
13173         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13174         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13175
13176         echo "sleep $((recalc_p * 2)) seconds..."
13177         sleep $((recalc_p * 2))
13178
13179         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13180
13181         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13182 }
13183 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13184
13185 test_125() { # 13358
13186         $LCTL get_param -n llite.*.client_type | grep -q local ||
13187                 skip "must run as local client"
13188         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13189                 skip_env "must have acl enabled"
13190         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13191
13192         test_mkdir $DIR/$tdir
13193         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13194         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13195         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13196 }
13197 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13198
13199 test_126() { # bug 12829/13455
13200         $GSS && skip_env "must run as gss disabled"
13201         $LCTL get_param -n llite.*.client_type | grep -q local ||
13202                 skip "must run as local client"
13203         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13204
13205         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13206         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13207         rm -f $DIR/$tfile
13208         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13209 }
13210 run_test 126 "check that the fsgid provided by the client is taken into account"
13211
13212 test_127a() { # bug 15521
13213         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13214         local name count samp unit min max sum sumsq
13215
13216         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13217         echo "stats before reset"
13218         $LCTL get_param osc.*.stats
13219         $LCTL set_param osc.*.stats=0
13220         local fsize=$((2048 * 1024))
13221
13222         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13223         cancel_lru_locks osc
13224         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13225
13226         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13227         stack_trap "rm -f $TMP/$tfile.tmp"
13228         while read name count samp unit min max sum sumsq; do
13229                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13230                 [ ! $min ] && error "Missing min value for $name proc entry"
13231                 eval $name=$count || error "Wrong proc format"
13232
13233                 case $name in
13234                 read_bytes|write_bytes)
13235                         [[ "$unit" =~ "bytes" ]] ||
13236                                 error "unit is not 'bytes': $unit"
13237                         (( $min >= 4096 )) || error "min is too small: $min"
13238                         (( $min <= $fsize )) || error "min is too big: $min"
13239                         (( $max >= 4096 )) || error "max is too small: $max"
13240                         (( $max <= $fsize )) || error "max is too big: $max"
13241                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13242                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13243                                 error "sumsquare is too small: $sumsq"
13244                         (( $sumsq <= $fsize * $fsize )) ||
13245                                 error "sumsquare is too big: $sumsq"
13246                         ;;
13247                 ost_read|ost_write)
13248                         [[ "$unit" =~ "usec" ]] ||
13249                                 error "unit is not 'usec': $unit"
13250                         ;;
13251                 *)      ;;
13252                 esac
13253         done < $DIR/$tfile.tmp
13254
13255         #check that we actually got some stats
13256         [ "$read_bytes" ] || error "Missing read_bytes stats"
13257         [ "$write_bytes" ] || error "Missing write_bytes stats"
13258         [ "$read_bytes" != 0 ] || error "no read done"
13259         [ "$write_bytes" != 0 ] || error "no write done"
13260 }
13261 run_test 127a "verify the client stats are sane"
13262
13263 test_127b() { # bug LU-333
13264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13265         local name count samp unit min max sum sumsq
13266
13267         echo "stats before reset"
13268         $LCTL get_param llite.*.stats
13269         $LCTL set_param llite.*.stats=0
13270
13271         # perform 2 reads and writes so MAX is different from SUM.
13272         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13273         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13274         cancel_lru_locks osc
13275         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13276         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13277
13278         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13279         stack_trap "rm -f $TMP/$tfile.tmp"
13280         while read name count samp unit min max sum sumsq; do
13281                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13282                 eval $name=$count || error "Wrong proc format"
13283
13284                 case $name in
13285                 read_bytes|write_bytes)
13286                         [[ "$unit" =~ "bytes" ]] ||
13287                                 error "unit is not 'bytes': $unit"
13288                         (( $count == 2 )) || error "count is not 2: $count"
13289                         (( $min == $PAGE_SIZE )) ||
13290                                 error "min is not $PAGE_SIZE: $min"
13291                         (( $max == $PAGE_SIZE )) ||
13292                                 error "max is not $PAGE_SIZE: $max"
13293                         (( $sum == $PAGE_SIZE * 2 )) ||
13294                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13295                         ;;
13296                 read|write)
13297                         [[ "$unit" =~ "usec" ]] ||
13298                                 error "unit is not 'usec': $unit"
13299                         ;;
13300                 *)      ;;
13301                 esac
13302         done < $TMP/$tfile.tmp
13303
13304         #check that we actually got some stats
13305         [ "$read_bytes" ] || error "Missing read_bytes stats"
13306         [ "$write_bytes" ] || error "Missing write_bytes stats"
13307         [ "$read_bytes" != 0 ] || error "no read done"
13308         [ "$write_bytes" != 0 ] || error "no write done"
13309 }
13310 run_test 127b "verify the llite client stats are sane"
13311
13312 test_127c() { # LU-12394
13313         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13314         local size
13315         local bsize
13316         local reads
13317         local writes
13318         local count
13319
13320         $LCTL set_param llite.*.extents_stats=1
13321         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13322
13323         # Use two stripes so there is enough space in default config
13324         $LFS setstripe -c 2 $DIR/$tfile
13325
13326         # Extent stats start at 0-4K and go in power of two buckets
13327         # LL_HIST_START = 12 --> 2^12 = 4K
13328         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13329         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13330         # small configs
13331         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13332                 do
13333                 # Write and read, 2x each, second time at a non-zero offset
13334                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13335                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13336                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13337                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13338                 rm -f $DIR/$tfile
13339         done
13340
13341         $LCTL get_param llite.*.extents_stats
13342
13343         count=2
13344         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13345                 do
13346                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13347                                 grep -m 1 $bsize)
13348                 reads=$(echo $bucket | awk '{print $5}')
13349                 writes=$(echo $bucket | awk '{print $9}')
13350                 [ "$reads" -eq $count ] ||
13351                         error "$reads reads in < $bsize bucket, expect $count"
13352                 [ "$writes" -eq $count ] ||
13353                         error "$writes writes in < $bsize bucket, expect $count"
13354         done
13355
13356         # Test mmap write and read
13357         $LCTL set_param llite.*.extents_stats=c
13358         size=512
13359         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13360         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13361         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13362
13363         $LCTL get_param llite.*.extents_stats
13364
13365         count=$(((size*1024) / PAGE_SIZE))
13366
13367         bsize=$((2 * PAGE_SIZE / 1024))K
13368
13369         bucket=$($LCTL get_param -n llite.*.extents_stats |
13370                         grep -m 1 $bsize)
13371         reads=$(echo $bucket | awk '{print $5}')
13372         writes=$(echo $bucket | awk '{print $9}')
13373         # mmap writes fault in the page first, creating an additonal read
13374         [ "$reads" -eq $((2 * count)) ] ||
13375                 error "$reads reads in < $bsize bucket, expect $count"
13376         [ "$writes" -eq $count ] ||
13377                 error "$writes writes in < $bsize bucket, expect $count"
13378 }
13379 run_test 127c "test llite extent stats with regular & mmap i/o"
13380
13381 test_128() { # bug 15212
13382         touch $DIR/$tfile
13383         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13384                 find $DIR/$tfile
13385                 find $DIR/$tfile
13386         EOF
13387
13388         result=$(grep error $TMP/$tfile.log)
13389         rm -f $DIR/$tfile $TMP/$tfile.log
13390         [ -z "$result" ] ||
13391                 error "consecutive find's under interactive lfs failed"
13392 }
13393 run_test 128 "interactive lfs for 2 consecutive find's"
13394
13395 set_dir_limits () {
13396         local mntdev
13397         local canondev
13398         local node
13399
13400         local ldproc=/proc/fs/ldiskfs
13401         local facets=$(get_facets MDS)
13402
13403         for facet in ${facets//,/ }; do
13404                 canondev=$(ldiskfs_canon \
13405                            *.$(convert_facet2label $facet).mntdev $facet)
13406                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13407                         ldproc=/sys/fs/ldiskfs
13408                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13409                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13410         done
13411 }
13412
13413 check_mds_dmesg() {
13414         local facets=$(get_facets MDS)
13415         for facet in ${facets//,/ }; do
13416                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13417         done
13418         return 1
13419 }
13420
13421 test_129() {
13422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13423         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13424                 skip "Need MDS version with at least 2.5.56"
13425         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13426                 skip_env "ldiskfs only test"
13427         fi
13428         remote_mds_nodsh && skip "remote MDS with nodsh"
13429
13430         local ENOSPC=28
13431         local has_warning=false
13432
13433         rm -rf $DIR/$tdir
13434         mkdir -p $DIR/$tdir
13435
13436         # block size of mds1
13437         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13438         set_dir_limits $maxsize $((maxsize * 6 / 8))
13439         stack_trap "set_dir_limits 0 0"
13440         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13441         local dirsize=$(stat -c%s "$DIR/$tdir")
13442         local nfiles=0
13443         while (( $dirsize <= $maxsize )); do
13444                 $MCREATE $DIR/$tdir/file_base_$nfiles
13445                 rc=$?
13446                 # check two errors:
13447                 # ENOSPC for ext4 max_dir_size, which has been used since
13448                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13449                 if (( rc == ENOSPC )); then
13450                         set_dir_limits 0 0
13451                         echo "rc=$rc returned as expected after $nfiles files"
13452
13453                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13454                                 error "create failed w/o dir size limit"
13455
13456                         # messages may be rate limited if test is run repeatedly
13457                         check_mds_dmesg '"is approaching max"' ||
13458                                 echo "warning message should be output"
13459                         check_mds_dmesg '"has reached max"' ||
13460                                 echo "reached message should be output"
13461
13462                         dirsize=$(stat -c%s "$DIR/$tdir")
13463
13464                         [[ $dirsize -ge $maxsize ]] && return 0
13465                         error "dirsize $dirsize < $maxsize after $nfiles files"
13466                 elif (( rc != 0 )); then
13467                         break
13468                 fi
13469                 nfiles=$((nfiles + 1))
13470                 dirsize=$(stat -c%s "$DIR/$tdir")
13471         done
13472
13473         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13474 }
13475 run_test 129 "test directory size limit ========================"
13476
13477 OLDIFS="$IFS"
13478 cleanup_130() {
13479         trap 0
13480         IFS="$OLDIFS"
13481 }
13482
13483 test_130a() {
13484         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13485         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13486
13487         trap cleanup_130 EXIT RETURN
13488
13489         local fm_file=$DIR/$tfile
13490         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13491         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13492                 error "dd failed for $fm_file"
13493
13494         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13495         filefrag -ves $fm_file
13496         RC=$?
13497         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13498                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13499         [ $RC != 0 ] && error "filefrag $fm_file failed"
13500
13501         filefrag_op=$(filefrag -ve -k $fm_file |
13502                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13503         lun=$($LFS getstripe -i $fm_file)
13504
13505         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13506         IFS=$'\n'
13507         tot_len=0
13508         for line in $filefrag_op
13509         do
13510                 frag_lun=`echo $line | cut -d: -f5`
13511                 ext_len=`echo $line | cut -d: -f4`
13512                 if (( $frag_lun != $lun )); then
13513                         cleanup_130
13514                         error "FIEMAP on 1-stripe file($fm_file) failed"
13515                         return
13516                 fi
13517                 (( tot_len += ext_len ))
13518         done
13519
13520         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13521                 cleanup_130
13522                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13523                 return
13524         fi
13525
13526         cleanup_130
13527
13528         echo "FIEMAP on single striped file succeeded"
13529 }
13530 run_test 130a "FIEMAP (1-stripe file)"
13531
13532 test_130b() {
13533         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13534
13535         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13536         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13537
13538         trap cleanup_130 EXIT RETURN
13539
13540         local fm_file=$DIR/$tfile
13541         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13542                         error "setstripe on $fm_file"
13543         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13544                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13545
13546         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13547                 error "dd failed on $fm_file"
13548
13549         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13550         filefrag_op=$(filefrag -ve -k $fm_file |
13551                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13552
13553         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13554                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13555
13556         IFS=$'\n'
13557         tot_len=0
13558         num_luns=1
13559         for line in $filefrag_op
13560         do
13561                 frag_lun=$(echo $line | cut -d: -f5 |
13562                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13563                 ext_len=$(echo $line | cut -d: -f4)
13564                 if (( $frag_lun != $last_lun )); then
13565                         if (( tot_len != 1024 )); then
13566                                 cleanup_130
13567                                 error "FIEMAP on $fm_file failed; returned " \
13568                                 "len $tot_len for OST $last_lun instead of 1024"
13569                                 return
13570                         else
13571                                 (( num_luns += 1 ))
13572                                 tot_len=0
13573                         fi
13574                 fi
13575                 (( tot_len += ext_len ))
13576                 last_lun=$frag_lun
13577         done
13578         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13579                 cleanup_130
13580                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13581                         "luns or wrong len for OST $last_lun"
13582                 return
13583         fi
13584
13585         cleanup_130
13586
13587         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13588 }
13589 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13590
13591 test_130c() {
13592         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13593
13594         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13595         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13596
13597         trap cleanup_130 EXIT RETURN
13598
13599         local fm_file=$DIR/$tfile
13600         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13601         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13602                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13603
13604         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13605                         error "dd failed on $fm_file"
13606
13607         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13608         filefrag_op=$(filefrag -ve -k $fm_file |
13609                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13610
13611         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13612                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13613
13614         IFS=$'\n'
13615         tot_len=0
13616         num_luns=1
13617         for line in $filefrag_op
13618         do
13619                 frag_lun=$(echo $line | cut -d: -f5 |
13620                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13621                 ext_len=$(echo $line | cut -d: -f4)
13622                 if (( $frag_lun != $last_lun )); then
13623                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13624                         if (( logical != 512 )); then
13625                                 cleanup_130
13626                                 error "FIEMAP on $fm_file failed; returned " \
13627                                 "logical start for lun $logical instead of 512"
13628                                 return
13629                         fi
13630                         if (( tot_len != 512 )); then
13631                                 cleanup_130
13632                                 error "FIEMAP on $fm_file failed; returned " \
13633                                 "len $tot_len for OST $last_lun instead of 1024"
13634                                 return
13635                         else
13636                                 (( num_luns += 1 ))
13637                                 tot_len=0
13638                         fi
13639                 fi
13640                 (( tot_len += ext_len ))
13641                 last_lun=$frag_lun
13642         done
13643         if (( num_luns != 2 || tot_len != 512 )); then
13644                 cleanup_130
13645                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13646                         "luns or wrong len for OST $last_lun"
13647                 return
13648         fi
13649
13650         cleanup_130
13651
13652         echo "FIEMAP on 2-stripe file with hole succeeded"
13653 }
13654 run_test 130c "FIEMAP (2-stripe file with hole)"
13655
13656 test_130d() {
13657         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13658
13659         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13660         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13661
13662         trap cleanup_130 EXIT RETURN
13663
13664         local fm_file=$DIR/$tfile
13665         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13666                         error "setstripe on $fm_file"
13667         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13668                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13669
13670         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13671         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13672                 error "dd failed on $fm_file"
13673
13674         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13675         filefrag_op=$(filefrag -ve -k $fm_file |
13676                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13677
13678         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13679                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13680
13681         IFS=$'\n'
13682         tot_len=0
13683         num_luns=1
13684         for line in $filefrag_op
13685         do
13686                 frag_lun=$(echo $line | cut -d: -f5 |
13687                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13688                 ext_len=$(echo $line | cut -d: -f4)
13689                 if (( $frag_lun != $last_lun )); then
13690                         if (( tot_len != 1024 )); then
13691                                 cleanup_130
13692                                 error "FIEMAP on $fm_file failed; returned " \
13693                                 "len $tot_len for OST $last_lun instead of 1024"
13694                                 return
13695                         else
13696                                 (( num_luns += 1 ))
13697                                 tot_len=0
13698                         fi
13699                 fi
13700                 (( tot_len += ext_len ))
13701                 last_lun=$frag_lun
13702         done
13703         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13704                 cleanup_130
13705                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13706                         "luns or wrong len for OST $last_lun"
13707                 return
13708         fi
13709
13710         cleanup_130
13711
13712         echo "FIEMAP on N-stripe file succeeded"
13713 }
13714 run_test 130d "FIEMAP (N-stripe file)"
13715
13716 test_130e() {
13717         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13718
13719         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13720         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13721
13722         trap cleanup_130 EXIT RETURN
13723
13724         local fm_file=$DIR/$tfile
13725         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13726
13727         NUM_BLKS=512
13728         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13729         for ((i = 0; i < $NUM_BLKS; i++)); do
13730                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13731                         conv=notrunc > /dev/null 2>&1
13732         done
13733
13734         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13735         filefrag_op=$(filefrag -ve -k $fm_file |
13736                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13737
13738         last_lun=$(echo $filefrag_op | cut -d: -f5)
13739
13740         IFS=$'\n'
13741         tot_len=0
13742         num_luns=1
13743         for line in $filefrag_op; do
13744                 frag_lun=$(echo $line | cut -d: -f5)
13745                 ext_len=$(echo $line | cut -d: -f4)
13746                 if [[ "$frag_lun" != "$last_lun" ]]; then
13747                         if (( tot_len != $EXPECTED_LEN )); then
13748                                 cleanup_130
13749                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13750                         else
13751                                 (( num_luns += 1 ))
13752                                 tot_len=0
13753                         fi
13754                 fi
13755                 (( tot_len += ext_len ))
13756                 last_lun=$frag_lun
13757         done
13758         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13759                 cleanup_130
13760                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13761         fi
13762
13763         echo "FIEMAP with continuation calls succeeded"
13764 }
13765 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13766
13767 test_130f() {
13768         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13769         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13770
13771         local fm_file=$DIR/$tfile
13772         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13773                 error "multiop create with lov_delay_create on $fm_file"
13774
13775         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13776         filefrag_extents=$(filefrag -vek $fm_file |
13777                            awk '/extents? found/ { print $2 }')
13778         if [[ "$filefrag_extents" != "0" ]]; then
13779                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13780         fi
13781
13782         rm -f $fm_file
13783 }
13784 run_test 130f "FIEMAP (unstriped file)"
13785
13786 test_130g() {
13787         local file=$DIR/$tfile
13788         local nr=$((OSTCOUNT * 100))
13789
13790         $LFS setstripe -C $nr $file ||
13791                 error "failed to setstripe -C $nr $file"
13792
13793         dd if=/dev/zero of=$file count=$nr bs=1M
13794         sync
13795         nr=$($LFS getstripe -c $file)
13796
13797         local extents=$(filefrag -v $file |
13798                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13799
13800         echo "filefrag list $extents extents in file with stripecount $nr"
13801         if (( extents < nr )); then
13802                 $LFS getstripe $file
13803                 filefrag -v $file
13804                 error "filefrag printed $extents < $nr extents"
13805         fi
13806
13807         rm -f $file
13808 }
13809 run_test 130g "FIEMAP (overstripe file)"
13810
13811 # Test for writev/readv
13812 test_131a() {
13813         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13814                 error "writev test failed"
13815         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13816                 error "readv failed"
13817         rm -f $DIR/$tfile
13818 }
13819 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13820
13821 test_131b() {
13822         local fsize=$((524288 + 1048576 + 1572864))
13823         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13824                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13825                         error "append writev test failed"
13826
13827         ((fsize += 1572864 + 1048576))
13828         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13829                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13830                         error "append writev test failed"
13831         rm -f $DIR/$tfile
13832 }
13833 run_test 131b "test append writev"
13834
13835 test_131c() {
13836         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13837         error "NOT PASS"
13838 }
13839 run_test 131c "test read/write on file w/o objects"
13840
13841 test_131d() {
13842         rwv -f $DIR/$tfile -w -n 1 1572864
13843         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13844         if [ "$NOB" != 1572864 ]; then
13845                 error "Short read filed: read $NOB bytes instead of 1572864"
13846         fi
13847         rm -f $DIR/$tfile
13848 }
13849 run_test 131d "test short read"
13850
13851 test_131e() {
13852         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13853         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13854         error "read hitting hole failed"
13855         rm -f $DIR/$tfile
13856 }
13857 run_test 131e "test read hitting hole"
13858
13859 check_stats() {
13860         local facet=$1
13861         local op=$2
13862         local want=${3:-0}
13863         local res
13864
13865         case $facet in
13866         mds*) res=$(do_facet $facet \
13867                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13868                  ;;
13869         ost*) res=$(do_facet $facet \
13870                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13871                  ;;
13872         *) error "Wrong facet '$facet'" ;;
13873         esac
13874         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13875         # if the argument $3 is zero, it means any stat increment is ok.
13876         if [[ $want -gt 0 ]]; then
13877                 local count=$(echo $res | awk '{ print $2 }')
13878                 [[ $count -ne $want ]] &&
13879                         error "The $op counter on $facet is $count, not $want"
13880         fi
13881 }
13882
13883 test_133a() {
13884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13885         remote_ost_nodsh && skip "remote OST with nodsh"
13886         remote_mds_nodsh && skip "remote MDS with nodsh"
13887         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13888                 skip_env "MDS doesn't support rename stats"
13889
13890         local testdir=$DIR/${tdir}/stats_testdir
13891
13892         mkdir -p $DIR/${tdir}
13893
13894         # clear stats.
13895         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13896         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13897
13898         # verify mdt stats first.
13899         mkdir ${testdir} || error "mkdir failed"
13900         check_stats $SINGLEMDS "mkdir" 1
13901         touch ${testdir}/${tfile} || error "touch failed"
13902         check_stats $SINGLEMDS "open" 1
13903         check_stats $SINGLEMDS "close" 1
13904         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13905                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13906                 check_stats $SINGLEMDS "mknod" 2
13907         }
13908         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13909         check_stats $SINGLEMDS "unlink" 1
13910         rm -f ${testdir}/${tfile} || error "file remove failed"
13911         check_stats $SINGLEMDS "unlink" 2
13912
13913         # remove working dir and check mdt stats again.
13914         rmdir ${testdir} || error "rmdir failed"
13915         check_stats $SINGLEMDS "rmdir" 1
13916
13917         local testdir1=$DIR/${tdir}/stats_testdir1
13918         mkdir -p ${testdir}
13919         mkdir -p ${testdir1}
13920         touch ${testdir1}/test1
13921         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13922         check_stats $SINGLEMDS "crossdir_rename" 1
13923
13924         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13925         check_stats $SINGLEMDS "samedir_rename" 1
13926
13927         rm -rf $DIR/${tdir}
13928 }
13929 run_test 133a "Verifying MDT stats ========================================"
13930
13931 test_133b() {
13932         local res
13933
13934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13935         remote_ost_nodsh && skip "remote OST with nodsh"
13936         remote_mds_nodsh && skip "remote MDS with nodsh"
13937
13938         local testdir=$DIR/${tdir}/stats_testdir
13939
13940         mkdir -p ${testdir} || error "mkdir failed"
13941         touch ${testdir}/${tfile} || error "touch failed"
13942         cancel_lru_locks mdc
13943
13944         # clear stats.
13945         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13946         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13947
13948         # extra mdt stats verification.
13949         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13950         check_stats $SINGLEMDS "setattr" 1
13951         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13952         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13953         then            # LU-1740
13954                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13955                 check_stats $SINGLEMDS "getattr" 1
13956         fi
13957         rm -rf $DIR/${tdir}
13958
13959         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13960         # so the check below is not reliable
13961         [ $MDSCOUNT -eq 1 ] || return 0
13962
13963         # Sleep to avoid a cached response.
13964         #define OBD_STATFS_CACHE_SECONDS 1
13965         sleep 2
13966         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13967         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13968         $LFS df || error "lfs failed"
13969         check_stats $SINGLEMDS "statfs" 1
13970
13971         # check aggregated statfs (LU-10018)
13972         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13973                 return 0
13974         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13975                 return 0
13976         sleep 2
13977         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13978         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13979         df $DIR
13980         check_stats $SINGLEMDS "statfs" 1
13981
13982         # We want to check that the client didn't send OST_STATFS to
13983         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13984         # extra care is needed here.
13985         if remote_mds; then
13986                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13987                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13988
13989                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13990                 [ "$res" ] && error "OST got STATFS"
13991         fi
13992
13993         return 0
13994 }
13995 run_test 133b "Verifying extra MDT stats =================================="
13996
13997 test_133c() {
13998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13999         remote_ost_nodsh && skip "remote OST with nodsh"
14000         remote_mds_nodsh && skip "remote MDS with nodsh"
14001
14002         local testdir=$DIR/$tdir/stats_testdir
14003
14004         test_mkdir -p $testdir
14005
14006         # verify obdfilter stats.
14007         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14008         sync
14009         cancel_lru_locks osc
14010         wait_delete_completed
14011
14012         # clear stats.
14013         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14014         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14015
14016         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14017                 error "dd failed"
14018         sync
14019         cancel_lru_locks osc
14020         check_stats ost1 "write" 1
14021
14022         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14023         check_stats ost1 "read" 1
14024
14025         > $testdir/$tfile || error "truncate failed"
14026         check_stats ost1 "punch" 1
14027
14028         rm -f $testdir/$tfile || error "file remove failed"
14029         wait_delete_completed
14030         check_stats ost1 "destroy" 1
14031
14032         rm -rf $DIR/$tdir
14033 }
14034 run_test 133c "Verifying OST stats ========================================"
14035
14036 order_2() {
14037         local value=$1
14038         local orig=$value
14039         local order=1
14040
14041         while [ $value -ge 2 ]; do
14042                 order=$((order*2))
14043                 value=$((value/2))
14044         done
14045
14046         if [ $orig -gt $order ]; then
14047                 order=$((order*2))
14048         fi
14049         echo $order
14050 }
14051
14052 size_in_KMGT() {
14053     local value=$1
14054     local size=('K' 'M' 'G' 'T');
14055     local i=0
14056     local size_string=$value
14057
14058     while [ $value -ge 1024 ]; do
14059         if [ $i -gt 3 ]; then
14060             #T is the biggest unit we get here, if that is bigger,
14061             #just return XXXT
14062             size_string=${value}T
14063             break
14064         fi
14065         value=$((value >> 10))
14066         if [ $value -lt 1024 ]; then
14067             size_string=${value}${size[$i]}
14068             break
14069         fi
14070         i=$((i + 1))
14071     done
14072
14073     echo $size_string
14074 }
14075
14076 get_rename_size() {
14077         local size=$1
14078         local context=${2:-.}
14079         local sample=$(do_facet $SINGLEMDS $LCTL \
14080                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14081                 grep -A1 $context |
14082                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14083         echo $sample
14084 }
14085
14086 test_133d() {
14087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14088         remote_ost_nodsh && skip "remote OST with nodsh"
14089         remote_mds_nodsh && skip "remote MDS with nodsh"
14090         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14091                 skip_env "MDS doesn't support rename stats"
14092
14093         local testdir1=$DIR/${tdir}/stats_testdir1
14094         local testdir2=$DIR/${tdir}/stats_testdir2
14095         mkdir -p $DIR/${tdir}
14096
14097         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14098
14099         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14100         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14101
14102         createmany -o $testdir1/test 512 || error "createmany failed"
14103
14104         # check samedir rename size
14105         mv ${testdir1}/test0 ${testdir1}/test_0
14106
14107         local testdir1_size=$(ls -l $DIR/${tdir} |
14108                 awk '/stats_testdir1/ {print $5}')
14109         local testdir2_size=$(ls -l $DIR/${tdir} |
14110                 awk '/stats_testdir2/ {print $5}')
14111
14112         testdir1_size=$(order_2 $testdir1_size)
14113         testdir2_size=$(order_2 $testdir2_size)
14114
14115         testdir1_size=$(size_in_KMGT $testdir1_size)
14116         testdir2_size=$(size_in_KMGT $testdir2_size)
14117
14118         echo "source rename dir size: ${testdir1_size}"
14119         echo "target rename dir size: ${testdir2_size}"
14120
14121         local cmd="do_facet $SINGLEMDS $LCTL "
14122         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14123
14124         eval $cmd || error "$cmd failed"
14125         local samedir=$($cmd | grep 'same_dir')
14126         local same_sample=$(get_rename_size $testdir1_size)
14127         [ -z "$samedir" ] && error "samedir_rename_size count error"
14128         [[ $same_sample -eq 1 ]] ||
14129                 error "samedir_rename_size error $same_sample"
14130         echo "Check same dir rename stats success"
14131
14132         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14133
14134         # check crossdir rename size
14135         mv ${testdir1}/test_0 ${testdir2}/test_0
14136
14137         testdir1_size=$(ls -l $DIR/${tdir} |
14138                 awk '/stats_testdir1/ {print $5}')
14139         testdir2_size=$(ls -l $DIR/${tdir} |
14140                 awk '/stats_testdir2/ {print $5}')
14141
14142         testdir1_size=$(order_2 $testdir1_size)
14143         testdir2_size=$(order_2 $testdir2_size)
14144
14145         testdir1_size=$(size_in_KMGT $testdir1_size)
14146         testdir2_size=$(size_in_KMGT $testdir2_size)
14147
14148         echo "source rename dir size: ${testdir1_size}"
14149         echo "target rename dir size: ${testdir2_size}"
14150
14151         eval $cmd || error "$cmd failed"
14152         local crossdir=$($cmd | grep 'crossdir')
14153         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14154         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14155         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14156         [[ $src_sample -eq 1 ]] ||
14157                 error "crossdir_rename_size error $src_sample"
14158         [[ $tgt_sample -eq 1 ]] ||
14159                 error "crossdir_rename_size error $tgt_sample"
14160         echo "Check cross dir rename stats success"
14161         rm -rf $DIR/${tdir}
14162 }
14163 run_test 133d "Verifying rename_stats ========================================"
14164
14165 test_133e() {
14166         remote_mds_nodsh && skip "remote MDS with nodsh"
14167         remote_ost_nodsh && skip "remote OST with nodsh"
14168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14169
14170         local testdir=$DIR/${tdir}/stats_testdir
14171         local ctr f0 f1 bs=32768 count=42 sum
14172
14173         mkdir -p ${testdir} || error "mkdir failed"
14174
14175         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14176
14177         for ctr in {write,read}_bytes; do
14178                 sync
14179                 cancel_lru_locks osc
14180
14181                 do_facet ost1 $LCTL set_param -n \
14182                         "obdfilter.*.exports.clear=clear"
14183
14184                 if [ $ctr = write_bytes ]; then
14185                         f0=/dev/zero
14186                         f1=${testdir}/${tfile}
14187                 else
14188                         f0=${testdir}/${tfile}
14189                         f1=/dev/null
14190                 fi
14191
14192                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14193                         error "dd failed"
14194                 sync
14195                 cancel_lru_locks osc
14196
14197                 sum=$(do_facet ost1 $LCTL get_param \
14198                         "obdfilter.*.exports.*.stats" |
14199                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14200                                 $1 == ctr { sum += $7 }
14201                                 END { printf("%0.0f", sum) }')
14202
14203                 if ((sum != bs * count)); then
14204                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14205                 fi
14206         done
14207
14208         rm -rf $DIR/${tdir}
14209 }
14210 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14211
14212 test_133f() {
14213         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14214                 skip "too old lustre for get_param -R ($facet_ver)"
14215
14216         # verifying readability.
14217         $LCTL get_param -R '*' &> /dev/null
14218
14219         # Verifing writability with badarea_io.
14220         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14221         local skipped_params='force_lbug|changelog_mask|daemon_file'
14222         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14223                 egrep -v "$skipped_params" |
14224                 xargs -n 1 find $proc_dirs -name |
14225                 xargs -n 1 badarea_io ||
14226                 error "client badarea_io failed"
14227
14228         # remount the FS in case writes/reads /proc break the FS
14229         cleanup || error "failed to unmount"
14230         setup || error "failed to setup"
14231 }
14232 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14233
14234 test_133g() {
14235         remote_mds_nodsh && skip "remote MDS with nodsh"
14236         remote_ost_nodsh && skip "remote OST with nodsh"
14237
14238         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14239         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14240         local facet
14241         for facet in mds1 ost1; do
14242                 local facet_ver=$(lustre_version_code $facet)
14243                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14244                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14245                 else
14246                         log "$facet: too old lustre for get_param -R"
14247                 fi
14248                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14249                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14250                                 tr -d = | egrep -v $skipped_params |
14251                                 xargs -n 1 find $proc_dirs -name |
14252                                 xargs -n 1 badarea_io" ||
14253                                         error "$facet badarea_io failed"
14254                 else
14255                         skip_noexit "$facet: too old lustre for get_param -R"
14256                 fi
14257         done
14258
14259         # remount the FS in case writes/reads /proc break the FS
14260         cleanup || error "failed to unmount"
14261         setup || error "failed to setup"
14262 }
14263 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14264
14265 test_133h() {
14266         remote_mds_nodsh && skip "remote MDS with nodsh"
14267         remote_ost_nodsh && skip "remote OST with nodsh"
14268         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14269                 skip "Need MDS version at least 2.9.54"
14270
14271         local facet
14272         for facet in client mds1 ost1; do
14273                 # Get the list of files that are missing the terminating newline
14274                 local plist=$(do_facet $facet
14275                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14276                 local ent
14277                 for ent in $plist; do
14278                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14279                                 awk -v FS='\v' -v RS='\v\v' \
14280                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14281                                         print FILENAME}'" 2>/dev/null)
14282                         [ -z $missing ] || {
14283                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14284                                 error "file does not end with newline: $facet-$ent"
14285                         }
14286                 done
14287         done
14288 }
14289 run_test 133h "Proc files should end with newlines"
14290
14291 test_134a() {
14292         remote_mds_nodsh && skip "remote MDS with nodsh"
14293         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14294                 skip "Need MDS version at least 2.7.54"
14295
14296         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14297         cancel_lru_locks mdc
14298
14299         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14300         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14301         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14302
14303         local nr=1000
14304         createmany -o $DIR/$tdir/f $nr ||
14305                 error "failed to create $nr files in $DIR/$tdir"
14306         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14307
14308         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14309         do_facet mds1 $LCTL set_param fail_loc=0x327
14310         do_facet mds1 $LCTL set_param fail_val=500
14311         touch $DIR/$tdir/m
14312
14313         echo "sleep 10 seconds ..."
14314         sleep 10
14315         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14316
14317         do_facet mds1 $LCTL set_param fail_loc=0
14318         do_facet mds1 $LCTL set_param fail_val=0
14319         [ $lck_cnt -lt $unused ] ||
14320                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14321
14322         rm $DIR/$tdir/m
14323         unlinkmany $DIR/$tdir/f $nr
14324 }
14325 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14326
14327 test_134b() {
14328         remote_mds_nodsh && skip "remote MDS with nodsh"
14329         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14330                 skip "Need MDS version at least 2.7.54"
14331
14332         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14333         cancel_lru_locks mdc
14334
14335         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14336                         ldlm.lock_reclaim_threshold_mb)
14337         # disable reclaim temporarily
14338         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14339
14340         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14341         do_facet mds1 $LCTL set_param fail_loc=0x328
14342         do_facet mds1 $LCTL set_param fail_val=500
14343
14344         $LCTL set_param debug=+trace
14345
14346         local nr=600
14347         createmany -o $DIR/$tdir/f $nr &
14348         local create_pid=$!
14349
14350         echo "Sleep $TIMEOUT seconds ..."
14351         sleep $TIMEOUT
14352         if ! ps -p $create_pid  > /dev/null 2>&1; then
14353                 do_facet mds1 $LCTL set_param fail_loc=0
14354                 do_facet mds1 $LCTL set_param fail_val=0
14355                 do_facet mds1 $LCTL set_param \
14356                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14357                 error "createmany finished incorrectly!"
14358         fi
14359         do_facet mds1 $LCTL set_param fail_loc=0
14360         do_facet mds1 $LCTL set_param fail_val=0
14361         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14362         wait $create_pid || return 1
14363
14364         unlinkmany $DIR/$tdir/f $nr
14365 }
14366 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14367
14368 test_135() {
14369         remote_mds_nodsh && skip "remote MDS with nodsh"
14370         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14371                 skip "Need MDS version at least 2.13.50"
14372         local fname
14373
14374         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14375
14376 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14377         #set only one record at plain llog
14378         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14379
14380         #fill already existed plain llog each 64767
14381         #wrapping whole catalog
14382         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14383
14384         createmany -o $DIR/$tdir/$tfile_ 64700
14385         for (( i = 0; i < 64700; i = i + 2 ))
14386         do
14387                 rm $DIR/$tdir/$tfile_$i &
14388                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14389                 local pid=$!
14390                 wait $pid
14391         done
14392
14393         #waiting osp synchronization
14394         wait_delete_completed
14395 }
14396 run_test 135 "Race catalog processing"
14397
14398 test_136() {
14399         remote_mds_nodsh && skip "remote MDS with nodsh"
14400         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14401                 skip "Need MDS version at least 2.13.50"
14402         local fname
14403
14404         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14405         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14406         #set only one record at plain llog
14407 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14408         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14409
14410         #fill already existed 2 plain llogs each 64767
14411         #wrapping whole catalog
14412         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14413         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14414         wait_delete_completed
14415
14416         createmany -o $DIR/$tdir/$tfile_ 10
14417         sleep 25
14418
14419         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14420         for (( i = 0; i < 10; i = i + 3 ))
14421         do
14422                 rm $DIR/$tdir/$tfile_$i &
14423                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14424                 local pid=$!
14425                 wait $pid
14426                 sleep 7
14427                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14428         done
14429
14430         #waiting osp synchronization
14431         wait_delete_completed
14432 }
14433 run_test 136 "Race catalog processing 2"
14434
14435 test_140() { #bug-17379
14436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14437
14438         test_mkdir $DIR/$tdir
14439         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14440         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14441
14442         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14443         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14444         local i=0
14445         while i=$((i + 1)); do
14446                 test_mkdir $i
14447                 cd $i || error "Changing to $i"
14448                 ln -s ../stat stat || error "Creating stat symlink"
14449                 # Read the symlink until ELOOP present,
14450                 # not LBUGing the system is considered success,
14451                 # we didn't overrun the stack.
14452                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14453                 if [ $ret -ne 0 ]; then
14454                         if [ $ret -eq 40 ]; then
14455                                 break  # -ELOOP
14456                         else
14457                                 error "Open stat symlink"
14458                                         return
14459                         fi
14460                 fi
14461         done
14462         i=$((i - 1))
14463         echo "The symlink depth = $i"
14464         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14465                 error "Invalid symlink depth"
14466
14467         # Test recursive symlink
14468         ln -s symlink_self symlink_self
14469         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14470         echo "open symlink_self returns $ret"
14471         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14472 }
14473 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14474
14475 test_150a() {
14476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14477
14478         local TF="$TMP/$tfile"
14479
14480         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14481         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14482         cp $TF $DIR/$tfile
14483         cancel_lru_locks $OSC
14484         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14485         remount_client $MOUNT
14486         df -P $MOUNT
14487         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14488
14489         $TRUNCATE $TF 6000
14490         $TRUNCATE $DIR/$tfile 6000
14491         cancel_lru_locks $OSC
14492         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14493
14494         echo "12345" >>$TF
14495         echo "12345" >>$DIR/$tfile
14496         cancel_lru_locks $OSC
14497         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14498
14499         echo "12345" >>$TF
14500         echo "12345" >>$DIR/$tfile
14501         cancel_lru_locks $OSC
14502         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14503 }
14504 run_test 150a "truncate/append tests"
14505
14506 test_150b() {
14507         check_set_fallocate_or_skip
14508
14509         touch $DIR/$tfile
14510         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14511         check_fallocate $DIR/$tfile || error "fallocate failed"
14512 }
14513 run_test 150b "Verify fallocate (prealloc) functionality"
14514
14515 test_150bb() {
14516         check_set_fallocate_or_skip
14517
14518         touch $DIR/$tfile
14519         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14520         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14521         > $DIR/$tfile
14522         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14523         # precomputed md5sum for 20MB of zeroes
14524         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14525         local sum=($(md5sum $DIR/$tfile))
14526
14527         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14528
14529         check_set_fallocate 1
14530
14531         > $DIR/$tfile
14532         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14533         sum=($(md5sum $DIR/$tfile))
14534
14535         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14536 }
14537 run_test 150bb "Verify fallocate modes both zero space"
14538
14539 test_150c() {
14540         check_set_fallocate_or_skip
14541         local striping="-c2"
14542
14543         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14544         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14545         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14546         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14547         local want=$((OSTCOUNT * 1048576))
14548
14549         # Must allocate all requested space, not more than 5% extra
14550         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14551                 error "bytes $bytes is not $want"
14552
14553         rm -f $DIR/$tfile
14554
14555         echo "verify fallocate on PFL file"
14556
14557         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14558
14559         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14560                 error "Create $DIR/$tfile failed"
14561         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14562                         error "fallocate failed"
14563         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14564         want=$((512 * 1048576))
14565
14566         # Must allocate all requested space, not more than 5% extra
14567         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14568                 error "bytes $bytes is not $want"
14569 }
14570 run_test 150c "Verify fallocate Size and Blocks"
14571
14572 test_150d() {
14573         check_set_fallocate_or_skip
14574         local striping="-c2"
14575
14576         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14577
14578         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14579         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14580                 error "setstripe failed"
14581         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14582         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14583         local want=$((OSTCOUNT * 1048576))
14584
14585         # Must allocate all requested space, not more than 5% extra
14586         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14587                 error "bytes $bytes is not $want"
14588 }
14589 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14590
14591 test_150e() {
14592         check_set_fallocate_or_skip
14593
14594         echo "df before:"
14595         $LFS df
14596         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14597         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14598                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14599
14600         # Find OST with Minimum Size
14601         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14602                        sort -un | head -1)
14603
14604         # Get 100MB per OST of the available space to reduce run time
14605         # else 60% of the available space if we are running SLOW tests
14606         if [ $SLOW == "no" ]; then
14607                 local space=$((1024 * 100 * OSTCOUNT))
14608         else
14609                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14610         fi
14611
14612         fallocate -l${space}k $DIR/$tfile ||
14613                 error "fallocate ${space}k $DIR/$tfile failed"
14614         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14615
14616         # get size immediately after fallocate. This should be correctly
14617         # updated
14618         local size=$(stat -c '%s' $DIR/$tfile)
14619         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14620
14621         # Sleep for a while for statfs to get updated. And not pull from cache.
14622         sleep 2
14623
14624         echo "df after fallocate:"
14625         $LFS df
14626
14627         (( size / 1024 == space )) || error "size $size != requested $space"
14628         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14629                 error "used $used < space $space"
14630
14631         rm $DIR/$tfile || error "rm failed"
14632         sync
14633         wait_delete_completed
14634
14635         echo "df after unlink:"
14636         $LFS df
14637 }
14638 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14639
14640 test_150f() {
14641         local size
14642         local blocks
14643         local want_size_before=20480 # in bytes
14644         local want_blocks_before=40 # 512 sized blocks
14645         local want_blocks_after=24  # 512 sized blocks
14646         local length=$(((want_blocks_before - want_blocks_after) * 512))
14647
14648         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14649                 skip "need at least 2.14.0 for fallocate punch"
14650
14651         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14652                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14653         fi
14654
14655         check_set_fallocate_or_skip
14656         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14657
14658         [[ "x$DOM" == "xyes" ]] &&
14659                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14660
14661         echo "Verify fallocate punch: Range within the file range"
14662         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14663                 error "dd failed for bs 4096 and count 5"
14664
14665         # Call fallocate with punch range which is within the file range
14666         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14667                 error "fallocate failed: offset 4096 and length $length"
14668         # client must see changes immediately after fallocate
14669         size=$(stat -c '%s' $DIR/$tfile)
14670         blocks=$(stat -c '%b' $DIR/$tfile)
14671
14672         # Verify punch worked.
14673         (( blocks == want_blocks_after )) ||
14674                 error "punch failed: blocks $blocks != $want_blocks_after"
14675
14676         (( size == want_size_before )) ||
14677                 error "punch failed: size $size != $want_size_before"
14678
14679         # Verify there is hole in file
14680         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14681         # precomputed md5sum
14682         local expect="4a9a834a2db02452929c0a348273b4aa"
14683
14684         cksum=($(md5sum $DIR/$tfile))
14685         [[ "${cksum[0]}" == "$expect" ]] ||
14686                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14687
14688         # Start second sub-case for fallocate punch.
14689         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14690         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14691                 error "dd failed for bs 4096 and count 5"
14692
14693         # Punch range less than block size will have no change in block count
14694         want_blocks_after=40  # 512 sized blocks
14695
14696         # Punch overlaps two blocks and less than blocksize
14697         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14698                 error "fallocate failed: offset 4000 length 3000"
14699         size=$(stat -c '%s' $DIR/$tfile)
14700         blocks=$(stat -c '%b' $DIR/$tfile)
14701
14702         # Verify punch worked.
14703         (( blocks == want_blocks_after )) ||
14704                 error "punch failed: blocks $blocks != $want_blocks_after"
14705
14706         (( size == want_size_before )) ||
14707                 error "punch failed: size $size != $want_size_before"
14708
14709         # Verify if range is really zero'ed out. We expect Zeros.
14710         # precomputed md5sum
14711         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14712         cksum=($(md5sum $DIR/$tfile))
14713         [[ "${cksum[0]}" == "$expect" ]] ||
14714                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14715 }
14716 run_test 150f "Verify fallocate punch functionality"
14717
14718 test_150g() {
14719         local space
14720         local size
14721         local blocks
14722         local blocks_after
14723         local size_after
14724         local BS=4096 # Block size in bytes
14725
14726         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14727                 skip "need at least 2.14.0 for fallocate punch"
14728
14729         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14730                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14731         fi
14732
14733         check_set_fallocate_or_skip
14734         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14735
14736         if [[ "x$DOM" == "xyes" ]]; then
14737                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14738                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14739         else
14740                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14741                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14742         fi
14743
14744         # Get 100MB per OST of the available space to reduce run time
14745         # else 60% of the available space if we are running SLOW tests
14746         if [ $SLOW == "no" ]; then
14747                 space=$((1024 * 100 * OSTCOUNT))
14748         else
14749                 # Find OST with Minimum Size
14750                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14751                         sort -un | head -1)
14752                 echo "min size OST: $space"
14753                 space=$(((space * 60)/100 * OSTCOUNT))
14754         fi
14755         # space in 1k units, round to 4k blocks
14756         local blkcount=$((space * 1024 / $BS))
14757
14758         echo "Verify fallocate punch: Very large Range"
14759         fallocate -l${space}k $DIR/$tfile ||
14760                 error "fallocate ${space}k $DIR/$tfile failed"
14761         # write 1M at the end, start and in the middle
14762         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14763                 error "dd failed: bs $BS count 256"
14764         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14765                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14766         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14767                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14768
14769         # Gather stats.
14770         size=$(stat -c '%s' $DIR/$tfile)
14771
14772         # gather punch length.
14773         local punch_size=$((size - (BS * 2)))
14774
14775         echo "punch_size = $punch_size"
14776         echo "size - punch_size: $((size - punch_size))"
14777         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14778
14779         # Call fallocate to punch all except 2 blocks. We leave the
14780         # first and the last block
14781         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14782         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14783                 error "fallocate failed: offset $BS length $punch_size"
14784
14785         size_after=$(stat -c '%s' $DIR/$tfile)
14786         blocks_after=$(stat -c '%b' $DIR/$tfile)
14787
14788         # Verify punch worked.
14789         # Size should be kept
14790         (( size == size_after )) ||
14791                 error "punch failed: size $size != $size_after"
14792
14793         # two 4k data blocks to remain plus possible 1 extra extent block
14794         (( blocks_after <= ((BS / 512) * 3) )) ||
14795                 error "too many blocks remains: $blocks_after"
14796
14797         # Verify that file has hole between the first and the last blocks
14798         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14799         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14800
14801         echo "Hole at [$hole_start, $hole_end)"
14802         (( hole_start == BS )) ||
14803                 error "no hole at offset $BS after punch"
14804
14805         (( hole_end == BS + punch_size )) ||
14806                 error "data at offset $hole_end < $((BS + punch_size))"
14807 }
14808 run_test 150g "Verify fallocate punch on large range"
14809
14810 #LU-2902 roc_hit was not able to read all values from lproc
14811 function roc_hit_init() {
14812         local list=$(comma_list $(osts_nodes))
14813         local dir=$DIR/$tdir-check
14814         local file=$dir/$tfile
14815         local BEFORE
14816         local AFTER
14817         local idx
14818
14819         test_mkdir $dir
14820         #use setstripe to do a write to every ost
14821         for i in $(seq 0 $((OSTCOUNT-1))); do
14822                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14823                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14824                 idx=$(printf %04x $i)
14825                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14826                         awk '$1 == "cache_access" {sum += $7}
14827                                 END { printf("%0.0f", sum) }')
14828
14829                 cancel_lru_locks osc
14830                 cat $file >/dev/null
14831
14832                 AFTER=$(get_osd_param $list *OST*$idx stats |
14833                         awk '$1 == "cache_access" {sum += $7}
14834                                 END { printf("%0.0f", sum) }')
14835
14836                 echo BEFORE:$BEFORE AFTER:$AFTER
14837                 if ! let "AFTER - BEFORE == 4"; then
14838                         rm -rf $dir
14839                         error "roc_hit is not safe to use"
14840                 fi
14841                 rm $file
14842         done
14843
14844         rm -rf $dir
14845 }
14846
14847 function roc_hit() {
14848         local list=$(comma_list $(osts_nodes))
14849         echo $(get_osd_param $list '' stats |
14850                 awk '$1 == "cache_hit" {sum += $7}
14851                         END { printf("%0.0f", sum) }')
14852 }
14853
14854 function set_cache() {
14855         local on=1
14856
14857         if [ "$2" == "off" ]; then
14858                 on=0;
14859         fi
14860         local list=$(comma_list $(osts_nodes))
14861         set_osd_param $list '' $1_cache_enable $on
14862
14863         cancel_lru_locks osc
14864 }
14865
14866 test_151() {
14867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14868         remote_ost_nodsh && skip "remote OST with nodsh"
14869
14870         local CPAGES=3
14871         local list=$(comma_list $(osts_nodes))
14872
14873         # check whether obdfilter is cache capable at all
14874         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14875                 skip "not cache-capable obdfilter"
14876         fi
14877
14878         # check cache is enabled on all obdfilters
14879         if get_osd_param $list '' read_cache_enable | grep 0; then
14880                 skip "oss cache is disabled"
14881         fi
14882
14883         set_osd_param $list '' writethrough_cache_enable 1
14884
14885         # check write cache is enabled on all obdfilters
14886         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14887                 skip "oss write cache is NOT enabled"
14888         fi
14889
14890         roc_hit_init
14891
14892         #define OBD_FAIL_OBD_NO_LRU  0x609
14893         do_nodes $list $LCTL set_param fail_loc=0x609
14894
14895         # pages should be in the case right after write
14896         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14897                 error "dd failed"
14898
14899         local BEFORE=$(roc_hit)
14900         cancel_lru_locks osc
14901         cat $DIR/$tfile >/dev/null
14902         local AFTER=$(roc_hit)
14903
14904         do_nodes $list $LCTL set_param fail_loc=0
14905
14906         if ! let "AFTER - BEFORE == CPAGES"; then
14907                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14908         fi
14909
14910         cancel_lru_locks osc
14911         # invalidates OST cache
14912         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14913         set_osd_param $list '' read_cache_enable 0
14914         cat $DIR/$tfile >/dev/null
14915
14916         # now data shouldn't be found in the cache
14917         BEFORE=$(roc_hit)
14918         cancel_lru_locks osc
14919         cat $DIR/$tfile >/dev/null
14920         AFTER=$(roc_hit)
14921         if let "AFTER - BEFORE != 0"; then
14922                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14923         fi
14924
14925         set_osd_param $list '' read_cache_enable 1
14926         rm -f $DIR/$tfile
14927 }
14928 run_test 151 "test cache on oss and controls ==============================="
14929
14930 test_152() {
14931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14932
14933         local TF="$TMP/$tfile"
14934
14935         # simulate ENOMEM during write
14936 #define OBD_FAIL_OST_NOMEM      0x226
14937         lctl set_param fail_loc=0x80000226
14938         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14939         cp $TF $DIR/$tfile
14940         sync || error "sync failed"
14941         lctl set_param fail_loc=0
14942
14943         # discard client's cache
14944         cancel_lru_locks osc
14945
14946         # simulate ENOMEM during read
14947         lctl set_param fail_loc=0x80000226
14948         cmp $TF $DIR/$tfile || error "cmp failed"
14949         lctl set_param fail_loc=0
14950
14951         rm -f $TF
14952 }
14953 run_test 152 "test read/write with enomem ============================"
14954
14955 test_153() {
14956         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14957 }
14958 run_test 153 "test if fdatasync does not crash ======================="
14959
14960 dot_lustre_fid_permission_check() {
14961         local fid=$1
14962         local ffid=$MOUNT/.lustre/fid/$fid
14963         local test_dir=$2
14964
14965         echo "stat fid $fid"
14966         stat $ffid > /dev/null || error "stat $ffid failed."
14967         echo "touch fid $fid"
14968         touch $ffid || error "touch $ffid failed."
14969         echo "write to fid $fid"
14970         cat /etc/hosts > $ffid || error "write $ffid failed."
14971         echo "read fid $fid"
14972         diff /etc/hosts $ffid || error "read $ffid failed."
14973         echo "append write to fid $fid"
14974         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14975         echo "rename fid $fid"
14976         mv $ffid $test_dir/$tfile.1 &&
14977                 error "rename $ffid to $tfile.1 should fail."
14978         touch $test_dir/$tfile.1
14979         mv $test_dir/$tfile.1 $ffid &&
14980                 error "rename $tfile.1 to $ffid should fail."
14981         rm -f $test_dir/$tfile.1
14982         echo "truncate fid $fid"
14983         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14984         echo "link fid $fid"
14985         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14986         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14987                 echo "setfacl fid $fid"
14988                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14989                 echo "getfacl fid $fid"
14990                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14991         fi
14992         echo "unlink fid $fid"
14993         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14994         echo "mknod fid $fid"
14995         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14996
14997         fid=[0xf00000400:0x1:0x0]
14998         ffid=$MOUNT/.lustre/fid/$fid
14999
15000         echo "stat non-exist fid $fid"
15001         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15002         echo "write to non-exist fid $fid"
15003         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15004         echo "link new fid $fid"
15005         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15006
15007         mkdir -p $test_dir/$tdir
15008         touch $test_dir/$tdir/$tfile
15009         fid=$($LFS path2fid $test_dir/$tdir)
15010         rc=$?
15011         [ $rc -ne 0 ] &&
15012                 error "error: could not get fid for $test_dir/$dir/$tfile."
15013
15014         ffid=$MOUNT/.lustre/fid/$fid
15015
15016         echo "ls $fid"
15017         ls $ffid > /dev/null || error "ls $ffid failed."
15018         echo "touch $fid/$tfile.1"
15019         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15020
15021         echo "touch $MOUNT/.lustre/fid/$tfile"
15022         touch $MOUNT/.lustre/fid/$tfile && \
15023                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15024
15025         echo "setxattr to $MOUNT/.lustre/fid"
15026         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15027
15028         echo "listxattr for $MOUNT/.lustre/fid"
15029         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15030
15031         echo "delxattr from $MOUNT/.lustre/fid"
15032         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15033
15034         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15035         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15036                 error "touch invalid fid should fail."
15037
15038         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15039         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15040                 error "touch non-normal fid should fail."
15041
15042         echo "rename $tdir to $MOUNT/.lustre/fid"
15043         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15044                 error "rename to $MOUNT/.lustre/fid should fail."
15045
15046         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15047         then            # LU-3547
15048                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15049                 local new_obf_mode=777
15050
15051                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15052                 chmod $new_obf_mode $DIR/.lustre/fid ||
15053                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15054
15055                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15056                 [ $obf_mode -eq $new_obf_mode ] ||
15057                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15058
15059                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15060                 chmod $old_obf_mode $DIR/.lustre/fid ||
15061                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15062         fi
15063
15064         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15065         fid=$($LFS path2fid $test_dir/$tfile-2)
15066
15067         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15068         then # LU-5424
15069                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15070                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15071                         error "create lov data thru .lustre failed"
15072         fi
15073         echo "cp /etc/passwd $test_dir/$tfile-2"
15074         cp /etc/passwd $test_dir/$tfile-2 ||
15075                 error "copy to $test_dir/$tfile-2 failed."
15076         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15077         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15078                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15079
15080         rm -rf $test_dir/tfile.lnk
15081         rm -rf $test_dir/$tfile-2
15082 }
15083
15084 test_154A() {
15085         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15086                 skip "Need MDS version at least 2.4.1"
15087
15088         local tf=$DIR/$tfile
15089         touch $tf
15090
15091         local fid=$($LFS path2fid $tf)
15092         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15093
15094         # check that we get the same pathname back
15095         local rootpath
15096         local found
15097         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15098                 echo "$rootpath $fid"
15099                 found=$($LFS fid2path $rootpath "$fid")
15100                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15101                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15102         done
15103
15104         # check wrong root path format
15105         rootpath=$MOUNT"_wrong"
15106         found=$($LFS fid2path $rootpath "$fid")
15107         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15108 }
15109 run_test 154A "lfs path2fid and fid2path basic checks"
15110
15111 test_154B() {
15112         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15113                 skip "Need MDS version at least 2.4.1"
15114
15115         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15116         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15117         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15118         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15119
15120         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15121         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15122
15123         # check that we get the same pathname
15124         echo "PFID: $PFID, name: $name"
15125         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15126         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15127         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15128                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15129
15130         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15131 }
15132 run_test 154B "verify the ll_decode_linkea tool"
15133
15134 test_154a() {
15135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15136         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15137         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15138                 skip "Need MDS version at least 2.2.51"
15139         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15140
15141         cp /etc/hosts $DIR/$tfile
15142
15143         fid=$($LFS path2fid $DIR/$tfile)
15144         rc=$?
15145         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15146
15147         dot_lustre_fid_permission_check "$fid" $DIR ||
15148                 error "dot lustre permission check $fid failed"
15149
15150         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15151
15152         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15153
15154         touch $MOUNT/.lustre/file &&
15155                 error "creation is not allowed under .lustre"
15156
15157         mkdir $MOUNT/.lustre/dir &&
15158                 error "mkdir is not allowed under .lustre"
15159
15160         rm -rf $DIR/$tfile
15161 }
15162 run_test 154a "Open-by-FID"
15163
15164 test_154b() {
15165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15166         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15168         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15169                 skip "Need MDS version at least 2.2.51"
15170
15171         local remote_dir=$DIR/$tdir/remote_dir
15172         local MDTIDX=1
15173         local rc=0
15174
15175         mkdir -p $DIR/$tdir
15176         $LFS mkdir -i $MDTIDX $remote_dir ||
15177                 error "create remote directory failed"
15178
15179         cp /etc/hosts $remote_dir/$tfile
15180
15181         fid=$($LFS path2fid $remote_dir/$tfile)
15182         rc=$?
15183         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15184
15185         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15186                 error "dot lustre permission check $fid failed"
15187         rm -rf $DIR/$tdir
15188 }
15189 run_test 154b "Open-by-FID for remote directory"
15190
15191 test_154c() {
15192         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15193                 skip "Need MDS version at least 2.4.1"
15194
15195         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15196         local FID1=$($LFS path2fid $DIR/$tfile.1)
15197         local FID2=$($LFS path2fid $DIR/$tfile.2)
15198         local FID3=$($LFS path2fid $DIR/$tfile.3)
15199
15200         local N=1
15201         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15202                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15203                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15204                 local want=FID$N
15205                 [ "$FID" = "${!want}" ] ||
15206                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15207                 N=$((N + 1))
15208         done
15209
15210         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15211         do
15212                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15213                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15214                 N=$((N + 1))
15215         done
15216 }
15217 run_test 154c "lfs path2fid and fid2path multiple arguments"
15218
15219 test_154d() {
15220         remote_mds_nodsh && skip "remote MDS with nodsh"
15221         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15222                 skip "Need MDS version at least 2.5.53"
15223
15224         if remote_mds; then
15225                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15226         else
15227                 nid="0@lo"
15228         fi
15229         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15230         local fd
15231         local cmd
15232
15233         rm -f $DIR/$tfile
15234         touch $DIR/$tfile
15235
15236         local fid=$($LFS path2fid $DIR/$tfile)
15237         # Open the file
15238         fd=$(free_fd)
15239         cmd="exec $fd<$DIR/$tfile"
15240         eval $cmd
15241         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15242         echo "$fid_list" | grep "$fid"
15243         rc=$?
15244
15245         cmd="exec $fd>/dev/null"
15246         eval $cmd
15247         if [ $rc -ne 0 ]; then
15248                 error "FID $fid not found in open files list $fid_list"
15249         fi
15250 }
15251 run_test 154d "Verify open file fid"
15252
15253 test_154e()
15254 {
15255         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15256                 skip "Need MDS version at least 2.6.50"
15257
15258         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15259                 error ".lustre returned by readdir"
15260         fi
15261 }
15262 run_test 154e ".lustre is not returned by readdir"
15263
15264 test_154f() {
15265         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15266
15267         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15268         mkdir_on_mdt0 $DIR/$tdir
15269         # test dirs inherit from its stripe
15270         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15271         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15272         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15273         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15274         touch $DIR/f
15275
15276         # get fid of parents
15277         local FID0=$($LFS path2fid $DIR/$tdir)
15278         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15279         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15280         local FID3=$($LFS path2fid $DIR)
15281
15282         # check that path2fid --parents returns expected <parent_fid>/name
15283         # 1) test for a directory (single parent)
15284         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15285         [ "$parent" == "$FID0/foo1" ] ||
15286                 error "expected parent: $FID0/foo1, got: $parent"
15287
15288         # 2) test for a file with nlink > 1 (multiple parents)
15289         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15290         echo "$parent" | grep -F "$FID1/$tfile" ||
15291                 error "$FID1/$tfile not returned in parent list"
15292         echo "$parent" | grep -F "$FID2/link" ||
15293                 error "$FID2/link not returned in parent list"
15294
15295         # 3) get parent by fid
15296         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15297         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15298         echo "$parent" | grep -F "$FID1/$tfile" ||
15299                 error "$FID1/$tfile not returned in parent list (by fid)"
15300         echo "$parent" | grep -F "$FID2/link" ||
15301                 error "$FID2/link not returned in parent list (by fid)"
15302
15303         # 4) test for entry in root directory
15304         parent=$($LFS path2fid --parents $DIR/f)
15305         echo "$parent" | grep -F "$FID3/f" ||
15306                 error "$FID3/f not returned in parent list"
15307
15308         # 5) test it on root directory
15309         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15310                 error "$MOUNT should not have parents"
15311
15312         # enable xattr caching and check that linkea is correctly updated
15313         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15314         save_lustre_params client "llite.*.xattr_cache" > $save
15315         lctl set_param llite.*.xattr_cache 1
15316
15317         # 6.1) linkea update on rename
15318         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15319
15320         # get parents by fid
15321         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15322         # foo1 should no longer be returned in parent list
15323         echo "$parent" | grep -F "$FID1" &&
15324                 error "$FID1 should no longer be in parent list"
15325         # the new path should appear
15326         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15327                 error "$FID2/$tfile.moved is not in parent list"
15328
15329         # 6.2) linkea update on unlink
15330         rm -f $DIR/$tdir/foo2/link
15331         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15332         # foo2/link should no longer be returned in parent list
15333         echo "$parent" | grep -F "$FID2/link" &&
15334                 error "$FID2/link should no longer be in parent list"
15335         true
15336
15337         rm -f $DIR/f
15338         restore_lustre_params < $save
15339         rm -f $save
15340 }
15341 run_test 154f "get parent fids by reading link ea"
15342
15343 test_154g()
15344 {
15345         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15346         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15347            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15348                 skip "Need MDS version at least 2.6.92"
15349
15350         mkdir_on_mdt0 $DIR/$tdir
15351         llapi_fid_test -d $DIR/$tdir
15352 }
15353 run_test 154g "various llapi FID tests"
15354
15355 test_155_small_load() {
15356     local temp=$TMP/$tfile
15357     local file=$DIR/$tfile
15358
15359     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15360         error "dd of=$temp bs=6096 count=1 failed"
15361     cp $temp $file
15362     cancel_lru_locks $OSC
15363     cmp $temp $file || error "$temp $file differ"
15364
15365     $TRUNCATE $temp 6000
15366     $TRUNCATE $file 6000
15367     cmp $temp $file || error "$temp $file differ (truncate1)"
15368
15369     echo "12345" >>$temp
15370     echo "12345" >>$file
15371     cmp $temp $file || error "$temp $file differ (append1)"
15372
15373     echo "12345" >>$temp
15374     echo "12345" >>$file
15375     cmp $temp $file || error "$temp $file differ (append2)"
15376
15377     rm -f $temp $file
15378     true
15379 }
15380
15381 test_155_big_load() {
15382         remote_ost_nodsh && skip "remote OST with nodsh"
15383
15384         local temp=$TMP/$tfile
15385         local file=$DIR/$tfile
15386
15387         free_min_max
15388         local cache_size=$(do_facet ost$((MAXI+1)) \
15389                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15390         local large_file_size=$((cache_size * 2))
15391
15392         echo "OSS cache size: $cache_size KB"
15393         echo "Large file size: $large_file_size KB"
15394
15395         [ $MAXV -le $large_file_size ] &&
15396                 skip_env "max available OST size needs > $large_file_size KB"
15397
15398         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15399
15400         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15401                 error "dd of=$temp bs=$large_file_size count=1k failed"
15402         cp $temp $file
15403         ls -lh $temp $file
15404         cancel_lru_locks osc
15405         cmp $temp $file || error "$temp $file differ"
15406
15407         rm -f $temp $file
15408         true
15409 }
15410
15411 save_writethrough() {
15412         local facets=$(get_facets OST)
15413
15414         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15415 }
15416
15417 test_155a() {
15418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15419
15420         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15421
15422         save_writethrough $p
15423
15424         set_cache read on
15425         set_cache writethrough on
15426         test_155_small_load
15427         restore_lustre_params < $p
15428         rm -f $p
15429 }
15430 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15431
15432 test_155b() {
15433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15434
15435         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15436
15437         save_writethrough $p
15438
15439         set_cache read on
15440         set_cache writethrough off
15441         test_155_small_load
15442         restore_lustre_params < $p
15443         rm -f $p
15444 }
15445 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15446
15447 test_155c() {
15448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15449
15450         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15451
15452         save_writethrough $p
15453
15454         set_cache read off
15455         set_cache writethrough on
15456         test_155_small_load
15457         restore_lustre_params < $p
15458         rm -f $p
15459 }
15460 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15461
15462 test_155d() {
15463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15464
15465         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15466
15467         save_writethrough $p
15468
15469         set_cache read off
15470         set_cache writethrough off
15471         test_155_small_load
15472         restore_lustre_params < $p
15473         rm -f $p
15474 }
15475 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15476
15477 test_155e() {
15478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15479
15480         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15481
15482         save_writethrough $p
15483
15484         set_cache read on
15485         set_cache writethrough on
15486         test_155_big_load
15487         restore_lustre_params < $p
15488         rm -f $p
15489 }
15490 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15491
15492 test_155f() {
15493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15494
15495         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15496
15497         save_writethrough $p
15498
15499         set_cache read on
15500         set_cache writethrough off
15501         test_155_big_load
15502         restore_lustre_params < $p
15503         rm -f $p
15504 }
15505 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15506
15507 test_155g() {
15508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15509
15510         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15511
15512         save_writethrough $p
15513
15514         set_cache read off
15515         set_cache writethrough on
15516         test_155_big_load
15517         restore_lustre_params < $p
15518         rm -f $p
15519 }
15520 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15521
15522 test_155h() {
15523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15524
15525         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15526
15527         save_writethrough $p
15528
15529         set_cache read off
15530         set_cache writethrough off
15531         test_155_big_load
15532         restore_lustre_params < $p
15533         rm -f $p
15534 }
15535 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15536
15537 test_156() {
15538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15539         remote_ost_nodsh && skip "remote OST with nodsh"
15540         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15541                 skip "stats not implemented on old servers"
15542         [ "$ost1_FSTYPE" = "zfs" ] &&
15543                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15544
15545         local CPAGES=3
15546         local BEFORE
15547         local AFTER
15548         local file="$DIR/$tfile"
15549         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15550
15551         save_writethrough $p
15552         roc_hit_init
15553
15554         log "Turn on read and write cache"
15555         set_cache read on
15556         set_cache writethrough on
15557
15558         log "Write data and read it back."
15559         log "Read should be satisfied from the cache."
15560         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15561         BEFORE=$(roc_hit)
15562         cancel_lru_locks osc
15563         cat $file >/dev/null
15564         AFTER=$(roc_hit)
15565         if ! let "AFTER - BEFORE == CPAGES"; then
15566                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15567         else
15568                 log "cache hits: before: $BEFORE, after: $AFTER"
15569         fi
15570
15571         log "Read again; it should be satisfied from the cache."
15572         BEFORE=$AFTER
15573         cancel_lru_locks osc
15574         cat $file >/dev/null
15575         AFTER=$(roc_hit)
15576         if ! let "AFTER - BEFORE == CPAGES"; then
15577                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15578         else
15579                 log "cache hits:: before: $BEFORE, after: $AFTER"
15580         fi
15581
15582         log "Turn off the read cache and turn on the write cache"
15583         set_cache read off
15584         set_cache writethrough on
15585
15586         log "Read again; it should be satisfied from the cache."
15587         BEFORE=$(roc_hit)
15588         cancel_lru_locks osc
15589         cat $file >/dev/null
15590         AFTER=$(roc_hit)
15591         if ! let "AFTER - BEFORE == CPAGES"; then
15592                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15593         else
15594                 log "cache hits:: before: $BEFORE, after: $AFTER"
15595         fi
15596
15597         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15598                 # > 2.12.56 uses pagecache if cached
15599                 log "Read again; it should not be satisfied from the cache."
15600                 BEFORE=$AFTER
15601                 cancel_lru_locks osc
15602                 cat $file >/dev/null
15603                 AFTER=$(roc_hit)
15604                 if ! let "AFTER - BEFORE == 0"; then
15605                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15606                 else
15607                         log "cache hits:: before: $BEFORE, after: $AFTER"
15608                 fi
15609         fi
15610
15611         log "Write data and read it back."
15612         log "Read should be satisfied from the cache."
15613         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15614         BEFORE=$(roc_hit)
15615         cancel_lru_locks osc
15616         cat $file >/dev/null
15617         AFTER=$(roc_hit)
15618         if ! let "AFTER - BEFORE == CPAGES"; then
15619                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15620         else
15621                 log "cache hits:: before: $BEFORE, after: $AFTER"
15622         fi
15623
15624         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15625                 # > 2.12.56 uses pagecache if cached
15626                 log "Read again; it should not be satisfied from the cache."
15627                 BEFORE=$AFTER
15628                 cancel_lru_locks osc
15629                 cat $file >/dev/null
15630                 AFTER=$(roc_hit)
15631                 if ! let "AFTER - BEFORE == 0"; then
15632                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15633                 else
15634                         log "cache hits:: before: $BEFORE, after: $AFTER"
15635                 fi
15636         fi
15637
15638         log "Turn off read and write cache"
15639         set_cache read off
15640         set_cache writethrough off
15641
15642         log "Write data and read it back"
15643         log "It should not be satisfied from the cache."
15644         rm -f $file
15645         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15646         cancel_lru_locks osc
15647         BEFORE=$(roc_hit)
15648         cat $file >/dev/null
15649         AFTER=$(roc_hit)
15650         if ! let "AFTER - BEFORE == 0"; then
15651                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15652         else
15653                 log "cache hits:: before: $BEFORE, after: $AFTER"
15654         fi
15655
15656         log "Turn on the read cache and turn off the write cache"
15657         set_cache read on
15658         set_cache writethrough off
15659
15660         log "Write data and read it back"
15661         log "It should not be satisfied from the cache."
15662         rm -f $file
15663         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15664         BEFORE=$(roc_hit)
15665         cancel_lru_locks osc
15666         cat $file >/dev/null
15667         AFTER=$(roc_hit)
15668         if ! let "AFTER - BEFORE == 0"; then
15669                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15670         else
15671                 log "cache hits:: before: $BEFORE, after: $AFTER"
15672         fi
15673
15674         log "Read again; it should be satisfied from the cache."
15675         BEFORE=$(roc_hit)
15676         cancel_lru_locks osc
15677         cat $file >/dev/null
15678         AFTER=$(roc_hit)
15679         if ! let "AFTER - BEFORE == CPAGES"; then
15680                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15681         else
15682                 log "cache hits:: before: $BEFORE, after: $AFTER"
15683         fi
15684
15685         restore_lustre_params < $p
15686         rm -f $p $file
15687 }
15688 run_test 156 "Verification of tunables"
15689
15690 test_160a() {
15691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15692         remote_mds_nodsh && skip "remote MDS with nodsh"
15693         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15694                 skip "Need MDS version at least 2.2.0"
15695
15696         changelog_register || error "changelog_register failed"
15697         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15698         changelog_users $SINGLEMDS | grep -q $cl_user ||
15699                 error "User $cl_user not found in changelog_users"
15700
15701         mkdir_on_mdt0 $DIR/$tdir
15702
15703         # change something
15704         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15705         changelog_clear 0 || error "changelog_clear failed"
15706         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15707         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15708         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15709         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15710         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15711         rm $DIR/$tdir/pics/desktop.jpg
15712
15713         echo "verifying changelog mask"
15714         changelog_chmask "-MKDIR"
15715         changelog_chmask "-CLOSE"
15716
15717         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15718         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15719
15720         changelog_chmask "+MKDIR"
15721         changelog_chmask "+CLOSE"
15722
15723         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15724         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15725
15726         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15727         CLOSES=$(changelog_dump | grep -c "CLOSE")
15728         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15729         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15730
15731         # verify contents
15732         echo "verifying target fid"
15733         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15734         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15735         [ "$fidc" == "$fidf" ] ||
15736                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15737         echo "verifying parent fid"
15738         # The FID returned from the Changelog may be the directory shard on
15739         # a different MDT, and not the FID returned by path2fid on the parent.
15740         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15741         # since this is what will matter when recreating this file in the tree.
15742         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15743         local pathp=$($LFS fid2path $MOUNT "$fidp")
15744         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15745                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15746
15747         echo "getting records for $cl_user"
15748         changelog_users $SINGLEMDS
15749         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15750         local nclr=3
15751         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15752                 error "changelog_clear failed"
15753         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15754         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15755         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15756                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15757
15758         local min0_rec=$(changelog_users $SINGLEMDS |
15759                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15760         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15761                           awk '{ print $1; exit; }')
15762
15763         changelog_dump | tail -n 5
15764         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15765         [ $first_rec == $((min0_rec + 1)) ] ||
15766                 error "first index should be $min0_rec + 1 not $first_rec"
15767
15768         # LU-3446 changelog index reset on MDT restart
15769         local cur_rec1=$(changelog_users $SINGLEMDS |
15770                          awk '/^current.index:/ { print $NF }')
15771         changelog_clear 0 ||
15772                 error "clear all changelog records for $cl_user failed"
15773         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15774         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15775                 error "Fail to start $SINGLEMDS"
15776         local cur_rec2=$(changelog_users $SINGLEMDS |
15777                          awk '/^current.index:/ { print $NF }')
15778         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15779         [ $cur_rec1 == $cur_rec2 ] ||
15780                 error "current index should be $cur_rec1 not $cur_rec2"
15781
15782         echo "verifying users from this test are deregistered"
15783         changelog_deregister || error "changelog_deregister failed"
15784         changelog_users $SINGLEMDS | grep -q $cl_user &&
15785                 error "User '$cl_user' still in changelog_users"
15786
15787         # lctl get_param -n mdd.*.changelog_users
15788         # current_index: 144
15789         # ID    index (idle seconds)
15790         # cl3   144   (2) mask=<list>
15791         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15792                 # this is the normal case where all users were deregistered
15793                 # make sure no new records are added when no users are present
15794                 local last_rec1=$(changelog_users $SINGLEMDS |
15795                                   awk '/^current.index:/ { print $NF }')
15796                 touch $DIR/$tdir/chloe
15797                 local last_rec2=$(changelog_users $SINGLEMDS |
15798                                   awk '/^current.index:/ { print $NF }')
15799                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15800                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15801         else
15802                 # any changelog users must be leftovers from a previous test
15803                 changelog_users $SINGLEMDS
15804                 echo "other changelog users; can't verify off"
15805         fi
15806 }
15807 run_test 160a "changelog sanity"
15808
15809 test_160b() { # LU-3587
15810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15811         remote_mds_nodsh && skip "remote MDS with nodsh"
15812         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15813                 skip "Need MDS version at least 2.2.0"
15814
15815         changelog_register || error "changelog_register failed"
15816         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15817         changelog_users $SINGLEMDS | grep -q $cl_user ||
15818                 error "User '$cl_user' not found in changelog_users"
15819
15820         local longname1=$(str_repeat a 255)
15821         local longname2=$(str_repeat b 255)
15822
15823         cd $DIR
15824         echo "creating very long named file"
15825         touch $longname1 || error "create of '$longname1' failed"
15826         echo "renaming very long named file"
15827         mv $longname1 $longname2
15828
15829         changelog_dump | grep RENME | tail -n 5
15830         rm -f $longname2
15831 }
15832 run_test 160b "Verify that very long rename doesn't crash in changelog"
15833
15834 test_160c() {
15835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15836         remote_mds_nodsh && skip "remote MDS with nodsh"
15837
15838         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15839                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15840                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15841                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15842
15843         local rc=0
15844
15845         # Registration step
15846         changelog_register || error "changelog_register failed"
15847
15848         rm -rf $DIR/$tdir
15849         mkdir -p $DIR/$tdir
15850         $MCREATE $DIR/$tdir/foo_160c
15851         changelog_chmask "-TRUNC"
15852         $TRUNCATE $DIR/$tdir/foo_160c 200
15853         changelog_chmask "+TRUNC"
15854         $TRUNCATE $DIR/$tdir/foo_160c 199
15855         changelog_dump | tail -n 5
15856         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15857         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15858 }
15859 run_test 160c "verify that changelog log catch the truncate event"
15860
15861 test_160d() {
15862         remote_mds_nodsh && skip "remote MDS with nodsh"
15863         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15865         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15866                 skip "Need MDS version at least 2.7.60"
15867
15868         # Registration step
15869         changelog_register || error "changelog_register failed"
15870
15871         mkdir -p $DIR/$tdir/migrate_dir
15872         changelog_clear 0 || error "changelog_clear failed"
15873
15874         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15875         changelog_dump | tail -n 5
15876         local migrates=$(changelog_dump | grep -c "MIGRT")
15877         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15878 }
15879 run_test 160d "verify that changelog log catch the migrate event"
15880
15881 test_160e() {
15882         remote_mds_nodsh && skip "remote MDS with nodsh"
15883
15884         # Create a user
15885         changelog_register || error "changelog_register failed"
15886
15887         local MDT0=$(facet_svc $SINGLEMDS)
15888         local rc
15889
15890         # No user (expect fail)
15891         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15892         rc=$?
15893         if [ $rc -eq 0 ]; then
15894                 error "Should fail without user"
15895         elif [ $rc -ne 4 ]; then
15896                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15897         fi
15898
15899         # Delete a future user (expect fail)
15900         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15901         rc=$?
15902         if [ $rc -eq 0 ]; then
15903                 error "Deleted non-existant user cl77"
15904         elif [ $rc -ne 2 ]; then
15905                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15906         fi
15907
15908         # Clear to a bad index (1 billion should be safe)
15909         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15910         rc=$?
15911
15912         if [ $rc -eq 0 ]; then
15913                 error "Successfully cleared to invalid CL index"
15914         elif [ $rc -ne 22 ]; then
15915                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15916         fi
15917 }
15918 run_test 160e "changelog negative testing (should return errors)"
15919
15920 test_160f() {
15921         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15922         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15923                 skip "Need MDS version at least 2.10.56"
15924
15925         local mdts=$(comma_list $(mdts_nodes))
15926
15927         # Create a user
15928         changelog_register || error "first changelog_register failed"
15929         changelog_register || error "second changelog_register failed"
15930         local cl_users
15931         declare -A cl_user1
15932         declare -A cl_user2
15933         local user_rec1
15934         local user_rec2
15935         local i
15936
15937         # generate some changelog records to accumulate on each MDT
15938         # use all_char because created files should be evenly distributed
15939         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15940                 error "test_mkdir $tdir failed"
15941         log "$(date +%s): creating first files"
15942         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15943                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15944                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15945         done
15946
15947         # check changelogs have been generated
15948         local start=$SECONDS
15949         local idle_time=$((MDSCOUNT * 5 + 5))
15950         local nbcl=$(changelog_dump | wc -l)
15951         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15952
15953         for param in "changelog_max_idle_time=$idle_time" \
15954                      "changelog_gc=1" \
15955                      "changelog_min_gc_interval=2" \
15956                      "changelog_min_free_cat_entries=3"; do
15957                 local MDT0=$(facet_svc $SINGLEMDS)
15958                 local var="${param%=*}"
15959                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15960
15961                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15962                 do_nodes $mdts $LCTL set_param mdd.*.$param
15963         done
15964
15965         # force cl_user2 to be idle (1st part), but also cancel the
15966         # cl_user1 records so that it is not evicted later in the test.
15967         local sleep1=$((idle_time / 2))
15968         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15969         sleep $sleep1
15970
15971         # simulate changelog catalog almost full
15972         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15973         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15974
15975         for i in $(seq $MDSCOUNT); do
15976                 cl_users=(${CL_USERS[mds$i]})
15977                 cl_user1[mds$i]="${cl_users[0]}"
15978                 cl_user2[mds$i]="${cl_users[1]}"
15979
15980                 [ -n "${cl_user1[mds$i]}" ] ||
15981                         error "mds$i: no user registered"
15982                 [ -n "${cl_user2[mds$i]}" ] ||
15983                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15984
15985                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15986                 [ -n "$user_rec1" ] ||
15987                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15988                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15989                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15990                 [ -n "$user_rec2" ] ||
15991                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15992                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15993                      "$user_rec1 + 2 == $user_rec2"
15994                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15995                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15996                               "$user_rec1 + 2, but is $user_rec2"
15997                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15998                 [ -n "$user_rec2" ] ||
15999                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16000                 [ $user_rec1 == $user_rec2 ] ||
16001                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16002                               "$user_rec1, but is $user_rec2"
16003         done
16004
16005         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16006         local sleep2=$((idle_time - (SECONDS - start) + 1))
16007         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16008         sleep $sleep2
16009
16010         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16011         # cl_user1 should be OK because it recently processed records.
16012         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16013         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16014                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16015                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16016         done
16017
16018         # ensure gc thread is done
16019         for i in $(mdts_nodes); do
16020                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16021                         error "$i: GC-thread not done"
16022         done
16023
16024         local first_rec
16025         for (( i = 1; i <= MDSCOUNT; i++ )); do
16026                 # check cl_user1 still registered
16027                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16028                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16029                 # check cl_user2 unregistered
16030                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16031                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16032
16033                 # check changelogs are present and starting at $user_rec1 + 1
16034                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16035                 [ -n "$user_rec1" ] ||
16036                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16037                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16038                             awk '{ print $1; exit; }')
16039
16040                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16041                 [ $((user_rec1 + 1)) == $first_rec ] ||
16042                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16043         done
16044 }
16045 run_test 160f "changelog garbage collect (timestamped users)"
16046
16047 test_160g() {
16048         remote_mds_nodsh && skip "remote MDS with nodsh"
16049         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16050                 skip "Need MDS version at least 2.14.55"
16051
16052         local mdts=$(comma_list $(mdts_nodes))
16053
16054         # Create a user
16055         changelog_register || error "first changelog_register failed"
16056         changelog_register || error "second changelog_register failed"
16057         local cl_users
16058         declare -A cl_user1
16059         declare -A cl_user2
16060         local user_rec1
16061         local user_rec2
16062         local i
16063
16064         # generate some changelog records to accumulate on each MDT
16065         # use all_char because created files should be evenly distributed
16066         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16067                 error "test_mkdir $tdir failed"
16068         for ((i = 0; i < MDSCOUNT; i++)); do
16069                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16070                         error "create $DIR/$tdir/d$i.1 failed"
16071         done
16072
16073         # check changelogs have been generated
16074         local nbcl=$(changelog_dump | wc -l)
16075         (( $nbcl > 0 )) || error "no changelogs found"
16076
16077         # reduce the max_idle_indexes value to make sure we exceed it
16078         for param in "changelog_max_idle_indexes=2" \
16079                      "changelog_gc=1" \
16080                      "changelog_min_gc_interval=2"; do
16081                 local MDT0=$(facet_svc $SINGLEMDS)
16082                 local var="${param%=*}"
16083                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16084
16085                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16086                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16087                         error "unable to set mdd.*.$param"
16088         done
16089
16090         local start=$SECONDS
16091         for i in $(seq $MDSCOUNT); do
16092                 cl_users=(${CL_USERS[mds$i]})
16093                 cl_user1[mds$i]="${cl_users[0]}"
16094                 cl_user2[mds$i]="${cl_users[1]}"
16095
16096                 [ -n "${cl_user1[mds$i]}" ] ||
16097                         error "mds$i: user1 is not registered"
16098                 [ -n "${cl_user2[mds$i]}" ] ||
16099                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16100
16101                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16102                 [ -n "$user_rec1" ] ||
16103                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16104                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16105                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16106                 [ -n "$user_rec2" ] ||
16107                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16108                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16109                      "$user_rec1 + 2 == $user_rec2"
16110                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16111                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16112                               "expected $user_rec1 + 2, but is $user_rec2"
16113                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16114                 [ -n "$user_rec2" ] ||
16115                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16116                 [ $user_rec1 == $user_rec2 ] ||
16117                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16118                               "expected $user_rec1, but is $user_rec2"
16119         done
16120
16121         # ensure we are past the previous changelog_min_gc_interval set above
16122         local sleep2=$((start + 2 - SECONDS))
16123         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16124         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16125         # cl_user1 should be OK because it recently processed records.
16126         for ((i = 0; i < MDSCOUNT; i++)); do
16127                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16128                         error "create $DIR/$tdir/d$i.3 failed"
16129         done
16130
16131         # ensure gc thread is done
16132         for i in $(mdts_nodes); do
16133                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16134                         error "$i: GC-thread not done"
16135         done
16136
16137         local first_rec
16138         for (( i = 1; i <= MDSCOUNT; i++ )); do
16139                 # check cl_user1 still registered
16140                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16141                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16142                 # check cl_user2 unregistered
16143                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16144                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16145
16146                 # check changelogs are present and starting at $user_rec1 + 1
16147                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16148                 [ -n "$user_rec1" ] ||
16149                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16150                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16151                             awk '{ print $1; exit; }')
16152
16153                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16154                 [ $((user_rec1 + 1)) == $first_rec ] ||
16155                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16156         done
16157 }
16158 run_test 160g "changelog garbage collect on idle records"
16159
16160 test_160h() {
16161         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16162         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16163                 skip "Need MDS version at least 2.10.56"
16164
16165         local mdts=$(comma_list $(mdts_nodes))
16166
16167         # Create a user
16168         changelog_register || error "first changelog_register failed"
16169         changelog_register || error "second changelog_register failed"
16170         local cl_users
16171         declare -A cl_user1
16172         declare -A cl_user2
16173         local user_rec1
16174         local user_rec2
16175         local i
16176
16177         # generate some changelog records to accumulate on each MDT
16178         # use all_char because created files should be evenly distributed
16179         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16180                 error "test_mkdir $tdir failed"
16181         for ((i = 0; i < MDSCOUNT; i++)); do
16182                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16183                         error "create $DIR/$tdir/d$i.1 failed"
16184         done
16185
16186         # check changelogs have been generated
16187         local nbcl=$(changelog_dump | wc -l)
16188         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16189
16190         for param in "changelog_max_idle_time=10" \
16191                      "changelog_gc=1" \
16192                      "changelog_min_gc_interval=2"; do
16193                 local MDT0=$(facet_svc $SINGLEMDS)
16194                 local var="${param%=*}"
16195                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16196
16197                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16198                 do_nodes $mdts $LCTL set_param mdd.*.$param
16199         done
16200
16201         # force cl_user2 to be idle (1st part)
16202         sleep 9
16203
16204         for i in $(seq $MDSCOUNT); do
16205                 cl_users=(${CL_USERS[mds$i]})
16206                 cl_user1[mds$i]="${cl_users[0]}"
16207                 cl_user2[mds$i]="${cl_users[1]}"
16208
16209                 [ -n "${cl_user1[mds$i]}" ] ||
16210                         error "mds$i: no user registered"
16211                 [ -n "${cl_user2[mds$i]}" ] ||
16212                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16213
16214                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16215                 [ -n "$user_rec1" ] ||
16216                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16217                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16218                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16219                 [ -n "$user_rec2" ] ||
16220                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16221                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16222                      "$user_rec1 + 2 == $user_rec2"
16223                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16224                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16225                               "$user_rec1 + 2, but is $user_rec2"
16226                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16227                 [ -n "$user_rec2" ] ||
16228                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16229                 [ $user_rec1 == $user_rec2 ] ||
16230                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16231                               "$user_rec1, but is $user_rec2"
16232         done
16233
16234         # force cl_user2 to be idle (2nd part) and to reach
16235         # changelog_max_idle_time
16236         sleep 2
16237
16238         # force each GC-thread start and block then
16239         # one per MDT/MDD, set fail_val accordingly
16240         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16241         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16242
16243         # generate more changelogs to trigger fail_loc
16244         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16245                 error "create $DIR/$tdir/${tfile}bis failed"
16246
16247         # stop MDT to stop GC-thread, should be done in back-ground as it will
16248         # block waiting for the thread to be released and exit
16249         declare -A stop_pids
16250         for i in $(seq $MDSCOUNT); do
16251                 stop mds$i &
16252                 stop_pids[mds$i]=$!
16253         done
16254
16255         for i in $(mdts_nodes); do
16256                 local facet
16257                 local nb=0
16258                 local facets=$(facets_up_on_host $i)
16259
16260                 for facet in ${facets//,/ }; do
16261                         if [[ $facet == mds* ]]; then
16262                                 nb=$((nb + 1))
16263                         fi
16264                 done
16265                 # ensure each MDS's gc threads are still present and all in "R"
16266                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16267                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16268                         error "$i: expected $nb GC-thread"
16269                 wait_update $i \
16270                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16271                         "R" 20 ||
16272                         error "$i: GC-thread not found in R-state"
16273                 # check umounts of each MDT on MDS have reached kthread_stop()
16274                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16275                         error "$i: expected $nb umount"
16276                 wait_update $i \
16277                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16278                         error "$i: umount not found in D-state"
16279         done
16280
16281         # release all GC-threads
16282         do_nodes $mdts $LCTL set_param fail_loc=0
16283
16284         # wait for MDT stop to complete
16285         for i in $(seq $MDSCOUNT); do
16286                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16287         done
16288
16289         # XXX
16290         # may try to check if any orphan changelog records are present
16291         # via ldiskfs/zfs and llog_reader...
16292
16293         # re-start/mount MDTs
16294         for i in $(seq $MDSCOUNT); do
16295                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16296                         error "Fail to start mds$i"
16297         done
16298
16299         local first_rec
16300         for i in $(seq $MDSCOUNT); do
16301                 # check cl_user1 still registered
16302                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16303                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16304                 # check cl_user2 unregistered
16305                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16306                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16307
16308                 # check changelogs are present and starting at $user_rec1 + 1
16309                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16310                 [ -n "$user_rec1" ] ||
16311                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16312                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16313                             awk '{ print $1; exit; }')
16314
16315                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16316                 [ $((user_rec1 + 1)) == $first_rec ] ||
16317                         error "mds$i: first index should be $user_rec1 + 1, " \
16318                               "but is $first_rec"
16319         done
16320 }
16321 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16322               "during mount"
16323
16324 test_160i() {
16325
16326         local mdts=$(comma_list $(mdts_nodes))
16327
16328         changelog_register || error "first changelog_register failed"
16329
16330         # generate some changelog records to accumulate on each MDT
16331         # use all_char because created files should be evenly distributed
16332         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16333                 error "test_mkdir $tdir failed"
16334         for ((i = 0; i < MDSCOUNT; i++)); do
16335                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16336                         error "create $DIR/$tdir/d$i.1 failed"
16337         done
16338
16339         # check changelogs have been generated
16340         local nbcl=$(changelog_dump | wc -l)
16341         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16342
16343         # simulate race between register and unregister
16344         # XXX as fail_loc is set per-MDS, with DNE configs the race
16345         # simulation will only occur for one MDT per MDS and for the
16346         # others the normal race scenario will take place
16347         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16348         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16349         do_nodes $mdts $LCTL set_param fail_val=1
16350
16351         # unregister 1st user
16352         changelog_deregister &
16353         local pid1=$!
16354         # wait some time for deregister work to reach race rdv
16355         sleep 2
16356         # register 2nd user
16357         changelog_register || error "2nd user register failed"
16358
16359         wait $pid1 || error "1st user deregister failed"
16360
16361         local i
16362         local last_rec
16363         declare -A LAST_REC
16364         for i in $(seq $MDSCOUNT); do
16365                 if changelog_users mds$i | grep "^cl"; then
16366                         # make sure new records are added with one user present
16367                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16368                                           awk '/^current.index:/ { print $NF }')
16369                 else
16370                         error "mds$i has no user registered"
16371                 fi
16372         done
16373
16374         # generate more changelog records to accumulate on each MDT
16375         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16376                 error "create $DIR/$tdir/${tfile}bis failed"
16377
16378         for i in $(seq $MDSCOUNT); do
16379                 last_rec=$(changelog_users $SINGLEMDS |
16380                            awk '/^current.index:/ { print $NF }')
16381                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16382                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16383                         error "changelogs are off on mds$i"
16384         done
16385 }
16386 run_test 160i "changelog user register/unregister race"
16387
16388 test_160j() {
16389         remote_mds_nodsh && skip "remote MDS with nodsh"
16390         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16391                 skip "Need MDS version at least 2.12.56"
16392
16393         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16394         stack_trap "umount $MOUNT2" EXIT
16395
16396         changelog_register || error "first changelog_register failed"
16397         stack_trap "changelog_deregister" EXIT
16398
16399         # generate some changelog
16400         # use all_char because created files should be evenly distributed
16401         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16402                 error "mkdir $tdir failed"
16403         for ((i = 0; i < MDSCOUNT; i++)); do
16404                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16405                         error "create $DIR/$tdir/d$i.1 failed"
16406         done
16407
16408         # open the changelog device
16409         exec 3>/dev/changelog-$FSNAME-MDT0000
16410         stack_trap "exec 3>&-" EXIT
16411         exec 4</dev/changelog-$FSNAME-MDT0000
16412         stack_trap "exec 4<&-" EXIT
16413
16414         # umount the first lustre mount
16415         umount $MOUNT
16416         stack_trap "mount_client $MOUNT" EXIT
16417
16418         # read changelog, which may or may not fail, but should not crash
16419         cat <&4 >/dev/null
16420
16421         # clear changelog
16422         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16423         changelog_users $SINGLEMDS | grep -q $cl_user ||
16424                 error "User $cl_user not found in changelog_users"
16425
16426         printf 'clear:'$cl_user':0' >&3
16427 }
16428 run_test 160j "client can be umounted while its chanangelog is being used"
16429
16430 test_160k() {
16431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16432         remote_mds_nodsh && skip "remote MDS with nodsh"
16433
16434         mkdir -p $DIR/$tdir/1/1
16435
16436         changelog_register || error "changelog_register failed"
16437         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16438
16439         changelog_users $SINGLEMDS | grep -q $cl_user ||
16440                 error "User '$cl_user' not found in changelog_users"
16441 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16442         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16443         rmdir $DIR/$tdir/1/1 & sleep 1
16444         mkdir $DIR/$tdir/2
16445         touch $DIR/$tdir/2/2
16446         rm -rf $DIR/$tdir/2
16447
16448         wait
16449         sleep 4
16450
16451         changelog_dump | grep rmdir || error "rmdir not recorded"
16452 }
16453 run_test 160k "Verify that changelog records are not lost"
16454
16455 # Verifies that a file passed as a parameter has recently had an operation
16456 # performed on it that has generated an MTIME changelog which contains the
16457 # correct parent FID. As files might reside on a different MDT from the
16458 # parent directory in DNE configurations, the FIDs are translated to paths
16459 # before being compared, which should be identical
16460 compare_mtime_changelog() {
16461         local file="${1}"
16462         local mdtidx
16463         local mtime
16464         local cl_fid
16465         local pdir
16466         local dir
16467
16468         mdtidx=$($LFS getstripe --mdt-index $file)
16469         mdtidx=$(printf "%04x" $mdtidx)
16470
16471         # Obtain the parent FID from the MTIME changelog
16472         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16473         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16474
16475         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16476         [ -z "$cl_fid" ] && error "parent FID not present"
16477
16478         # Verify that the path for the parent FID is the same as the path for
16479         # the test directory
16480         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16481
16482         dir=$(dirname $1)
16483
16484         [[ "${pdir%/}" == "$dir" ]] ||
16485                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16486 }
16487
16488 test_160l() {
16489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16490
16491         remote_mds_nodsh && skip "remote MDS with nodsh"
16492         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16493                 skip "Need MDS version at least 2.13.55"
16494
16495         local cl_user
16496
16497         changelog_register || error "changelog_register failed"
16498         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16499
16500         changelog_users $SINGLEMDS | grep -q $cl_user ||
16501                 error "User '$cl_user' not found in changelog_users"
16502
16503         # Clear some types so that MTIME changelogs are generated
16504         changelog_chmask "-CREAT"
16505         changelog_chmask "-CLOSE"
16506
16507         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16508
16509         # Test CL_MTIME during setattr
16510         touch $DIR/$tdir/$tfile
16511         compare_mtime_changelog $DIR/$tdir/$tfile
16512
16513         # Test CL_MTIME during close
16514         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16515         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16516 }
16517 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16518
16519 test_160m() {
16520         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16521         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16522                 skip "Need MDS version at least 2.14.51"
16523         local cl_users
16524         local cl_user1
16525         local cl_user2
16526         local pid1
16527
16528         # Create a user
16529         changelog_register || error "first changelog_register failed"
16530         changelog_register || error "second changelog_register failed"
16531
16532         cl_users=(${CL_USERS[mds1]})
16533         cl_user1="${cl_users[0]}"
16534         cl_user2="${cl_users[1]}"
16535         # generate some changelog records to accumulate on MDT0
16536         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16537         createmany -m $DIR/$tdir/$tfile 50 ||
16538                 error "create $DIR/$tdir/$tfile failed"
16539         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16540         rm -f $DIR/$tdir
16541
16542         # check changelogs have been generated
16543         local nbcl=$(changelog_dump | wc -l)
16544         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16545
16546 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16547         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16548
16549         __changelog_clear mds1 $cl_user1 +10
16550         __changelog_clear mds1 $cl_user2 0 &
16551         pid1=$!
16552         sleep 2
16553         __changelog_clear mds1 $cl_user1 0 ||
16554                 error "fail to cancel record for $cl_user1"
16555         wait $pid1
16556         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16557 }
16558 run_test 160m "Changelog clear race"
16559
16560 test_160n() {
16561         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16562         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16563                 skip "Need MDS version at least 2.14.51"
16564         local cl_users
16565         local cl_user1
16566         local cl_user2
16567         local pid1
16568         local first_rec
16569         local last_rec=0
16570
16571         # Create a user
16572         changelog_register || error "first changelog_register failed"
16573
16574         cl_users=(${CL_USERS[mds1]})
16575         cl_user1="${cl_users[0]}"
16576
16577         # generate some changelog records to accumulate on MDT0
16578         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16579         first_rec=$(changelog_users $SINGLEMDS |
16580                         awk '/^current.index:/ { print $NF }')
16581         while (( last_rec < (( first_rec + 65000)) )); do
16582                 createmany -m $DIR/$tdir/$tfile 10000 ||
16583                         error "create $DIR/$tdir/$tfile failed"
16584
16585                 for i in $(seq 0 10000); do
16586                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16587                                 > /dev/null
16588                 done
16589
16590                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16591                         error "unlinkmany failed unlink"
16592                 last_rec=$(changelog_users $SINGLEMDS |
16593                         awk '/^current.index:/ { print $NF }')
16594                 echo last record $last_rec
16595                 (( last_rec == 0 )) && error "no changelog found"
16596         done
16597
16598 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16599         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16600
16601         __changelog_clear mds1 $cl_user1 0 &
16602         pid1=$!
16603         sleep 2
16604         __changelog_clear mds1 $cl_user1 0 ||
16605                 error "fail to cancel record for $cl_user1"
16606         wait $pid1
16607         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16608 }
16609 run_test 160n "Changelog destroy race"
16610
16611 test_160o() {
16612         local mdt="$(facet_svc $SINGLEMDS)"
16613
16614         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16615         remote_mds_nodsh && skip "remote MDS with nodsh"
16616         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16617                 skip "Need MDS version at least 2.14.52"
16618
16619         changelog_register --user test_160o -m unlnk+close+open ||
16620                 error "changelog_register failed"
16621
16622         do_facet $SINGLEMDS $LCTL --device $mdt \
16623                                 changelog_register -u "Tt3_-#" &&
16624                 error "bad symbols in name should fail"
16625
16626         do_facet $SINGLEMDS $LCTL --device $mdt \
16627                                 changelog_register -u test_160o &&
16628                 error "the same name registration should fail"
16629
16630         do_facet $SINGLEMDS $LCTL --device $mdt \
16631                         changelog_register -u test_160toolongname &&
16632                 error "too long name registration should fail"
16633
16634         changelog_chmask "MARK+HSM"
16635         lctl get_param mdd.*.changelog*mask
16636         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16637         changelog_users $SINGLEMDS | grep -q $cl_user ||
16638                 error "User $cl_user not found in changelog_users"
16639         #verify username
16640         echo $cl_user | grep -q test_160o ||
16641                 error "User $cl_user has no specific name 'test160o'"
16642
16643         # change something
16644         changelog_clear 0 || error "changelog_clear failed"
16645         # generate some changelog records to accumulate on MDT0
16646         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16647         touch $DIR/$tdir/$tfile                 # open 1
16648
16649         OPENS=$(changelog_dump | grep -c "OPEN")
16650         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16651
16652         # must be no MKDIR it wasn't set as user mask
16653         MKDIR=$(changelog_dump | grep -c "MKDIR")
16654         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16655
16656         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16657                                 mdd.$mdt.changelog_current_mask -n)
16658         # register maskless user
16659         changelog_register || error "changelog_register failed"
16660         # effective mask should be not changed because it is not minimal
16661         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16662                                 mdd.$mdt.changelog_current_mask -n)
16663         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16664         # set server mask to minimal value
16665         changelog_chmask "MARK"
16666         # check effective mask again, should be treated as DEFMASK now
16667         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16668                                 mdd.$mdt.changelog_current_mask -n)
16669         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16670
16671         do_facet $SINGLEMDS $LCTL --device $mdt \
16672                                 changelog_deregister -u test_160o ||
16673                 error "cannot deregister by name"
16674 }
16675 run_test 160o "changelog user name and mask"
16676
16677 test_160p() {
16678         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16679         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16680                 skip "Need MDS version at least 2.14.51"
16681         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16682         local cl_users
16683         local cl_user1
16684         local entry_count
16685
16686         # Create a user
16687         changelog_register || error "first changelog_register failed"
16688
16689         cl_users=(${CL_USERS[mds1]})
16690         cl_user1="${cl_users[0]}"
16691
16692         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16693         createmany -m $DIR/$tdir/$tfile 50 ||
16694                 error "create $DIR/$tdir/$tfile failed"
16695         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16696         rm -rf $DIR/$tdir
16697
16698         # check changelogs have been generated
16699         entry_count=$(changelog_dump | wc -l)
16700         ((entry_count != 0)) || error "no changelog entries found"
16701
16702         # remove changelog_users and check that orphan entries are removed
16703         stop mds1
16704         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16705         start mds1 || error "cannot start mdt"
16706         entry_count=$(changelog_dump | wc -l)
16707         ((entry_count == 0)) ||
16708                 error "found $entry_count changelog entries, expected none"
16709 }
16710 run_test 160p "Changelog orphan cleanup with no users"
16711
16712 test_160q() {
16713         local mdt="$(facet_svc $SINGLEMDS)"
16714         local clu
16715
16716         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16717         remote_mds_nodsh && skip "remote MDS with nodsh"
16718         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16719                 skip "Need MDS version at least 2.14.54"
16720
16721         # set server mask to minimal value like server init does
16722         changelog_chmask "MARK"
16723         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16724                 error "changelog_register failed"
16725         # check effective mask again, should be treated as DEFMASK now
16726         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16727                                 mdd.$mdt.changelog_current_mask -n)
16728         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16729                 error "changelog_deregister failed"
16730         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16731 }
16732 run_test 160q "changelog effective mask is DEFMASK if not set"
16733
16734 test_160s() {
16735         remote_mds_nodsh && skip "remote MDS with nodsh"
16736         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16737                 skip "Need MDS version at least 2.14.55"
16738
16739         local mdts=$(comma_list $(mdts_nodes))
16740
16741         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16742         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16743                                        fail_val=$((24 * 3600 * 10))
16744
16745         # Create a user which is 10 days old
16746         changelog_register || error "first changelog_register failed"
16747         local cl_users
16748         declare -A cl_user1
16749         local i
16750
16751         # generate some changelog records to accumulate on each MDT
16752         # use all_char because created files should be evenly distributed
16753         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16754                 error "test_mkdir $tdir failed"
16755         for ((i = 0; i < MDSCOUNT; i++)); do
16756                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16757                         error "create $DIR/$tdir/d$i.1 failed"
16758         done
16759
16760         # check changelogs have been generated
16761         local nbcl=$(changelog_dump | wc -l)
16762         (( nbcl > 0 )) || error "no changelogs found"
16763
16764         # reduce the max_idle_indexes value to make sure we exceed it
16765         for param in "changelog_max_idle_indexes=2097446912" \
16766                      "changelog_max_idle_time=2592000" \
16767                      "changelog_gc=1" \
16768                      "changelog_min_gc_interval=2"; do
16769                 local MDT0=$(facet_svc $SINGLEMDS)
16770                 local var="${param%=*}"
16771                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16772
16773                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16774                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16775                         error "unable to set mdd.*.$param"
16776         done
16777
16778         local start=$SECONDS
16779         for i in $(seq $MDSCOUNT); do
16780                 cl_users=(${CL_USERS[mds$i]})
16781                 cl_user1[mds$i]="${cl_users[0]}"
16782
16783                 [[ -n "${cl_user1[mds$i]}" ]] ||
16784                         error "mds$i: no user registered"
16785         done
16786
16787         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16788         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16789
16790         # ensure we are past the previous changelog_min_gc_interval set above
16791         local sleep2=$((start + 2 - SECONDS))
16792         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16793
16794         # Generate one more changelog to trigger GC
16795         for ((i = 0; i < MDSCOUNT; i++)); do
16796                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16797                         error "create $DIR/$tdir/d$i.3 failed"
16798         done
16799
16800         # ensure gc thread is done
16801         for node in $(mdts_nodes); do
16802                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16803                         error "$node: GC-thread not done"
16804         done
16805
16806         do_nodes $mdts $LCTL set_param fail_loc=0
16807
16808         for (( i = 1; i <= MDSCOUNT; i++ )); do
16809                 # check cl_user1 is purged
16810                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16811                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16812         done
16813         return 0
16814 }
16815 run_test 160s "changelog garbage collect on idle records * time"
16816
16817 test_161a() {
16818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16819
16820         test_mkdir -c1 $DIR/$tdir
16821         cp /etc/hosts $DIR/$tdir/$tfile
16822         test_mkdir -c1 $DIR/$tdir/foo1
16823         test_mkdir -c1 $DIR/$tdir/foo2
16824         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16825         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16826         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16827         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16828         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16829         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16830                 $LFS fid2path $DIR $FID
16831                 error "bad link ea"
16832         fi
16833         # middle
16834         rm $DIR/$tdir/foo2/zachary
16835         # last
16836         rm $DIR/$tdir/foo2/thor
16837         # first
16838         rm $DIR/$tdir/$tfile
16839         # rename
16840         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16841         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16842                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16843         rm $DIR/$tdir/foo2/maggie
16844
16845         # overflow the EA
16846         local longname=$tfile.avg_len_is_thirty_two_
16847         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16848                 error_noexit 'failed to unlink many hardlinks'" EXIT
16849         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16850                 error "failed to hardlink many files"
16851         links=$($LFS fid2path $DIR $FID | wc -l)
16852         echo -n "${links}/1000 links in link EA"
16853         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16854 }
16855 run_test 161a "link ea sanity"
16856
16857 test_161b() {
16858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16859         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16860
16861         local MDTIDX=1
16862         local remote_dir=$DIR/$tdir/remote_dir
16863
16864         mkdir -p $DIR/$tdir
16865         $LFS mkdir -i $MDTIDX $remote_dir ||
16866                 error "create remote directory failed"
16867
16868         cp /etc/hosts $remote_dir/$tfile
16869         mkdir -p $remote_dir/foo1
16870         mkdir -p $remote_dir/foo2
16871         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16872         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16873         ln $remote_dir/$tfile $remote_dir/foo1/luna
16874         ln $remote_dir/$tfile $remote_dir/foo2/thor
16875
16876         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16877                      tr -d ']')
16878         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16879                 $LFS fid2path $DIR $FID
16880                 error "bad link ea"
16881         fi
16882         # middle
16883         rm $remote_dir/foo2/zachary
16884         # last
16885         rm $remote_dir/foo2/thor
16886         # first
16887         rm $remote_dir/$tfile
16888         # rename
16889         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16890         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16891         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16892                 $LFS fid2path $DIR $FID
16893                 error "bad link rename"
16894         fi
16895         rm $remote_dir/foo2/maggie
16896
16897         # overflow the EA
16898         local longname=filename_avg_len_is_thirty_two_
16899         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16900                 error "failed to hardlink many files"
16901         links=$($LFS fid2path $DIR $FID | wc -l)
16902         echo -n "${links}/1000 links in link EA"
16903         [[ ${links} -gt 60 ]] ||
16904                 error "expected at least 60 links in link EA"
16905         unlinkmany $remote_dir/foo2/$longname 1000 ||
16906         error "failed to unlink many hardlinks"
16907 }
16908 run_test 161b "link ea sanity under remote directory"
16909
16910 test_161c() {
16911         remote_mds_nodsh && skip "remote MDS with nodsh"
16912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16913         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16914                 skip "Need MDS version at least 2.1.5"
16915
16916         # define CLF_RENAME_LAST 0x0001
16917         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16918         changelog_register || error "changelog_register failed"
16919
16920         rm -rf $DIR/$tdir
16921         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16922         touch $DIR/$tdir/foo_161c
16923         touch $DIR/$tdir/bar_161c
16924         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16925         changelog_dump | grep RENME | tail -n 5
16926         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16927         changelog_clear 0 || error "changelog_clear failed"
16928         if [ x$flags != "x0x1" ]; then
16929                 error "flag $flags is not 0x1"
16930         fi
16931
16932         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16933         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16934         touch $DIR/$tdir/foo_161c
16935         touch $DIR/$tdir/bar_161c
16936         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16937         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16938         changelog_dump | grep RENME | tail -n 5
16939         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16940         changelog_clear 0 || error "changelog_clear failed"
16941         if [ x$flags != "x0x0" ]; then
16942                 error "flag $flags is not 0x0"
16943         fi
16944         echo "rename overwrite a target having nlink > 1," \
16945                 "changelog record has flags of $flags"
16946
16947         # rename doesn't overwrite a target (changelog flag 0x0)
16948         touch $DIR/$tdir/foo_161c
16949         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16950         changelog_dump | grep RENME | tail -n 5
16951         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16952         changelog_clear 0 || error "changelog_clear failed"
16953         if [ x$flags != "x0x0" ]; then
16954                 error "flag $flags is not 0x0"
16955         fi
16956         echo "rename doesn't overwrite a target," \
16957                 "changelog record has flags of $flags"
16958
16959         # define CLF_UNLINK_LAST 0x0001
16960         # unlink a file having nlink = 1 (changelog flag 0x1)
16961         rm -f $DIR/$tdir/foo2_161c
16962         changelog_dump | grep UNLNK | tail -n 5
16963         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16964         changelog_clear 0 || error "changelog_clear failed"
16965         if [ x$flags != "x0x1" ]; then
16966                 error "flag $flags is not 0x1"
16967         fi
16968         echo "unlink a file having nlink = 1," \
16969                 "changelog record has flags of $flags"
16970
16971         # unlink a file having nlink > 1 (changelog flag 0x0)
16972         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16973         rm -f $DIR/$tdir/foobar_161c
16974         changelog_dump | grep UNLNK | tail -n 5
16975         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16976         changelog_clear 0 || error "changelog_clear failed"
16977         if [ x$flags != "x0x0" ]; then
16978                 error "flag $flags is not 0x0"
16979         fi
16980         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16981 }
16982 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16983
16984 test_161d() {
16985         remote_mds_nodsh && skip "remote MDS with nodsh"
16986         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16987
16988         local pid
16989         local fid
16990
16991         changelog_register || error "changelog_register failed"
16992
16993         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16994         # interfer with $MOUNT/.lustre/fid/ access
16995         mkdir $DIR/$tdir
16996         [[ $? -eq 0 ]] || error "mkdir failed"
16997
16998         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16999         $LCTL set_param fail_loc=0x8000140c
17000         # 5s pause
17001         $LCTL set_param fail_val=5
17002
17003         # create file
17004         echo foofoo > $DIR/$tdir/$tfile &
17005         pid=$!
17006
17007         # wait for create to be delayed
17008         sleep 2
17009
17010         ps -p $pid
17011         [[ $? -eq 0 ]] || error "create should be blocked"
17012
17013         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17014         stack_trap "rm -f $tempfile"
17015         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17016         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17017         # some delay may occur during ChangeLog publishing and file read just
17018         # above, that could allow file write to happen finally
17019         [[ -s $tempfile ]] && echo "file should be empty"
17020
17021         $LCTL set_param fail_loc=0
17022
17023         wait $pid
17024         [[ $? -eq 0 ]] || error "create failed"
17025 }
17026 run_test 161d "create with concurrent .lustre/fid access"
17027
17028 check_path() {
17029         local expected="$1"
17030         shift
17031         local fid="$2"
17032
17033         local path
17034         path=$($LFS fid2path "$@")
17035         local rc=$?
17036
17037         if [ $rc -ne 0 ]; then
17038                 error "path looked up of '$expected' failed: rc=$rc"
17039         elif [ "$path" != "$expected" ]; then
17040                 error "path looked up '$path' instead of '$expected'"
17041         else
17042                 echo "FID '$fid' resolves to path '$path' as expected"
17043         fi
17044 }
17045
17046 test_162a() { # was test_162
17047         test_mkdir -p -c1 $DIR/$tdir/d2
17048         touch $DIR/$tdir/d2/$tfile
17049         touch $DIR/$tdir/d2/x1
17050         touch $DIR/$tdir/d2/x2
17051         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17052         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17053         # regular file
17054         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17055         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17056
17057         # softlink
17058         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17059         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17060         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17061
17062         # softlink to wrong file
17063         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17064         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17065         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17066
17067         # hardlink
17068         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17069         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17070         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17071         # fid2path dir/fsname should both work
17072         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17073         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17074
17075         # hardlink count: check that there are 2 links
17076         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17077         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17078
17079         # hardlink indexing: remove the first link
17080         rm $DIR/$tdir/d2/p/q/r/hlink
17081         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17082 }
17083 run_test 162a "path lookup sanity"
17084
17085 test_162b() {
17086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17088
17089         mkdir $DIR/$tdir
17090         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17091                                 error "create striped dir failed"
17092
17093         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17094                                         tail -n 1 | awk '{print $2}')
17095         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17096
17097         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17098         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17099
17100         # regular file
17101         for ((i=0;i<5;i++)); do
17102                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17103                         error "get fid for f$i failed"
17104                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17105
17106                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17107                         error "get fid for d$i failed"
17108                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17109         done
17110
17111         return 0
17112 }
17113 run_test 162b "striped directory path lookup sanity"
17114
17115 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17116 test_162c() {
17117         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17118                 skip "Need MDS version at least 2.7.51"
17119
17120         local lpath=$tdir.local
17121         local rpath=$tdir.remote
17122
17123         test_mkdir $DIR/$lpath
17124         test_mkdir $DIR/$rpath
17125
17126         for ((i = 0; i <= 101; i++)); do
17127                 lpath="$lpath/$i"
17128                 mkdir $DIR/$lpath
17129                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17130                         error "get fid for local directory $DIR/$lpath failed"
17131                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17132
17133                 rpath="$rpath/$i"
17134                 test_mkdir $DIR/$rpath
17135                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17136                         error "get fid for remote directory $DIR/$rpath failed"
17137                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17138         done
17139
17140         return 0
17141 }
17142 run_test 162c "fid2path works with paths 100 or more directories deep"
17143
17144 oalr_event_count() {
17145         local event="${1}"
17146         local trace="${2}"
17147
17148         awk -v name="${FSNAME}-OST0000" \
17149             -v event="${event}" \
17150             '$1 == "TRACE" && $2 == event && $3 == name' \
17151             "${trace}" |
17152         wc -l
17153 }
17154
17155 oalr_expect_event_count() {
17156         local event="${1}"
17157         local trace="${2}"
17158         local expect="${3}"
17159         local count
17160
17161         count=$(oalr_event_count "${event}" "${trace}")
17162         if ((count == expect)); then
17163                 return 0
17164         fi
17165
17166         error_noexit "${event} event count was '${count}', expected ${expect}"
17167         cat "${trace}" >&2
17168         exit 1
17169 }
17170
17171 cleanup_165() {
17172         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17173         stop ost1
17174         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17175 }
17176
17177 setup_165() {
17178         sync # Flush previous IOs so we can count log entries.
17179         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17180         stack_trap cleanup_165 EXIT
17181 }
17182
17183 test_165a() {
17184         local trace="/tmp/${tfile}.trace"
17185         local rc
17186         local count
17187
17188         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17189                 skip "OFD access log unsupported"
17190
17191         setup_165
17192         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17193         sleep 5
17194
17195         do_facet ost1 ofd_access_log_reader --list
17196         stop ost1
17197
17198         do_facet ost1 killall -TERM ofd_access_log_reader
17199         wait
17200         rc=$?
17201
17202         if ((rc != 0)); then
17203                 error "ofd_access_log_reader exited with rc = '${rc}'"
17204         fi
17205
17206         # Parse trace file for discovery events:
17207         oalr_expect_event_count alr_log_add "${trace}" 1
17208         oalr_expect_event_count alr_log_eof "${trace}" 1
17209         oalr_expect_event_count alr_log_free "${trace}" 1
17210 }
17211 run_test 165a "ofd access log discovery"
17212
17213 test_165b() {
17214         local trace="/tmp/${tfile}.trace"
17215         local file="${DIR}/${tfile}"
17216         local pfid1
17217         local pfid2
17218         local -a entry
17219         local rc
17220         local count
17221         local size
17222         local flags
17223
17224         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17225                 skip "OFD access log unsupported"
17226
17227         setup_165
17228         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17229         sleep 5
17230
17231         do_facet ost1 ofd_access_log_reader --list
17232
17233         lfs setstripe -c 1 -i 0 "${file}"
17234         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17235                 error "cannot create '${file}'"
17236
17237         sleep 5
17238         do_facet ost1 killall -TERM ofd_access_log_reader
17239         wait
17240         rc=$?
17241
17242         if ((rc != 0)); then
17243                 error "ofd_access_log_reader exited with rc = '${rc}'"
17244         fi
17245
17246         oalr_expect_event_count alr_log_entry "${trace}" 1
17247
17248         pfid1=$($LFS path2fid "${file}")
17249
17250         # 1     2             3   4    5     6   7    8    9     10
17251         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17252         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17253
17254         echo "entry = '${entry[*]}'" >&2
17255
17256         pfid2=${entry[4]}
17257         if [[ "${pfid1}" != "${pfid2}" ]]; then
17258                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17259         fi
17260
17261         size=${entry[8]}
17262         if ((size != 1048576)); then
17263                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17264         fi
17265
17266         flags=${entry[10]}
17267         if [[ "${flags}" != "w" ]]; then
17268                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17269         fi
17270
17271         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17272         sleep 5
17273
17274         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17275                 error "cannot read '${file}'"
17276         sleep 5
17277
17278         do_facet ost1 killall -TERM ofd_access_log_reader
17279         wait
17280         rc=$?
17281
17282         if ((rc != 0)); then
17283                 error "ofd_access_log_reader exited with rc = '${rc}'"
17284         fi
17285
17286         oalr_expect_event_count alr_log_entry "${trace}" 1
17287
17288         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17289         echo "entry = '${entry[*]}'" >&2
17290
17291         pfid2=${entry[4]}
17292         if [[ "${pfid1}" != "${pfid2}" ]]; then
17293                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17294         fi
17295
17296         size=${entry[8]}
17297         if ((size != 524288)); then
17298                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17299         fi
17300
17301         flags=${entry[10]}
17302         if [[ "${flags}" != "r" ]]; then
17303                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17304         fi
17305 }
17306 run_test 165b "ofd access log entries are produced and consumed"
17307
17308 test_165c() {
17309         local trace="/tmp/${tfile}.trace"
17310         local file="${DIR}/${tdir}/${tfile}"
17311
17312         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17313                 skip "OFD access log unsupported"
17314
17315         test_mkdir "${DIR}/${tdir}"
17316
17317         setup_165
17318         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17319         sleep 5
17320
17321         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17322
17323         # 4096 / 64 = 64. Create twice as many entries.
17324         for ((i = 0; i < 128; i++)); do
17325                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17326                         error "cannot create file"
17327         done
17328
17329         sync
17330
17331         do_facet ost1 killall -TERM ofd_access_log_reader
17332         wait
17333         rc=$?
17334         if ((rc != 0)); then
17335                 error "ofd_access_log_reader exited with rc = '${rc}'"
17336         fi
17337
17338         unlinkmany  "${file}-%d" 128
17339 }
17340 run_test 165c "full ofd access logs do not block IOs"
17341
17342 oal_get_read_count() {
17343         local stats="$1"
17344
17345         # STATS lustre-OST0001 alr_read_count 1
17346
17347         do_facet ost1 cat "${stats}" |
17348         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17349              END { print count; }'
17350 }
17351
17352 oal_expect_read_count() {
17353         local stats="$1"
17354         local count
17355         local expect="$2"
17356
17357         # Ask ofd_access_log_reader to write stats.
17358         do_facet ost1 killall -USR1 ofd_access_log_reader
17359
17360         # Allow some time for things to happen.
17361         sleep 1
17362
17363         count=$(oal_get_read_count "${stats}")
17364         if ((count == expect)); then
17365                 return 0
17366         fi
17367
17368         error_noexit "bad read count, got ${count}, expected ${expect}"
17369         do_facet ost1 cat "${stats}" >&2
17370         exit 1
17371 }
17372
17373 test_165d() {
17374         local stats="/tmp/${tfile}.stats"
17375         local file="${DIR}/${tdir}/${tfile}"
17376         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17377
17378         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17379                 skip "OFD access log unsupported"
17380
17381         test_mkdir "${DIR}/${tdir}"
17382
17383         setup_165
17384         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17385         sleep 5
17386
17387         lfs setstripe -c 1 -i 0 "${file}"
17388
17389         do_facet ost1 lctl set_param "${param}=rw"
17390         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17391                 error "cannot create '${file}'"
17392         oal_expect_read_count "${stats}" 1
17393
17394         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17395                 error "cannot read '${file}'"
17396         oal_expect_read_count "${stats}" 2
17397
17398         do_facet ost1 lctl set_param "${param}=r"
17399         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17400                 error "cannot create '${file}'"
17401         oal_expect_read_count "${stats}" 2
17402
17403         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17404                 error "cannot read '${file}'"
17405         oal_expect_read_count "${stats}" 3
17406
17407         do_facet ost1 lctl set_param "${param}=w"
17408         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17409                 error "cannot create '${file}'"
17410         oal_expect_read_count "${stats}" 4
17411
17412         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17413                 error "cannot read '${file}'"
17414         oal_expect_read_count "${stats}" 4
17415
17416         do_facet ost1 lctl set_param "${param}=0"
17417         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17418                 error "cannot create '${file}'"
17419         oal_expect_read_count "${stats}" 4
17420
17421         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17422                 error "cannot read '${file}'"
17423         oal_expect_read_count "${stats}" 4
17424
17425         do_facet ost1 killall -TERM ofd_access_log_reader
17426         wait
17427         rc=$?
17428         if ((rc != 0)); then
17429                 error "ofd_access_log_reader exited with rc = '${rc}'"
17430         fi
17431 }
17432 run_test 165d "ofd_access_log mask works"
17433
17434 test_165e() {
17435         local stats="/tmp/${tfile}.stats"
17436         local file0="${DIR}/${tdir}-0/${tfile}"
17437         local file1="${DIR}/${tdir}-1/${tfile}"
17438
17439         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17440                 skip "OFD access log unsupported"
17441
17442         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17443
17444         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17445         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17446
17447         lfs setstripe -c 1 -i 0 "${file0}"
17448         lfs setstripe -c 1 -i 0 "${file1}"
17449
17450         setup_165
17451         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17452         sleep 5
17453
17454         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17455                 error "cannot create '${file0}'"
17456         sync
17457         oal_expect_read_count "${stats}" 0
17458
17459         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17460                 error "cannot create '${file1}'"
17461         sync
17462         oal_expect_read_count "${stats}" 1
17463
17464         do_facet ost1 killall -TERM ofd_access_log_reader
17465         wait
17466         rc=$?
17467         if ((rc != 0)); then
17468                 error "ofd_access_log_reader exited with rc = '${rc}'"
17469         fi
17470 }
17471 run_test 165e "ofd_access_log MDT index filter works"
17472
17473 test_165f() {
17474         local trace="/tmp/${tfile}.trace"
17475         local rc
17476         local count
17477
17478         setup_165
17479         do_facet ost1 timeout 60 ofd_access_log_reader \
17480                 --exit-on-close --debug=- --trace=- > "${trace}" &
17481         sleep 5
17482         stop ost1
17483
17484         wait
17485         rc=$?
17486
17487         if ((rc != 0)); then
17488                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17489                 cat "${trace}"
17490                 exit 1
17491         fi
17492 }
17493 run_test 165f "ofd_access_log_reader --exit-on-close works"
17494
17495 test_169() {
17496         # do directio so as not to populate the page cache
17497         log "creating a 10 Mb file"
17498         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17499                 error "multiop failed while creating a file"
17500         log "starting reads"
17501         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17502         log "truncating the file"
17503         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17504                 error "multiop failed while truncating the file"
17505         log "killing dd"
17506         kill %+ || true # reads might have finished
17507         echo "wait until dd is finished"
17508         wait
17509         log "removing the temporary file"
17510         rm -rf $DIR/$tfile || error "tmp file removal failed"
17511 }
17512 run_test 169 "parallel read and truncate should not deadlock"
17513
17514 test_170() {
17515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17516
17517         $LCTL clear     # bug 18514
17518         $LCTL debug_daemon start $TMP/${tfile}_log_good
17519         touch $DIR/$tfile
17520         $LCTL debug_daemon stop
17521         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17522                 error "sed failed to read log_good"
17523
17524         $LCTL debug_daemon start $TMP/${tfile}_log_good
17525         rm -rf $DIR/$tfile
17526         $LCTL debug_daemon stop
17527
17528         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17529                error "lctl df log_bad failed"
17530
17531         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17532         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17533
17534         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17535         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17536
17537         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17538                 error "bad_line good_line1 good_line2 are empty"
17539
17540         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17541         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17542         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17543
17544         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17545         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17546         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17547
17548         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17549                 error "bad_line_new good_line_new are empty"
17550
17551         local expected_good=$((good_line1 + good_line2*2))
17552
17553         rm -f $TMP/${tfile}*
17554         # LU-231, short malformed line may not be counted into bad lines
17555         if [ $bad_line -ne $bad_line_new ] &&
17556                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17557                 error "expected $bad_line bad lines, but got $bad_line_new"
17558                 return 1
17559         fi
17560
17561         if [ $expected_good -ne $good_line_new ]; then
17562                 error "expected $expected_good good lines, but got $good_line_new"
17563                 return 2
17564         fi
17565         true
17566 }
17567 run_test 170 "test lctl df to handle corrupted log ====================="
17568
17569 test_171() { # bug20592
17570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17571
17572         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17573         $LCTL set_param fail_loc=0x50e
17574         $LCTL set_param fail_val=3000
17575         multiop_bg_pause $DIR/$tfile O_s || true
17576         local MULTIPID=$!
17577         kill -USR1 $MULTIPID
17578         # cause log dump
17579         sleep 3
17580         wait $MULTIPID
17581         if dmesg | grep "recursive fault"; then
17582                 error "caught a recursive fault"
17583         fi
17584         $LCTL set_param fail_loc=0
17585         true
17586 }
17587 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17588
17589 # it would be good to share it with obdfilter-survey/iokit-libecho code
17590 setup_obdecho_osc () {
17591         local rc=0
17592         local ost_nid=$1
17593         local obdfilter_name=$2
17594         echo "Creating new osc for $obdfilter_name on $ost_nid"
17595         # make sure we can find loopback nid
17596         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17597
17598         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17599                            ${obdfilter_name}_osc_UUID || rc=2; }
17600         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17601                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17602         return $rc
17603 }
17604
17605 cleanup_obdecho_osc () {
17606         local obdfilter_name=$1
17607         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17608         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17609         return 0
17610 }
17611
17612 obdecho_test() {
17613         local OBD=$1
17614         local node=$2
17615         local pages=${3:-64}
17616         local rc=0
17617         local id
17618
17619         local count=10
17620         local obd_size=$(get_obd_size $node $OBD)
17621         local page_size=$(get_page_size $node)
17622         if [[ -n "$obd_size" ]]; then
17623                 local new_count=$((obd_size / (pages * page_size / 1024)))
17624                 [[ $new_count -ge $count ]] || count=$new_count
17625         fi
17626
17627         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17628         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17629                            rc=2; }
17630         if [ $rc -eq 0 ]; then
17631             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17632             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17633         fi
17634         echo "New object id is $id"
17635         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17636                            rc=4; }
17637         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17638                            "test_brw $count w v $pages $id" || rc=4; }
17639         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17640                            rc=4; }
17641         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17642                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17643         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17644                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17645         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17646         return $rc
17647 }
17648
17649 test_180a() {
17650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17651
17652         if ! [ -d /sys/fs/lustre/echo_client ] &&
17653            ! module_loaded obdecho; then
17654                 load_module obdecho/obdecho &&
17655                         stack_trap "rmmod obdecho" EXIT ||
17656                         error "unable to load obdecho on client"
17657         fi
17658
17659         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17660         local host=$($LCTL get_param -n osc.$osc.import |
17661                      awk '/current_connection:/ { print $2 }' )
17662         local target=$($LCTL get_param -n osc.$osc.import |
17663                        awk '/target:/ { print $2 }' )
17664         target=${target%_UUID}
17665
17666         if [ -n "$target" ]; then
17667                 setup_obdecho_osc $host $target &&
17668                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17669                         { error "obdecho setup failed with $?"; return; }
17670
17671                 obdecho_test ${target}_osc client ||
17672                         error "obdecho_test failed on ${target}_osc"
17673         else
17674                 $LCTL get_param osc.$osc.import
17675                 error "there is no osc.$osc.import target"
17676         fi
17677 }
17678 run_test 180a "test obdecho on osc"
17679
17680 test_180b() {
17681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17682         remote_ost_nodsh && skip "remote OST with nodsh"
17683
17684         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17685                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17686                 error "failed to load module obdecho"
17687
17688         local target=$(do_facet ost1 $LCTL dl |
17689                        awk '/obdfilter/ { print $4; exit; }')
17690
17691         if [ -n "$target" ]; then
17692                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17693         else
17694                 do_facet ost1 $LCTL dl
17695                 error "there is no obdfilter target on ost1"
17696         fi
17697 }
17698 run_test 180b "test obdecho directly on obdfilter"
17699
17700 test_180c() { # LU-2598
17701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17702         remote_ost_nodsh && skip "remote OST with nodsh"
17703         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17704                 skip "Need MDS version at least 2.4.0"
17705
17706         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17707                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17708                 error "failed to load module obdecho"
17709
17710         local target=$(do_facet ost1 $LCTL dl |
17711                        awk '/obdfilter/ { print $4; exit; }')
17712
17713         if [ -n "$target" ]; then
17714                 local pages=16384 # 64MB bulk I/O RPC size
17715
17716                 obdecho_test "$target" ost1 "$pages" ||
17717                         error "obdecho_test with pages=$pages failed with $?"
17718         else
17719                 do_facet ost1 $LCTL dl
17720                 error "there is no obdfilter target on ost1"
17721         fi
17722 }
17723 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17724
17725 test_181() { # bug 22177
17726         test_mkdir $DIR/$tdir
17727         # create enough files to index the directory
17728         createmany -o $DIR/$tdir/foobar 4000
17729         # print attributes for debug purpose
17730         lsattr -d .
17731         # open dir
17732         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17733         MULTIPID=$!
17734         # remove the files & current working dir
17735         unlinkmany $DIR/$tdir/foobar 4000
17736         rmdir $DIR/$tdir
17737         kill -USR1 $MULTIPID
17738         wait $MULTIPID
17739         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17740         return 0
17741 }
17742 run_test 181 "Test open-unlinked dir ========================"
17743
17744 test_182() {
17745         local fcount=1000
17746         local tcount=10
17747
17748         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17749
17750         $LCTL set_param mdc.*.rpc_stats=clear
17751
17752         for (( i = 0; i < $tcount; i++ )) ; do
17753                 mkdir $DIR/$tdir/$i
17754         done
17755
17756         for (( i = 0; i < $tcount; i++ )) ; do
17757                 createmany -o $DIR/$tdir/$i/f- $fcount &
17758         done
17759         wait
17760
17761         for (( i = 0; i < $tcount; i++ )) ; do
17762                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17763         done
17764         wait
17765
17766         $LCTL get_param mdc.*.rpc_stats
17767
17768         rm -rf $DIR/$tdir
17769 }
17770 run_test 182 "Test parallel modify metadata operations ================"
17771
17772 test_183() { # LU-2275
17773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17774         remote_mds_nodsh && skip "remote MDS with nodsh"
17775         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17776                 skip "Need MDS version at least 2.3.56"
17777
17778         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17779         echo aaa > $DIR/$tdir/$tfile
17780
17781 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17782         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17783
17784         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17785         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17786
17787         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17788
17789         # Flush negative dentry cache
17790         touch $DIR/$tdir/$tfile
17791
17792         # We are not checking for any leaked references here, they'll
17793         # become evident next time we do cleanup with module unload.
17794         rm -rf $DIR/$tdir
17795 }
17796 run_test 183 "No crash or request leak in case of strange dispositions ========"
17797
17798 # test suite 184 is for LU-2016, LU-2017
17799 test_184a() {
17800         check_swap_layouts_support
17801
17802         dir0=$DIR/$tdir/$testnum
17803         test_mkdir -p -c1 $dir0
17804         ref1=/etc/passwd
17805         ref2=/etc/group
17806         file1=$dir0/f1
17807         file2=$dir0/f2
17808         $LFS setstripe -c1 $file1
17809         cp $ref1 $file1
17810         $LFS setstripe -c2 $file2
17811         cp $ref2 $file2
17812         gen1=$($LFS getstripe -g $file1)
17813         gen2=$($LFS getstripe -g $file2)
17814
17815         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17816         gen=$($LFS getstripe -g $file1)
17817         [[ $gen1 != $gen ]] ||
17818                 "Layout generation on $file1 does not change"
17819         gen=$($LFS getstripe -g $file2)
17820         [[ $gen2 != $gen ]] ||
17821                 "Layout generation on $file2 does not change"
17822
17823         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17824         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17825
17826         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17827 }
17828 run_test 184a "Basic layout swap"
17829
17830 test_184b() {
17831         check_swap_layouts_support
17832
17833         dir0=$DIR/$tdir/$testnum
17834         mkdir -p $dir0 || error "creating dir $dir0"
17835         file1=$dir0/f1
17836         file2=$dir0/f2
17837         file3=$dir0/f3
17838         dir1=$dir0/d1
17839         dir2=$dir0/d2
17840         mkdir $dir1 $dir2
17841         $LFS setstripe -c1 $file1
17842         $LFS setstripe -c2 $file2
17843         $LFS setstripe -c1 $file3
17844         chown $RUNAS_ID $file3
17845         gen1=$($LFS getstripe -g $file1)
17846         gen2=$($LFS getstripe -g $file2)
17847
17848         $LFS swap_layouts $dir1 $dir2 &&
17849                 error "swap of directories layouts should fail"
17850         $LFS swap_layouts $dir1 $file1 &&
17851                 error "swap of directory and file layouts should fail"
17852         $RUNAS $LFS swap_layouts $file1 $file2 &&
17853                 error "swap of file we cannot write should fail"
17854         $LFS swap_layouts $file1 $file3 &&
17855                 error "swap of file with different owner should fail"
17856         /bin/true # to clear error code
17857 }
17858 run_test 184b "Forbidden layout swap (will generate errors)"
17859
17860 test_184c() {
17861         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17862         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17863         check_swap_layouts_support
17864         check_swap_layout_no_dom $DIR
17865
17866         local dir0=$DIR/$tdir/$testnum
17867         mkdir -p $dir0 || error "creating dir $dir0"
17868
17869         local ref1=$dir0/ref1
17870         local ref2=$dir0/ref2
17871         local file1=$dir0/file1
17872         local file2=$dir0/file2
17873         # create a file large enough for the concurrent test
17874         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17875         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17876         echo "ref file size: ref1($(stat -c %s $ref1))," \
17877              "ref2($(stat -c %s $ref2))"
17878
17879         cp $ref2 $file2
17880         dd if=$ref1 of=$file1 bs=16k &
17881         local DD_PID=$!
17882
17883         # Make sure dd starts to copy file, but wait at most 5 seconds
17884         local loops=0
17885         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17886
17887         $LFS swap_layouts $file1 $file2
17888         local rc=$?
17889         wait $DD_PID
17890         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17891         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17892
17893         # how many bytes copied before swapping layout
17894         local copied=$(stat -c %s $file2)
17895         local remaining=$(stat -c %s $ref1)
17896         remaining=$((remaining - copied))
17897         echo "Copied $copied bytes before swapping layout..."
17898
17899         cmp -n $copied $file1 $ref2 | grep differ &&
17900                 error "Content mismatch [0, $copied) of ref2 and file1"
17901         cmp -n $copied $file2 $ref1 ||
17902                 error "Content mismatch [0, $copied) of ref1 and file2"
17903         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17904                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17905
17906         # clean up
17907         rm -f $ref1 $ref2 $file1 $file2
17908 }
17909 run_test 184c "Concurrent write and layout swap"
17910
17911 test_184d() {
17912         check_swap_layouts_support
17913         check_swap_layout_no_dom $DIR
17914         [ -z "$(which getfattr 2>/dev/null)" ] &&
17915                 skip_env "no getfattr command"
17916
17917         local file1=$DIR/$tdir/$tfile-1
17918         local file2=$DIR/$tdir/$tfile-2
17919         local file3=$DIR/$tdir/$tfile-3
17920         local lovea1
17921         local lovea2
17922
17923         mkdir -p $DIR/$tdir
17924         touch $file1 || error "create $file1 failed"
17925         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17926                 error "create $file2 failed"
17927         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17928                 error "create $file3 failed"
17929         lovea1=$(get_layout_param $file1)
17930
17931         $LFS swap_layouts $file2 $file3 ||
17932                 error "swap $file2 $file3 layouts failed"
17933         $LFS swap_layouts $file1 $file2 ||
17934                 error "swap $file1 $file2 layouts failed"
17935
17936         lovea2=$(get_layout_param $file2)
17937         echo "$lovea1"
17938         echo "$lovea2"
17939         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17940
17941         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17942         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17943 }
17944 run_test 184d "allow stripeless layouts swap"
17945
17946 test_184e() {
17947         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17948                 skip "Need MDS version at least 2.6.94"
17949         check_swap_layouts_support
17950         check_swap_layout_no_dom $DIR
17951         [ -z "$(which getfattr 2>/dev/null)" ] &&
17952                 skip_env "no getfattr command"
17953
17954         local file1=$DIR/$tdir/$tfile-1
17955         local file2=$DIR/$tdir/$tfile-2
17956         local file3=$DIR/$tdir/$tfile-3
17957         local lovea
17958
17959         mkdir -p $DIR/$tdir
17960         touch $file1 || error "create $file1 failed"
17961         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17962                 error "create $file2 failed"
17963         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17964                 error "create $file3 failed"
17965
17966         $LFS swap_layouts $file1 $file2 ||
17967                 error "swap $file1 $file2 layouts failed"
17968
17969         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17970         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17971
17972         echo 123 > $file1 || error "Should be able to write into $file1"
17973
17974         $LFS swap_layouts $file1 $file3 ||
17975                 error "swap $file1 $file3 layouts failed"
17976
17977         echo 123 > $file1 || error "Should be able to write into $file1"
17978
17979         rm -rf $file1 $file2 $file3
17980 }
17981 run_test 184e "Recreate layout after stripeless layout swaps"
17982
17983 test_184f() {
17984         # Create a file with name longer than sizeof(struct stat) ==
17985         # 144 to see if we can get chars from the file name to appear
17986         # in the returned striping. Note that 'f' == 0x66.
17987         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17988
17989         mkdir -p $DIR/$tdir
17990         mcreate $DIR/$tdir/$file
17991         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17992                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17993         fi
17994 }
17995 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17996
17997 test_185() { # LU-2441
17998         # LU-3553 - no volatile file support in old servers
17999         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18000                 skip "Need MDS version at least 2.3.60"
18001
18002         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18003         touch $DIR/$tdir/spoo
18004         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18005         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18006                 error "cannot create/write a volatile file"
18007         [ "$FILESET" == "" ] &&
18008         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18009                 error "FID is still valid after close"
18010
18011         multiop_bg_pause $DIR/$tdir vVw4096_c
18012         local multi_pid=$!
18013
18014         local OLD_IFS=$IFS
18015         IFS=":"
18016         local fidv=($fid)
18017         IFS=$OLD_IFS
18018         # assume that the next FID for this client is sequential, since stdout
18019         # is unfortunately eaten by multiop_bg_pause
18020         local n=$((${fidv[1]} + 1))
18021         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18022         if [ "$FILESET" == "" ]; then
18023                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18024                         error "FID is missing before close"
18025         fi
18026         kill -USR1 $multi_pid
18027         # 1 second delay, so if mtime change we will see it
18028         sleep 1
18029         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18030         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18031 }
18032 run_test 185 "Volatile file support"
18033
18034 function create_check_volatile() {
18035         local idx=$1
18036         local tgt
18037
18038         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18039         local PID=$!
18040         sleep 1
18041         local FID=$(cat /tmp/${tfile}.fid)
18042         [ "$FID" == "" ] && error "can't get FID for volatile"
18043         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18044         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18045         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18046         kill -USR1 $PID
18047         wait
18048         sleep 1
18049         cancel_lru_locks mdc # flush opencache
18050         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18051         return 0
18052 }
18053
18054 test_185a(){
18055         # LU-12516 - volatile creation via .lustre
18056         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18057                 skip "Need MDS version at least 2.3.55"
18058
18059         create_check_volatile 0
18060         [ $MDSCOUNT -lt 2 ] && return 0
18061
18062         # DNE case
18063         create_check_volatile 1
18064
18065         return 0
18066 }
18067 run_test 185a "Volatile file creation in .lustre/fid/"
18068
18069 test_187a() {
18070         remote_mds_nodsh && skip "remote MDS with nodsh"
18071         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18072                 skip "Need MDS version at least 2.3.0"
18073
18074         local dir0=$DIR/$tdir/$testnum
18075         mkdir -p $dir0 || error "creating dir $dir0"
18076
18077         local file=$dir0/file1
18078         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18079         local dv1=$($LFS data_version $file)
18080         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18081         local dv2=$($LFS data_version $file)
18082         [[ $dv1 != $dv2 ]] ||
18083                 error "data version did not change on write $dv1 == $dv2"
18084
18085         # clean up
18086         rm -f $file1
18087 }
18088 run_test 187a "Test data version change"
18089
18090 test_187b() {
18091         remote_mds_nodsh && skip "remote MDS with nodsh"
18092         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18093                 skip "Need MDS version at least 2.3.0"
18094
18095         local dir0=$DIR/$tdir/$testnum
18096         mkdir -p $dir0 || error "creating dir $dir0"
18097
18098         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18099         [[ ${DV[0]} != ${DV[1]} ]] ||
18100                 error "data version did not change on write"\
18101                       " ${DV[0]} == ${DV[1]}"
18102
18103         # clean up
18104         rm -f $file1
18105 }
18106 run_test 187b "Test data version change on volatile file"
18107
18108 test_200() {
18109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18110         remote_mgs_nodsh && skip "remote MGS with nodsh"
18111         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18112
18113         local POOL=${POOL:-cea1}
18114         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18115         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18116         # Pool OST targets
18117         local first_ost=0
18118         local last_ost=$(($OSTCOUNT - 1))
18119         local ost_step=2
18120         local ost_list=$(seq $first_ost $ost_step $last_ost)
18121         local ost_range="$first_ost $last_ost $ost_step"
18122         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18123         local file_dir=$POOL_ROOT/file_tst
18124         local subdir=$test_path/subdir
18125         local rc=0
18126
18127         while : ; do
18128                 # former test_200a test_200b
18129                 pool_add $POOL                          || { rc=$? ; break; }
18130                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18131                 # former test_200c test_200d
18132                 mkdir -p $test_path
18133                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18134                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18135                 mkdir -p $subdir
18136                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18137                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18138                                                         || { rc=$? ; break; }
18139                 # former test_200e test_200f
18140                 local files=$((OSTCOUNT*3))
18141                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18142                                                         || { rc=$? ; break; }
18143                 pool_create_files $POOL $file_dir $files "$ost_list" \
18144                                                         || { rc=$? ; break; }
18145                 # former test_200g test_200h
18146                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18147                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18148
18149                 # former test_201a test_201b test_201c
18150                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18151
18152                 local f=$test_path/$tfile
18153                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18154                 pool_remove $POOL $f                    || { rc=$? ; break; }
18155                 break
18156         done
18157
18158         destroy_test_pools
18159
18160         return $rc
18161 }
18162 run_test 200 "OST pools"
18163
18164 # usage: default_attr <count | size | offset>
18165 default_attr() {
18166         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18167 }
18168
18169 # usage: check_default_stripe_attr
18170 check_default_stripe_attr() {
18171         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18172         case $1 in
18173         --stripe-count|-c)
18174                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18175         --stripe-size|-S)
18176                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18177         --stripe-index|-i)
18178                 EXPECTED=-1;;
18179         *)
18180                 error "unknown getstripe attr '$1'"
18181         esac
18182
18183         [ $ACTUAL == $EXPECTED ] ||
18184                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18185 }
18186
18187 test_204a() {
18188         test_mkdir $DIR/$tdir
18189         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18190
18191         check_default_stripe_attr --stripe-count
18192         check_default_stripe_attr --stripe-size
18193         check_default_stripe_attr --stripe-index
18194 }
18195 run_test 204a "Print default stripe attributes"
18196
18197 test_204b() {
18198         test_mkdir $DIR/$tdir
18199         $LFS setstripe --stripe-count 1 $DIR/$tdir
18200
18201         check_default_stripe_attr --stripe-size
18202         check_default_stripe_attr --stripe-index
18203 }
18204 run_test 204b "Print default stripe size and offset"
18205
18206 test_204c() {
18207         test_mkdir $DIR/$tdir
18208         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18209
18210         check_default_stripe_attr --stripe-count
18211         check_default_stripe_attr --stripe-index
18212 }
18213 run_test 204c "Print default stripe count and offset"
18214
18215 test_204d() {
18216         test_mkdir $DIR/$tdir
18217         $LFS setstripe --stripe-index 0 $DIR/$tdir
18218
18219         check_default_stripe_attr --stripe-count
18220         check_default_stripe_attr --stripe-size
18221 }
18222 run_test 204d "Print default stripe count and size"
18223
18224 test_204e() {
18225         test_mkdir $DIR/$tdir
18226         $LFS setstripe -d $DIR/$tdir
18227
18228         check_default_stripe_attr --stripe-count --raw
18229         check_default_stripe_attr --stripe-size --raw
18230         check_default_stripe_attr --stripe-index --raw
18231 }
18232 run_test 204e "Print raw stripe attributes"
18233
18234 test_204f() {
18235         test_mkdir $DIR/$tdir
18236         $LFS setstripe --stripe-count 1 $DIR/$tdir
18237
18238         check_default_stripe_attr --stripe-size --raw
18239         check_default_stripe_attr --stripe-index --raw
18240 }
18241 run_test 204f "Print raw stripe size and offset"
18242
18243 test_204g() {
18244         test_mkdir $DIR/$tdir
18245         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18246
18247         check_default_stripe_attr --stripe-count --raw
18248         check_default_stripe_attr --stripe-index --raw
18249 }
18250 run_test 204g "Print raw stripe count and offset"
18251
18252 test_204h() {
18253         test_mkdir $DIR/$tdir
18254         $LFS setstripe --stripe-index 0 $DIR/$tdir
18255
18256         check_default_stripe_attr --stripe-count --raw
18257         check_default_stripe_attr --stripe-size --raw
18258 }
18259 run_test 204h "Print raw stripe count and size"
18260
18261 # Figure out which job scheduler is being used, if any,
18262 # or use a fake one
18263 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18264         JOBENV=SLURM_JOB_ID
18265 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18266         JOBENV=LSB_JOBID
18267 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18268         JOBENV=PBS_JOBID
18269 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18270         JOBENV=LOADL_STEP_ID
18271 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18272         JOBENV=JOB_ID
18273 else
18274         $LCTL list_param jobid_name > /dev/null 2>&1
18275         if [ $? -eq 0 ]; then
18276                 JOBENV=nodelocal
18277         else
18278                 JOBENV=FAKE_JOBID
18279         fi
18280 fi
18281 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18282
18283 verify_jobstats() {
18284         local cmd=($1)
18285         shift
18286         local facets="$@"
18287
18288 # we don't really need to clear the stats for this test to work, since each
18289 # command has a unique jobid, but it makes debugging easier if needed.
18290 #       for facet in $facets; do
18291 #               local dev=$(convert_facet2label $facet)
18292 #               # clear old jobstats
18293 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18294 #       done
18295
18296         # use a new JobID for each test, or we might see an old one
18297         [ "$JOBENV" = "FAKE_JOBID" ] &&
18298                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18299
18300         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18301
18302         [ "$JOBENV" = "nodelocal" ] && {
18303                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18304                 $LCTL set_param jobid_name=$FAKE_JOBID
18305                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18306         }
18307
18308         log "Test: ${cmd[*]}"
18309         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18310
18311         if [ $JOBENV = "FAKE_JOBID" ]; then
18312                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18313         else
18314                 ${cmd[*]}
18315         fi
18316
18317         # all files are created on OST0000
18318         for facet in $facets; do
18319                 local stats="*.$(convert_facet2label $facet).job_stats"
18320
18321                 # strip out libtool wrappers for in-tree executables
18322                 if (( $(do_facet $facet lctl get_param $stats |
18323                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18324                         do_facet $facet lctl get_param $stats
18325                         error "No jobstats for $JOBVAL found on $facet::$stats"
18326                 fi
18327         done
18328 }
18329
18330 jobstats_set() {
18331         local new_jobenv=$1
18332
18333         set_persistent_param_and_check client "jobid_var" \
18334                 "$FSNAME.sys.jobid_var" $new_jobenv
18335 }
18336
18337 test_205a() { # Job stats
18338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18339         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18340                 skip "Need MDS version with at least 2.7.1"
18341         remote_mgs_nodsh && skip "remote MGS with nodsh"
18342         remote_mds_nodsh && skip "remote MDS with nodsh"
18343         remote_ost_nodsh && skip "remote OST with nodsh"
18344         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18345                 skip "Server doesn't support jobstats"
18346         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18347
18348         local old_jobenv=$($LCTL get_param -n jobid_var)
18349         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18350
18351         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18352                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18353         else
18354                 stack_trap "do_facet mgs $PERM_CMD \
18355                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18356         fi
18357         changelog_register
18358
18359         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18360                                 mdt.*.job_cleanup_interval | head -n 1)
18361         local new_interval=5
18362         do_facet $SINGLEMDS \
18363                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18364         stack_trap "do_facet $SINGLEMDS \
18365                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18366         local start=$SECONDS
18367
18368         local cmd
18369         # mkdir
18370         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18371         verify_jobstats "$cmd" "$SINGLEMDS"
18372         # rmdir
18373         cmd="rmdir $DIR/$tdir"
18374         verify_jobstats "$cmd" "$SINGLEMDS"
18375         # mkdir on secondary MDT
18376         if [ $MDSCOUNT -gt 1 ]; then
18377                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18378                 verify_jobstats "$cmd" "mds2"
18379         fi
18380         # mknod
18381         cmd="mknod $DIR/$tfile c 1 3"
18382         verify_jobstats "$cmd" "$SINGLEMDS"
18383         # unlink
18384         cmd="rm -f $DIR/$tfile"
18385         verify_jobstats "$cmd" "$SINGLEMDS"
18386         # create all files on OST0000 so verify_jobstats can find OST stats
18387         # open & close
18388         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18389         verify_jobstats "$cmd" "$SINGLEMDS"
18390         # setattr
18391         cmd="touch $DIR/$tfile"
18392         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18393         # write
18394         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18395         verify_jobstats "$cmd" "ost1"
18396         # read
18397         cancel_lru_locks osc
18398         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18399         verify_jobstats "$cmd" "ost1"
18400         # truncate
18401         cmd="$TRUNCATE $DIR/$tfile 0"
18402         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18403         # rename
18404         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18405         verify_jobstats "$cmd" "$SINGLEMDS"
18406         # jobstats expiry - sleep until old stats should be expired
18407         local left=$((new_interval + 5 - (SECONDS - start)))
18408         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18409                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18410                         "0" $left
18411         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18412         verify_jobstats "$cmd" "$SINGLEMDS"
18413         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18414             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18415
18416         # Ensure that jobid are present in changelog (if supported by MDS)
18417         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18418                 changelog_dump | tail -10
18419                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18420                 [ $jobids -eq 9 ] ||
18421                         error "Wrong changelog jobid count $jobids != 9"
18422
18423                 # LU-5862
18424                 JOBENV="disable"
18425                 jobstats_set $JOBENV
18426                 touch $DIR/$tfile
18427                 changelog_dump | grep $tfile
18428                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18429                 [ $jobids -eq 0 ] ||
18430                         error "Unexpected jobids when jobid_var=$JOBENV"
18431         fi
18432
18433         # test '%j' access to environment variable - if supported
18434         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18435                 JOBENV="JOBCOMPLEX"
18436                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18437
18438                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18439         fi
18440
18441         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18442                 JOBENV="JOBCOMPLEX"
18443                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18444
18445                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18446         fi
18447
18448         # test '%j' access to per-session jobid - if supported
18449         if lctl list_param jobid_this_session > /dev/null 2>&1
18450         then
18451                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18452                 lctl set_param jobid_this_session=$USER
18453
18454                 JOBENV="JOBCOMPLEX"
18455                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18456
18457                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18458         fi
18459 }
18460 run_test 205a "Verify job stats"
18461
18462 # LU-13117, LU-13597
18463 test_205b() {
18464         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18465                 skip "Need MDS version at least 2.13.54.91"
18466
18467         job_stats="mdt.*.job_stats"
18468         $LCTL set_param $job_stats=clear
18469         # Setting jobid_var to USER might not be supported
18470         $LCTL set_param jobid_var=USER || true
18471         $LCTL set_param jobid_name="%e.%u"
18472         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18473         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18474                 grep "job_id:.*foolish" &&
18475                         error "Unexpected jobid found"
18476         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18477                 grep "open:.*min.*max.*sum" ||
18478                         error "wrong job_stats format found"
18479 }
18480 run_test 205b "Verify job stats jobid and output format"
18481
18482 # LU-13733
18483 test_205c() {
18484         $LCTL set_param llite.*.stats=0
18485         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18486         $LCTL get_param llite.*.stats
18487         $LCTL get_param llite.*.stats | grep \
18488                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18489                         error "wrong client stats format found"
18490 }
18491 run_test 205c "Verify client stats format"
18492
18493 # LU-1480, LU-1773 and LU-1657
18494 test_206() {
18495         mkdir -p $DIR/$tdir
18496         $LFS setstripe -c -1 $DIR/$tdir
18497 #define OBD_FAIL_LOV_INIT 0x1403
18498         $LCTL set_param fail_loc=0xa0001403
18499         $LCTL set_param fail_val=1
18500         touch $DIR/$tdir/$tfile || true
18501 }
18502 run_test 206 "fail lov_init_raid0() doesn't lbug"
18503
18504 test_207a() {
18505         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18506         local fsz=`stat -c %s $DIR/$tfile`
18507         cancel_lru_locks mdc
18508
18509         # do not return layout in getattr intent
18510 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18511         $LCTL set_param fail_loc=0x170
18512         local sz=`stat -c %s $DIR/$tfile`
18513
18514         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18515
18516         rm -rf $DIR/$tfile
18517 }
18518 run_test 207a "can refresh layout at glimpse"
18519
18520 test_207b() {
18521         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18522         local cksum=`md5sum $DIR/$tfile`
18523         local fsz=`stat -c %s $DIR/$tfile`
18524         cancel_lru_locks mdc
18525         cancel_lru_locks osc
18526
18527         # do not return layout in getattr intent
18528 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18529         $LCTL set_param fail_loc=0x171
18530
18531         # it will refresh layout after the file is opened but before read issues
18532         echo checksum is "$cksum"
18533         echo "$cksum" |md5sum -c --quiet || error "file differs"
18534
18535         rm -rf $DIR/$tfile
18536 }
18537 run_test 207b "can refresh layout at open"
18538
18539 test_208() {
18540         # FIXME: in this test suite, only RD lease is used. This is okay
18541         # for now as only exclusive open is supported. After generic lease
18542         # is done, this test suite should be revised. - Jinshan
18543
18544         remote_mds_nodsh && skip "remote MDS with nodsh"
18545         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18546                 skip "Need MDS version at least 2.4.52"
18547
18548         echo "==== test 1: verify get lease work"
18549         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18550
18551         echo "==== test 2: verify lease can be broken by upcoming open"
18552         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18553         local PID=$!
18554         sleep 1
18555
18556         $MULTIOP $DIR/$tfile oO_RDWR:c
18557         kill -USR1 $PID && wait $PID || error "break lease error"
18558
18559         echo "==== test 3: verify lease can't be granted if an open already exists"
18560         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18561         local PID=$!
18562         sleep 1
18563
18564         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18565         kill -USR1 $PID && wait $PID || error "open file error"
18566
18567         echo "==== test 4: lease can sustain over recovery"
18568         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18569         PID=$!
18570         sleep 1
18571
18572         fail mds1
18573
18574         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18575
18576         echo "==== test 5: lease broken can't be regained by replay"
18577         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18578         PID=$!
18579         sleep 1
18580
18581         # open file to break lease and then recovery
18582         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18583         fail mds1
18584
18585         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18586
18587         rm -f $DIR/$tfile
18588 }
18589 run_test 208 "Exclusive open"
18590
18591 test_209() {
18592         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18593                 skip_env "must have disp_stripe"
18594
18595         touch $DIR/$tfile
18596         sync; sleep 5; sync;
18597
18598         echo 3 > /proc/sys/vm/drop_caches
18599         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18600                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18601         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18602
18603         # open/close 500 times
18604         for i in $(seq 500); do
18605                 cat $DIR/$tfile
18606         done
18607
18608         echo 3 > /proc/sys/vm/drop_caches
18609         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18610                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18611         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18612
18613         echo "before: $req_before, after: $req_after"
18614         [ $((req_after - req_before)) -ge 300 ] &&
18615                 error "open/close requests are not freed"
18616         return 0
18617 }
18618 run_test 209 "read-only open/close requests should be freed promptly"
18619
18620 test_210() {
18621         local pid
18622
18623         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18624         pid=$!
18625         sleep 1
18626
18627         $LFS getstripe $DIR/$tfile
18628         kill -USR1 $pid
18629         wait $pid || error "multiop failed"
18630
18631         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18632         pid=$!
18633         sleep 1
18634
18635         $LFS getstripe $DIR/$tfile
18636         kill -USR1 $pid
18637         wait $pid || error "multiop failed"
18638 }
18639 run_test 210 "lfs getstripe does not break leases"
18640
18641 test_212() {
18642         size=`date +%s`
18643         size=$((size % 8192 + 1))
18644         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18645         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18646         rm -f $DIR/f212 $DIR/f212.xyz
18647 }
18648 run_test 212 "Sendfile test ============================================"
18649
18650 test_213() {
18651         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18652         cancel_lru_locks osc
18653         lctl set_param fail_loc=0x8000040f
18654         # generate a read lock
18655         cat $DIR/$tfile > /dev/null
18656         # write to the file, it will try to cancel the above read lock.
18657         cat /etc/hosts >> $DIR/$tfile
18658 }
18659 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18660
18661 test_214() { # for bug 20133
18662         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18663         for (( i=0; i < 340; i++ )) ; do
18664                 touch $DIR/$tdir/d214c/a$i
18665         done
18666
18667         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18668         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18669         ls $DIR/d214c || error "ls $DIR/d214c failed"
18670         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18671         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18672 }
18673 run_test 214 "hash-indexed directory test - bug 20133"
18674
18675 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18676 create_lnet_proc_files() {
18677         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18678 }
18679
18680 # counterpart of create_lnet_proc_files
18681 remove_lnet_proc_files() {
18682         rm -f $TMP/lnet_$1.sys
18683 }
18684
18685 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18686 # 3rd arg as regexp for body
18687 check_lnet_proc_stats() {
18688         local l=$(cat "$TMP/lnet_$1" |wc -l)
18689         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18690
18691         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18692 }
18693
18694 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18695 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18696 # optional and can be regexp for 2nd line (lnet.routes case)
18697 check_lnet_proc_entry() {
18698         local blp=2          # blp stands for 'position of 1st line of body'
18699         [ -z "$5" ] || blp=3 # lnet.routes case
18700
18701         local l=$(cat "$TMP/lnet_$1" |wc -l)
18702         # subtracting one from $blp because the body can be empty
18703         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18704
18705         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18706                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18707
18708         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18709                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18710
18711         # bail out if any unexpected line happened
18712         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18713         [ "$?" != 0 ] || error "$2 misformatted"
18714 }
18715
18716 test_215() { # for bugs 18102, 21079, 21517
18717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18718
18719         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18720         local P='[1-9][0-9]*'           # positive numeric
18721         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18722         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18723         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18724         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18725
18726         local L1 # regexp for 1st line
18727         local L2 # regexp for 2nd line (optional)
18728         local BR # regexp for the rest (body)
18729
18730         # lnet.stats should look as 11 space-separated non-negative numerics
18731         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18732         create_lnet_proc_files "stats"
18733         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18734         remove_lnet_proc_files "stats"
18735
18736         # lnet.routes should look like this:
18737         # Routing disabled/enabled
18738         # net hops priority state router
18739         # where net is a string like tcp0, hops > 0, priority >= 0,
18740         # state is up/down,
18741         # router is a string like 192.168.1.1@tcp2
18742         L1="^Routing (disabled|enabled)$"
18743         L2="^net +hops +priority +state +router$"
18744         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18745         create_lnet_proc_files "routes"
18746         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18747         remove_lnet_proc_files "routes"
18748
18749         # lnet.routers should look like this:
18750         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18751         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18752         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18753         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18754         L1="^ref +rtr_ref +alive +router$"
18755         BR="^$P +$P +(up|down) +$NID$"
18756         create_lnet_proc_files "routers"
18757         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18758         remove_lnet_proc_files "routers"
18759
18760         # lnet.peers should look like this:
18761         # nid refs state last max rtr min tx min queue
18762         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18763         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18764         # numeric (0 or >0 or <0), queue >= 0.
18765         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18766         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18767         create_lnet_proc_files "peers"
18768         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18769         remove_lnet_proc_files "peers"
18770
18771         # lnet.buffers  should look like this:
18772         # pages count credits min
18773         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18774         L1="^pages +count +credits +min$"
18775         BR="^ +$N +$N +$I +$I$"
18776         create_lnet_proc_files "buffers"
18777         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18778         remove_lnet_proc_files "buffers"
18779
18780         # lnet.nis should look like this:
18781         # nid status alive refs peer rtr max tx min
18782         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18783         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18784         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18785         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18786         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18787         create_lnet_proc_files "nis"
18788         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18789         remove_lnet_proc_files "nis"
18790
18791         # can we successfully write to lnet.stats?
18792         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18793 }
18794 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18795
18796 test_216() { # bug 20317
18797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18798         remote_ost_nodsh && skip "remote OST with nodsh"
18799
18800         local node
18801         local facets=$(get_facets OST)
18802         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18803
18804         save_lustre_params client "osc.*.contention_seconds" > $p
18805         save_lustre_params $facets \
18806                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18807         save_lustre_params $facets \
18808                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18809         save_lustre_params $facets \
18810                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18811         clear_stats osc.*.osc_stats
18812
18813         # agressive lockless i/o settings
18814         do_nodes $(comma_list $(osts_nodes)) \
18815                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18816                         ldlm.namespaces.filter-*.contended_locks=0 \
18817                         ldlm.namespaces.filter-*.contention_seconds=60"
18818         lctl set_param -n osc.*.contention_seconds=60
18819
18820         $DIRECTIO write $DIR/$tfile 0 10 4096
18821         $CHECKSTAT -s 40960 $DIR/$tfile
18822
18823         # disable lockless i/o
18824         do_nodes $(comma_list $(osts_nodes)) \
18825                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18826                         ldlm.namespaces.filter-*.contended_locks=32 \
18827                         ldlm.namespaces.filter-*.contention_seconds=0"
18828         lctl set_param -n osc.*.contention_seconds=0
18829         clear_stats osc.*.osc_stats
18830
18831         dd if=/dev/zero of=$DIR/$tfile count=0
18832         $CHECKSTAT -s 0 $DIR/$tfile
18833
18834         restore_lustre_params <$p
18835         rm -f $p
18836         rm $DIR/$tfile
18837 }
18838 run_test 216 "check lockless direct write updates file size and kms correctly"
18839
18840 test_217() { # bug 22430
18841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18842
18843         local node
18844         local nid
18845
18846         for node in $(nodes_list); do
18847                 nid=$(host_nids_address $node $NETTYPE)
18848                 if [[ $nid = *-* ]] ; then
18849                         echo "lctl ping $(h2nettype $nid)"
18850                         lctl ping $(h2nettype $nid)
18851                 else
18852                         echo "skipping $node (no hyphen detected)"
18853                 fi
18854         done
18855 }
18856 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18857
18858 test_218() {
18859        # do directio so as not to populate the page cache
18860        log "creating a 10 Mb file"
18861        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18862        log "starting reads"
18863        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18864        log "truncating the file"
18865        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18866        log "killing dd"
18867        kill %+ || true # reads might have finished
18868        echo "wait until dd is finished"
18869        wait
18870        log "removing the temporary file"
18871        rm -rf $DIR/$tfile || error "tmp file removal failed"
18872 }
18873 run_test 218 "parallel read and truncate should not deadlock"
18874
18875 test_219() {
18876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18877
18878         # write one partial page
18879         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18880         # set no grant so vvp_io_commit_write will do sync write
18881         $LCTL set_param fail_loc=0x411
18882         # write a full page at the end of file
18883         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18884
18885         $LCTL set_param fail_loc=0
18886         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18887         $LCTL set_param fail_loc=0x411
18888         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18889
18890         # LU-4201
18891         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18892         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18893 }
18894 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18895
18896 test_220() { #LU-325
18897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18898         remote_ost_nodsh && skip "remote OST with nodsh"
18899         remote_mds_nodsh && skip "remote MDS with nodsh"
18900         remote_mgs_nodsh && skip "remote MGS with nodsh"
18901
18902         local OSTIDX=0
18903
18904         # create on MDT0000 so the last_id and next_id are correct
18905         mkdir_on_mdt0 $DIR/$tdir
18906         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18907         OST=${OST%_UUID}
18908
18909         # on the mdt's osc
18910         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18911         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18912                         osp.$mdtosc_proc1.prealloc_last_id)
18913         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18914                         osp.$mdtosc_proc1.prealloc_next_id)
18915
18916         $LFS df -i
18917
18918         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18919         #define OBD_FAIL_OST_ENOINO              0x229
18920         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18921         create_pool $FSNAME.$TESTNAME || return 1
18922         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18923
18924         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18925
18926         MDSOBJS=$((last_id - next_id))
18927         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18928
18929         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18930         echo "OST still has $count kbytes free"
18931
18932         echo "create $MDSOBJS files @next_id..."
18933         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18934
18935         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18936                         osp.$mdtosc_proc1.prealloc_last_id)
18937         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18938                         osp.$mdtosc_proc1.prealloc_next_id)
18939
18940         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18941         $LFS df -i
18942
18943         echo "cleanup..."
18944
18945         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18946         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18947
18948         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18949                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18950         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18951                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18952         echo "unlink $MDSOBJS files @$next_id..."
18953         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18954 }
18955 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18956
18957 test_221() {
18958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18959
18960         dd if=`which date` of=$MOUNT/date oflag=sync
18961         chmod +x $MOUNT/date
18962
18963         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18964         $LCTL set_param fail_loc=0x80001401
18965
18966         $MOUNT/date > /dev/null
18967         rm -f $MOUNT/date
18968 }
18969 run_test 221 "make sure fault and truncate race to not cause OOM"
18970
18971 test_222a () {
18972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18973
18974         rm -rf $DIR/$tdir
18975         test_mkdir $DIR/$tdir
18976         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18977         createmany -o $DIR/$tdir/$tfile 10
18978         cancel_lru_locks mdc
18979         cancel_lru_locks osc
18980         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18981         $LCTL set_param fail_loc=0x31a
18982         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18983         $LCTL set_param fail_loc=0
18984         rm -r $DIR/$tdir
18985 }
18986 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18987
18988 test_222b () {
18989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18990
18991         rm -rf $DIR/$tdir
18992         test_mkdir $DIR/$tdir
18993         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18994         createmany -o $DIR/$tdir/$tfile 10
18995         cancel_lru_locks mdc
18996         cancel_lru_locks osc
18997         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18998         $LCTL set_param fail_loc=0x31a
18999         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19000         $LCTL set_param fail_loc=0
19001 }
19002 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19003
19004 test_223 () {
19005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19006
19007         rm -rf $DIR/$tdir
19008         test_mkdir $DIR/$tdir
19009         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19010         createmany -o $DIR/$tdir/$tfile 10
19011         cancel_lru_locks mdc
19012         cancel_lru_locks osc
19013         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19014         $LCTL set_param fail_loc=0x31b
19015         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19016         $LCTL set_param fail_loc=0
19017         rm -r $DIR/$tdir
19018 }
19019 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19020
19021 test_224a() { # LU-1039, MRP-303
19022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19023         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19024         $LCTL set_param fail_loc=0x508
19025         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19026         $LCTL set_param fail_loc=0
19027         df $DIR
19028 }
19029 run_test 224a "Don't panic on bulk IO failure"
19030
19031 test_224bd_sub() { # LU-1039, MRP-303
19032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19033         local timeout=$1
19034
19035         shift
19036         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19037
19038         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19039
19040         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19041         cancel_lru_locks osc
19042         set_checksums 0
19043         stack_trap "set_checksums $ORIG_CSUM" EXIT
19044         local at_max_saved=0
19045
19046         # adaptive timeouts may prevent seeing the issue
19047         if at_is_enabled; then
19048                 at_max_saved=$(at_max_get mds)
19049                 at_max_set 0 mds client
19050                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19051         fi
19052
19053         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19054         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19055         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19056
19057         do_facet ost1 $LCTL set_param fail_loc=0
19058         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19059         df $DIR
19060 }
19061
19062 test_224b() {
19063         test_224bd_sub 3 error "dd failed"
19064 }
19065 run_test 224b "Don't panic on bulk IO failure"
19066
19067 test_224c() { # LU-6441
19068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19069         remote_mds_nodsh && skip "remote MDS with nodsh"
19070
19071         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19072         save_writethrough $p
19073         set_cache writethrough on
19074
19075         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19076         local at_max=$($LCTL get_param -n at_max)
19077         local timeout=$($LCTL get_param -n timeout)
19078         local test_at="at_max"
19079         local param_at="$FSNAME.sys.at_max"
19080         local test_timeout="timeout"
19081         local param_timeout="$FSNAME.sys.timeout"
19082
19083         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19084
19085         set_persistent_param_and_check client "$test_at" "$param_at" 0
19086         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19087
19088         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19089         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19090         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19091         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19092         sync
19093         do_facet ost1 "$LCTL set_param fail_loc=0"
19094
19095         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19096         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19097                 $timeout
19098
19099         $LCTL set_param -n $pages_per_rpc
19100         restore_lustre_params < $p
19101         rm -f $p
19102 }
19103 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19104
19105 test_224d() { # LU-11169
19106         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19107 }
19108 run_test 224d "Don't corrupt data on bulk IO timeout"
19109
19110 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19111 test_225a () {
19112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19113         if [ -z ${MDSSURVEY} ]; then
19114                 skip_env "mds-survey not found"
19115         fi
19116         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19117                 skip "Need MDS version at least 2.2.51"
19118
19119         local mds=$(facet_host $SINGLEMDS)
19120         local target=$(do_nodes $mds 'lctl dl' |
19121                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19122
19123         local cmd1="file_count=1000 thrhi=4"
19124         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19125         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19126         local cmd="$cmd1 $cmd2 $cmd3"
19127
19128         rm -f ${TMP}/mds_survey*
19129         echo + $cmd
19130         eval $cmd || error "mds-survey with zero-stripe failed"
19131         cat ${TMP}/mds_survey*
19132         rm -f ${TMP}/mds_survey*
19133 }
19134 run_test 225a "Metadata survey sanity with zero-stripe"
19135
19136 test_225b () {
19137         if [ -z ${MDSSURVEY} ]; then
19138                 skip_env "mds-survey not found"
19139         fi
19140         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19141                 skip "Need MDS version at least 2.2.51"
19142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19143         remote_mds_nodsh && skip "remote MDS with nodsh"
19144         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19145                 skip_env "Need to mount OST to test"
19146         fi
19147
19148         local mds=$(facet_host $SINGLEMDS)
19149         local target=$(do_nodes $mds 'lctl dl' |
19150                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19151
19152         local cmd1="file_count=1000 thrhi=4"
19153         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19154         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19155         local cmd="$cmd1 $cmd2 $cmd3"
19156
19157         rm -f ${TMP}/mds_survey*
19158         echo + $cmd
19159         eval $cmd || error "mds-survey with stripe_count failed"
19160         cat ${TMP}/mds_survey*
19161         rm -f ${TMP}/mds_survey*
19162 }
19163 run_test 225b "Metadata survey sanity with stripe_count = 1"
19164
19165 mcreate_path2fid () {
19166         local mode=$1
19167         local major=$2
19168         local minor=$3
19169         local name=$4
19170         local desc=$5
19171         local path=$DIR/$tdir/$name
19172         local fid
19173         local rc
19174         local fid_path
19175
19176         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19177                 error "cannot create $desc"
19178
19179         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19180         rc=$?
19181         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19182
19183         fid_path=$($LFS fid2path $MOUNT $fid)
19184         rc=$?
19185         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19186
19187         [ "$path" == "$fid_path" ] ||
19188                 error "fid2path returned $fid_path, expected $path"
19189
19190         echo "pass with $path and $fid"
19191 }
19192
19193 test_226a () {
19194         rm -rf $DIR/$tdir
19195         mkdir -p $DIR/$tdir
19196
19197         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19198         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19199         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19200         mcreate_path2fid 0040666 0 0 dir "directory"
19201         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19202         mcreate_path2fid 0100666 0 0 file "regular file"
19203         mcreate_path2fid 0120666 0 0 link "symbolic link"
19204         mcreate_path2fid 0140666 0 0 sock "socket"
19205 }
19206 run_test 226a "call path2fid and fid2path on files of all type"
19207
19208 test_226b () {
19209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19210
19211         local MDTIDX=1
19212
19213         rm -rf $DIR/$tdir
19214         mkdir -p $DIR/$tdir
19215         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19216                 error "create remote directory failed"
19217         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19218         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19219                                 "character special file (null)"
19220         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19221                                 "character special file (no device)"
19222         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19223         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19224                                 "block special file (loop)"
19225         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19226         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19227         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19228 }
19229 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19230
19231 test_226c () {
19232         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19233         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19234                 skip "Need MDS version at least 2.13.55"
19235
19236         local submnt=/mnt/submnt
19237         local srcfile=/etc/passwd
19238         local dstfile=$submnt/passwd
19239         local path
19240         local fid
19241
19242         rm -rf $DIR/$tdir
19243         rm -rf $submnt
19244         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19245                 error "create remote directory failed"
19246         mkdir -p $submnt || error "create $submnt failed"
19247         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19248                 error "mount $submnt failed"
19249         stack_trap "umount $submnt" EXIT
19250
19251         cp $srcfile $dstfile
19252         fid=$($LFS path2fid $dstfile)
19253         path=$($LFS fid2path $submnt "$fid")
19254         [ "$path" = "$dstfile" ] ||
19255                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19256 }
19257 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19258
19259 # LU-1299 Executing or running ldd on a truncated executable does not
19260 # cause an out-of-memory condition.
19261 test_227() {
19262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19263         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19264
19265         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19266         chmod +x $MOUNT/date
19267
19268         $MOUNT/date > /dev/null
19269         ldd $MOUNT/date > /dev/null
19270         rm -f $MOUNT/date
19271 }
19272 run_test 227 "running truncated executable does not cause OOM"
19273
19274 # LU-1512 try to reuse idle OI blocks
19275 test_228a() {
19276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19277         remote_mds_nodsh && skip "remote MDS with nodsh"
19278         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19279
19280         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19281         local myDIR=$DIR/$tdir
19282
19283         mkdir -p $myDIR
19284         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19285         $LCTL set_param fail_loc=0x80001002
19286         createmany -o $myDIR/t- 10000
19287         $LCTL set_param fail_loc=0
19288         # The guard is current the largest FID holder
19289         touch $myDIR/guard
19290         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19291                     tr -d '[')
19292         local IDX=$(($SEQ % 64))
19293
19294         do_facet $SINGLEMDS sync
19295         # Make sure journal flushed.
19296         sleep 6
19297         local blk1=$(do_facet $SINGLEMDS \
19298                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19299                      grep Blockcount | awk '{print $4}')
19300
19301         # Remove old files, some OI blocks will become idle.
19302         unlinkmany $myDIR/t- 10000
19303         # Create new files, idle OI blocks should be reused.
19304         createmany -o $myDIR/t- 2000
19305         do_facet $SINGLEMDS sync
19306         # Make sure journal flushed.
19307         sleep 6
19308         local blk2=$(do_facet $SINGLEMDS \
19309                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19310                      grep Blockcount | awk '{print $4}')
19311
19312         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19313 }
19314 run_test 228a "try to reuse idle OI blocks"
19315
19316 test_228b() {
19317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19318         remote_mds_nodsh && skip "remote MDS with nodsh"
19319         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19320
19321         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19322         local myDIR=$DIR/$tdir
19323
19324         mkdir -p $myDIR
19325         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19326         $LCTL set_param fail_loc=0x80001002
19327         createmany -o $myDIR/t- 10000
19328         $LCTL set_param fail_loc=0
19329         # The guard is current the largest FID holder
19330         touch $myDIR/guard
19331         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19332                     tr -d '[')
19333         local IDX=$(($SEQ % 64))
19334
19335         do_facet $SINGLEMDS sync
19336         # Make sure journal flushed.
19337         sleep 6
19338         local blk1=$(do_facet $SINGLEMDS \
19339                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19340                      grep Blockcount | awk '{print $4}')
19341
19342         # Remove old files, some OI blocks will become idle.
19343         unlinkmany $myDIR/t- 10000
19344
19345         # stop the MDT
19346         stop $SINGLEMDS || error "Fail to stop MDT."
19347         # remount the MDT
19348         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19349
19350         df $MOUNT || error "Fail to df."
19351         # Create new files, idle OI blocks should be reused.
19352         createmany -o $myDIR/t- 2000
19353         do_facet $SINGLEMDS sync
19354         # Make sure journal flushed.
19355         sleep 6
19356         local blk2=$(do_facet $SINGLEMDS \
19357                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19358                      grep Blockcount | awk '{print $4}')
19359
19360         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19361 }
19362 run_test 228b "idle OI blocks can be reused after MDT restart"
19363
19364 #LU-1881
19365 test_228c() {
19366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19367         remote_mds_nodsh && skip "remote MDS with nodsh"
19368         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19369
19370         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19371         local myDIR=$DIR/$tdir
19372
19373         mkdir -p $myDIR
19374         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19375         $LCTL set_param fail_loc=0x80001002
19376         # 20000 files can guarantee there are index nodes in the OI file
19377         createmany -o $myDIR/t- 20000
19378         $LCTL set_param fail_loc=0
19379         # The guard is current the largest FID holder
19380         touch $myDIR/guard
19381         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19382                     tr -d '[')
19383         local IDX=$(($SEQ % 64))
19384
19385         do_facet $SINGLEMDS sync
19386         # Make sure journal flushed.
19387         sleep 6
19388         local blk1=$(do_facet $SINGLEMDS \
19389                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19390                      grep Blockcount | awk '{print $4}')
19391
19392         # Remove old files, some OI blocks will become idle.
19393         unlinkmany $myDIR/t- 20000
19394         rm -f $myDIR/guard
19395         # The OI file should become empty now
19396
19397         # Create new files, idle OI blocks should be reused.
19398         createmany -o $myDIR/t- 2000
19399         do_facet $SINGLEMDS sync
19400         # Make sure journal flushed.
19401         sleep 6
19402         local blk2=$(do_facet $SINGLEMDS \
19403                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19404                      grep Blockcount | awk '{print $4}')
19405
19406         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19407 }
19408 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19409
19410 test_229() { # LU-2482, LU-3448
19411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19412         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19413         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19414                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19415
19416         rm -f $DIR/$tfile
19417
19418         # Create a file with a released layout and stripe count 2.
19419         $MULTIOP $DIR/$tfile H2c ||
19420                 error "failed to create file with released layout"
19421
19422         $LFS getstripe -v $DIR/$tfile
19423
19424         local pattern=$($LFS getstripe -L $DIR/$tfile)
19425         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19426
19427         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19428                 error "getstripe"
19429         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19430         stat $DIR/$tfile || error "failed to stat released file"
19431
19432         chown $RUNAS_ID $DIR/$tfile ||
19433                 error "chown $RUNAS_ID $DIR/$tfile failed"
19434
19435         chgrp $RUNAS_ID $DIR/$tfile ||
19436                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19437
19438         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19439         rm $DIR/$tfile || error "failed to remove released file"
19440 }
19441 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19442
19443 test_230a() {
19444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19446         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19447                 skip "Need MDS version at least 2.11.52"
19448
19449         local MDTIDX=1
19450
19451         test_mkdir $DIR/$tdir
19452         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19453         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19454         [ $mdt_idx -ne 0 ] &&
19455                 error "create local directory on wrong MDT $mdt_idx"
19456
19457         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19458                         error "create remote directory failed"
19459         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19460         [ $mdt_idx -ne $MDTIDX ] &&
19461                 error "create remote directory on wrong MDT $mdt_idx"
19462
19463         createmany -o $DIR/$tdir/test_230/t- 10 ||
19464                 error "create files on remote directory failed"
19465         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19466         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19467         rm -r $DIR/$tdir || error "unlink remote directory failed"
19468 }
19469 run_test 230a "Create remote directory and files under the remote directory"
19470
19471 test_230b() {
19472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19474         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19475                 skip "Need MDS version at least 2.11.52"
19476
19477         local MDTIDX=1
19478         local mdt_index
19479         local i
19480         local file
19481         local pid
19482         local stripe_count
19483         local migrate_dir=$DIR/$tdir/migrate_dir
19484         local other_dir=$DIR/$tdir/other_dir
19485
19486         test_mkdir $DIR/$tdir
19487         test_mkdir -i0 -c1 $migrate_dir
19488         test_mkdir -i0 -c1 $other_dir
19489         for ((i=0; i<10; i++)); do
19490                 mkdir -p $migrate_dir/dir_${i}
19491                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19492                         error "create files under remote dir failed $i"
19493         done
19494
19495         cp /etc/passwd $migrate_dir/$tfile
19496         cp /etc/passwd $other_dir/$tfile
19497         chattr +SAD $migrate_dir
19498         chattr +SAD $migrate_dir/$tfile
19499
19500         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19501         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19502         local old_dir_mode=$(stat -c%f $migrate_dir)
19503         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19504
19505         mkdir -p $migrate_dir/dir_default_stripe2
19506         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19507         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19508
19509         mkdir -p $other_dir
19510         ln $migrate_dir/$tfile $other_dir/luna
19511         ln $migrate_dir/$tfile $migrate_dir/sofia
19512         ln $other_dir/$tfile $migrate_dir/david
19513         ln -s $migrate_dir/$tfile $other_dir/zachary
19514         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19515         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19516
19517         local len
19518         local lnktgt
19519
19520         # inline symlink
19521         for len in 58 59 60; do
19522                 lnktgt=$(str_repeat 'l' $len)
19523                 touch $migrate_dir/$lnktgt
19524                 ln -s $lnktgt $migrate_dir/${len}char_ln
19525         done
19526
19527         # PATH_MAX
19528         for len in 4094 4095; do
19529                 lnktgt=$(str_repeat 'l' $len)
19530                 ln -s $lnktgt $migrate_dir/${len}char_ln
19531         done
19532
19533         # NAME_MAX
19534         for len in 254 255; do
19535                 touch $migrate_dir/$(str_repeat 'l' $len)
19536         done
19537
19538         $LFS migrate -m $MDTIDX $migrate_dir ||
19539                 error "fails on migrating remote dir to MDT1"
19540
19541         echo "migratate to MDT1, then checking.."
19542         for ((i = 0; i < 10; i++)); do
19543                 for file in $(find $migrate_dir/dir_${i}); do
19544                         mdt_index=$($LFS getstripe -m $file)
19545                         # broken symlink getstripe will fail
19546                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19547                                 error "$file is not on MDT${MDTIDX}"
19548                 done
19549         done
19550
19551         # the multiple link file should still in MDT0
19552         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19553         [ $mdt_index == 0 ] ||
19554                 error "$file is not on MDT${MDTIDX}"
19555
19556         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19557         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19558                 error " expect $old_dir_flag get $new_dir_flag"
19559
19560         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19561         [ "$old_file_flag" = "$new_file_flag" ] ||
19562                 error " expect $old_file_flag get $new_file_flag"
19563
19564         local new_dir_mode=$(stat -c%f $migrate_dir)
19565         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19566                 error "expect mode $old_dir_mode get $new_dir_mode"
19567
19568         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19569         [ "$old_file_mode" = "$new_file_mode" ] ||
19570                 error "expect mode $old_file_mode get $new_file_mode"
19571
19572         diff /etc/passwd $migrate_dir/$tfile ||
19573                 error "$tfile different after migration"
19574
19575         diff /etc/passwd $other_dir/luna ||
19576                 error "luna different after migration"
19577
19578         diff /etc/passwd $migrate_dir/sofia ||
19579                 error "sofia different after migration"
19580
19581         diff /etc/passwd $migrate_dir/david ||
19582                 error "david different after migration"
19583
19584         diff /etc/passwd $other_dir/zachary ||
19585                 error "zachary different after migration"
19586
19587         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19588                 error "${tfile}_ln different after migration"
19589
19590         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19591                 error "${tfile}_ln_other different after migration"
19592
19593         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19594         [ $stripe_count = 2 ] ||
19595                 error "dir strpe_count $d != 2 after migration."
19596
19597         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19598         [ $stripe_count = 2 ] ||
19599                 error "file strpe_count $d != 2 after migration."
19600
19601         #migrate back to MDT0
19602         MDTIDX=0
19603
19604         $LFS migrate -m $MDTIDX $migrate_dir ||
19605                 error "fails on migrating remote dir to MDT0"
19606
19607         echo "migrate back to MDT0, checking.."
19608         for file in $(find $migrate_dir); do
19609                 mdt_index=$($LFS getstripe -m $file)
19610                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19611                         error "$file is not on MDT${MDTIDX}"
19612         done
19613
19614         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19615         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19616                 error " expect $old_dir_flag get $new_dir_flag"
19617
19618         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19619         [ "$old_file_flag" = "$new_file_flag" ] ||
19620                 error " expect $old_file_flag get $new_file_flag"
19621
19622         local new_dir_mode=$(stat -c%f $migrate_dir)
19623         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19624                 error "expect mode $old_dir_mode get $new_dir_mode"
19625
19626         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19627         [ "$old_file_mode" = "$new_file_mode" ] ||
19628                 error "expect mode $old_file_mode get $new_file_mode"
19629
19630         diff /etc/passwd ${migrate_dir}/$tfile ||
19631                 error "$tfile different after migration"
19632
19633         diff /etc/passwd ${other_dir}/luna ||
19634                 error "luna different after migration"
19635
19636         diff /etc/passwd ${migrate_dir}/sofia ||
19637                 error "sofia different after migration"
19638
19639         diff /etc/passwd ${other_dir}/zachary ||
19640                 error "zachary different after migration"
19641
19642         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19643                 error "${tfile}_ln different after migration"
19644
19645         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19646                 error "${tfile}_ln_other different after migration"
19647
19648         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19649         [ $stripe_count = 2 ] ||
19650                 error "dir strpe_count $d != 2 after migration."
19651
19652         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19653         [ $stripe_count = 2 ] ||
19654                 error "file strpe_count $d != 2 after migration."
19655
19656         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19657 }
19658 run_test 230b "migrate directory"
19659
19660 test_230c() {
19661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19662         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19663         remote_mds_nodsh && skip "remote MDS with nodsh"
19664         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19665                 skip "Need MDS version at least 2.11.52"
19666
19667         local MDTIDX=1
19668         local total=3
19669         local mdt_index
19670         local file
19671         local migrate_dir=$DIR/$tdir/migrate_dir
19672
19673         #If migrating directory fails in the middle, all entries of
19674         #the directory is still accessiable.
19675         test_mkdir $DIR/$tdir
19676         test_mkdir -i0 -c1 $migrate_dir
19677         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19678         stat $migrate_dir
19679         createmany -o $migrate_dir/f $total ||
19680                 error "create files under ${migrate_dir} failed"
19681
19682         # fail after migrating top dir, and this will fail only once, so the
19683         # first sub file migration will fail (currently f3), others succeed.
19684         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19685         do_facet mds1 lctl set_param fail_loc=0x1801
19686         local t=$(ls $migrate_dir | wc -l)
19687         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19688                 error "migrate should fail"
19689         local u=$(ls $migrate_dir | wc -l)
19690         [ "$u" == "$t" ] || error "$u != $t during migration"
19691
19692         # add new dir/file should succeed
19693         mkdir $migrate_dir/dir ||
19694                 error "mkdir failed under migrating directory"
19695         touch $migrate_dir/file ||
19696                 error "create file failed under migrating directory"
19697
19698         # add file with existing name should fail
19699         for file in $migrate_dir/f*; do
19700                 stat $file > /dev/null || error "stat $file failed"
19701                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19702                         error "open(O_CREAT|O_EXCL) $file should fail"
19703                 $MULTIOP $file m && error "create $file should fail"
19704                 touch $DIR/$tdir/remote_dir/$tfile ||
19705                         error "touch $tfile failed"
19706                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19707                         error "link $file should fail"
19708                 mdt_index=$($LFS getstripe -m $file)
19709                 if [ $mdt_index == 0 ]; then
19710                         # file failed to migrate is not allowed to rename to
19711                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19712                                 error "rename to $file should fail"
19713                 else
19714                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19715                                 error "rename to $file failed"
19716                 fi
19717                 echo hello >> $file || error "write $file failed"
19718         done
19719
19720         # resume migration with different options should fail
19721         $LFS migrate -m 0 $migrate_dir &&
19722                 error "migrate -m 0 $migrate_dir should fail"
19723
19724         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19725                 error "migrate -c 2 $migrate_dir should fail"
19726
19727         # resume migration should succeed
19728         $LFS migrate -m $MDTIDX $migrate_dir ||
19729                 error "migrate $migrate_dir failed"
19730
19731         echo "Finish migration, then checking.."
19732         for file in $(find $migrate_dir); do
19733                 mdt_index=$($LFS getstripe -m $file)
19734                 [ $mdt_index == $MDTIDX ] ||
19735                         error "$file is not on MDT${MDTIDX}"
19736         done
19737
19738         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19739 }
19740 run_test 230c "check directory accessiblity if migration failed"
19741
19742 test_230d() {
19743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19744         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19745         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19746                 skip "Need MDS version at least 2.11.52"
19747         # LU-11235
19748         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19749
19750         local migrate_dir=$DIR/$tdir/migrate_dir
19751         local old_index
19752         local new_index
19753         local old_count
19754         local new_count
19755         local new_hash
19756         local mdt_index
19757         local i
19758         local j
19759
19760         old_index=$((RANDOM % MDSCOUNT))
19761         old_count=$((MDSCOUNT - old_index))
19762         new_index=$((RANDOM % MDSCOUNT))
19763         new_count=$((MDSCOUNT - new_index))
19764         new_hash=1 # for all_char
19765
19766         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19767         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19768
19769         test_mkdir $DIR/$tdir
19770         test_mkdir -i $old_index -c $old_count $migrate_dir
19771
19772         for ((i=0; i<100; i++)); do
19773                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19774                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19775                         error "create files under remote dir failed $i"
19776         done
19777
19778         echo -n "Migrate from MDT$old_index "
19779         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19780         echo -n "to MDT$new_index"
19781         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19782         echo
19783
19784         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19785         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19786                 error "migrate remote dir error"
19787
19788         echo "Finish migration, then checking.."
19789         for file in $(find $migrate_dir -maxdepth 1); do
19790                 mdt_index=$($LFS getstripe -m $file)
19791                 if [ $mdt_index -lt $new_index ] ||
19792                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19793                         error "$file is on MDT$mdt_index"
19794                 fi
19795         done
19796
19797         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19798 }
19799 run_test 230d "check migrate big directory"
19800
19801 test_230e() {
19802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19803         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19804         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19805                 skip "Need MDS version at least 2.11.52"
19806
19807         local i
19808         local j
19809         local a_fid
19810         local b_fid
19811
19812         mkdir_on_mdt0 $DIR/$tdir
19813         mkdir $DIR/$tdir/migrate_dir
19814         mkdir $DIR/$tdir/other_dir
19815         touch $DIR/$tdir/migrate_dir/a
19816         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19817         ls $DIR/$tdir/other_dir
19818
19819         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19820                 error "migrate dir fails"
19821
19822         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19823         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19824
19825         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19826         [ $mdt_index == 0 ] || error "a is not on MDT0"
19827
19828         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19829                 error "migrate dir fails"
19830
19831         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19832         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19833
19834         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19835         [ $mdt_index == 1 ] || error "a is not on MDT1"
19836
19837         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19838         [ $mdt_index == 1 ] || error "b is not on MDT1"
19839
19840         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19841         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19842
19843         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19844
19845         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19846 }
19847 run_test 230e "migrate mulitple local link files"
19848
19849 test_230f() {
19850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19851         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19852         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19853                 skip "Need MDS version at least 2.11.52"
19854
19855         local a_fid
19856         local ln_fid
19857
19858         mkdir -p $DIR/$tdir
19859         mkdir $DIR/$tdir/migrate_dir
19860         $LFS mkdir -i1 $DIR/$tdir/other_dir
19861         touch $DIR/$tdir/migrate_dir/a
19862         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19863         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19864         ls $DIR/$tdir/other_dir
19865
19866         # a should be migrated to MDT1, since no other links on MDT0
19867         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19868                 error "#1 migrate dir fails"
19869         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19870         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19871         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19872         [ $mdt_index == 1 ] || error "a is not on MDT1"
19873
19874         # a should stay on MDT1, because it is a mulitple link file
19875         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19876                 error "#2 migrate dir fails"
19877         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19878         [ $mdt_index == 1 ] || error "a is not on MDT1"
19879
19880         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19881                 error "#3 migrate dir fails"
19882
19883         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19884         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19885         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19886
19887         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19888         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19889
19890         # a should be migrated to MDT0, since no other links on MDT1
19891         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19892                 error "#4 migrate dir fails"
19893         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19894         [ $mdt_index == 0 ] || error "a is not on MDT0"
19895
19896         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19897 }
19898 run_test 230f "migrate mulitple remote link files"
19899
19900 test_230g() {
19901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19903         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19904                 skip "Need MDS version at least 2.11.52"
19905
19906         mkdir -p $DIR/$tdir/migrate_dir
19907
19908         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19909                 error "migrating dir to non-exist MDT succeeds"
19910         true
19911 }
19912 run_test 230g "migrate dir to non-exist MDT"
19913
19914 test_230h() {
19915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19916         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19917         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19918                 skip "Need MDS version at least 2.11.52"
19919
19920         local mdt_index
19921
19922         mkdir -p $DIR/$tdir/migrate_dir
19923
19924         $LFS migrate -m1 $DIR &&
19925                 error "migrating mountpoint1 should fail"
19926
19927         $LFS migrate -m1 $DIR/$tdir/.. &&
19928                 error "migrating mountpoint2 should fail"
19929
19930         # same as mv
19931         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19932                 error "migrating $tdir/migrate_dir/.. should fail"
19933
19934         true
19935 }
19936 run_test 230h "migrate .. and root"
19937
19938 test_230i() {
19939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19940         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19941         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19942                 skip "Need MDS version at least 2.11.52"
19943
19944         mkdir -p $DIR/$tdir/migrate_dir
19945
19946         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19947                 error "migration fails with a tailing slash"
19948
19949         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19950                 error "migration fails with two tailing slashes"
19951 }
19952 run_test 230i "lfs migrate -m tolerates trailing slashes"
19953
19954 test_230j() {
19955         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19956         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19957                 skip "Need MDS version at least 2.11.52"
19958
19959         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19960         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19961                 error "create $tfile failed"
19962         cat /etc/passwd > $DIR/$tdir/$tfile
19963
19964         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19965
19966         cmp /etc/passwd $DIR/$tdir/$tfile ||
19967                 error "DoM file mismatch after migration"
19968 }
19969 run_test 230j "DoM file data not changed after dir migration"
19970
19971 test_230k() {
19972         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19973         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19974                 skip "Need MDS version at least 2.11.56"
19975
19976         local total=20
19977         local files_on_starting_mdt=0
19978
19979         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19980         $LFS getdirstripe $DIR/$tdir
19981         for i in $(seq $total); do
19982                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19983                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19984                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19985         done
19986
19987         echo "$files_on_starting_mdt files on MDT0"
19988
19989         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19990         $LFS getdirstripe $DIR/$tdir
19991
19992         files_on_starting_mdt=0
19993         for i in $(seq $total); do
19994                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19995                         error "file $tfile.$i mismatch after migration"
19996                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19997                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19998         done
19999
20000         echo "$files_on_starting_mdt files on MDT1 after migration"
20001         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20002
20003         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20004         $LFS getdirstripe $DIR/$tdir
20005
20006         files_on_starting_mdt=0
20007         for i in $(seq $total); do
20008                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20009                         error "file $tfile.$i mismatch after 2nd migration"
20010                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20011                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20012         done
20013
20014         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20015         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20016
20017         true
20018 }
20019 run_test 230k "file data not changed after dir migration"
20020
20021 test_230l() {
20022         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20023         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20024                 skip "Need MDS version at least 2.11.56"
20025
20026         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20027         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20028                 error "create files under remote dir failed $i"
20029         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20030 }
20031 run_test 230l "readdir between MDTs won't crash"
20032
20033 test_230m() {
20034         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20035         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20036                 skip "Need MDS version at least 2.11.56"
20037
20038         local MDTIDX=1
20039         local mig_dir=$DIR/$tdir/migrate_dir
20040         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20041         local shortstr="b"
20042         local val
20043
20044         echo "Creating files and dirs with xattrs"
20045         test_mkdir $DIR/$tdir
20046         test_mkdir -i0 -c1 $mig_dir
20047         mkdir $mig_dir/dir
20048         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20049                 error "cannot set xattr attr1 on dir"
20050         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20051                 error "cannot set xattr attr2 on dir"
20052         touch $mig_dir/dir/f0
20053         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20054                 error "cannot set xattr attr1 on file"
20055         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20056                 error "cannot set xattr attr2 on file"
20057         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20058         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20059         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20060         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20061         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20062         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20063         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20064         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20065         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20066
20067         echo "Migrating to MDT1"
20068         $LFS migrate -m $MDTIDX $mig_dir ||
20069                 error "fails on migrating dir to MDT1"
20070
20071         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20072         echo "Checking xattrs"
20073         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20074         [ "$val" = $longstr ] ||
20075                 error "expecting xattr1 $longstr on dir, found $val"
20076         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20077         [ "$val" = $shortstr ] ||
20078                 error "expecting xattr2 $shortstr on dir, found $val"
20079         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20080         [ "$val" = $longstr ] ||
20081                 error "expecting xattr1 $longstr on file, found $val"
20082         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20083         [ "$val" = $shortstr ] ||
20084                 error "expecting xattr2 $shortstr on file, found $val"
20085 }
20086 run_test 230m "xattrs not changed after dir migration"
20087
20088 test_230n() {
20089         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20090         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20091                 skip "Need MDS version at least 2.13.53"
20092
20093         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20094         cat /etc/hosts > $DIR/$tdir/$tfile
20095         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20096         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20097
20098         cmp /etc/hosts $DIR/$tdir/$tfile ||
20099                 error "File data mismatch after migration"
20100 }
20101 run_test 230n "Dir migration with mirrored file"
20102
20103 test_230o() {
20104         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20105         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20106                 skip "Need MDS version at least 2.13.52"
20107
20108         local mdts=$(comma_list $(mdts_nodes))
20109         local timeout=100
20110         local restripe_status
20111         local delta
20112         local i
20113
20114         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20115
20116         # in case "crush" hash type is not set
20117         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20118
20119         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20120                            mdt.*MDT0000.enable_dir_restripe)
20121         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20122         stack_trap "do_nodes $mdts $LCTL set_param \
20123                     mdt.*.enable_dir_restripe=$restripe_status"
20124
20125         mkdir $DIR/$tdir
20126         createmany -m $DIR/$tdir/f 100 ||
20127                 error "create files under remote dir failed $i"
20128         createmany -d $DIR/$tdir/d 100 ||
20129                 error "create dirs under remote dir failed $i"
20130
20131         for i in $(seq 2 $MDSCOUNT); do
20132                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20133                 $LFS setdirstripe -c $i $DIR/$tdir ||
20134                         error "split -c $i $tdir failed"
20135                 wait_update $HOSTNAME \
20136                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20137                         error "dir split not finished"
20138                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20139                         awk '/migrate/ {sum += $2} END { print sum }')
20140                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20141                 # delta is around total_files/stripe_count
20142                 (( $delta < 200 / (i - 1) + 4 )) ||
20143                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20144         done
20145 }
20146 run_test 230o "dir split"
20147
20148 test_230p() {
20149         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20150         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20151                 skip "Need MDS version at least 2.13.52"
20152
20153         local mdts=$(comma_list $(mdts_nodes))
20154         local timeout=100
20155         local restripe_status
20156         local delta
20157         local c
20158
20159         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20160
20161         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20162
20163         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20164                            mdt.*MDT0000.enable_dir_restripe)
20165         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20166         stack_trap "do_nodes $mdts $LCTL set_param \
20167                     mdt.*.enable_dir_restripe=$restripe_status"
20168
20169         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20170         createmany -m $DIR/$tdir/f 100 ||
20171                 error "create files under remote dir failed"
20172         createmany -d $DIR/$tdir/d 100 ||
20173                 error "create dirs under remote dir failed"
20174
20175         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20176                 local mdt_hash="crush"
20177
20178                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20179                 $LFS setdirstripe -c $c $DIR/$tdir ||
20180                         error "split -c $c $tdir failed"
20181                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20182                         mdt_hash="$mdt_hash,fixed"
20183                 elif [ $c -eq 1 ]; then
20184                         mdt_hash="none"
20185                 fi
20186                 wait_update $HOSTNAME \
20187                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20188                         error "dir merge not finished"
20189                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20190                         awk '/migrate/ {sum += $2} END { print sum }')
20191                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20192                 # delta is around total_files/stripe_count
20193                 (( delta < 200 / c + 4 )) ||
20194                         error "$delta files migrated >= $((200 / c + 4))"
20195         done
20196 }
20197 run_test 230p "dir merge"
20198
20199 test_230q() {
20200         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20201         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20202                 skip "Need MDS version at least 2.13.52"
20203
20204         local mdts=$(comma_list $(mdts_nodes))
20205         local saved_threshold=$(do_facet mds1 \
20206                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20207         local saved_delta=$(do_facet mds1 \
20208                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20209         local threshold=100
20210         local delta=2
20211         local total=0
20212         local stripe_count=0
20213         local stripe_index
20214         local nr_files
20215         local create
20216
20217         # test with fewer files on ZFS
20218         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20219
20220         stack_trap "do_nodes $mdts $LCTL set_param \
20221                     mdt.*.dir_split_count=$saved_threshold"
20222         stack_trap "do_nodes $mdts $LCTL set_param \
20223                     mdt.*.dir_split_delta=$saved_delta"
20224         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20225         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20226         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20227         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20228         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20229         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20230
20231         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20232         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20233
20234         create=$((threshold * 3 / 2))
20235         while [ $stripe_count -lt $MDSCOUNT ]; do
20236                 createmany -m $DIR/$tdir/f $total $create ||
20237                         error "create sub files failed"
20238                 stat $DIR/$tdir > /dev/null
20239                 total=$((total + create))
20240                 stripe_count=$((stripe_count + delta))
20241                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20242
20243                 wait_update $HOSTNAME \
20244                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20245                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20246
20247                 wait_update $HOSTNAME \
20248                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20249                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20250
20251                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20252                 echo "$nr_files/$total files on MDT$stripe_index after split"
20253                 # allow 10% margin of imbalance with crush hash
20254                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20255                         error "$nr_files files on MDT$stripe_index after split"
20256
20257                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20258                 [ $nr_files -eq $total ] ||
20259                         error "total sub files $nr_files != $total"
20260         done
20261
20262         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20263
20264         echo "fixed layout directory won't auto split"
20265         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20266         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20267                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20268         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20269                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20270 }
20271 run_test 230q "dir auto split"
20272
20273 test_230r() {
20274         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20275         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20276         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20277                 skip "Need MDS version at least 2.13.54"
20278
20279         # maximum amount of local locks:
20280         # parent striped dir - 2 locks
20281         # new stripe in parent to migrate to - 1 lock
20282         # source and target - 2 locks
20283         # Total 5 locks for regular file
20284         mkdir -p $DIR/$tdir
20285         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20286         touch $DIR/$tdir/dir1/eee
20287
20288         # create 4 hardlink for 4 more locks
20289         # Total: 9 locks > RS_MAX_LOCKS (8)
20290         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20291         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20292         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20293         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20294         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20295         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20296         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20297         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20298
20299         cancel_lru_locks mdc
20300
20301         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20302                 error "migrate dir fails"
20303
20304         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20305 }
20306 run_test 230r "migrate with too many local locks"
20307
20308 test_230s() {
20309         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20310                 skip "Need MDS version at least 2.13.57"
20311
20312         local mdts=$(comma_list $(mdts_nodes))
20313         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20314                                 mdt.*MDT0000.enable_dir_restripe)
20315
20316         stack_trap "do_nodes $mdts $LCTL set_param \
20317                     mdt.*.enable_dir_restripe=$restripe_status"
20318
20319         local st
20320         for st in 0 1; do
20321                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20322                 test_mkdir $DIR/$tdir
20323                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20324                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20325                 rmdir $DIR/$tdir
20326         done
20327 }
20328 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20329
20330 test_230t()
20331 {
20332         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20333         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20334                 skip "Need MDS version at least 2.14.50"
20335
20336         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20337         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20338         $LFS project -p 1 -s $DIR/$tdir ||
20339                 error "set $tdir project id failed"
20340         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20341                 error "set subdir project id failed"
20342         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20343 }
20344 run_test 230t "migrate directory with project ID set"
20345
20346 test_230u()
20347 {
20348         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20349         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20350                 skip "Need MDS version at least 2.14.53"
20351
20352         local count
20353
20354         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20355         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20356         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20357         for i in $(seq 0 $((MDSCOUNT - 1))); do
20358                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20359                 echo "$count dirs migrated to MDT$i"
20360         done
20361         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20362         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20363 }
20364 run_test 230u "migrate directory by QOS"
20365
20366 test_230v()
20367 {
20368         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20369         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20370                 skip "Need MDS version at least 2.14.53"
20371
20372         local count
20373
20374         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20375         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20376         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20377         for i in $(seq 0 $((MDSCOUNT - 1))); do
20378                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20379                 echo "$count subdirs migrated to MDT$i"
20380                 (( i == 3 )) && (( count > 0 )) &&
20381                         error "subdir shouldn't be migrated to MDT3"
20382         done
20383         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20384         (( count == 3 )) || error "dirs migrated to $count MDTs"
20385 }
20386 run_test 230v "subdir migrated to the MDT where its parent is located"
20387
20388 test_230w() {
20389         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20390         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20391                 skip "Need MDS version at least 2.14.53"
20392
20393         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20394
20395         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20396                 error "migrate failed"
20397
20398         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20399                 error "$tdir stripe count mismatch"
20400
20401         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20402                 error "$tdir/sub is striped"
20403 }
20404 run_test 230w "non-recursive mode dir migration"
20405
20406 test_231a()
20407 {
20408         # For simplicity this test assumes that max_pages_per_rpc
20409         # is the same across all OSCs
20410         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20411         local bulk_size=$((max_pages * PAGE_SIZE))
20412         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20413                                        head -n 1)
20414
20415         mkdir -p $DIR/$tdir
20416         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20417                 error "failed to set stripe with -S ${brw_size}M option"
20418
20419         # clear the OSC stats
20420         $LCTL set_param osc.*.stats=0 &>/dev/null
20421         stop_writeback
20422
20423         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20424         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20425                 oflag=direct &>/dev/null || error "dd failed"
20426
20427         sync; sleep 1; sync # just to be safe
20428         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20429         if [ x$nrpcs != "x1" ]; then
20430                 $LCTL get_param osc.*.stats
20431                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20432         fi
20433
20434         start_writeback
20435         # Drop the OSC cache, otherwise we will read from it
20436         cancel_lru_locks osc
20437
20438         # clear the OSC stats
20439         $LCTL set_param osc.*.stats=0 &>/dev/null
20440
20441         # Client reads $bulk_size.
20442         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20443                 iflag=direct &>/dev/null || error "dd failed"
20444
20445         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20446         if [ x$nrpcs != "x1" ]; then
20447                 $LCTL get_param osc.*.stats
20448                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20449         fi
20450 }
20451 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20452
20453 test_231b() {
20454         mkdir -p $DIR/$tdir
20455         local i
20456         for i in {0..1023}; do
20457                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20458                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20459                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20460         done
20461         sync
20462 }
20463 run_test 231b "must not assert on fully utilized OST request buffer"
20464
20465 test_232a() {
20466         mkdir -p $DIR/$tdir
20467         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20468
20469         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20470         do_facet ost1 $LCTL set_param fail_loc=0x31c
20471
20472         # ignore dd failure
20473         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20474
20475         do_facet ost1 $LCTL set_param fail_loc=0
20476         umount_client $MOUNT || error "umount failed"
20477         mount_client $MOUNT || error "mount failed"
20478         stop ost1 || error "cannot stop ost1"
20479         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20480 }
20481 run_test 232a "failed lock should not block umount"
20482
20483 test_232b() {
20484         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20485                 skip "Need MDS version at least 2.10.58"
20486
20487         mkdir -p $DIR/$tdir
20488         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20489         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20490         sync
20491         cancel_lru_locks osc
20492
20493         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20494         do_facet ost1 $LCTL set_param fail_loc=0x31c
20495
20496         # ignore failure
20497         $LFS data_version $DIR/$tdir/$tfile || true
20498
20499         do_facet ost1 $LCTL set_param fail_loc=0
20500         umount_client $MOUNT || error "umount failed"
20501         mount_client $MOUNT || error "mount failed"
20502         stop ost1 || error "cannot stop ost1"
20503         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20504 }
20505 run_test 232b "failed data version lock should not block umount"
20506
20507 test_233a() {
20508         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20509                 skip "Need MDS version at least 2.3.64"
20510         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20511
20512         local fid=$($LFS path2fid $MOUNT)
20513
20514         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20515                 error "cannot access $MOUNT using its FID '$fid'"
20516 }
20517 run_test 233a "checking that OBF of the FS root succeeds"
20518
20519 test_233b() {
20520         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20521                 skip "Need MDS version at least 2.5.90"
20522         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20523
20524         local fid=$($LFS path2fid $MOUNT/.lustre)
20525
20526         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20527                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20528
20529         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20530         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20531                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20532 }
20533 run_test 233b "checking that OBF of the FS .lustre succeeds"
20534
20535 test_234() {
20536         local p="$TMP/sanityN-$TESTNAME.parameters"
20537         save_lustre_params client "llite.*.xattr_cache" > $p
20538         lctl set_param llite.*.xattr_cache 1 ||
20539                 skip_env "xattr cache is not supported"
20540
20541         mkdir -p $DIR/$tdir || error "mkdir failed"
20542         touch $DIR/$tdir/$tfile || error "touch failed"
20543         # OBD_FAIL_LLITE_XATTR_ENOMEM
20544         $LCTL set_param fail_loc=0x1405
20545         getfattr -n user.attr $DIR/$tdir/$tfile &&
20546                 error "getfattr should have failed with ENOMEM"
20547         $LCTL set_param fail_loc=0x0
20548         rm -rf $DIR/$tdir
20549
20550         restore_lustre_params < $p
20551         rm -f $p
20552 }
20553 run_test 234 "xattr cache should not crash on ENOMEM"
20554
20555 test_235() {
20556         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20557                 skip "Need MDS version at least 2.4.52"
20558
20559         flock_deadlock $DIR/$tfile
20560         local RC=$?
20561         case $RC in
20562                 0)
20563                 ;;
20564                 124) error "process hangs on a deadlock"
20565                 ;;
20566                 *) error "error executing flock_deadlock $DIR/$tfile"
20567                 ;;
20568         esac
20569 }
20570 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20571
20572 #LU-2935
20573 test_236() {
20574         check_swap_layouts_support
20575
20576         local ref1=/etc/passwd
20577         local ref2=/etc/group
20578         local file1=$DIR/$tdir/f1
20579         local file2=$DIR/$tdir/f2
20580
20581         test_mkdir -c1 $DIR/$tdir
20582         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20583         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20584         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20585         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20586         local fd=$(free_fd)
20587         local cmd="exec $fd<>$file2"
20588         eval $cmd
20589         rm $file2
20590         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20591                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20592         cmd="exec $fd>&-"
20593         eval $cmd
20594         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20595
20596         #cleanup
20597         rm -rf $DIR/$tdir
20598 }
20599 run_test 236 "Layout swap on open unlinked file"
20600
20601 # LU-4659 linkea consistency
20602 test_238() {
20603         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20604                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20605                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20606                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20607
20608         touch $DIR/$tfile
20609         ln $DIR/$tfile $DIR/$tfile.lnk
20610         touch $DIR/$tfile.new
20611         mv $DIR/$tfile.new $DIR/$tfile
20612         local fid1=$($LFS path2fid $DIR/$tfile)
20613         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20614         local path1=$($LFS fid2path $FSNAME "$fid1")
20615         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20616         local path2=$($LFS fid2path $FSNAME "$fid2")
20617         [ $tfile.lnk == $path2 ] ||
20618                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20619         rm -f $DIR/$tfile*
20620 }
20621 run_test 238 "Verify linkea consistency"
20622
20623 test_239A() { # was test_239
20624         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20625                 skip "Need MDS version at least 2.5.60"
20626
20627         local list=$(comma_list $(mdts_nodes))
20628
20629         mkdir -p $DIR/$tdir
20630         createmany -o $DIR/$tdir/f- 5000
20631         unlinkmany $DIR/$tdir/f- 5000
20632         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20633                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20634         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20635                         osp.*MDT*.sync_in_flight" | calc_sum)
20636         [ "$changes" -eq 0 ] || error "$changes not synced"
20637 }
20638 run_test 239A "osp_sync test"
20639
20640 test_239a() { #LU-5297
20641         remote_mds_nodsh && skip "remote MDS with nodsh"
20642
20643         touch $DIR/$tfile
20644         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20645         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20646         chgrp $RUNAS_GID $DIR/$tfile
20647         wait_delete_completed
20648 }
20649 run_test 239a "process invalid osp sync record correctly"
20650
20651 test_239b() { #LU-5297
20652         remote_mds_nodsh && skip "remote MDS with nodsh"
20653
20654         touch $DIR/$tfile1
20655         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20656         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20657         chgrp $RUNAS_GID $DIR/$tfile1
20658         wait_delete_completed
20659         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20660         touch $DIR/$tfile2
20661         chgrp $RUNAS_GID $DIR/$tfile2
20662         wait_delete_completed
20663 }
20664 run_test 239b "process osp sync record with ENOMEM error correctly"
20665
20666 test_240() {
20667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20668         remote_mds_nodsh && skip "remote MDS with nodsh"
20669
20670         mkdir -p $DIR/$tdir
20671
20672         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20673                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20674         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20675                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20676
20677         umount_client $MOUNT || error "umount failed"
20678         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20679         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20680         mount_client $MOUNT || error "failed to mount client"
20681
20682         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20683         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20684 }
20685 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20686
20687 test_241_bio() {
20688         local count=$1
20689         local bsize=$2
20690
20691         for LOOP in $(seq $count); do
20692                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20693                 cancel_lru_locks $OSC || true
20694         done
20695 }
20696
20697 test_241_dio() {
20698         local count=$1
20699         local bsize=$2
20700
20701         for LOOP in $(seq $1); do
20702                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20703                         2>/dev/null
20704         done
20705 }
20706
20707 test_241a() { # was test_241
20708         local bsize=$PAGE_SIZE
20709
20710         (( bsize < 40960 )) && bsize=40960
20711         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20712         ls -la $DIR/$tfile
20713         cancel_lru_locks $OSC
20714         test_241_bio 1000 $bsize &
20715         PID=$!
20716         test_241_dio 1000 $bsize
20717         wait $PID
20718 }
20719 run_test 241a "bio vs dio"
20720
20721 test_241b() {
20722         local bsize=$PAGE_SIZE
20723
20724         (( bsize < 40960 )) && bsize=40960
20725         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20726         ls -la $DIR/$tfile
20727         test_241_dio 1000 $bsize &
20728         PID=$!
20729         test_241_dio 1000 $bsize
20730         wait $PID
20731 }
20732 run_test 241b "dio vs dio"
20733
20734 test_242() {
20735         remote_mds_nodsh && skip "remote MDS with nodsh"
20736
20737         mkdir_on_mdt0 $DIR/$tdir
20738         touch $DIR/$tdir/$tfile
20739
20740         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20741         do_facet mds1 lctl set_param fail_loc=0x105
20742         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20743
20744         do_facet mds1 lctl set_param fail_loc=0
20745         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20746 }
20747 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20748
20749 test_243()
20750 {
20751         test_mkdir $DIR/$tdir
20752         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20753 }
20754 run_test 243 "various group lock tests"
20755
20756 test_244a()
20757 {
20758         test_mkdir $DIR/$tdir
20759         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20760         sendfile_grouplock $DIR/$tdir/$tfile || \
20761                 error "sendfile+grouplock failed"
20762         rm -rf $DIR/$tdir
20763 }
20764 run_test 244a "sendfile with group lock tests"
20765
20766 test_244b()
20767 {
20768         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20769
20770         local threads=50
20771         local size=$((1024*1024))
20772
20773         test_mkdir $DIR/$tdir
20774         for i in $(seq 1 $threads); do
20775                 local file=$DIR/$tdir/file_$((i / 10))
20776                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20777                 local pids[$i]=$!
20778         done
20779         for i in $(seq 1 $threads); do
20780                 wait ${pids[$i]}
20781         done
20782 }
20783 run_test 244b "multi-threaded write with group lock"
20784
20785 test_245() {
20786         local flagname="multi_mod_rpcs"
20787         local connect_data_name="max_mod_rpcs"
20788         local out
20789
20790         # check if multiple modify RPCs flag is set
20791         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20792                 grep "connect_flags:")
20793         echo "$out"
20794
20795         echo "$out" | grep -qw $flagname
20796         if [ $? -ne 0 ]; then
20797                 echo "connect flag $flagname is not set"
20798                 return
20799         fi
20800
20801         # check if multiple modify RPCs data is set
20802         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20803         echo "$out"
20804
20805         echo "$out" | grep -qw $connect_data_name ||
20806                 error "import should have connect data $connect_data_name"
20807 }
20808 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20809
20810 cleanup_247() {
20811         local submount=$1
20812
20813         trap 0
20814         umount_client $submount
20815         rmdir $submount
20816 }
20817
20818 test_247a() {
20819         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20820                 grep -q subtree ||
20821                 skip_env "Fileset feature is not supported"
20822
20823         local submount=${MOUNT}_$tdir
20824
20825         mkdir $MOUNT/$tdir
20826         mkdir -p $submount || error "mkdir $submount failed"
20827         FILESET="$FILESET/$tdir" mount_client $submount ||
20828                 error "mount $submount failed"
20829         trap "cleanup_247 $submount" EXIT
20830         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20831         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20832                 error "read $MOUNT/$tdir/$tfile failed"
20833         cleanup_247 $submount
20834 }
20835 run_test 247a "mount subdir as fileset"
20836
20837 test_247b() {
20838         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20839                 skip_env "Fileset feature is not supported"
20840
20841         local submount=${MOUNT}_$tdir
20842
20843         rm -rf $MOUNT/$tdir
20844         mkdir -p $submount || error "mkdir $submount failed"
20845         SKIP_FILESET=1
20846         FILESET="$FILESET/$tdir" mount_client $submount &&
20847                 error "mount $submount should fail"
20848         rmdir $submount
20849 }
20850 run_test 247b "mount subdir that dose not exist"
20851
20852 test_247c() {
20853         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20854                 skip_env "Fileset feature is not supported"
20855
20856         local submount=${MOUNT}_$tdir
20857
20858         mkdir -p $MOUNT/$tdir/dir1
20859         mkdir -p $submount || error "mkdir $submount failed"
20860         trap "cleanup_247 $submount" EXIT
20861         FILESET="$FILESET/$tdir" mount_client $submount ||
20862                 error "mount $submount failed"
20863         local fid=$($LFS path2fid $MOUNT/)
20864         $LFS fid2path $submount $fid && error "fid2path should fail"
20865         cleanup_247 $submount
20866 }
20867 run_test 247c "running fid2path outside subdirectory root"
20868
20869 test_247d() {
20870         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20871                 skip "Fileset feature is not supported"
20872
20873         local submount=${MOUNT}_$tdir
20874
20875         mkdir -p $MOUNT/$tdir/dir1
20876         mkdir -p $submount || error "mkdir $submount failed"
20877         FILESET="$FILESET/$tdir" mount_client $submount ||
20878                 error "mount $submount failed"
20879         trap "cleanup_247 $submount" EXIT
20880
20881         local td=$submount/dir1
20882         local fid=$($LFS path2fid $td)
20883         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20884
20885         # check that we get the same pathname back
20886         local rootpath
20887         local found
20888         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20889                 echo "$rootpath $fid"
20890                 found=$($LFS fid2path $rootpath "$fid")
20891                 [ -n "found" ] || error "fid2path should succeed"
20892                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20893         done
20894         # check wrong root path format
20895         rootpath=$submount"_wrong"
20896         found=$($LFS fid2path $rootpath "$fid")
20897         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20898
20899         cleanup_247 $submount
20900 }
20901 run_test 247d "running fid2path inside subdirectory root"
20902
20903 # LU-8037
20904 test_247e() {
20905         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20906                 grep -q subtree ||
20907                 skip "Fileset feature is not supported"
20908
20909         local submount=${MOUNT}_$tdir
20910
20911         mkdir $MOUNT/$tdir
20912         mkdir -p $submount || error "mkdir $submount failed"
20913         FILESET="$FILESET/.." mount_client $submount &&
20914                 error "mount $submount should fail"
20915         rmdir $submount
20916 }
20917 run_test 247e "mount .. as fileset"
20918
20919 test_247f() {
20920         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20921         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20922                 skip "Need at least version 2.13.52"
20923         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20924                 skip "Need at least version 2.14.50"
20925         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20926                 grep -q subtree ||
20927                 skip "Fileset feature is not supported"
20928
20929         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20930         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20931                 error "mkdir remote failed"
20932         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20933                 error "mkdir remote/subdir failed"
20934         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20935                 error "mkdir striped failed"
20936         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20937
20938         local submount=${MOUNT}_$tdir
20939
20940         mkdir -p $submount || error "mkdir $submount failed"
20941         stack_trap "rmdir $submount"
20942
20943         local dir
20944         local stat
20945         local fileset=$FILESET
20946         local mdts=$(comma_list $(mdts_nodes))
20947
20948         stat=$(do_facet mds1 $LCTL get_param -n \
20949                 mdt.*MDT0000.enable_remote_subdir_mount)
20950         stack_trap "do_nodes $mdts $LCTL set_param \
20951                 mdt.*.enable_remote_subdir_mount=$stat"
20952
20953         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20954         stack_trap "umount_client $submount"
20955         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20956                 error "mount remote dir $dir should fail"
20957
20958         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20959                 $tdir/striped/. ; do
20960                 FILESET="$fileset/$dir" mount_client $submount ||
20961                         error "mount $dir failed"
20962                 umount_client $submount
20963         done
20964
20965         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20966         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20967                 error "mount $tdir/remote failed"
20968 }
20969 run_test 247f "mount striped or remote directory as fileset"
20970
20971 test_247g() {
20972         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20973         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20974                 skip "Need at least version 2.14.50"
20975
20976         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20977                 error "mkdir $tdir failed"
20978         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20979
20980         local submount=${MOUNT}_$tdir
20981
20982         mkdir -p $submount || error "mkdir $submount failed"
20983         stack_trap "rmdir $submount"
20984
20985         FILESET="$fileset/$tdir" mount_client $submount ||
20986                 error "mount $dir failed"
20987         stack_trap "umount $submount"
20988
20989         local mdts=$(comma_list $(mdts_nodes))
20990
20991         local nrpcs
20992
20993         stat $submount > /dev/null
20994         cancel_lru_locks $MDC
20995         stat $submount > /dev/null
20996         stat $submount/$tfile > /dev/null
20997         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20998         stat $submount/$tfile > /dev/null
20999         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21000                 awk '/getattr/ {sum += $2} END {print sum}')
21001
21002         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21003 }
21004 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21005
21006 test_248a() {
21007         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21008         [ -z "$fast_read_sav" ] && skip "no fast read support"
21009
21010         # create a large file for fast read verification
21011         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21012
21013         # make sure the file is created correctly
21014         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21015                 { rm -f $DIR/$tfile; skip "file creation error"; }
21016
21017         echo "Test 1: verify that fast read is 4 times faster on cache read"
21018
21019         # small read with fast read enabled
21020         $LCTL set_param -n llite.*.fast_read=1
21021         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21022                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21023                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21024         # small read with fast read disabled
21025         $LCTL set_param -n llite.*.fast_read=0
21026         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21027                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21028                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21029
21030         # verify that fast read is 4 times faster for cache read
21031         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21032                 error_not_in_vm "fast read was not 4 times faster: " \
21033                            "$t_fast vs $t_slow"
21034
21035         echo "Test 2: verify the performance between big and small read"
21036         $LCTL set_param -n llite.*.fast_read=1
21037
21038         # 1k non-cache read
21039         cancel_lru_locks osc
21040         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21041                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21042                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21043
21044         # 1M non-cache read
21045         cancel_lru_locks osc
21046         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21047                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21048                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21049
21050         # verify that big IO is not 4 times faster than small IO
21051         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21052                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21053
21054         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21055         rm -f $DIR/$tfile
21056 }
21057 run_test 248a "fast read verification"
21058
21059 test_248b() {
21060         # Default short_io_bytes=16384, try both smaller and larger sizes.
21061         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21062         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21063         echo "bs=53248 count=113 normal buffered write"
21064         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21065                 error "dd of initial data file failed"
21066         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21067
21068         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21069         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21070                 error "dd with sync normal writes failed"
21071         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21072
21073         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21074         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21075                 error "dd with sync small writes failed"
21076         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21077
21078         cancel_lru_locks osc
21079
21080         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21081         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21082         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21083         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21084                 iflag=direct || error "dd with O_DIRECT small read failed"
21085         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21086         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21087                 error "compare $TMP/$tfile.1 failed"
21088
21089         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21090         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21091
21092         # just to see what the maximum tunable value is, and test parsing
21093         echo "test invalid parameter 2MB"
21094         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21095                 error "too-large short_io_bytes allowed"
21096         echo "test maximum parameter 512KB"
21097         # if we can set a larger short_io_bytes, run test regardless of version
21098         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21099                 # older clients may not allow setting it this large, that's OK
21100                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21101                         skip "Need at least client version 2.13.50"
21102                 error "medium short_io_bytes failed"
21103         fi
21104         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21105         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21106
21107         echo "test large parameter 64KB"
21108         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21109         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21110
21111         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21112         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21113                 error "dd with sync large writes failed"
21114         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21115
21116         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21117         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21118         num=$((113 * 4096 / PAGE_SIZE))
21119         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21120         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21121                 error "dd with O_DIRECT large writes failed"
21122         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21123                 error "compare $DIR/$tfile.3 failed"
21124
21125         cancel_lru_locks osc
21126
21127         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21128         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21129                 error "dd with O_DIRECT large read failed"
21130         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21131                 error "compare $TMP/$tfile.2 failed"
21132
21133         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21134         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21135                 error "dd with O_DIRECT large read failed"
21136         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21137                 error "compare $TMP/$tfile.3 failed"
21138 }
21139 run_test 248b "test short_io read and write for both small and large sizes"
21140
21141 test_249() { # LU-7890
21142         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21143                 skip "Need at least version 2.8.54"
21144
21145         rm -f $DIR/$tfile
21146         $LFS setstripe -c 1 $DIR/$tfile
21147         # Offset 2T == 4k * 512M
21148         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21149                 error "dd to 2T offset failed"
21150 }
21151 run_test 249 "Write above 2T file size"
21152
21153 test_250() {
21154         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21155          && skip "no 16TB file size limit on ZFS"
21156
21157         $LFS setstripe -c 1 $DIR/$tfile
21158         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21159         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21160         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21161         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21162                 conv=notrunc,fsync && error "append succeeded"
21163         return 0
21164 }
21165 run_test 250 "Write above 16T limit"
21166
21167 test_251() {
21168         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21169
21170         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21171         #Skip once - writing the first stripe will succeed
21172         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21173         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21174                 error "short write happened"
21175
21176         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21177         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21178                 error "short read happened"
21179
21180         rm -f $DIR/$tfile
21181 }
21182 run_test 251 "Handling short read and write correctly"
21183
21184 test_252() {
21185         remote_mds_nodsh && skip "remote MDS with nodsh"
21186         remote_ost_nodsh && skip "remote OST with nodsh"
21187         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21188                 skip_env "ldiskfs only test"
21189         fi
21190
21191         local tgt
21192         local dev
21193         local out
21194         local uuid
21195         local num
21196         local gen
21197
21198         # check lr_reader on OST0000
21199         tgt=ost1
21200         dev=$(facet_device $tgt)
21201         out=$(do_facet $tgt $LR_READER $dev)
21202         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21203         echo "$out"
21204         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21205         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21206                 error "Invalid uuid returned by $LR_READER on target $tgt"
21207         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21208
21209         # check lr_reader -c on MDT0000
21210         tgt=mds1
21211         dev=$(facet_device $tgt)
21212         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21213                 skip "$LR_READER does not support additional options"
21214         fi
21215         out=$(do_facet $tgt $LR_READER -c $dev)
21216         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21217         echo "$out"
21218         num=$(echo "$out" | grep -c "mdtlov")
21219         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21220                 error "Invalid number of mdtlov clients returned by $LR_READER"
21221         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21222
21223         # check lr_reader -cr on MDT0000
21224         out=$(do_facet $tgt $LR_READER -cr $dev)
21225         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21226         echo "$out"
21227         echo "$out" | grep -q "^reply_data:$" ||
21228                 error "$LR_READER should have returned 'reply_data' section"
21229         num=$(echo "$out" | grep -c "client_generation")
21230         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21231 }
21232 run_test 252 "check lr_reader tool"
21233
21234 test_253() {
21235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21236         remote_mds_nodsh && skip "remote MDS with nodsh"
21237         remote_mgs_nodsh && skip "remote MGS with nodsh"
21238
21239         local ostidx=0
21240         local rc=0
21241         local ost_name=$(ostname_from_index $ostidx)
21242
21243         # on the mdt's osc
21244         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21245         do_facet $SINGLEMDS $LCTL get_param -n \
21246                 osp.$mdtosc_proc1.reserved_mb_high ||
21247                 skip  "remote MDS does not support reserved_mb_high"
21248
21249         rm -rf $DIR/$tdir
21250         wait_mds_ost_sync
21251         wait_delete_completed
21252         mkdir $DIR/$tdir
21253
21254         pool_add $TESTNAME || error "Pool creation failed"
21255         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21256
21257         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21258                 error "Setstripe failed"
21259
21260         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21261
21262         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21263                     grep "watermarks")
21264         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21265
21266         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21267                         osp.$mdtosc_proc1.prealloc_status)
21268         echo "prealloc_status $oa_status"
21269
21270         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21271                 error "File creation should fail"
21272
21273         #object allocation was stopped, but we still able to append files
21274         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21275                 oflag=append || error "Append failed"
21276
21277         rm -f $DIR/$tdir/$tfile.0
21278
21279         # For this test, we want to delete the files we created to go out of
21280         # space but leave the watermark, so we remain nearly out of space
21281         ost_watermarks_enospc_delete_files $tfile $ostidx
21282
21283         wait_delete_completed
21284
21285         sleep_maxage
21286
21287         for i in $(seq 10 12); do
21288                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21289                         2>/dev/null || error "File creation failed after rm"
21290         done
21291
21292         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21293                         osp.$mdtosc_proc1.prealloc_status)
21294         echo "prealloc_status $oa_status"
21295
21296         if (( oa_status != 0 )); then
21297                 error "Object allocation still disable after rm"
21298         fi
21299 }
21300 run_test 253 "Check object allocation limit"
21301
21302 test_254() {
21303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21304         remote_mds_nodsh && skip "remote MDS with nodsh"
21305
21306         local mdt=$(facet_svc $SINGLEMDS)
21307
21308         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21309                 skip "MDS does not support changelog_size"
21310
21311         local cl_user
21312
21313         changelog_register || error "changelog_register failed"
21314
21315         changelog_clear 0 || error "changelog_clear failed"
21316
21317         local size1=$(do_facet $SINGLEMDS \
21318                       $LCTL get_param -n mdd.$mdt.changelog_size)
21319         echo "Changelog size $size1"
21320
21321         rm -rf $DIR/$tdir
21322         $LFS mkdir -i 0 $DIR/$tdir
21323         # change something
21324         mkdir -p $DIR/$tdir/pics/2008/zachy
21325         touch $DIR/$tdir/pics/2008/zachy/timestamp
21326         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21327         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21328         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21329         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21330         rm $DIR/$tdir/pics/desktop.jpg
21331
21332         local size2=$(do_facet $SINGLEMDS \
21333                       $LCTL get_param -n mdd.$mdt.changelog_size)
21334         echo "Changelog size after work $size2"
21335
21336         (( $size2 > $size1 )) ||
21337                 error "new Changelog size=$size2 less than old size=$size1"
21338 }
21339 run_test 254 "Check changelog size"
21340
21341 ladvise_no_type()
21342 {
21343         local type=$1
21344         local file=$2
21345
21346         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21347                 awk -F: '{print $2}' | grep $type > /dev/null
21348         if [ $? -ne 0 ]; then
21349                 return 0
21350         fi
21351         return 1
21352 }
21353
21354 ladvise_no_ioctl()
21355 {
21356         local file=$1
21357
21358         lfs ladvise -a willread $file > /dev/null 2>&1
21359         if [ $? -eq 0 ]; then
21360                 return 1
21361         fi
21362
21363         lfs ladvise -a willread $file 2>&1 |
21364                 grep "Inappropriate ioctl for device" > /dev/null
21365         if [ $? -eq 0 ]; then
21366                 return 0
21367         fi
21368         return 1
21369 }
21370
21371 percent() {
21372         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21373 }
21374
21375 # run a random read IO workload
21376 # usage: random_read_iops <filename> <filesize> <iosize>
21377 random_read_iops() {
21378         local file=$1
21379         local fsize=$2
21380         local iosize=${3:-4096}
21381
21382         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21383                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21384 }
21385
21386 drop_file_oss_cache() {
21387         local file="$1"
21388         local nodes="$2"
21389
21390         $LFS ladvise -a dontneed $file 2>/dev/null ||
21391                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21392 }
21393
21394 ladvise_willread_performance()
21395 {
21396         local repeat=10
21397         local average_origin=0
21398         local average_cache=0
21399         local average_ladvise=0
21400
21401         for ((i = 1; i <= $repeat; i++)); do
21402                 echo "Iter $i/$repeat: reading without willread hint"
21403                 cancel_lru_locks osc
21404                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21405                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21406                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21407                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21408
21409                 cancel_lru_locks osc
21410                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21411                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21412                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21413
21414                 cancel_lru_locks osc
21415                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21416                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21417                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21418                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21419                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21420         done
21421         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21422         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21423         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21424
21425         speedup_cache=$(percent $average_cache $average_origin)
21426         speedup_ladvise=$(percent $average_ladvise $average_origin)
21427
21428         echo "Average uncached read: $average_origin"
21429         echo "Average speedup with OSS cached read: " \
21430                 "$average_cache = +$speedup_cache%"
21431         echo "Average speedup with ladvise willread: " \
21432                 "$average_ladvise = +$speedup_ladvise%"
21433
21434         local lowest_speedup=20
21435         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21436                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21437                         "got $average_cache%. Skipping ladvise willread check."
21438                 return 0
21439         fi
21440
21441         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21442         # it is still good to run until then to exercise 'ladvise willread'
21443         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21444                 [ "$ost1_FSTYPE" = "zfs" ] &&
21445                 echo "osd-zfs does not support dontneed or drop_caches" &&
21446                 return 0
21447
21448         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21449         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21450                 error_not_in_vm "Speedup with willread is less than " \
21451                         "$lowest_speedup%, got $average_ladvise%"
21452 }
21453
21454 test_255a() {
21455         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21456                 skip "lustre < 2.8.54 does not support ladvise "
21457         remote_ost_nodsh && skip "remote OST with nodsh"
21458
21459         stack_trap "rm -f $DIR/$tfile"
21460         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21461
21462         ladvise_no_type willread $DIR/$tfile &&
21463                 skip "willread ladvise is not supported"
21464
21465         ladvise_no_ioctl $DIR/$tfile &&
21466                 skip "ladvise ioctl is not supported"
21467
21468         local size_mb=100
21469         local size=$((size_mb * 1048576))
21470         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21471                 error "dd to $DIR/$tfile failed"
21472
21473         lfs ladvise -a willread $DIR/$tfile ||
21474                 error "Ladvise failed with no range argument"
21475
21476         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21477                 error "Ladvise failed with no -l or -e argument"
21478
21479         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21480                 error "Ladvise failed with only -e argument"
21481
21482         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21483                 error "Ladvise failed with only -l argument"
21484
21485         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21486                 error "End offset should not be smaller than start offset"
21487
21488         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21489                 error "End offset should not be equal to start offset"
21490
21491         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21492                 error "Ladvise failed with overflowing -s argument"
21493
21494         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21495                 error "Ladvise failed with overflowing -e argument"
21496
21497         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21498                 error "Ladvise failed with overflowing -l argument"
21499
21500         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21501                 error "Ladvise succeeded with conflicting -l and -e arguments"
21502
21503         echo "Synchronous ladvise should wait"
21504         local delay=4
21505 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21506         do_nodes $(comma_list $(osts_nodes)) \
21507                 $LCTL set_param fail_val=$delay fail_loc=0x237
21508
21509         local start_ts=$SECONDS
21510         lfs ladvise -a willread $DIR/$tfile ||
21511                 error "Ladvise failed with no range argument"
21512         local end_ts=$SECONDS
21513         local inteval_ts=$((end_ts - start_ts))
21514
21515         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21516                 error "Synchronous advice didn't wait reply"
21517         fi
21518
21519         echo "Asynchronous ladvise shouldn't wait"
21520         local start_ts=$SECONDS
21521         lfs ladvise -a willread -b $DIR/$tfile ||
21522                 error "Ladvise failed with no range argument"
21523         local end_ts=$SECONDS
21524         local inteval_ts=$((end_ts - start_ts))
21525
21526         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21527                 error "Asynchronous advice blocked"
21528         fi
21529
21530         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21531         ladvise_willread_performance
21532 }
21533 run_test 255a "check 'lfs ladvise -a willread'"
21534
21535 facet_meminfo() {
21536         local facet=$1
21537         local info=$2
21538
21539         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21540 }
21541
21542 test_255b() {
21543         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21544                 skip "lustre < 2.8.54 does not support ladvise "
21545         remote_ost_nodsh && skip "remote OST with nodsh"
21546
21547         stack_trap "rm -f $DIR/$tfile"
21548         lfs setstripe -c 1 -i 0 $DIR/$tfile
21549
21550         ladvise_no_type dontneed $DIR/$tfile &&
21551                 skip "dontneed ladvise is not supported"
21552
21553         ladvise_no_ioctl $DIR/$tfile &&
21554                 skip "ladvise ioctl is not supported"
21555
21556         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21557                 [ "$ost1_FSTYPE" = "zfs" ] &&
21558                 skip "zfs-osd does not support 'ladvise dontneed'"
21559
21560         local size_mb=100
21561         local size=$((size_mb * 1048576))
21562         # In order to prevent disturbance of other processes, only check 3/4
21563         # of the memory usage
21564         local kibibytes=$((size_mb * 1024 * 3 / 4))
21565
21566         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21567                 error "dd to $DIR/$tfile failed"
21568
21569         #force write to complete before dropping OST cache & checking memory
21570         sync
21571
21572         local total=$(facet_meminfo ost1 MemTotal)
21573         echo "Total memory: $total KiB"
21574
21575         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21576         local before_read=$(facet_meminfo ost1 Cached)
21577         echo "Cache used before read: $before_read KiB"
21578
21579         lfs ladvise -a willread $DIR/$tfile ||
21580                 error "Ladvise willread failed"
21581         local after_read=$(facet_meminfo ost1 Cached)
21582         echo "Cache used after read: $after_read KiB"
21583
21584         lfs ladvise -a dontneed $DIR/$tfile ||
21585                 error "Ladvise dontneed again failed"
21586         local no_read=$(facet_meminfo ost1 Cached)
21587         echo "Cache used after dontneed ladvise: $no_read KiB"
21588
21589         if [ $total -lt $((before_read + kibibytes)) ]; then
21590                 echo "Memory is too small, abort checking"
21591                 return 0
21592         fi
21593
21594         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21595                 error "Ladvise willread should use more memory" \
21596                         "than $kibibytes KiB"
21597         fi
21598
21599         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21600                 error "Ladvise dontneed should release more memory" \
21601                         "than $kibibytes KiB"
21602         fi
21603 }
21604 run_test 255b "check 'lfs ladvise -a dontneed'"
21605
21606 test_255c() {
21607         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21608                 skip "lustre < 2.10.50 does not support lockahead"
21609
21610         local ost1_imp=$(get_osc_import_name client ost1)
21611         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21612                          cut -d'.' -f2)
21613         local count
21614         local new_count
21615         local difference
21616         local i
21617         local rc
21618
21619         test_mkdir -p $DIR/$tdir
21620         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21621
21622         #test 10 returns only success/failure
21623         i=10
21624         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21625         rc=$?
21626         if [ $rc -eq 255 ]; then
21627                 error "Ladvise test${i} failed, ${rc}"
21628         fi
21629
21630         #test 11 counts lock enqueue requests, all others count new locks
21631         i=11
21632         count=$(do_facet ost1 \
21633                 $LCTL get_param -n ost.OSS.ost.stats)
21634         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21635
21636         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21637         rc=$?
21638         if [ $rc -eq 255 ]; then
21639                 error "Ladvise test${i} failed, ${rc}"
21640         fi
21641
21642         new_count=$(do_facet ost1 \
21643                 $LCTL get_param -n ost.OSS.ost.stats)
21644         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21645                    awk '{ print $2 }')
21646
21647         difference="$((new_count - count))"
21648         if [ $difference -ne $rc ]; then
21649                 error "Ladvise test${i}, bad enqueue count, returned " \
21650                       "${rc}, actual ${difference}"
21651         fi
21652
21653         for i in $(seq 12 21); do
21654                 # If we do not do this, we run the risk of having too many
21655                 # locks and starting lock cancellation while we are checking
21656                 # lock counts.
21657                 cancel_lru_locks osc
21658
21659                 count=$($LCTL get_param -n \
21660                        ldlm.namespaces.$imp_name.lock_unused_count)
21661
21662                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21663                 rc=$?
21664                 if [ $rc -eq 255 ]; then
21665                         error "Ladvise test ${i} failed, ${rc}"
21666                 fi
21667
21668                 new_count=$($LCTL get_param -n \
21669                        ldlm.namespaces.$imp_name.lock_unused_count)
21670                 difference="$((new_count - count))"
21671
21672                 # Test 15 output is divided by 100 to map down to valid return
21673                 if [ $i -eq 15 ]; then
21674                         rc="$((rc * 100))"
21675                 fi
21676
21677                 if [ $difference -ne $rc ]; then
21678                         error "Ladvise test ${i}, bad lock count, returned " \
21679                               "${rc}, actual ${difference}"
21680                 fi
21681         done
21682
21683         #test 22 returns only success/failure
21684         i=22
21685         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21686         rc=$?
21687         if [ $rc -eq 255 ]; then
21688                 error "Ladvise test${i} failed, ${rc}"
21689         fi
21690 }
21691 run_test 255c "suite of ladvise lockahead tests"
21692
21693 test_256() {
21694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21695         remote_mds_nodsh && skip "remote MDS with nodsh"
21696         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21697         changelog_users $SINGLEMDS | grep "^cl" &&
21698                 skip "active changelog user"
21699
21700         local cl_user
21701         local cat_sl
21702         local mdt_dev
21703
21704         mdt_dev=$(mdsdevname 1)
21705         echo $mdt_dev
21706
21707         changelog_register || error "changelog_register failed"
21708
21709         rm -rf $DIR/$tdir
21710         mkdir_on_mdt0 $DIR/$tdir
21711
21712         changelog_clear 0 || error "changelog_clear failed"
21713
21714         # change something
21715         touch $DIR/$tdir/{1..10}
21716
21717         # stop the MDT
21718         stop $SINGLEMDS || error "Fail to stop MDT"
21719
21720         # remount the MDT
21721
21722         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21723
21724         #after mount new plainllog is used
21725         touch $DIR/$tdir/{11..19}
21726         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21727         stack_trap "rm -f $tmpfile"
21728         cat_sl=$(do_facet $SINGLEMDS "sync; \
21729                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21730                  llog_reader $tmpfile | grep -c type=1064553b")
21731         do_facet $SINGLEMDS llog_reader $tmpfile
21732
21733         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21734
21735         changelog_clear 0 || error "changelog_clear failed"
21736
21737         cat_sl=$(do_facet $SINGLEMDS "sync; \
21738                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21739                  llog_reader $tmpfile | grep -c type=1064553b")
21740
21741         if (( cat_sl == 2 )); then
21742                 error "Empty plain llog was not deleted from changelog catalog"
21743         elif (( cat_sl != 1 )); then
21744                 error "Active plain llog shouldn't be deleted from catalog"
21745         fi
21746 }
21747 run_test 256 "Check llog delete for empty and not full state"
21748
21749 test_257() {
21750         remote_mds_nodsh && skip "remote MDS with nodsh"
21751         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21752                 skip "Need MDS version at least 2.8.55"
21753
21754         test_mkdir $DIR/$tdir
21755
21756         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21757                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21758         stat $DIR/$tdir
21759
21760 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21761         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21762         local facet=mds$((mdtidx + 1))
21763         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21764         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21765
21766         stop $facet || error "stop MDS failed"
21767         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21768                 error "start MDS fail"
21769         wait_recovery_complete $facet
21770 }
21771 run_test 257 "xattr locks are not lost"
21772
21773 # Verify we take the i_mutex when security requires it
21774 test_258a() {
21775 #define OBD_FAIL_IMUTEX_SEC 0x141c
21776         $LCTL set_param fail_loc=0x141c
21777         touch $DIR/$tfile
21778         chmod u+s $DIR/$tfile
21779         chmod a+rwx $DIR/$tfile
21780         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21781         RC=$?
21782         if [ $RC -ne 0 ]; then
21783                 error "error, failed to take i_mutex, rc=$?"
21784         fi
21785         rm -f $DIR/$tfile
21786 }
21787 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21788
21789 # Verify we do NOT take the i_mutex in the normal case
21790 test_258b() {
21791 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21792         $LCTL set_param fail_loc=0x141d
21793         touch $DIR/$tfile
21794         chmod a+rwx $DIR
21795         chmod a+rw $DIR/$tfile
21796         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21797         RC=$?
21798         if [ $RC -ne 0 ]; then
21799                 error "error, took i_mutex unnecessarily, rc=$?"
21800         fi
21801         rm -f $DIR/$tfile
21802
21803 }
21804 run_test 258b "verify i_mutex security behavior"
21805
21806 test_259() {
21807         local file=$DIR/$tfile
21808         local before
21809         local after
21810
21811         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21812
21813         stack_trap "rm -f $file" EXIT
21814
21815         wait_delete_completed
21816         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21817         echo "before: $before"
21818
21819         $LFS setstripe -i 0 -c 1 $file
21820         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21821         sync_all_data
21822         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21823         echo "after write: $after"
21824
21825 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21826         do_facet ost1 $LCTL set_param fail_loc=0x2301
21827         $TRUNCATE $file 0
21828         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21829         echo "after truncate: $after"
21830
21831         stop ost1
21832         do_facet ost1 $LCTL set_param fail_loc=0
21833         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21834         sleep 2
21835         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21836         echo "after restart: $after"
21837         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21838                 error "missing truncate?"
21839
21840         return 0
21841 }
21842 run_test 259 "crash at delayed truncate"
21843
21844 test_260() {
21845 #define OBD_FAIL_MDC_CLOSE               0x806
21846         $LCTL set_param fail_loc=0x80000806
21847         touch $DIR/$tfile
21848
21849 }
21850 run_test 260 "Check mdc_close fail"
21851
21852 ### Data-on-MDT sanity tests ###
21853 test_270a() {
21854         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21855                 skip "Need MDS version at least 2.10.55 for DoM"
21856
21857         # create DoM file
21858         local dom=$DIR/$tdir/dom_file
21859         local tmp=$DIR/$tdir/tmp_file
21860
21861         mkdir_on_mdt0 $DIR/$tdir
21862
21863         # basic checks for DoM component creation
21864         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21865                 error "Can set MDT layout to non-first entry"
21866
21867         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21868                 error "Can define multiple entries as MDT layout"
21869
21870         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21871
21872         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21873         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21874         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21875
21876         local mdtidx=$($LFS getstripe -m $dom)
21877         local mdtname=MDT$(printf %04x $mdtidx)
21878         local facet=mds$((mdtidx + 1))
21879         local space_check=1
21880
21881         # Skip free space checks with ZFS
21882         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21883
21884         # write
21885         sync
21886         local size_tmp=$((65536 * 3))
21887         local mdtfree1=$(do_facet $facet \
21888                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21889
21890         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21891         # check also direct IO along write
21892         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21893         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21894         sync
21895         cmp $tmp $dom || error "file data is different"
21896         [ $(stat -c%s $dom) == $size_tmp ] ||
21897                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21898         if [ $space_check == 1 ]; then
21899                 local mdtfree2=$(do_facet $facet \
21900                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21901
21902                 # increase in usage from by $size_tmp
21903                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21904                         error "MDT free space wrong after write: " \
21905                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21906         fi
21907
21908         # truncate
21909         local size_dom=10000
21910
21911         $TRUNCATE $dom $size_dom
21912         [ $(stat -c%s $dom) == $size_dom ] ||
21913                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21914         if [ $space_check == 1 ]; then
21915                 mdtfree1=$(do_facet $facet \
21916                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21917                 # decrease in usage from $size_tmp to new $size_dom
21918                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21919                   $(((size_tmp - size_dom) / 1024)) ] ||
21920                         error "MDT free space is wrong after truncate: " \
21921                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21922         fi
21923
21924         # append
21925         cat $tmp >> $dom
21926         sync
21927         size_dom=$((size_dom + size_tmp))
21928         [ $(stat -c%s $dom) == $size_dom ] ||
21929                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21930         if [ $space_check == 1 ]; then
21931                 mdtfree2=$(do_facet $facet \
21932                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21933                 # increase in usage by $size_tmp from previous
21934                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21935                         error "MDT free space is wrong after append: " \
21936                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21937         fi
21938
21939         # delete
21940         rm $dom
21941         if [ $space_check == 1 ]; then
21942                 mdtfree1=$(do_facet $facet \
21943                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21944                 # decrease in usage by $size_dom from previous
21945                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21946                         error "MDT free space is wrong after removal: " \
21947                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21948         fi
21949
21950         # combined striping
21951         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21952                 error "Can't create DoM + OST striping"
21953
21954         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21955         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21956         # check also direct IO along write
21957         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21958         sync
21959         cmp $tmp $dom || error "file data is different"
21960         [ $(stat -c%s $dom) == $size_tmp ] ||
21961                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21962         rm $dom $tmp
21963
21964         return 0
21965 }
21966 run_test 270a "DoM: basic functionality tests"
21967
21968 test_270b() {
21969         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21970                 skip "Need MDS version at least 2.10.55"
21971
21972         local dom=$DIR/$tdir/dom_file
21973         local max_size=1048576
21974
21975         mkdir -p $DIR/$tdir
21976         $LFS setstripe -E $max_size -L mdt $dom
21977
21978         # truncate over the limit
21979         $TRUNCATE $dom $(($max_size + 1)) &&
21980                 error "successful truncate over the maximum size"
21981         # write over the limit
21982         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21983                 error "successful write over the maximum size"
21984         # append over the limit
21985         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21986         echo "12345" >> $dom && error "successful append over the maximum size"
21987         rm $dom
21988
21989         return 0
21990 }
21991 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21992
21993 test_270c() {
21994         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21995                 skip "Need MDS version at least 2.10.55"
21996
21997         mkdir -p $DIR/$tdir
21998         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21999
22000         # check files inherit DoM EA
22001         touch $DIR/$tdir/first
22002         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22003                 error "bad pattern"
22004         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22005                 error "bad stripe count"
22006         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22007                 error "bad stripe size"
22008
22009         # check directory inherits DoM EA and uses it as default
22010         mkdir $DIR/$tdir/subdir
22011         touch $DIR/$tdir/subdir/second
22012         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22013                 error "bad pattern in sub-directory"
22014         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22015                 error "bad stripe count in sub-directory"
22016         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22017                 error "bad stripe size in sub-directory"
22018         return 0
22019 }
22020 run_test 270c "DoM: DoM EA inheritance tests"
22021
22022 test_270d() {
22023         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22024                 skip "Need MDS version at least 2.10.55"
22025
22026         mkdir -p $DIR/$tdir
22027         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22028
22029         # inherit default DoM striping
22030         mkdir $DIR/$tdir/subdir
22031         touch $DIR/$tdir/subdir/f1
22032
22033         # change default directory striping
22034         $LFS setstripe -c 1 $DIR/$tdir/subdir
22035         touch $DIR/$tdir/subdir/f2
22036         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22037                 error "wrong default striping in file 2"
22038         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22039                 error "bad pattern in file 2"
22040         return 0
22041 }
22042 run_test 270d "DoM: change striping from DoM to RAID0"
22043
22044 test_270e() {
22045         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22046                 skip "Need MDS version at least 2.10.55"
22047
22048         mkdir -p $DIR/$tdir/dom
22049         mkdir -p $DIR/$tdir/norm
22050         DOMFILES=20
22051         NORMFILES=10
22052         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22053         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22054
22055         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22056         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22057
22058         # find DoM files by layout
22059         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22060         [ $NUM -eq  $DOMFILES ] ||
22061                 error "lfs find -L: found $NUM, expected $DOMFILES"
22062         echo "Test 1: lfs find 20 DOM files by layout: OK"
22063
22064         # there should be 1 dir with default DOM striping
22065         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22066         [ $NUM -eq  1 ] ||
22067                 error "lfs find -L: found $NUM, expected 1 dir"
22068         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22069
22070         # find DoM files by stripe size
22071         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22072         [ $NUM -eq  $DOMFILES ] ||
22073                 error "lfs find -S: found $NUM, expected $DOMFILES"
22074         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22075
22076         # find files by stripe offset except DoM files
22077         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22078         [ $NUM -eq  $NORMFILES ] ||
22079                 error "lfs find -i: found $NUM, expected $NORMFILES"
22080         echo "Test 5: lfs find no DOM files by stripe index: OK"
22081         return 0
22082 }
22083 run_test 270e "DoM: lfs find with DoM files test"
22084
22085 test_270f() {
22086         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22087                 skip "Need MDS version at least 2.10.55"
22088
22089         local mdtname=${FSNAME}-MDT0000-mdtlov
22090         local dom=$DIR/$tdir/dom_file
22091         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22092                                                 lod.$mdtname.dom_stripesize)
22093         local dom_limit=131072
22094
22095         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22096         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22097                                                 lod.$mdtname.dom_stripesize)
22098         [ ${dom_limit} -eq ${dom_current} ] ||
22099                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22100
22101         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22102         $LFS setstripe -d $DIR/$tdir
22103         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22104                 error "Can't set directory default striping"
22105
22106         # exceed maximum stripe size
22107         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22108                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22109         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22110                 error "Able to create DoM component size more than LOD limit"
22111
22112         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22113         dom_current=$(do_facet mds1 $LCTL get_param -n \
22114                                                 lod.$mdtname.dom_stripesize)
22115         [ 0 -eq ${dom_current} ] ||
22116                 error "Can't set zero DoM stripe limit"
22117         rm $dom
22118
22119         # attempt to create DoM file on server with disabled DoM should
22120         # remove DoM entry from layout and be succeed
22121         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22122                 error "Can't create DoM file (DoM is disabled)"
22123         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22124                 error "File has DoM component while DoM is disabled"
22125         rm $dom
22126
22127         # attempt to create DoM file with only DoM stripe should return error
22128         $LFS setstripe -E $dom_limit -L mdt $dom &&
22129                 error "Able to create DoM-only file while DoM is disabled"
22130
22131         # too low values to be aligned with smallest stripe size 64K
22132         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22133         dom_current=$(do_facet mds1 $LCTL get_param -n \
22134                                                 lod.$mdtname.dom_stripesize)
22135         [ 30000 -eq ${dom_current} ] &&
22136                 error "Can set too small DoM stripe limit"
22137
22138         # 64K is a minimal stripe size in Lustre, expect limit of that size
22139         [ 65536 -eq ${dom_current} ] ||
22140                 error "Limit is not set to 64K but ${dom_current}"
22141
22142         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22143         dom_current=$(do_facet mds1 $LCTL get_param -n \
22144                                                 lod.$mdtname.dom_stripesize)
22145         echo $dom_current
22146         [ 2147483648 -eq ${dom_current} ] &&
22147                 error "Can set too large DoM stripe limit"
22148
22149         do_facet mds1 $LCTL set_param -n \
22150                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22151         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22152                 error "Can't create DoM component size after limit change"
22153         do_facet mds1 $LCTL set_param -n \
22154                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22155         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22156                 error "Can't create DoM file after limit decrease"
22157         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22158                 error "Can create big DoM component after limit decrease"
22159         touch ${dom}_def ||
22160                 error "Can't create file with old default layout"
22161
22162         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22163         return 0
22164 }
22165 run_test 270f "DoM: maximum DoM stripe size checks"
22166
22167 test_270g() {
22168         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22169                 skip "Need MDS version at least 2.13.52"
22170         local dom=$DIR/$tdir/$tfile
22171
22172         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22173         local lodname=${FSNAME}-MDT0000-mdtlov
22174
22175         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22176         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22177         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22178         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22179
22180         local dom_limit=1024
22181         local dom_threshold="50%"
22182
22183         $LFS setstripe -d $DIR/$tdir
22184         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22185                 error "Can't set directory default striping"
22186
22187         do_facet mds1 $LCTL set_param -n \
22188                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22189         # set 0 threshold and create DOM file to change tunable stripesize
22190         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22191         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22192                 error "Failed to create $dom file"
22193         # now tunable dom_cur_stripesize should reach maximum
22194         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22195                                         lod.${lodname}.dom_stripesize_cur_kb)
22196         [[ $dom_current == $dom_limit ]] ||
22197                 error "Current DOM stripesize is not maximum"
22198         rm $dom
22199
22200         # set threshold for further tests
22201         do_facet mds1 $LCTL set_param -n \
22202                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22203         echo "DOM threshold is $dom_threshold free space"
22204         local dom_def
22205         local dom_set
22206         # Spoof bfree to exceed threshold
22207         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22208         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22209         for spfree in 40 20 0 15 30 55; do
22210                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22211                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22212                         error "Failed to create $dom file"
22213                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22214                                         lod.${lodname}.dom_stripesize_cur_kb)
22215                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22216                 [[ $dom_def != $dom_current ]] ||
22217                         error "Default stripe size was not changed"
22218                 if [[ $spfree > 0 ]] ; then
22219                         dom_set=$($LFS getstripe -S $dom)
22220                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22221                                 error "DOM component size is still old"
22222                 else
22223                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22224                                 error "DoM component is set with no free space"
22225                 fi
22226                 rm $dom
22227                 dom_current=$dom_def
22228         done
22229 }
22230 run_test 270g "DoM: default DoM stripe size depends on free space"
22231
22232 test_270h() {
22233         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22234                 skip "Need MDS version at least 2.13.53"
22235
22236         local mdtname=${FSNAME}-MDT0000-mdtlov
22237         local dom=$DIR/$tdir/$tfile
22238         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22239
22240         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22241         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22242
22243         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22244         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22245                 error "can't create OST file"
22246         # mirrored file with DOM entry in the second mirror
22247         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22248                 error "can't create mirror with DoM component"
22249
22250         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22251
22252         # DOM component in the middle and has other enries in the same mirror,
22253         # should succeed but lost DoM component
22254         $LFS setstripe --copy=${dom}_1 $dom ||
22255                 error "Can't create file from OST|DOM mirror layout"
22256         # check new file has no DoM layout after all
22257         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22258                 error "File has DoM component while DoM is disabled"
22259 }
22260 run_test 270h "DoM: DoM stripe removal when disabled on server"
22261
22262 test_270i() {
22263         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22264                 skip "Need MDS version at least 2.14.54"
22265
22266         mkdir $DIR/$tdir
22267         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22268                 error "setstripe should fail" || true
22269 }
22270 run_test 270i "DoM: setting invalid DoM striping should fail"
22271
22272 test_271a() {
22273         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22274                 skip "Need MDS version at least 2.10.55"
22275
22276         local dom=$DIR/$tdir/dom
22277
22278         mkdir -p $DIR/$tdir
22279
22280         $LFS setstripe -E 1024K -L mdt $dom
22281
22282         lctl set_param -n mdc.*.stats=clear
22283         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22284         cat $dom > /dev/null
22285         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22286         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22287         ls $dom
22288         rm -f $dom
22289 }
22290 run_test 271a "DoM: data is cached for read after write"
22291
22292 test_271b() {
22293         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22294                 skip "Need MDS version at least 2.10.55"
22295
22296         local dom=$DIR/$tdir/dom
22297
22298         mkdir -p $DIR/$tdir
22299
22300         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22301
22302         lctl set_param -n mdc.*.stats=clear
22303         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22304         cancel_lru_locks mdc
22305         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22306         # second stat to check size is cached on client
22307         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22308         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22309         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22310         rm -f $dom
22311 }
22312 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22313
22314 test_271ba() {
22315         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22316                 skip "Need MDS version at least 2.10.55"
22317
22318         local dom=$DIR/$tdir/dom
22319
22320         mkdir -p $DIR/$tdir
22321
22322         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22323
22324         lctl set_param -n mdc.*.stats=clear
22325         lctl set_param -n osc.*.stats=clear
22326         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22327         cancel_lru_locks mdc
22328         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22329         # second stat to check size is cached on client
22330         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22331         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22332         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22333         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22334         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22335         rm -f $dom
22336 }
22337 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22338
22339
22340 get_mdc_stats() {
22341         local mdtidx=$1
22342         local param=$2
22343         local mdt=MDT$(printf %04x $mdtidx)
22344
22345         if [ -z $param ]; then
22346                 lctl get_param -n mdc.*$mdt*.stats
22347         else
22348                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22349         fi
22350 }
22351
22352 test_271c() {
22353         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22354                 skip "Need MDS version at least 2.10.55"
22355
22356         local dom=$DIR/$tdir/dom
22357
22358         mkdir -p $DIR/$tdir
22359
22360         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22361
22362         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22363         local facet=mds$((mdtidx + 1))
22364
22365         cancel_lru_locks mdc
22366         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22367         createmany -o $dom 1000
22368         lctl set_param -n mdc.*.stats=clear
22369         smalliomany -w $dom 1000 200
22370         get_mdc_stats $mdtidx
22371         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22372         # Each file has 1 open, 1 IO enqueues, total 2000
22373         # but now we have also +1 getxattr for security.capability, total 3000
22374         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22375         unlinkmany $dom 1000
22376
22377         cancel_lru_locks mdc
22378         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22379         createmany -o $dom 1000
22380         lctl set_param -n mdc.*.stats=clear
22381         smalliomany -w $dom 1000 200
22382         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22383         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22384         # for OPEN and IO lock.
22385         [ $((enq - enq_2)) -ge 1000 ] ||
22386                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22387         unlinkmany $dom 1000
22388         return 0
22389 }
22390 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22391
22392 cleanup_271def_tests() {
22393         trap 0
22394         rm -f $1
22395 }
22396
22397 test_271d() {
22398         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22399                 skip "Need MDS version at least 2.10.57"
22400
22401         local dom=$DIR/$tdir/dom
22402         local tmp=$TMP/$tfile
22403         trap "cleanup_271def_tests $tmp" EXIT
22404
22405         mkdir -p $DIR/$tdir
22406
22407         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22408
22409         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22410
22411         cancel_lru_locks mdc
22412         dd if=/dev/urandom of=$tmp bs=1000 count=1
22413         dd if=$tmp of=$dom bs=1000 count=1
22414         cancel_lru_locks mdc
22415
22416         cat /etc/hosts >> $tmp
22417         lctl set_param -n mdc.*.stats=clear
22418
22419         # append data to the same file it should update local page
22420         echo "Append to the same page"
22421         cat /etc/hosts >> $dom
22422         local num=$(get_mdc_stats $mdtidx ost_read)
22423         local ra=$(get_mdc_stats $mdtidx req_active)
22424         local rw=$(get_mdc_stats $mdtidx req_waittime)
22425
22426         [ -z $num ] || error "$num READ RPC occured"
22427         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22428         echo "... DONE"
22429
22430         # compare content
22431         cmp $tmp $dom || error "file miscompare"
22432
22433         cancel_lru_locks mdc
22434         lctl set_param -n mdc.*.stats=clear
22435
22436         echo "Open and read file"
22437         cat $dom > /dev/null
22438         local num=$(get_mdc_stats $mdtidx ost_read)
22439         local ra=$(get_mdc_stats $mdtidx req_active)
22440         local rw=$(get_mdc_stats $mdtidx req_waittime)
22441
22442         [ -z $num ] || error "$num READ RPC occured"
22443         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22444         echo "... DONE"
22445
22446         # compare content
22447         cmp $tmp $dom || error "file miscompare"
22448
22449         return 0
22450 }
22451 run_test 271d "DoM: read on open (1K file in reply buffer)"
22452
22453 test_271f() {
22454         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22455                 skip "Need MDS version at least 2.10.57"
22456
22457         local dom=$DIR/$tdir/dom
22458         local tmp=$TMP/$tfile
22459         trap "cleanup_271def_tests $tmp" EXIT
22460
22461         mkdir -p $DIR/$tdir
22462
22463         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22464
22465         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22466
22467         cancel_lru_locks mdc
22468         dd if=/dev/urandom of=$tmp bs=265000 count=1
22469         dd if=$tmp of=$dom bs=265000 count=1
22470         cancel_lru_locks mdc
22471         cat /etc/hosts >> $tmp
22472         lctl set_param -n mdc.*.stats=clear
22473
22474         echo "Append to the same page"
22475         cat /etc/hosts >> $dom
22476         local num=$(get_mdc_stats $mdtidx ost_read)
22477         local ra=$(get_mdc_stats $mdtidx req_active)
22478         local rw=$(get_mdc_stats $mdtidx req_waittime)
22479
22480         [ -z $num ] || error "$num READ RPC occured"
22481         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22482         echo "... DONE"
22483
22484         # compare content
22485         cmp $tmp $dom || error "file miscompare"
22486
22487         cancel_lru_locks mdc
22488         lctl set_param -n mdc.*.stats=clear
22489
22490         echo "Open and read file"
22491         cat $dom > /dev/null
22492         local num=$(get_mdc_stats $mdtidx ost_read)
22493         local ra=$(get_mdc_stats $mdtidx req_active)
22494         local rw=$(get_mdc_stats $mdtidx req_waittime)
22495
22496         [ -z $num ] && num=0
22497         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22498         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22499         echo "... DONE"
22500
22501         # compare content
22502         cmp $tmp $dom || error "file miscompare"
22503
22504         return 0
22505 }
22506 run_test 271f "DoM: read on open (200K file and read tail)"
22507
22508 test_271g() {
22509         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22510                 skip "Skipping due to old client or server version"
22511
22512         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22513         # to get layout
22514         $CHECKSTAT -t file $DIR1/$tfile
22515
22516         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22517         MULTIOP_PID=$!
22518         sleep 1
22519         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22520         $LCTL set_param fail_loc=0x80000314
22521         rm $DIR1/$tfile || error "Unlink fails"
22522         RC=$?
22523         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22524         [ $RC -eq 0 ] || error "Failed write to stale object"
22525 }
22526 run_test 271g "Discard DoM data vs client flush race"
22527
22528 test_272a() {
22529         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22530                 skip "Need MDS version at least 2.11.50"
22531
22532         local dom=$DIR/$tdir/dom
22533         mkdir -p $DIR/$tdir
22534
22535         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22536         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22537                 error "failed to write data into $dom"
22538         local old_md5=$(md5sum $dom)
22539
22540         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22541                 error "failed to migrate to the same DoM component"
22542
22543         local new_md5=$(md5sum $dom)
22544
22545         [ "$old_md5" == "$new_md5" ] ||
22546                 error "md5sum differ: $old_md5, $new_md5"
22547
22548         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22549                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22550 }
22551 run_test 272a "DoM migration: new layout with the same DOM component"
22552
22553 test_272b() {
22554         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22555                 skip "Need MDS version at least 2.11.50"
22556
22557         local dom=$DIR/$tdir/dom
22558         mkdir -p $DIR/$tdir
22559         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22560
22561         local mdtidx=$($LFS getstripe -m $dom)
22562         local mdtname=MDT$(printf %04x $mdtidx)
22563         local facet=mds$((mdtidx + 1))
22564
22565         local mdtfree1=$(do_facet $facet \
22566                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22567         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22568                 error "failed to write data into $dom"
22569         local old_md5=$(md5sum $dom)
22570         cancel_lru_locks mdc
22571         local mdtfree1=$(do_facet $facet \
22572                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22573
22574         $LFS migrate -c2 $dom ||
22575                 error "failed to migrate to the new composite layout"
22576         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22577                 error "MDT stripe was not removed"
22578
22579         cancel_lru_locks mdc
22580         local new_md5=$(md5sum $dom)
22581         [ "$old_md5" == "$new_md5" ] ||
22582                 error "$old_md5 != $new_md5"
22583
22584         # Skip free space checks with ZFS
22585         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22586                 local mdtfree2=$(do_facet $facet \
22587                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22588                 [ $mdtfree2 -gt $mdtfree1 ] ||
22589                         error "MDT space is not freed after migration"
22590         fi
22591         return 0
22592 }
22593 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22594
22595 test_272c() {
22596         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22597                 skip "Need MDS version at least 2.11.50"
22598
22599         local dom=$DIR/$tdir/$tfile
22600         mkdir -p $DIR/$tdir
22601         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22602
22603         local mdtidx=$($LFS getstripe -m $dom)
22604         local mdtname=MDT$(printf %04x $mdtidx)
22605         local facet=mds$((mdtidx + 1))
22606
22607         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22608                 error "failed to write data into $dom"
22609         local old_md5=$(md5sum $dom)
22610         cancel_lru_locks mdc
22611         local mdtfree1=$(do_facet $facet \
22612                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22613
22614         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22615                 error "failed to migrate to the new composite layout"
22616         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22617                 error "MDT stripe was not removed"
22618
22619         cancel_lru_locks mdc
22620         local new_md5=$(md5sum $dom)
22621         [ "$old_md5" == "$new_md5" ] ||
22622                 error "$old_md5 != $new_md5"
22623
22624         # Skip free space checks with ZFS
22625         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22626                 local mdtfree2=$(do_facet $facet \
22627                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22628                 [ $mdtfree2 -gt $mdtfree1 ] ||
22629                         error "MDS space is not freed after migration"
22630         fi
22631         return 0
22632 }
22633 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22634
22635 test_272d() {
22636         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22637                 skip "Need MDS version at least 2.12.55"
22638
22639         local dom=$DIR/$tdir/$tfile
22640         mkdir -p $DIR/$tdir
22641         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22642
22643         local mdtidx=$($LFS getstripe -m $dom)
22644         local mdtname=MDT$(printf %04x $mdtidx)
22645         local facet=mds$((mdtidx + 1))
22646
22647         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22648                 error "failed to write data into $dom"
22649         local old_md5=$(md5sum $dom)
22650         cancel_lru_locks mdc
22651         local mdtfree1=$(do_facet $facet \
22652                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22653
22654         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22655                 error "failed mirroring to the new composite layout"
22656         $LFS mirror resync $dom ||
22657                 error "failed mirror resync"
22658         $LFS mirror split --mirror-id 1 -d $dom ||
22659                 error "failed mirror split"
22660
22661         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22662                 error "MDT stripe was not removed"
22663
22664         cancel_lru_locks mdc
22665         local new_md5=$(md5sum $dom)
22666         [ "$old_md5" == "$new_md5" ] ||
22667                 error "$old_md5 != $new_md5"
22668
22669         # Skip free space checks with ZFS
22670         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22671                 local mdtfree2=$(do_facet $facet \
22672                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22673                 [ $mdtfree2 -gt $mdtfree1 ] ||
22674                         error "MDS space is not freed after DOM mirror deletion"
22675         fi
22676         return 0
22677 }
22678 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22679
22680 test_272e() {
22681         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22682                 skip "Need MDS version at least 2.12.55"
22683
22684         local dom=$DIR/$tdir/$tfile
22685         mkdir -p $DIR/$tdir
22686         $LFS setstripe -c 2 $dom
22687
22688         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22689                 error "failed to write data into $dom"
22690         local old_md5=$(md5sum $dom)
22691         cancel_lru_locks mdc
22692
22693         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22694                 error "failed mirroring to the DOM layout"
22695         $LFS mirror resync $dom ||
22696                 error "failed mirror resync"
22697         $LFS mirror split --mirror-id 1 -d $dom ||
22698                 error "failed mirror split"
22699
22700         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22701                 error "MDT stripe was not removed"
22702
22703         cancel_lru_locks mdc
22704         local new_md5=$(md5sum $dom)
22705         [ "$old_md5" == "$new_md5" ] ||
22706                 error "$old_md5 != $new_md5"
22707
22708         return 0
22709 }
22710 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22711
22712 test_272f() {
22713         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22714                 skip "Need MDS version at least 2.12.55"
22715
22716         local dom=$DIR/$tdir/$tfile
22717         mkdir -p $DIR/$tdir
22718         $LFS setstripe -c 2 $dom
22719
22720         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22721                 error "failed to write data into $dom"
22722         local old_md5=$(md5sum $dom)
22723         cancel_lru_locks mdc
22724
22725         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22726                 error "failed migrating to the DOM file"
22727
22728         cancel_lru_locks mdc
22729         local new_md5=$(md5sum $dom)
22730         [ "$old_md5" != "$new_md5" ] &&
22731                 error "$old_md5 != $new_md5"
22732
22733         return 0
22734 }
22735 run_test 272f "DoM migration: OST-striped file to DOM file"
22736
22737 test_273a() {
22738         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22739                 skip "Need MDS version at least 2.11.50"
22740
22741         # Layout swap cannot be done if either file has DOM component,
22742         # this will never be supported, migration should be used instead
22743
22744         local dom=$DIR/$tdir/$tfile
22745         mkdir -p $DIR/$tdir
22746
22747         $LFS setstripe -c2 ${dom}_plain
22748         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22749         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22750                 error "can swap layout with DoM component"
22751         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22752                 error "can swap layout with DoM component"
22753
22754         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22755         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22756                 error "can swap layout with DoM component"
22757         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22758                 error "can swap layout with DoM component"
22759         return 0
22760 }
22761 run_test 273a "DoM: layout swapping should fail with DOM"
22762
22763 test_273b() {
22764         mkdir -p $DIR/$tdir
22765         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22766
22767 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22768         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22769
22770         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22771 }
22772 run_test 273b "DoM: race writeback and object destroy"
22773
22774 test_275() {
22775         remote_ost_nodsh && skip "remote OST with nodsh"
22776         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22777                 skip "Need OST version >= 2.10.57"
22778
22779         local file=$DIR/$tfile
22780         local oss
22781
22782         oss=$(comma_list $(osts_nodes))
22783
22784         dd if=/dev/urandom of=$file bs=1M count=2 ||
22785                 error "failed to create a file"
22786         cancel_lru_locks osc
22787
22788         #lock 1
22789         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22790                 error "failed to read a file"
22791
22792 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22793         $LCTL set_param fail_loc=0x8000031f
22794
22795         cancel_lru_locks osc &
22796         sleep 1
22797
22798 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22799         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22800         #IO takes another lock, but matches the PENDING one
22801         #and places it to the IO RPC
22802         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22803                 error "failed to read a file with PENDING lock"
22804 }
22805 run_test 275 "Read on a canceled duplicate lock"
22806
22807 test_276() {
22808         remote_ost_nodsh && skip "remote OST with nodsh"
22809         local pid
22810
22811         do_facet ost1 "(while true; do \
22812                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22813                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22814         pid=$!
22815
22816         for LOOP in $(seq 20); do
22817                 stop ost1
22818                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22819         done
22820         kill -9 $pid
22821         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22822                 rm $TMP/sanity_276_pid"
22823 }
22824 run_test 276 "Race between mount and obd_statfs"
22825
22826 test_277() {
22827         $LCTL set_param ldlm.namespaces.*.lru_size=0
22828         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22829         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22830                         grep ^used_mb | awk '{print $2}')
22831         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22832         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22833                 oflag=direct conv=notrunc
22834         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22835                         grep ^used_mb | awk '{print $2}')
22836         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22837 }
22838 run_test 277 "Direct IO shall drop page cache"
22839
22840 test_278() {
22841         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22842         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22843         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22844                 skip "needs the same host for mdt1 mdt2" && return
22845
22846         local pid1
22847         local pid2
22848
22849 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22850         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22851         stop mds2 &
22852         pid2=$!
22853
22854         stop mds1
22855
22856         echo "Starting MDTs"
22857         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22858         wait $pid2
22859 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22860 #will return NULL
22861         do_facet mds2 $LCTL set_param fail_loc=0
22862
22863         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22864         wait_recovery_complete mds2
22865 }
22866 run_test 278 "Race starting MDS between MDTs stop/start"
22867
22868 test_280() {
22869         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22870                 skip "Need MGS version at least 2.13.52"
22871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22872         combined_mgs_mds || skip "needs combined MGS/MDT"
22873
22874         umount_client $MOUNT
22875 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22876         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22877
22878         mount_client $MOUNT &
22879         sleep 1
22880         stop mgs || error "stop mgs failed"
22881         #for a race mgs would crash
22882         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22883         # make sure we unmount client before remounting
22884         wait
22885         umount_client $MOUNT
22886         mount_client $MOUNT || error "mount client failed"
22887 }
22888 run_test 280 "Race between MGS umount and client llog processing"
22889
22890 cleanup_test_300() {
22891         trap 0
22892         umask $SAVE_UMASK
22893 }
22894 test_striped_dir() {
22895         local mdt_index=$1
22896         local stripe_count
22897         local stripe_index
22898
22899         mkdir -p $DIR/$tdir
22900
22901         SAVE_UMASK=$(umask)
22902         trap cleanup_test_300 RETURN EXIT
22903
22904         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22905                                                 $DIR/$tdir/striped_dir ||
22906                 error "set striped dir error"
22907
22908         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22909         [ "$mode" = "755" ] || error "expect 755 got $mode"
22910
22911         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22912                 error "getdirstripe failed"
22913         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22914         if [ "$stripe_count" != "2" ]; then
22915                 error "1:stripe_count is $stripe_count, expect 2"
22916         fi
22917         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22918         if [ "$stripe_count" != "2" ]; then
22919                 error "2:stripe_count is $stripe_count, expect 2"
22920         fi
22921
22922         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22923         if [ "$stripe_index" != "$mdt_index" ]; then
22924                 error "stripe_index is $stripe_index, expect $mdt_index"
22925         fi
22926
22927         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22928                 error "nlink error after create striped dir"
22929
22930         mkdir $DIR/$tdir/striped_dir/a
22931         mkdir $DIR/$tdir/striped_dir/b
22932
22933         stat $DIR/$tdir/striped_dir/a ||
22934                 error "create dir under striped dir failed"
22935         stat $DIR/$tdir/striped_dir/b ||
22936                 error "create dir under striped dir failed"
22937
22938         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22939                 error "nlink error after mkdir"
22940
22941         rmdir $DIR/$tdir/striped_dir/a
22942         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22943                 error "nlink error after rmdir"
22944
22945         rmdir $DIR/$tdir/striped_dir/b
22946         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22947                 error "nlink error after rmdir"
22948
22949         chattr +i $DIR/$tdir/striped_dir
22950         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22951                 error "immutable flags not working under striped dir!"
22952         chattr -i $DIR/$tdir/striped_dir
22953
22954         rmdir $DIR/$tdir/striped_dir ||
22955                 error "rmdir striped dir error"
22956
22957         cleanup_test_300
22958
22959         true
22960 }
22961
22962 test_300a() {
22963         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22964                 skip "skipped for lustre < 2.7.0"
22965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22966         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22967
22968         test_striped_dir 0 || error "failed on striped dir on MDT0"
22969         test_striped_dir 1 || error "failed on striped dir on MDT0"
22970 }
22971 run_test 300a "basic striped dir sanity test"
22972
22973 test_300b() {
22974         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22975                 skip "skipped for lustre < 2.7.0"
22976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22977         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22978
22979         local i
22980         local mtime1
22981         local mtime2
22982         local mtime3
22983
22984         test_mkdir $DIR/$tdir || error "mkdir fail"
22985         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22986                 error "set striped dir error"
22987         for i in {0..9}; do
22988                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22989                 sleep 1
22990                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22991                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22992                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22993                 sleep 1
22994                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22995                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22996                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22997         done
22998         true
22999 }
23000 run_test 300b "check ctime/mtime for striped dir"
23001
23002 test_300c() {
23003         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23004                 skip "skipped for lustre < 2.7.0"
23005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23006         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23007
23008         local file_count
23009
23010         mkdir_on_mdt0 $DIR/$tdir
23011         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23012                 error "set striped dir error"
23013
23014         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23015                 error "chown striped dir failed"
23016
23017         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23018                 error "create 5k files failed"
23019
23020         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23021
23022         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23023
23024         rm -rf $DIR/$tdir
23025 }
23026 run_test 300c "chown && check ls under striped directory"
23027
23028 test_300d() {
23029         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23030                 skip "skipped for lustre < 2.7.0"
23031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23033
23034         local stripe_count
23035         local file
23036
23037         mkdir -p $DIR/$tdir
23038         $LFS setstripe -c 2 $DIR/$tdir
23039
23040         #local striped directory
23041         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23042                 error "set striped dir error"
23043         #look at the directories for debug purposes
23044         ls -l $DIR/$tdir
23045         $LFS getdirstripe $DIR/$tdir
23046         ls -l $DIR/$tdir/striped_dir
23047         $LFS getdirstripe $DIR/$tdir/striped_dir
23048         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23049                 error "create 10 files failed"
23050
23051         #remote striped directory
23052         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23053                 error "set striped dir error"
23054         #look at the directories for debug purposes
23055         ls -l $DIR/$tdir
23056         $LFS getdirstripe $DIR/$tdir
23057         ls -l $DIR/$tdir/remote_striped_dir
23058         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23059         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23060                 error "create 10 files failed"
23061
23062         for file in $(find $DIR/$tdir); do
23063                 stripe_count=$($LFS getstripe -c $file)
23064                 [ $stripe_count -eq 2 ] ||
23065                         error "wrong stripe $stripe_count for $file"
23066         done
23067
23068         rm -rf $DIR/$tdir
23069 }
23070 run_test 300d "check default stripe under striped directory"
23071
23072 test_300e() {
23073         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23074                 skip "Need MDS version at least 2.7.55"
23075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23076         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23077
23078         local stripe_count
23079         local file
23080
23081         mkdir -p $DIR/$tdir
23082
23083         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23084                 error "set striped dir error"
23085
23086         touch $DIR/$tdir/striped_dir/a
23087         touch $DIR/$tdir/striped_dir/b
23088         touch $DIR/$tdir/striped_dir/c
23089
23090         mkdir $DIR/$tdir/striped_dir/dir_a
23091         mkdir $DIR/$tdir/striped_dir/dir_b
23092         mkdir $DIR/$tdir/striped_dir/dir_c
23093
23094         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23095                 error "set striped adir under striped dir error"
23096
23097         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23098                 error "set striped bdir under striped dir error"
23099
23100         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23101                 error "set striped cdir under striped dir error"
23102
23103         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23104                 error "rename dir under striped dir fails"
23105
23106         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23107                 error "rename dir under different stripes fails"
23108
23109         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23110                 error "rename file under striped dir should succeed"
23111
23112         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23113                 error "rename dir under striped dir should succeed"
23114
23115         rm -rf $DIR/$tdir
23116 }
23117 run_test 300e "check rename under striped directory"
23118
23119 test_300f() {
23120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23122         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23123                 skip "Need MDS version at least 2.7.55"
23124
23125         local stripe_count
23126         local file
23127
23128         rm -rf $DIR/$tdir
23129         mkdir -p $DIR/$tdir
23130
23131         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23132                 error "set striped dir error"
23133
23134         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23135                 error "set striped dir error"
23136
23137         touch $DIR/$tdir/striped_dir/a
23138         mkdir $DIR/$tdir/striped_dir/dir_a
23139         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23140                 error "create striped dir under striped dir fails"
23141
23142         touch $DIR/$tdir/striped_dir1/b
23143         mkdir $DIR/$tdir/striped_dir1/dir_b
23144         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23145                 error "create striped dir under striped dir fails"
23146
23147         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23148                 error "rename dir under different striped dir should fail"
23149
23150         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23151                 error "rename striped dir under diff striped dir should fail"
23152
23153         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23154                 error "rename file under diff striped dirs fails"
23155
23156         rm -rf $DIR/$tdir
23157 }
23158 run_test 300f "check rename cross striped directory"
23159
23160 test_300_check_default_striped_dir()
23161 {
23162         local dirname=$1
23163         local default_count=$2
23164         local default_index=$3
23165         local stripe_count
23166         local stripe_index
23167         local dir_stripe_index
23168         local dir
23169
23170         echo "checking $dirname $default_count $default_index"
23171         $LFS setdirstripe -D -c $default_count -i $default_index \
23172                                 -H all_char $DIR/$tdir/$dirname ||
23173                 error "set default stripe on striped dir error"
23174         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23175         [ $stripe_count -eq $default_count ] ||
23176                 error "expect $default_count get $stripe_count for $dirname"
23177
23178         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23179         [ $stripe_index -eq $default_index ] ||
23180                 error "expect $default_index get $stripe_index for $dirname"
23181
23182         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23183                                                 error "create dirs failed"
23184
23185         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23186         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23187         for dir in $(find $DIR/$tdir/$dirname/*); do
23188                 stripe_count=$($LFS getdirstripe -c $dir)
23189                 (( $stripe_count == $default_count )) ||
23190                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23191                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23192                 error "stripe count $default_count != $stripe_count for $dir"
23193
23194                 stripe_index=$($LFS getdirstripe -i $dir)
23195                 [ $default_index -eq -1 ] ||
23196                         [ $stripe_index -eq $default_index ] ||
23197                         error "$stripe_index != $default_index for $dir"
23198
23199                 #check default stripe
23200                 stripe_count=$($LFS getdirstripe -D -c $dir)
23201                 [ $stripe_count -eq $default_count ] ||
23202                 error "default count $default_count != $stripe_count for $dir"
23203
23204                 stripe_index=$($LFS getdirstripe -D -i $dir)
23205                 [ $stripe_index -eq $default_index ] ||
23206                 error "default index $default_index != $stripe_index for $dir"
23207         done
23208         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23209 }
23210
23211 test_300g() {
23212         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23213         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23214                 skip "Need MDS version at least 2.7.55"
23215
23216         local dir
23217         local stripe_count
23218         local stripe_index
23219
23220         mkdir_on_mdt0 $DIR/$tdir
23221         mkdir $DIR/$tdir/normal_dir
23222
23223         #Checking when client cache stripe index
23224         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23225         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23226                 error "create striped_dir failed"
23227
23228         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23229                 error "create dir0 fails"
23230         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23231         [ $stripe_index -eq 0 ] ||
23232                 error "dir0 expect index 0 got $stripe_index"
23233
23234         mkdir $DIR/$tdir/striped_dir/dir1 ||
23235                 error "create dir1 fails"
23236         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23237         [ $stripe_index -eq 1 ] ||
23238                 error "dir1 expect index 1 got $stripe_index"
23239
23240         #check default stripe count/stripe index
23241         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23242         test_300_check_default_striped_dir normal_dir 1 0
23243         test_300_check_default_striped_dir normal_dir -1 1
23244         test_300_check_default_striped_dir normal_dir 2 -1
23245
23246         #delete default stripe information
23247         echo "delete default stripeEA"
23248         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23249                 error "set default stripe on striped dir error"
23250
23251         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23252         for dir in $(find $DIR/$tdir/normal_dir/*); do
23253                 stripe_count=$($LFS getdirstripe -c $dir)
23254                 [ $stripe_count -eq 0 ] ||
23255                         error "expect 1 get $stripe_count for $dir"
23256         done
23257 }
23258 run_test 300g "check default striped directory for normal directory"
23259
23260 test_300h() {
23261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23262         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23263                 skip "Need MDS version at least 2.7.55"
23264
23265         local dir
23266         local stripe_count
23267
23268         mkdir $DIR/$tdir
23269         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23270                 error "set striped dir error"
23271
23272         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23273         test_300_check_default_striped_dir striped_dir 1 0
23274         test_300_check_default_striped_dir striped_dir -1 1
23275         test_300_check_default_striped_dir striped_dir 2 -1
23276
23277         #delete default stripe information
23278         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23279                 error "set default stripe on striped dir error"
23280
23281         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23282         for dir in $(find $DIR/$tdir/striped_dir/*); do
23283                 stripe_count=$($LFS getdirstripe -c $dir)
23284                 [ $stripe_count -eq 0 ] ||
23285                         error "expect 1 get $stripe_count for $dir"
23286         done
23287 }
23288 run_test 300h "check default striped directory for striped directory"
23289
23290 test_300i() {
23291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23292         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23293         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23294                 skip "Need MDS version at least 2.7.55"
23295
23296         local stripe_count
23297         local file
23298
23299         mkdir $DIR/$tdir
23300
23301         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23302                 error "set striped dir error"
23303
23304         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23305                 error "create files under striped dir failed"
23306
23307         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23308                 error "set striped hashdir error"
23309
23310         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23311                 error "create dir0 under hash dir failed"
23312         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23313                 error "create dir1 under hash dir failed"
23314         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23315                 error "create dir2 under hash dir failed"
23316
23317         # unfortunately, we need to umount to clear dir layout cache for now
23318         # once we fully implement dir layout, we can drop this
23319         umount_client $MOUNT || error "umount failed"
23320         mount_client $MOUNT || error "mount failed"
23321
23322         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23323         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23324         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23325
23326         #set the stripe to be unknown hash type
23327         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23328         $LCTL set_param fail_loc=0x1901
23329         for ((i = 0; i < 10; i++)); do
23330                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23331                         error "stat f-$i failed"
23332                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23333         done
23334
23335         touch $DIR/$tdir/striped_dir/f0 &&
23336                 error "create under striped dir with unknown hash should fail"
23337
23338         $LCTL set_param fail_loc=0
23339
23340         umount_client $MOUNT || error "umount failed"
23341         mount_client $MOUNT || error "mount failed"
23342
23343         return 0
23344 }
23345 run_test 300i "client handle unknown hash type striped directory"
23346
23347 test_300j() {
23348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23350         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23351                 skip "Need MDS version at least 2.7.55"
23352
23353         local stripe_count
23354         local file
23355
23356         mkdir $DIR/$tdir
23357
23358         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23359         $LCTL set_param fail_loc=0x1702
23360         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23361                 error "set striped dir error"
23362
23363         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23364                 error "create files under striped dir failed"
23365
23366         $LCTL set_param fail_loc=0
23367
23368         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23369
23370         return 0
23371 }
23372 run_test 300j "test large update record"
23373
23374 test_300k() {
23375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23377         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23378                 skip "Need MDS version at least 2.7.55"
23379
23380         # this test needs a huge transaction
23381         local kb
23382         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23383              osd*.$FSNAME-MDT0000.kbytestotal")
23384         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23385
23386         local stripe_count
23387         local file
23388
23389         mkdir $DIR/$tdir
23390
23391         #define OBD_FAIL_LARGE_STRIPE   0x1703
23392         $LCTL set_param fail_loc=0x1703
23393         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23394                 error "set striped dir error"
23395         $LCTL set_param fail_loc=0
23396
23397         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23398                 error "getstripeddir fails"
23399         rm -rf $DIR/$tdir/striped_dir ||
23400                 error "unlink striped dir fails"
23401
23402         return 0
23403 }
23404 run_test 300k "test large striped directory"
23405
23406 test_300l() {
23407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23408         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23409         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23410                 skip "Need MDS version at least 2.7.55"
23411
23412         local stripe_index
23413
23414         test_mkdir -p $DIR/$tdir/striped_dir
23415         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23416                         error "chown $RUNAS_ID failed"
23417         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23418                 error "set default striped dir failed"
23419
23420         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23421         $LCTL set_param fail_loc=0x80000158
23422         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23423
23424         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23425         [ $stripe_index -eq 1 ] ||
23426                 error "expect 1 get $stripe_index for $dir"
23427 }
23428 run_test 300l "non-root user to create dir under striped dir with stale layout"
23429
23430 test_300m() {
23431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23432         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23433         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23434                 skip "Need MDS version at least 2.7.55"
23435
23436         mkdir -p $DIR/$tdir/striped_dir
23437         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23438                 error "set default stripes dir error"
23439
23440         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23441
23442         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23443         [ $stripe_count -eq 0 ] ||
23444                         error "expect 0 get $stripe_count for a"
23445
23446         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23447                 error "set default stripes dir error"
23448
23449         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23450
23451         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23452         [ $stripe_count -eq 0 ] ||
23453                         error "expect 0 get $stripe_count for b"
23454
23455         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23456                 error "set default stripes dir error"
23457
23458         mkdir $DIR/$tdir/striped_dir/c &&
23459                 error "default stripe_index is invalid, mkdir c should fails"
23460
23461         rm -rf $DIR/$tdir || error "rmdir fails"
23462 }
23463 run_test 300m "setstriped directory on single MDT FS"
23464
23465 cleanup_300n() {
23466         local list=$(comma_list $(mdts_nodes))
23467
23468         trap 0
23469         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23470 }
23471
23472 test_300n() {
23473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23475         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23476                 skip "Need MDS version at least 2.7.55"
23477         remote_mds_nodsh && skip "remote MDS with nodsh"
23478
23479         local stripe_index
23480         local list=$(comma_list $(mdts_nodes))
23481
23482         trap cleanup_300n RETURN EXIT
23483         mkdir -p $DIR/$tdir
23484         chmod 777 $DIR/$tdir
23485         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23486                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23487                 error "create striped dir succeeds with gid=0"
23488
23489         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23490         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23491                 error "create striped dir fails with gid=-1"
23492
23493         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23494         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23495                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23496                 error "set default striped dir succeeds with gid=0"
23497
23498
23499         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23500         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23501                 error "set default striped dir fails with gid=-1"
23502
23503
23504         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23505         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23506                                         error "create test_dir fails"
23507         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23508                                         error "create test_dir1 fails"
23509         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23510                                         error "create test_dir2 fails"
23511         cleanup_300n
23512 }
23513 run_test 300n "non-root user to create dir under striped dir with default EA"
23514
23515 test_300o() {
23516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23518         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23519                 skip "Need MDS version at least 2.7.55"
23520
23521         local numfree1
23522         local numfree2
23523
23524         mkdir -p $DIR/$tdir
23525
23526         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23527         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23528         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23529                 skip "not enough free inodes $numfree1 $numfree2"
23530         fi
23531
23532         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23533         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23534         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23535                 skip "not enough free space $numfree1 $numfree2"
23536         fi
23537
23538         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23539                 error "setdirstripe fails"
23540
23541         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23542                 error "create dirs fails"
23543
23544         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23545         ls $DIR/$tdir/striped_dir > /dev/null ||
23546                 error "ls striped dir fails"
23547         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23548                 error "unlink big striped dir fails"
23549 }
23550 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23551
23552 test_300p() {
23553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23555         remote_mds_nodsh && skip "remote MDS with nodsh"
23556
23557         mkdir_on_mdt0 $DIR/$tdir
23558
23559         #define OBD_FAIL_OUT_ENOSPC     0x1704
23560         do_facet mds2 lctl set_param fail_loc=0x80001704
23561         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23562                  && error "create striped directory should fail"
23563
23564         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23565
23566         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23567         true
23568 }
23569 run_test 300p "create striped directory without space"
23570
23571 test_300q() {
23572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23573         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23574
23575         local fd=$(free_fd)
23576         local cmd="exec $fd<$tdir"
23577         cd $DIR
23578         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23579         eval $cmd
23580         cmd="exec $fd<&-"
23581         trap "eval $cmd" EXIT
23582         cd $tdir || error "cd $tdir fails"
23583         rmdir  ../$tdir || error "rmdir $tdir fails"
23584         mkdir local_dir && error "create dir succeeds"
23585         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23586         eval $cmd
23587         return 0
23588 }
23589 run_test 300q "create remote directory under orphan directory"
23590
23591 test_300r() {
23592         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23593                 skip "Need MDS version at least 2.7.55" && return
23594         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23595
23596         mkdir $DIR/$tdir
23597
23598         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23599                 error "set striped dir error"
23600
23601         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23602                 error "getstripeddir fails"
23603
23604         local stripe_count
23605         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23606                       awk '/lmv_stripe_count:/ { print $2 }')
23607
23608         [ $MDSCOUNT -ne $stripe_count ] &&
23609                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23610
23611         rm -rf $DIR/$tdir/striped_dir ||
23612                 error "unlink striped dir fails"
23613 }
23614 run_test 300r "test -1 striped directory"
23615
23616 test_300s_helper() {
23617         local count=$1
23618
23619         local stripe_dir=$DIR/$tdir/striped_dir.$count
23620
23621         $LFS mkdir -c $count $stripe_dir ||
23622                 error "lfs mkdir -c error"
23623
23624         $LFS getdirstripe $stripe_dir ||
23625                 error "lfs getdirstripe fails"
23626
23627         local stripe_count
23628         stripe_count=$($LFS getdirstripe $stripe_dir |
23629                       awk '/lmv_stripe_count:/ { print $2 }')
23630
23631         [ $count -ne $stripe_count ] &&
23632                 error_noexit "bad stripe count $stripe_count expected $count"
23633
23634         local dupe_stripes
23635         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23636                 awk '/0x/ {count[$1] += 1}; END {
23637                         for (idx in count) {
23638                                 if (count[idx]>1) {
23639                                         print "index " idx " count " count[idx]
23640                                 }
23641                         }
23642                 }')
23643
23644         if [[ -n "$dupe_stripes" ]] ; then
23645                 lfs getdirstripe $stripe_dir
23646                 error_noexit "Dupe MDT above: $dupe_stripes "
23647         fi
23648
23649         rm -rf $stripe_dir ||
23650                 error_noexit "unlink $stripe_dir fails"
23651 }
23652
23653 test_300s() {
23654         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23655                 skip "Need MDS version at least 2.7.55" && return
23656         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23657
23658         mkdir $DIR/$tdir
23659         for count in $(seq 2 $MDSCOUNT); do
23660                 test_300s_helper $count
23661         done
23662 }
23663 run_test 300s "test lfs mkdir -c without -i"
23664
23665
23666 prepare_remote_file() {
23667         mkdir $DIR/$tdir/src_dir ||
23668                 error "create remote source failed"
23669
23670         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23671                  error "cp to remote source failed"
23672         touch $DIR/$tdir/src_dir/a
23673
23674         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23675                 error "create remote target dir failed"
23676
23677         touch $DIR/$tdir/tgt_dir/b
23678
23679         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23680                 error "rename dir cross MDT failed!"
23681
23682         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23683                 error "src_child still exists after rename"
23684
23685         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23686                 error "missing file(a) after rename"
23687
23688         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23689                 error "diff after rename"
23690 }
23691
23692 test_310a() {
23693         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23695
23696         local remote_file=$DIR/$tdir/tgt_dir/b
23697
23698         mkdir -p $DIR/$tdir
23699
23700         prepare_remote_file || error "prepare remote file failed"
23701
23702         #open-unlink file
23703         $OPENUNLINK $remote_file $remote_file ||
23704                 error "openunlink $remote_file failed"
23705         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23706 }
23707 run_test 310a "open unlink remote file"
23708
23709 test_310b() {
23710         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23712
23713         local remote_file=$DIR/$tdir/tgt_dir/b
23714
23715         mkdir -p $DIR/$tdir
23716
23717         prepare_remote_file || error "prepare remote file failed"
23718
23719         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23720         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23721         $CHECKSTAT -t file $remote_file || error "check file failed"
23722 }
23723 run_test 310b "unlink remote file with multiple links while open"
23724
23725 test_310c() {
23726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23727         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23728
23729         local remote_file=$DIR/$tdir/tgt_dir/b
23730
23731         mkdir -p $DIR/$tdir
23732
23733         prepare_remote_file || error "prepare remote file failed"
23734
23735         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23736         multiop_bg_pause $remote_file O_uc ||
23737                         error "mulitop failed for remote file"
23738         MULTIPID=$!
23739         $MULTIOP $DIR/$tfile Ouc
23740         kill -USR1 $MULTIPID
23741         wait $MULTIPID
23742 }
23743 run_test 310c "open-unlink remote file with multiple links"
23744
23745 #LU-4825
23746 test_311() {
23747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23748         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23749         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23750                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23751         remote_mds_nodsh && skip "remote MDS with nodsh"
23752
23753         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23754         local mdts=$(comma_list $(mdts_nodes))
23755
23756         mkdir -p $DIR/$tdir
23757         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23758         createmany -o $DIR/$tdir/$tfile. 1000
23759
23760         # statfs data is not real time, let's just calculate it
23761         old_iused=$((old_iused + 1000))
23762
23763         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23764                         osp.*OST0000*MDT0000.create_count")
23765         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23766                                 osp.*OST0000*MDT0000.max_create_count")
23767         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23768
23769         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23770         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23771         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23772
23773         unlinkmany $DIR/$tdir/$tfile. 1000
23774
23775         do_nodes $mdts "$LCTL set_param -n \
23776                         osp.*OST0000*.max_create_count=$max_count"
23777         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23778                 do_nodes $mdts "$LCTL set_param -n \
23779                                 osp.*OST0000*.create_count=$count"
23780         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23781                         grep "=0" && error "create_count is zero"
23782
23783         local new_iused
23784         for i in $(seq 120); do
23785                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23786                 # system may be too busy to destroy all objs in time, use
23787                 # a somewhat small value to not fail autotest
23788                 [ $((old_iused - new_iused)) -gt 400 ] && break
23789                 sleep 1
23790         done
23791
23792         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23793         [ $((old_iused - new_iused)) -gt 400 ] ||
23794                 error "objs not destroyed after unlink"
23795 }
23796 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23797
23798 zfs_oid_to_objid()
23799 {
23800         local ost=$1
23801         local objid=$2
23802
23803         local vdevdir=$(dirname $(facet_vdevice $ost))
23804         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23805         local zfs_zapid=$(do_facet $ost $cmd |
23806                           grep -w "/O/0/d$((objid%32))" -C 5 |
23807                           awk '/Object/{getline; print $1}')
23808         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23809                           awk "/$objid = /"'{printf $3}')
23810
23811         echo $zfs_objid
23812 }
23813
23814 zfs_object_blksz() {
23815         local ost=$1
23816         local objid=$2
23817
23818         local vdevdir=$(dirname $(facet_vdevice $ost))
23819         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23820         local blksz=$(do_facet $ost $cmd $objid |
23821                       awk '/dblk/{getline; printf $4}')
23822
23823         case "${blksz: -1}" in
23824                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23825                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23826                 *) ;;
23827         esac
23828
23829         echo $blksz
23830 }
23831
23832 test_312() { # LU-4856
23833         remote_ost_nodsh && skip "remote OST with nodsh"
23834         [ "$ost1_FSTYPE" = "zfs" ] ||
23835                 skip_env "the test only applies to zfs"
23836
23837         local max_blksz=$(do_facet ost1 \
23838                           $ZFS get -p recordsize $(facet_device ost1) |
23839                           awk '!/VALUE/{print $3}')
23840
23841         # to make life a little bit easier
23842         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23843         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23844
23845         local tf=$DIR/$tdir/$tfile
23846         touch $tf
23847         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23848
23849         # Get ZFS object id
23850         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23851         # block size change by sequential overwrite
23852         local bs
23853
23854         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23855                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23856
23857                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23858                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23859         done
23860         rm -f $tf
23861
23862         # block size change by sequential append write
23863         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23864         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23865         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23866         local count
23867
23868         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23869                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23870                         oflag=sync conv=notrunc
23871
23872                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23873                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23874                         error "blksz error, actual $blksz, " \
23875                                 "expected: 2 * $count * $PAGE_SIZE"
23876         done
23877         rm -f $tf
23878
23879         # random write
23880         touch $tf
23881         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23882         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23883
23884         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23885         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23886         [ $blksz -eq $PAGE_SIZE ] ||
23887                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23888
23889         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23890         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23891         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23892
23893         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23894         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23895         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23896 }
23897 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23898
23899 test_313() {
23900         remote_ost_nodsh && skip "remote OST with nodsh"
23901
23902         local file=$DIR/$tfile
23903
23904         rm -f $file
23905         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23906
23907         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23908         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23909         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23910                 error "write should failed"
23911         do_facet ost1 "$LCTL set_param fail_loc=0"
23912         rm -f $file
23913 }
23914 run_test 313 "io should fail after last_rcvd update fail"
23915
23916 test_314() {
23917         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23918
23919         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23920         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23921         rm -f $DIR/$tfile
23922         wait_delete_completed
23923         do_facet ost1 "$LCTL set_param fail_loc=0"
23924 }
23925 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23926
23927 test_315() { # LU-618
23928         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23929
23930         local file=$DIR/$tfile
23931         rm -f $file
23932
23933         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23934                 error "multiop file write failed"
23935         $MULTIOP $file oO_RDONLY:r4063232_c &
23936         PID=$!
23937
23938         sleep 2
23939
23940         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23941         kill -USR1 $PID
23942
23943         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23944         rm -f $file
23945 }
23946 run_test 315 "read should be accounted"
23947
23948 test_316() {
23949         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23950         large_xattr_enabled || skip_env "ea_inode feature disabled"
23951
23952         rm -rf $DIR/$tdir/d
23953         mkdir -p $DIR/$tdir/d
23954         chown nobody $DIR/$tdir/d
23955         touch $DIR/$tdir/d/file
23956
23957         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23958 }
23959 run_test 316 "lfs mv"
23960
23961 test_317() {
23962         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23963                 skip "Need MDS version at least 2.11.53"
23964         if [ "$ost1_FSTYPE" == "zfs" ]; then
23965                 skip "LU-10370: no implementation for ZFS"
23966         fi
23967
23968         local trunc_sz
23969         local grant_blk_size
23970
23971         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23972                         awk '/grant_block_size:/ { print $2; exit; }')
23973         #
23974         # Create File of size 5M. Truncate it to below size's and verify
23975         # blocks count.
23976         #
23977         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23978                 error "Create file $DIR/$tfile failed"
23979         stack_trap "rm -f $DIR/$tfile" EXIT
23980
23981         for trunc_sz in 2097152 4097 4000 509 0; do
23982                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23983                         error "truncate $tfile to $trunc_sz failed"
23984                 local sz=$(stat --format=%s $DIR/$tfile)
23985                 local blk=$(stat --format=%b $DIR/$tfile)
23986                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23987                                      grant_blk_size) * 8))
23988
23989                 if [[ $blk -ne $trunc_blk ]]; then
23990                         $(which stat) $DIR/$tfile
23991                         error "Expected Block $trunc_blk got $blk for $tfile"
23992                 fi
23993
23994                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23995                         error "Expected Size $trunc_sz got $sz for $tfile"
23996         done
23997
23998         #
23999         # sparse file test
24000         # Create file with a hole and write actual 65536 bytes which aligned
24001         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24002         #
24003         local bs=65536
24004         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24005                 error "Create file : $DIR/$tfile"
24006
24007         #
24008         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24009         # blocks. The block count must drop to 8.
24010         #
24011         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24012                 ((bs - grant_blk_size) + 1)))
24013         $TRUNCATE $DIR/$tfile $trunc_sz ||
24014                 error "truncate $tfile to $trunc_sz failed"
24015
24016         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24017         sz=$(stat --format=%s $DIR/$tfile)
24018         blk=$(stat --format=%b $DIR/$tfile)
24019
24020         if [[ $blk -ne $trunc_bsz ]]; then
24021                 $(which stat) $DIR/$tfile
24022                 error "Expected Block $trunc_bsz got $blk for $tfile"
24023         fi
24024
24025         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24026                 error "Expected Size $trunc_sz got $sz for $tfile"
24027 }
24028 run_test 317 "Verify blocks get correctly update after truncate"
24029
24030 test_318() {
24031         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24032         local old_max_active=$($LCTL get_param -n \
24033                             ${llite_name}.max_read_ahead_async_active \
24034                             2>/dev/null)
24035
24036         $LCTL set_param llite.*.max_read_ahead_async_active=256
24037         local max_active=$($LCTL get_param -n \
24038                            ${llite_name}.max_read_ahead_async_active \
24039                            2>/dev/null)
24040         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24041
24042         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24043                 error "set max_read_ahead_async_active should succeed"
24044
24045         $LCTL set_param llite.*.max_read_ahead_async_active=512
24046         max_active=$($LCTL get_param -n \
24047                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24048         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24049
24050         # restore @max_active
24051         [ $old_max_active -ne 0 ] && $LCTL set_param \
24052                 llite.*.max_read_ahead_async_active=$old_max_active
24053
24054         local old_threshold=$($LCTL get_param -n \
24055                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24056         local max_per_file_mb=$($LCTL get_param -n \
24057                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24058
24059         local invalid=$(($max_per_file_mb + 1))
24060         $LCTL set_param \
24061                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24062                         && error "set $invalid should fail"
24063
24064         local valid=$(($invalid - 1))
24065         $LCTL set_param \
24066                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24067                         error "set $valid should succeed"
24068         local threshold=$($LCTL get_param -n \
24069                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24070         [ $threshold -eq $valid ] || error \
24071                 "expect threshold $valid got $threshold"
24072         $LCTL set_param \
24073                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24074 }
24075 run_test 318 "Verify async readahead tunables"
24076
24077 test_319() {
24078         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24079
24080         local before=$(date +%s)
24081         local evict
24082         local mdir=$DIR/$tdir
24083         local file=$mdir/xxx
24084
24085         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24086         touch $file
24087
24088 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24089         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24090         $LFS mv -m1 $file &
24091
24092         sleep 1
24093         dd if=$file of=/dev/null
24094         wait
24095         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24096           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24097
24098         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24099 }
24100 run_test 319 "lost lease lock on migrate error"
24101
24102 test_398a() { # LU-4198
24103         local ost1_imp=$(get_osc_import_name client ost1)
24104         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24105                          cut -d'.' -f2)
24106
24107         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24108         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24109
24110         # request a new lock on client
24111         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24112
24113         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24114         local lock_count=$($LCTL get_param -n \
24115                            ldlm.namespaces.$imp_name.lru_size)
24116         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24117
24118         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24119
24120         # no lock cached, should use lockless IO and not enqueue new lock
24121         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24122         lock_count=$($LCTL get_param -n \
24123                      ldlm.namespaces.$imp_name.lru_size)
24124         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24125 }
24126 run_test 398a "direct IO should cancel lock otherwise lockless"
24127
24128 test_398b() { # LU-4198
24129         which fio || skip_env "no fio installed"
24130         $LFS setstripe -c -1 $DIR/$tfile
24131
24132         local size=12
24133         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24134
24135         local njobs=4
24136         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24137         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24138                 --numjobs=$njobs --fallocate=none \
24139                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24140                 --filename=$DIR/$tfile &
24141         bg_pid=$!
24142
24143         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24144         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24145                 --numjobs=$njobs --fallocate=none \
24146                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24147                 --filename=$DIR/$tfile || true
24148         wait $bg_pid
24149
24150         rm -f $DIR/$tfile
24151 }
24152 run_test 398b "DIO and buffer IO race"
24153
24154 test_398c() { # LU-4198
24155         local ost1_imp=$(get_osc_import_name client ost1)
24156         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24157                          cut -d'.' -f2)
24158
24159         which fio || skip_env "no fio installed"
24160
24161         saved_debug=$($LCTL get_param -n debug)
24162         $LCTL set_param debug=0
24163
24164         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24165         ((size /= 1024)) # by megabytes
24166         ((size /= 2)) # write half of the OST at most
24167         [ $size -gt 40 ] && size=40 #reduce test time anyway
24168
24169         $LFS setstripe -c 1 $DIR/$tfile
24170
24171         # it seems like ldiskfs reserves more space than necessary if the
24172         # writing blocks are not mapped, so it extends the file firstly
24173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24174         cancel_lru_locks osc
24175
24176         # clear and verify rpc_stats later
24177         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24178
24179         local njobs=4
24180         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24181         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24182                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24183                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24184                 --filename=$DIR/$tfile
24185         [ $? -eq 0 ] || error "fio write error"
24186
24187         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24188                 error "Locks were requested while doing AIO"
24189
24190         # get the percentage of 1-page I/O
24191         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24192                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24193                 awk '{print $7}')
24194         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24195
24196         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24197         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24198                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24199                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24200                 --filename=$DIR/$tfile
24201         [ $? -eq 0 ] || error "fio mixed read write error"
24202
24203         echo "AIO with large block size ${size}M"
24204         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24205                 --numjobs=1 --fallocate=none --ioengine=libaio \
24206                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24207                 --filename=$DIR/$tfile
24208         [ $? -eq 0 ] || error "fio large block size failed"
24209
24210         rm -f $DIR/$tfile
24211         $LCTL set_param debug="$saved_debug"
24212 }
24213 run_test 398c "run fio to test AIO"
24214
24215 test_398d() { #  LU-13846
24216         which aiocp || skip_env "no aiocp installed"
24217         local aio_file=$DIR/$tfile.aio
24218
24219         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24220
24221         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24222         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24223         stack_trap "rm -f $DIR/$tfile $aio_file"
24224
24225         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24226
24227         # make sure we don't crash and fail properly
24228         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24229                 error "aio not aligned with PAGE SIZE should fail"
24230
24231         rm -f $DIR/$tfile $aio_file
24232 }
24233 run_test 398d "run aiocp to verify block size > stripe size"
24234
24235 test_398e() {
24236         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24237         touch $DIR/$tfile.new
24238         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24239 }
24240 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24241
24242 test_398f() { #  LU-14687
24243         which aiocp || skip_env "no aiocp installed"
24244         local aio_file=$DIR/$tfile.aio
24245
24246         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24247
24248         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24249         stack_trap "rm -f $DIR/$tfile $aio_file"
24250
24251         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24252         $LCTL set_param fail_loc=0x1418
24253         # make sure we don't crash and fail properly
24254         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24255                 error "aio with page allocation failure succeeded"
24256         $LCTL set_param fail_loc=0
24257         diff $DIR/$tfile $aio_file
24258         [[ $? != 0 ]] || error "no diff after failed aiocp"
24259 }
24260 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24261
24262 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24263 # stripe and i/o size must be > stripe size
24264 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24265 # single RPC in flight.  This test shows async DIO submission is working by
24266 # showing multiple RPCs in flight.
24267 test_398g() { #  LU-13798
24268         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24269
24270         # We need to do some i/o first to acquire enough grant to put our RPCs
24271         # in flight; otherwise a new connection may not have enough grant
24272         # available
24273         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24274                 error "parallel dio failed"
24275         stack_trap "rm -f $DIR/$tfile"
24276
24277         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24278         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24279         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24280         stack_trap "$LCTL set_param -n $pages_per_rpc"
24281
24282         # Recreate file so it's empty
24283         rm -f $DIR/$tfile
24284         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24285         #Pause rpc completion to guarantee we see multiple rpcs in flight
24286         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24287         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24288         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24289
24290         # Clear rpc stats
24291         $LCTL set_param osc.*.rpc_stats=c
24292
24293         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24294                 error "parallel dio failed"
24295         stack_trap "rm -f $DIR/$tfile"
24296
24297         $LCTL get_param osc.*-OST0000-*.rpc_stats
24298         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24299                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24300                 grep "8:" | awk '{print $8}')
24301         # We look at the "8 rpcs in flight" field, and verify A) it is present
24302         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24303         # as expected for an 8M DIO to a file with 1M stripes.
24304         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24305
24306         # Verify turning off parallel dio works as expected
24307         # Clear rpc stats
24308         $LCTL set_param osc.*.rpc_stats=c
24309         $LCTL set_param llite.*.parallel_dio=0
24310         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24311
24312         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24313                 error "dio with parallel dio disabled failed"
24314
24315         # Ideally, we would see only one RPC in flight here, but there is an
24316         # unavoidable race between i/o completion and RPC in flight counting,
24317         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24318         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24319         # So instead we just verify it's always < 8.
24320         $LCTL get_param osc.*-OST0000-*.rpc_stats
24321         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24322                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24323                 grep '^$' -B1 | grep . | awk '{print $1}')
24324         [ $ret != "8:" ] ||
24325                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24326 }
24327 run_test 398g "verify parallel dio async RPC submission"
24328
24329 test_398h() { #  LU-13798
24330         local dio_file=$DIR/$tfile.dio
24331
24332         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24333
24334         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24335         stack_trap "rm -f $DIR/$tfile $dio_file"
24336
24337         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24338                 error "parallel dio failed"
24339         diff $DIR/$tfile $dio_file
24340         [[ $? == 0 ]] || error "file diff after aiocp"
24341 }
24342 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24343
24344 test_398i() { #  LU-13798
24345         local dio_file=$DIR/$tfile.dio
24346
24347         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24348
24349         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24350         stack_trap "rm -f $DIR/$tfile $dio_file"
24351
24352         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24353         $LCTL set_param fail_loc=0x1418
24354         # make sure we don't crash and fail properly
24355         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24356                 error "parallel dio page allocation failure succeeded"
24357         diff $DIR/$tfile $dio_file
24358         [[ $? != 0 ]] || error "no diff after failed aiocp"
24359 }
24360 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24361
24362 test_398j() { #  LU-13798
24363         # Stripe size > RPC size but less than i/o size tests split across
24364         # stripes and RPCs for individual i/o op
24365         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24366
24367         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24368         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24369         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24370         stack_trap "$LCTL set_param -n $pages_per_rpc"
24371
24372         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24373                 error "parallel dio write failed"
24374         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24375
24376         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24377                 error "parallel dio read failed"
24378         diff $DIR/$tfile $DIR/$tfile.2
24379         [[ $? == 0 ]] || error "file diff after parallel dio read"
24380 }
24381 run_test 398j "test parallel dio where stripe size > rpc_size"
24382
24383 test_398k() { #  LU-13798
24384         wait_delete_completed
24385         wait_mds_ost_sync
24386
24387         # 4 stripe file; we will cause out of space on OST0
24388         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24389
24390         # Fill OST0 (if it's not too large)
24391         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24392                    head -n1)
24393         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24394                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24395         fi
24396         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24397         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24398                 error "dd should fill OST0"
24399         stack_trap "rm -f $DIR/$tfile.1"
24400
24401         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24402         err=$?
24403
24404         ls -la $DIR/$tfile
24405         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24406                 error "file is not 0 bytes in size"
24407
24408         # dd above should not succeed, but don't error until here so we can
24409         # get debug info above
24410         [[ $err != 0 ]] ||
24411                 error "parallel dio write with enospc succeeded"
24412         stack_trap "rm -f $DIR/$tfile"
24413 }
24414 run_test 398k "test enospc on first stripe"
24415
24416 test_398l() { #  LU-13798
24417         wait_delete_completed
24418         wait_mds_ost_sync
24419
24420         # 4 stripe file; we will cause out of space on OST0
24421         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24422         # happens on the second i/o chunk we issue
24423         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24424
24425         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24426         stack_trap "rm -f $DIR/$tfile"
24427
24428         # Fill OST0 (if it's not too large)
24429         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24430                    head -n1)
24431         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24432                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24433         fi
24434         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24435         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24436                 error "dd should fill OST0"
24437         stack_trap "rm -f $DIR/$tfile.1"
24438
24439         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24440         err=$?
24441         stack_trap "rm -f $DIR/$tfile.2"
24442
24443         # Check that short write completed as expected
24444         ls -la $DIR/$tfile.2
24445         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24446                 error "file is not 1M in size"
24447
24448         # dd above should not succeed, but don't error until here so we can
24449         # get debug info above
24450         [[ $err != 0 ]] ||
24451                 error "parallel dio write with enospc succeeded"
24452
24453         # Truncate source file to same length as output file and diff them
24454         $TRUNCATE $DIR/$tfile 1048576
24455         diff $DIR/$tfile $DIR/$tfile.2
24456         [[ $? == 0 ]] || error "data incorrect after short write"
24457 }
24458 run_test 398l "test enospc on intermediate stripe/RPC"
24459
24460 test_398m() { #  LU-13798
24461         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24462
24463         # Set up failure on OST0, the first stripe:
24464         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24465         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24466         # So this fail_val specifies OST0
24467         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24468         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24469
24470         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24471                 error "parallel dio write with failure on first stripe succeeded"
24472         stack_trap "rm -f $DIR/$tfile"
24473         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24474
24475         # Place data in file for read
24476         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24477                 error "parallel dio write failed"
24478
24479         # Fail read on OST0, first stripe
24480         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24481         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24482         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24483                 error "parallel dio read with error on first stripe succeeded"
24484         rm -f $DIR/$tfile.2
24485         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24486
24487         # Switch to testing on OST1, second stripe
24488         # Clear file contents, maintain striping
24489         echo > $DIR/$tfile
24490         # Set up failure on OST1, second stripe:
24491         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24492         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24493
24494         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24495                 error "parallel dio write with failure on first stripe succeeded"
24496         stack_trap "rm -f $DIR/$tfile"
24497         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24498
24499         # Place data in file for read
24500         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24501                 error "parallel dio write failed"
24502
24503         # Fail read on OST1, second stripe
24504         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24505         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24506         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24507                 error "parallel dio read with error on first stripe succeeded"
24508         rm -f $DIR/$tfile.2
24509         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24510 }
24511 run_test 398m "test RPC failures with parallel dio"
24512
24513 # Parallel submission of DIO should not cause problems for append, but it's
24514 # important to verify.
24515 test_398n() { #  LU-13798
24516         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24517
24518         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24519                 error "dd to create source file failed"
24520         stack_trap "rm -f $DIR/$tfile"
24521
24522         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24523                 error "parallel dio write with failure on second stripe succeeded"
24524         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24525         diff $DIR/$tfile $DIR/$tfile.1
24526         [[ $? == 0 ]] || error "data incorrect after append"
24527
24528 }
24529 run_test 398n "test append with parallel DIO"
24530
24531 test_fake_rw() {
24532         local read_write=$1
24533         if [ "$read_write" = "write" ]; then
24534                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24535         elif [ "$read_write" = "read" ]; then
24536                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24537         else
24538                 error "argument error"
24539         fi
24540
24541         # turn off debug for performance testing
24542         local saved_debug=$($LCTL get_param -n debug)
24543         $LCTL set_param debug=0
24544
24545         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24546
24547         # get ost1 size - $FSNAME-OST0000
24548         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24549         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24550         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24551
24552         if [ "$read_write" = "read" ]; then
24553                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24554         fi
24555
24556         local start_time=$(date +%s.%N)
24557         $dd_cmd bs=1M count=$blocks oflag=sync ||
24558                 error "real dd $read_write error"
24559         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24560
24561         if [ "$read_write" = "write" ]; then
24562                 rm -f $DIR/$tfile
24563         fi
24564
24565         # define OBD_FAIL_OST_FAKE_RW           0x238
24566         do_facet ost1 $LCTL set_param fail_loc=0x238
24567
24568         local start_time=$(date +%s.%N)
24569         $dd_cmd bs=1M count=$blocks oflag=sync ||
24570                 error "fake dd $read_write error"
24571         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24572
24573         if [ "$read_write" = "write" ]; then
24574                 # verify file size
24575                 cancel_lru_locks osc
24576                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24577                         error "$tfile size not $blocks MB"
24578         fi
24579         do_facet ost1 $LCTL set_param fail_loc=0
24580
24581         echo "fake $read_write $duration_fake vs. normal $read_write" \
24582                 "$duration in seconds"
24583         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24584                 error_not_in_vm "fake write is slower"
24585
24586         $LCTL set_param -n debug="$saved_debug"
24587         rm -f $DIR/$tfile
24588 }
24589 test_399a() { # LU-7655 for OST fake write
24590         remote_ost_nodsh && skip "remote OST with nodsh"
24591
24592         test_fake_rw write
24593 }
24594 run_test 399a "fake write should not be slower than normal write"
24595
24596 test_399b() { # LU-8726 for OST fake read
24597         remote_ost_nodsh && skip "remote OST with nodsh"
24598         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24599                 skip_env "ldiskfs only test"
24600         fi
24601
24602         test_fake_rw read
24603 }
24604 run_test 399b "fake read should not be slower than normal read"
24605
24606 test_400a() { # LU-1606, was conf-sanity test_74
24607         if ! which $CC > /dev/null 2>&1; then
24608                 skip_env "$CC is not installed"
24609         fi
24610
24611         local extra_flags=''
24612         local out=$TMP/$tfile
24613         local prefix=/usr/include/lustre
24614         local prog
24615
24616         # Oleg removes c files in his test rig so test if any c files exist
24617         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24618                 skip_env "Needed c test files are missing"
24619
24620         if ! [[ -d $prefix ]]; then
24621                 # Assume we're running in tree and fixup the include path.
24622                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24623                 extra_flags+=" -L$LUSTRE/utils/.lib"
24624         fi
24625
24626         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24627                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24628                         error "client api broken"
24629         done
24630         rm -f $out
24631 }
24632 run_test 400a "Lustre client api program can compile and link"
24633
24634 test_400b() { # LU-1606, LU-5011
24635         local header
24636         local out=$TMP/$tfile
24637         local prefix=/usr/include/linux/lustre
24638
24639         # We use a hard coded prefix so that this test will not fail
24640         # when run in tree. There are headers in lustre/include/lustre/
24641         # that are not packaged (like lustre_idl.h) and have more
24642         # complicated include dependencies (like config.h and lnet/types.h).
24643         # Since this test about correct packaging we just skip them when
24644         # they don't exist (see below) rather than try to fixup cppflags.
24645
24646         if ! which $CC > /dev/null 2>&1; then
24647                 skip_env "$CC is not installed"
24648         fi
24649
24650         for header in $prefix/*.h; do
24651                 if ! [[ -f "$header" ]]; then
24652                         continue
24653                 fi
24654
24655                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24656                         continue # lustre_ioctl.h is internal header
24657                 fi
24658
24659                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24660                         error "cannot compile '$header'"
24661         done
24662         rm -f $out
24663 }
24664 run_test 400b "packaged headers can be compiled"
24665
24666 test_401a() { #LU-7437
24667         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24668         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24669
24670         #count the number of parameters by "list_param -R"
24671         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24672         #count the number of parameters by listing proc files
24673         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24674         echo "proc_dirs='$proc_dirs'"
24675         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24676         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24677                       sort -u | wc -l)
24678
24679         [ $params -eq $procs ] ||
24680                 error "found $params parameters vs. $procs proc files"
24681
24682         # test the list_param -D option only returns directories
24683         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24684         #count the number of parameters by listing proc directories
24685         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24686                 sort -u | wc -l)
24687
24688         [ $params -eq $procs ] ||
24689                 error "found $params parameters vs. $procs proc files"
24690 }
24691 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24692
24693 test_401b() {
24694         # jobid_var may not allow arbitrary values, so use jobid_name
24695         # if available
24696         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24697                 local testname=jobid_name tmp='testing%p'
24698         else
24699                 local testname=jobid_var tmp=testing
24700         fi
24701
24702         local save=$($LCTL get_param -n $testname)
24703
24704         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24705                 error "no error returned when setting bad parameters"
24706
24707         local jobid_new=$($LCTL get_param -n foe $testname baz)
24708         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24709
24710         $LCTL set_param -n fog=bam $testname=$save bat=fog
24711         local jobid_old=$($LCTL get_param -n foe $testname bag)
24712         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24713 }
24714 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24715
24716 test_401c() {
24717         # jobid_var may not allow arbitrary values, so use jobid_name
24718         # if available
24719         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24720                 local testname=jobid_name
24721         else
24722                 local testname=jobid_var
24723         fi
24724
24725         local jobid_var_old=$($LCTL get_param -n $testname)
24726         local jobid_var_new
24727
24728         $LCTL set_param $testname= &&
24729                 error "no error returned for 'set_param a='"
24730
24731         jobid_var_new=$($LCTL get_param -n $testname)
24732         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24733                 error "$testname was changed by setting without value"
24734
24735         $LCTL set_param $testname &&
24736                 error "no error returned for 'set_param a'"
24737
24738         jobid_var_new=$($LCTL get_param -n $testname)
24739         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24740                 error "$testname was changed by setting without value"
24741 }
24742 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24743
24744 test_401d() {
24745         # jobid_var may not allow arbitrary values, so use jobid_name
24746         # if available
24747         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24748                 local testname=jobid_name new_value='foo=bar%p'
24749         else
24750                 local testname=jobid_var new_valuie=foo=bar
24751         fi
24752
24753         local jobid_var_old=$($LCTL get_param -n $testname)
24754         local jobid_var_new
24755
24756         $LCTL set_param $testname=$new_value ||
24757                 error "'set_param a=b' did not accept a value containing '='"
24758
24759         jobid_var_new=$($LCTL get_param -n $testname)
24760         [[ "$jobid_var_new" == "$new_value" ]] ||
24761                 error "'set_param a=b' failed on a value containing '='"
24762
24763         # Reset the $testname to test the other format
24764         $LCTL set_param $testname=$jobid_var_old
24765         jobid_var_new=$($LCTL get_param -n $testname)
24766         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24767                 error "failed to reset $testname"
24768
24769         $LCTL set_param $testname $new_value ||
24770                 error "'set_param a b' did not accept a value containing '='"
24771
24772         jobid_var_new=$($LCTL get_param -n $testname)
24773         [[ "$jobid_var_new" == "$new_value" ]] ||
24774                 error "'set_param a b' failed on a value containing '='"
24775
24776         $LCTL set_param $testname $jobid_var_old
24777         jobid_var_new=$($LCTL get_param -n $testname)
24778         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24779                 error "failed to reset $testname"
24780 }
24781 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24782
24783 test_401e() { # LU-14779
24784         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24785                 error "lctl list_param MGC* failed"
24786         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24787         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24788                 error "lctl get_param lru_size failed"
24789 }
24790 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24791
24792 test_402() {
24793         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24794         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24795                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24796         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24797                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24798                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24799         remote_mds_nodsh && skip "remote MDS with nodsh"
24800
24801         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24802 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24803         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24804         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24805                 echo "Touch failed - OK"
24806 }
24807 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24808
24809 test_403() {
24810         local file1=$DIR/$tfile.1
24811         local file2=$DIR/$tfile.2
24812         local tfile=$TMP/$tfile
24813
24814         rm -f $file1 $file2 $tfile
24815
24816         touch $file1
24817         ln $file1 $file2
24818
24819         # 30 sec OBD_TIMEOUT in ll_getattr()
24820         # right before populating st_nlink
24821         $LCTL set_param fail_loc=0x80001409
24822         stat -c %h $file1 > $tfile &
24823
24824         # create an alias, drop all locks and reclaim the dentry
24825         < $file2
24826         cancel_lru_locks mdc
24827         cancel_lru_locks osc
24828         sysctl -w vm.drop_caches=2
24829
24830         wait
24831
24832         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24833
24834         rm -f $tfile $file1 $file2
24835 }
24836 run_test 403 "i_nlink should not drop to zero due to aliasing"
24837
24838 test_404() { # LU-6601
24839         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24840                 skip "Need server version newer than 2.8.52"
24841         remote_mds_nodsh && skip "remote MDS with nodsh"
24842
24843         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24844                 awk '/osp .*-osc-MDT/ { print $4}')
24845
24846         local osp
24847         for osp in $mosps; do
24848                 echo "Deactivate: " $osp
24849                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24850                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24851                         awk -vp=$osp '$4 == p { print $2 }')
24852                 [ $stat = IN ] || {
24853                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24854                         error "deactivate error"
24855                 }
24856                 echo "Activate: " $osp
24857                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24858                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24859                         awk -vp=$osp '$4 == p { print $2 }')
24860                 [ $stat = UP ] || {
24861                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24862                         error "activate error"
24863                 }
24864         done
24865 }
24866 run_test 404 "validate manual {de}activated works properly for OSPs"
24867
24868 test_405() {
24869         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24870         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24871                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24872                         skip "Layout swap lock is not supported"
24873
24874         check_swap_layouts_support
24875         check_swap_layout_no_dom $DIR
24876
24877         test_mkdir $DIR/$tdir
24878         swap_lock_test -d $DIR/$tdir ||
24879                 error "One layout swap locked test failed"
24880 }
24881 run_test 405 "Various layout swap lock tests"
24882
24883 test_406() {
24884         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24885         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24886         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24888         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24889                 skip "Need MDS version at least 2.8.50"
24890
24891         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24892         local test_pool=$TESTNAME
24893
24894         pool_add $test_pool || error "pool_add failed"
24895         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24896                 error "pool_add_targets failed"
24897
24898         save_layout_restore_at_exit $MOUNT
24899
24900         # parent set default stripe count only, child will stripe from both
24901         # parent and fs default
24902         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24903                 error "setstripe $MOUNT failed"
24904         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24905         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24906         for i in $(seq 10); do
24907                 local f=$DIR/$tdir/$tfile.$i
24908                 touch $f || error "touch failed"
24909                 local count=$($LFS getstripe -c $f)
24910                 [ $count -eq $OSTCOUNT ] ||
24911                         error "$f stripe count $count != $OSTCOUNT"
24912                 local offset=$($LFS getstripe -i $f)
24913                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24914                 local size=$($LFS getstripe -S $f)
24915                 [ $size -eq $((def_stripe_size * 2)) ] ||
24916                         error "$f stripe size $size != $((def_stripe_size * 2))"
24917                 local pool=$($LFS getstripe -p $f)
24918                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24919         done
24920
24921         # change fs default striping, delete parent default striping, now child
24922         # will stripe from new fs default striping only
24923         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24924                 error "change $MOUNT default stripe failed"
24925         $LFS setstripe -c 0 $DIR/$tdir ||
24926                 error "delete $tdir default stripe failed"
24927         for i in $(seq 11 20); do
24928                 local f=$DIR/$tdir/$tfile.$i
24929                 touch $f || error "touch $f failed"
24930                 local count=$($LFS getstripe -c $f)
24931                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24932                 local offset=$($LFS getstripe -i $f)
24933                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24934                 local size=$($LFS getstripe -S $f)
24935                 [ $size -eq $def_stripe_size ] ||
24936                         error "$f stripe size $size != $def_stripe_size"
24937                 local pool=$($LFS getstripe -p $f)
24938                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24939         done
24940
24941         unlinkmany $DIR/$tdir/$tfile. 1 20
24942
24943         local f=$DIR/$tdir/$tfile
24944         pool_remove_all_targets $test_pool $f
24945         pool_remove $test_pool $f
24946 }
24947 run_test 406 "DNE support fs default striping"
24948
24949 test_407() {
24950         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24951         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24952                 skip "Need MDS version at least 2.8.55"
24953         remote_mds_nodsh && skip "remote MDS with nodsh"
24954
24955         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24956                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24957         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24958                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24959         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24960
24961         #define OBD_FAIL_DT_TXN_STOP    0x2019
24962         for idx in $(seq $MDSCOUNT); do
24963                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24964         done
24965         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24966         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24967                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24968         true
24969 }
24970 run_test 407 "transaction fail should cause operation fail"
24971
24972 test_408() {
24973         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24974
24975         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24976         lctl set_param fail_loc=0x8000040a
24977         # let ll_prepare_partial_page() fail
24978         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24979
24980         rm -f $DIR/$tfile
24981
24982         # create at least 100 unused inodes so that
24983         # shrink_icache_memory(0) should not return 0
24984         touch $DIR/$tfile-{0..100}
24985         rm -f $DIR/$tfile-{0..100}
24986         sync
24987
24988         echo 2 > /proc/sys/vm/drop_caches
24989 }
24990 run_test 408 "drop_caches should not hang due to page leaks"
24991
24992 test_409()
24993 {
24994         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24995
24996         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24997         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24998         touch $DIR/$tdir/guard || error "(2) Fail to create"
24999
25000         local PREFIX=$(str_repeat 'A' 128)
25001         echo "Create 1K hard links start at $(date)"
25002         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25003                 error "(3) Fail to hard link"
25004
25005         echo "Links count should be right although linkEA overflow"
25006         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25007         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25008         [ $linkcount -eq 1001 ] ||
25009                 error "(5) Unexpected hard links count: $linkcount"
25010
25011         echo "List all links start at $(date)"
25012         ls -l $DIR/$tdir/foo > /dev/null ||
25013                 error "(6) Fail to list $DIR/$tdir/foo"
25014
25015         echo "Unlink hard links start at $(date)"
25016         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25017                 error "(7) Fail to unlink"
25018         echo "Unlink hard links finished at $(date)"
25019 }
25020 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25021
25022 test_410()
25023 {
25024         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25025                 skip "Need client version at least 2.9.59"
25026         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25027                 skip "Need MODULES build"
25028
25029         # Create a file, and stat it from the kernel
25030         local testfile=$DIR/$tfile
25031         touch $testfile
25032
25033         local run_id=$RANDOM
25034         local my_ino=$(stat --format "%i" $testfile)
25035
25036         # Try to insert the module. This will always fail as the
25037         # module is designed to not be inserted.
25038         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25039             &> /dev/null
25040
25041         # Anything but success is a test failure
25042         dmesg | grep -q \
25043             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25044             error "no inode match"
25045 }
25046 run_test 410 "Test inode number returned from kernel thread"
25047
25048 cleanup_test411_cgroup() {
25049         trap 0
25050         rmdir "$1"
25051 }
25052
25053 test_411() {
25054         local cg_basedir=/sys/fs/cgroup/memory
25055         # LU-9966
25056         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25057                 skip "no setup for cgroup"
25058
25059         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25060                 error "test file creation failed"
25061         cancel_lru_locks osc
25062
25063         # Create a very small memory cgroup to force a slab allocation error
25064         local cgdir=$cg_basedir/osc_slab_alloc
25065         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25066         trap "cleanup_test411_cgroup $cgdir" EXIT
25067         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25068         echo 1M > $cgdir/memory.limit_in_bytes
25069
25070         # Should not LBUG, just be killed by oom-killer
25071         # dd will return 0 even allocation failure in some environment.
25072         # So don't check return value
25073         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25074         cleanup_test411_cgroup $cgdir
25075
25076         return 0
25077 }
25078 run_test 411 "Slab allocation error with cgroup does not LBUG"
25079
25080 test_412() {
25081         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25082         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
25083                 skip "Need server version at least 2.10.55"
25084         fi
25085
25086         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25087                 error "mkdir failed"
25088         $LFS getdirstripe $DIR/$tdir
25089         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25090         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25091                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25092         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25093         [ $stripe_count -eq 2 ] ||
25094                 error "expect 2 get $stripe_count"
25095 }
25096 run_test 412 "mkdir on specific MDTs"
25097
25098 generate_uneven_mdts() {
25099         local threshold=$1
25100         local lmv_qos_maxage
25101         local lod_qos_maxage
25102         local ffree
25103         local bavail
25104         local max
25105         local min
25106         local max_index
25107         local min_index
25108         local tmp
25109         local i
25110
25111         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25112         $LCTL set_param lmv.*.qos_maxage=1
25113         stack_trap "$LCTL set_param \
25114                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25115         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25116                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25117         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25118                 lod.*.mdt_qos_maxage=1
25119         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25120                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25121
25122         echo
25123         echo "Check for uneven MDTs: "
25124
25125         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25126         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25127         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25128
25129         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25130         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25131         max_index=0
25132         min_index=0
25133         for ((i = 1; i < ${#ffree[@]}; i++)); do
25134                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25135                 if [ $tmp -gt $max ]; then
25136                         max=$tmp
25137                         max_index=$i
25138                 fi
25139                 if [ $tmp -lt $min ]; then
25140                         min=$tmp
25141                         min_index=$i
25142                 fi
25143         done
25144
25145         (( ${ffree[min_index]} > 0 )) ||
25146                 skip "no free files in MDT$min_index"
25147         (( ${ffree[min_index]} < 10000000 )) ||
25148                 skip "too many free files in MDT$min_index"
25149
25150         # Check if we need to generate uneven MDTs
25151         local diff=$(((max - min) * 100 / min))
25152         local testdir=$DIR/$tdir-fillmdt
25153         local start
25154
25155         mkdir -p $testdir
25156
25157         i=0
25158         while (( diff < threshold )); do
25159                 # generate uneven MDTs, create till $threshold% diff
25160                 echo -n "weight diff=$diff% must be > $threshold% ..."
25161                 echo "Fill MDT$min_index with 1000 files: loop $i"
25162                 testdir=$DIR/$tdir-fillmdt/$i
25163                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25164                         error "mkdir $testdir failed"
25165                 $LFS setstripe -E 1M -L mdt $testdir ||
25166                         error "setstripe $testdir failed"
25167                 start=$SECONDS
25168                 for F in f.{0..999}; do
25169                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25170                                 /dev/null 2>&1 || error "dd $F failed"
25171                 done
25172
25173                 # wait for QOS to update
25174                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25175
25176                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25177                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25178                 max=$(((${ffree[max_index]} >> 8) * \
25179                         (${bavail[max_index]} * bsize >> 16)))
25180                 min=$(((${ffree[min_index]} >> 8) * \
25181                         (${bavail[min_index]} * bsize >> 16)))
25182                 diff=$(((max - min) * 100 / min))
25183                 i=$((i + 1))
25184         done
25185
25186         echo "MDT filesfree available: ${ffree[@]}"
25187         echo "MDT blocks available: ${bavail[@]}"
25188         echo "weight diff=$diff%"
25189 }
25190
25191 test_qos_mkdir() {
25192         local mkdir_cmd=$1
25193         local stripe_count=$2
25194         local mdts=$(comma_list $(mdts_nodes))
25195
25196         local testdir
25197         local lmv_qos_prio_free
25198         local lmv_qos_threshold_rr
25199         local lmv_qos_maxage
25200         local lod_qos_prio_free
25201         local lod_qos_threshold_rr
25202         local lod_qos_maxage
25203         local count
25204         local i
25205
25206         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25207         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25208         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25209                 head -n1)
25210         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25211         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25212         stack_trap "$LCTL set_param \
25213                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25214         stack_trap "$LCTL set_param \
25215                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25216         stack_trap "$LCTL set_param \
25217                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25218
25219         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25220                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25221         lod_qos_prio_free=${lod_qos_prio_free%%%}
25222         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25223                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25224         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25225         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25226                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25227         stack_trap "do_nodes $mdts $LCTL set_param \
25228                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25229         stack_trap "do_nodes $mdts $LCTL set_param \
25230                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25231         stack_trap "do_nodes $mdts $LCTL set_param \
25232                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25233
25234         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25235         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25236
25237         testdir=$DIR/$tdir-s$stripe_count/rr
25238
25239         local stripe_index=$($LFS getstripe -m $testdir)
25240         local test_mkdir_rr=true
25241
25242         getfattr -d -m dmv -e hex $testdir | grep dmv
25243         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25244                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25245                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25246                         test_mkdir_rr=false
25247         fi
25248
25249         echo
25250         $test_mkdir_rr &&
25251                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25252                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25253
25254         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25255         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25256                 eval $mkdir_cmd $testdir/subdir$i ||
25257                         error "$mkdir_cmd subdir$i failed"
25258         done
25259
25260         for (( i = 0; i < $MDSCOUNT; i++ )); do
25261                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25262                 echo "$count directories created on MDT$i"
25263                 if $test_mkdir_rr; then
25264                         (( $count == 100 )) ||
25265                                 error "subdirs are not evenly distributed"
25266                 elif (( $i == $stripe_index )); then
25267                         (( $count == 100 * MDSCOUNT )) ||
25268                                 error "$count subdirs created on MDT$i"
25269                 else
25270                         (( $count == 0 )) ||
25271                                 error "$count subdirs created on MDT$i"
25272                 fi
25273
25274                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25275                         count=$($LFS getdirstripe $testdir/* |
25276                                 grep -c -P "^\s+$i\t")
25277                         echo "$count stripes created on MDT$i"
25278                         # deviation should < 5% of average
25279                         (( $count >= 95 * stripe_count &&
25280                            $count <= 105 * stripe_count)) ||
25281                                 error "stripes are not evenly distributed"
25282                 fi
25283         done
25284
25285         echo
25286         echo "Check for uneven MDTs: "
25287
25288         local ffree
25289         local bavail
25290         local max
25291         local min
25292         local max_index
25293         local min_index
25294         local tmp
25295
25296         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25297         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25298         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25299
25300         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25301         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25302         max_index=0
25303         min_index=0
25304         for ((i = 1; i < ${#ffree[@]}; i++)); do
25305                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25306                 if [ $tmp -gt $max ]; then
25307                         max=$tmp
25308                         max_index=$i
25309                 fi
25310                 if [ $tmp -lt $min ]; then
25311                         min=$tmp
25312                         min_index=$i
25313                 fi
25314         done
25315
25316         (( ${ffree[min_index]} > 0 )) ||
25317                 skip "no free files in MDT$min_index"
25318         (( ${ffree[min_index]} < 10000000 )) ||
25319                 skip "too many free files in MDT$min_index"
25320
25321         echo "MDT filesfree available: ${ffree[@]}"
25322         echo "MDT blocks available: ${bavail[@]}"
25323         echo "weight diff=$(((max - min) * 100 / min))%"
25324         echo
25325         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25326
25327         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25328         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25329         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25330         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25331         # decrease statfs age, so that it can be updated in time
25332         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25333         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25334
25335         sleep 1
25336
25337         testdir=$DIR/$tdir-s$stripe_count/qos
25338         local num=200
25339
25340         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25341         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25342                 eval $mkdir_cmd $testdir/subdir$i ||
25343                         error "$mkdir_cmd subdir$i failed"
25344         done
25345
25346         max=0
25347         for (( i = 0; i < $MDSCOUNT; i++ )); do
25348                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25349                 (( count > max )) && max=$count
25350                 echo "$count directories created on MDT$i"
25351         done
25352
25353         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25354
25355         # D-value should > 10% of averge
25356         (( max - min > num / 10 )) ||
25357                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25358
25359         # ditto for stripes
25360         if (( stripe_count > 1 )); then
25361                 max=0
25362                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25363                         count=$($LFS getdirstripe $testdir/* |
25364                                 grep -c -P "^\s+$i\t")
25365                         (( count > max )) && max=$count
25366                         echo "$count stripes created on MDT$i"
25367                 done
25368
25369                 min=$($LFS getdirstripe $testdir/* |
25370                         grep -c -P "^\s+$min_index\t")
25371                 (( max - min > num * stripe_count / 10 )) ||
25372                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25373         fi
25374 }
25375
25376 most_full_mdt() {
25377         local ffree
25378         local bavail
25379         local bsize
25380         local min
25381         local min_index
25382         local tmp
25383
25384         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25385         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25386         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25387
25388         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25389         min_index=0
25390         for ((i = 1; i < ${#ffree[@]}; i++)); do
25391                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25392                 (( tmp < min )) && min=$tmp && min_index=$i
25393         done
25394
25395         echo -n $min_index
25396 }
25397
25398 test_413a() {
25399         [ $MDSCOUNT -lt 2 ] &&
25400                 skip "We need at least 2 MDTs for this test"
25401
25402         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25403                 skip "Need server version at least 2.12.52"
25404
25405         local stripe_count
25406
25407         generate_uneven_mdts 100
25408         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25409                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25410                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25411                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25412                         error "mkdir failed"
25413                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25414         done
25415 }
25416 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25417
25418 test_413b() {
25419         [ $MDSCOUNT -lt 2 ] &&
25420                 skip "We need at least 2 MDTs for this test"
25421
25422         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25423                 skip "Need server version at least 2.12.52"
25424
25425         local testdir
25426         local stripe_count
25427
25428         generate_uneven_mdts 100
25429         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25430                 testdir=$DIR/$tdir-s$stripe_count
25431                 mkdir $testdir || error "mkdir $testdir failed"
25432                 mkdir $testdir/rr || error "mkdir rr failed"
25433                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25434                         error "mkdir qos failed"
25435                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25436                         $testdir/rr || error "setdirstripe rr failed"
25437                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25438                         error "setdirstripe failed"
25439                 test_qos_mkdir "mkdir" $stripe_count
25440         done
25441 }
25442 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25443
25444 test_413c() {
25445         (( $MDSCOUNT >= 2 )) ||
25446                 skip "We need at least 2 MDTs for this test"
25447
25448         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25449                 skip "Need server version at least 2.14.51"
25450
25451         local testdir
25452         local inherit
25453         local inherit_rr
25454
25455         testdir=$DIR/${tdir}-s1
25456         mkdir $testdir || error "mkdir $testdir failed"
25457         mkdir $testdir/rr || error "mkdir rr failed"
25458         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25459         # default max_inherit is -1, default max_inherit_rr is 0
25460         $LFS setdirstripe -D -c 1 $testdir/rr ||
25461                 error "setdirstripe rr failed"
25462         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25463                 error "setdirstripe qos failed"
25464         test_qos_mkdir "mkdir" 1
25465
25466         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25467         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25468         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25469         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25470         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25471
25472         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25473         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25474         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25475         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25476         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25477         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25478         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25479                 error "level2 shouldn't have default LMV" || true
25480 }
25481 run_test 413c "mkdir with default LMV max inherit rr"
25482
25483 test_413d() {
25484         (( MDSCOUNT >= 2 )) ||
25485                 skip "We need at least 2 MDTs for this test"
25486
25487         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25488                 skip "Need server version at least 2.14.51"
25489
25490         local lmv_qos_threshold_rr
25491
25492         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25493                 head -n1)
25494         stack_trap "$LCTL set_param \
25495                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25496
25497         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25498         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25499         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25500                 error "$tdir shouldn't have default LMV"
25501         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25502                 error "mkdir sub failed"
25503
25504         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25505
25506         (( count == 100 )) || error "$count subdirs on MDT0"
25507 }
25508 run_test 413d "inherit ROOT default LMV"
25509
25510 test_413z() {
25511         local pids=""
25512         local subdir
25513         local pid
25514
25515         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25516                 unlinkmany $subdir/f. 1000 &
25517                 pids="$pids $!"
25518         done
25519
25520         for pid in $pids; do
25521                 wait $pid
25522         done
25523 }
25524 run_test 413z "413 test cleanup"
25525
25526 test_414() {
25527 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25528         $LCTL set_param fail_loc=0x80000521
25529         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25530         rm -f $DIR/$tfile
25531 }
25532 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25533
25534 test_415() {
25535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25536         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25537                 skip "Need server version at least 2.11.52"
25538
25539         # LU-11102
25540         local total
25541         local setattr_pid
25542         local start_time
25543         local end_time
25544         local duration
25545
25546         total=500
25547         # this test may be slow on ZFS
25548         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25549
25550         # though this test is designed for striped directory, let's test normal
25551         # directory too since lock is always saved as CoS lock.
25552         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25553         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25554
25555         (
25556                 while true; do
25557                         touch $DIR/$tdir
25558                 done
25559         ) &
25560         setattr_pid=$!
25561
25562         start_time=$(date +%s)
25563         for i in $(seq $total); do
25564                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25565                         > /dev/null
25566         done
25567         end_time=$(date +%s)
25568         duration=$((end_time - start_time))
25569
25570         kill -9 $setattr_pid
25571
25572         echo "rename $total files took $duration sec"
25573         [ $duration -lt 100 ] || error "rename took $duration sec"
25574 }
25575 run_test 415 "lock revoke is not missing"
25576
25577 test_416() {
25578         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25579                 skip "Need server version at least 2.11.55"
25580
25581         # define OBD_FAIL_OSD_TXN_START    0x19a
25582         do_facet mds1 lctl set_param fail_loc=0x19a
25583
25584         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25585
25586         true
25587 }
25588 run_test 416 "transaction start failure won't cause system hung"
25589
25590 cleanup_417() {
25591         trap 0
25592         do_nodes $(comma_list $(mdts_nodes)) \
25593                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25594         do_nodes $(comma_list $(mdts_nodes)) \
25595                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25596         do_nodes $(comma_list $(mdts_nodes)) \
25597                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25598 }
25599
25600 test_417() {
25601         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25602         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25603                 skip "Need MDS version at least 2.11.56"
25604
25605         trap cleanup_417 RETURN EXIT
25606
25607         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25608         do_nodes $(comma_list $(mdts_nodes)) \
25609                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25610         $LFS migrate -m 0 $DIR/$tdir.1 &&
25611                 error "migrate dir $tdir.1 should fail"
25612
25613         do_nodes $(comma_list $(mdts_nodes)) \
25614                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25615         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25616                 error "create remote dir $tdir.2 should fail"
25617
25618         do_nodes $(comma_list $(mdts_nodes)) \
25619                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25620         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25621                 error "create striped dir $tdir.3 should fail"
25622         true
25623 }
25624 run_test 417 "disable remote dir, striped dir and dir migration"
25625
25626 # Checks that the outputs of df [-i] and lfs df [-i] match
25627 #
25628 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25629 check_lfs_df() {
25630         local dir=$2
25631         local inodes
25632         local df_out
25633         local lfs_df_out
25634         local count
25635         local passed=false
25636
25637         # blocks or inodes
25638         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25639
25640         for count in {1..100}; do
25641                 do_nodes "$CLIENTS" \
25642                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25643                 sync; sleep 0.2
25644
25645                 # read the lines of interest
25646                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25647                         error "df $inodes $dir | tail -n +2 failed"
25648                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25649                         error "lfs df $inodes $dir | grep summary: failed"
25650
25651                 # skip first substrings of each output as they are different
25652                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25653                 # compare the two outputs
25654                 passed=true
25655                 #  skip "available" on MDT until LU-13997 is fixed.
25656                 #for i in {1..5}; do
25657                 for i in 1 2 4 5; do
25658                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25659                 done
25660                 $passed && break
25661         done
25662
25663         if ! $passed; then
25664                 df -P $inodes $dir
25665                 echo
25666                 lfs df $inodes $dir
25667                 error "df and lfs df $1 output mismatch: "      \
25668                       "df ${inodes}: ${df_out[*]}, "            \
25669                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25670         fi
25671 }
25672
25673 test_418() {
25674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25675
25676         local dir=$DIR/$tdir
25677         local numfiles=$((RANDOM % 4096 + 2))
25678         local numblocks=$((RANDOM % 256 + 1))
25679
25680         wait_delete_completed
25681         test_mkdir $dir
25682
25683         # check block output
25684         check_lfs_df blocks $dir
25685         # check inode output
25686         check_lfs_df inodes $dir
25687
25688         # create a single file and retest
25689         echo "Creating a single file and testing"
25690         createmany -o $dir/$tfile- 1 &>/dev/null ||
25691                 error "creating 1 file in $dir failed"
25692         check_lfs_df blocks $dir
25693         check_lfs_df inodes $dir
25694
25695         # create a random number of files
25696         echo "Creating $((numfiles - 1)) files and testing"
25697         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25698                 error "creating $((numfiles - 1)) files in $dir failed"
25699
25700         # write a random number of blocks to the first test file
25701         echo "Writing $numblocks 4K blocks and testing"
25702         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25703                 count=$numblocks &>/dev/null ||
25704                 error "dd to $dir/${tfile}-0 failed"
25705
25706         # retest
25707         check_lfs_df blocks $dir
25708         check_lfs_df inodes $dir
25709
25710         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25711                 error "unlinking $numfiles files in $dir failed"
25712 }
25713 run_test 418 "df and lfs df outputs match"
25714
25715 test_419()
25716 {
25717         local dir=$DIR/$tdir
25718
25719         mkdir -p $dir
25720         touch $dir/file
25721
25722         cancel_lru_locks mdc
25723
25724         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25725         $LCTL set_param fail_loc=0x1410
25726         cat $dir/file
25727         $LCTL set_param fail_loc=0
25728         rm -rf $dir
25729 }
25730 run_test 419 "Verify open file by name doesn't crash kernel"
25731
25732 test_420()
25733 {
25734         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25735                 skip "Need MDS version at least 2.12.53"
25736
25737         local SAVE_UMASK=$(umask)
25738         local dir=$DIR/$tdir
25739         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25740
25741         mkdir -p $dir
25742         umask 0000
25743         mkdir -m03777 $dir/testdir
25744         ls -dn $dir/testdir
25745         # Need to remove trailing '.' when SELinux is enabled
25746         local dirperms=$(ls -dn $dir/testdir |
25747                          awk '{ sub(/\.$/, "", $1); print $1}')
25748         [ $dirperms == "drwxrwsrwt" ] ||
25749                 error "incorrect perms on $dir/testdir"
25750
25751         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25752                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25753         ls -n $dir/testdir/testfile
25754         local fileperms=$(ls -n $dir/testdir/testfile |
25755                           awk '{ sub(/\.$/, "", $1); print $1}')
25756         [ $fileperms == "-rwxr-xr-x" ] ||
25757                 error "incorrect perms on $dir/testdir/testfile"
25758
25759         umask $SAVE_UMASK
25760 }
25761 run_test 420 "clear SGID bit on non-directories for non-members"
25762
25763 test_421a() {
25764         local cnt
25765         local fid1
25766         local fid2
25767
25768         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25769                 skip "Need MDS version at least 2.12.54"
25770
25771         test_mkdir $DIR/$tdir
25772         createmany -o $DIR/$tdir/f 3
25773         cnt=$(ls -1 $DIR/$tdir | wc -l)
25774         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25775
25776         fid1=$(lfs path2fid $DIR/$tdir/f1)
25777         fid2=$(lfs path2fid $DIR/$tdir/f2)
25778         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25779
25780         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25781         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25782
25783         cnt=$(ls -1 $DIR/$tdir | wc -l)
25784         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25785
25786         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25787         createmany -o $DIR/$tdir/f 3
25788         cnt=$(ls -1 $DIR/$tdir | wc -l)
25789         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25790
25791         fid1=$(lfs path2fid $DIR/$tdir/f1)
25792         fid2=$(lfs path2fid $DIR/$tdir/f2)
25793         echo "remove using fsname $FSNAME"
25794         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25795
25796         cnt=$(ls -1 $DIR/$tdir | wc -l)
25797         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25798 }
25799 run_test 421a "simple rm by fid"
25800
25801 test_421b() {
25802         local cnt
25803         local FID1
25804         local FID2
25805
25806         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25807                 skip "Need MDS version at least 2.12.54"
25808
25809         test_mkdir $DIR/$tdir
25810         createmany -o $DIR/$tdir/f 3
25811         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25812         MULTIPID=$!
25813
25814         FID1=$(lfs path2fid $DIR/$tdir/f1)
25815         FID2=$(lfs path2fid $DIR/$tdir/f2)
25816         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25817
25818         kill -USR1 $MULTIPID
25819         wait
25820
25821         cnt=$(ls $DIR/$tdir | wc -l)
25822         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25823 }
25824 run_test 421b "rm by fid on open file"
25825
25826 test_421c() {
25827         local cnt
25828         local FIDS
25829
25830         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25831                 skip "Need MDS version at least 2.12.54"
25832
25833         test_mkdir $DIR/$tdir
25834         createmany -o $DIR/$tdir/f 3
25835         touch $DIR/$tdir/$tfile
25836         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25837         cnt=$(ls -1 $DIR/$tdir | wc -l)
25838         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25839
25840         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25841         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25842
25843         cnt=$(ls $DIR/$tdir | wc -l)
25844         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25845 }
25846 run_test 421c "rm by fid against hardlinked files"
25847
25848 test_421d() {
25849         local cnt
25850         local FIDS
25851
25852         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25853                 skip "Need MDS version at least 2.12.54"
25854
25855         test_mkdir $DIR/$tdir
25856         createmany -o $DIR/$tdir/f 4097
25857         cnt=$(ls -1 $DIR/$tdir | wc -l)
25858         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25859
25860         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25861         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25862
25863         cnt=$(ls $DIR/$tdir | wc -l)
25864         rm -rf $DIR/$tdir
25865         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25866 }
25867 run_test 421d "rmfid en masse"
25868
25869 test_421e() {
25870         local cnt
25871         local FID
25872
25873         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25874         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25875                 skip "Need MDS version at least 2.12.54"
25876
25877         mkdir -p $DIR/$tdir
25878         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25879         createmany -o $DIR/$tdir/striped_dir/f 512
25880         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25881         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25882
25883         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25884                 sed "s/[/][^:]*://g")
25885         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25886
25887         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25888         rm -rf $DIR/$tdir
25889         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25890 }
25891 run_test 421e "rmfid in DNE"
25892
25893 test_421f() {
25894         local cnt
25895         local FID
25896
25897         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25898                 skip "Need MDS version at least 2.12.54"
25899
25900         test_mkdir $DIR/$tdir
25901         touch $DIR/$tdir/f
25902         cnt=$(ls -1 $DIR/$tdir | wc -l)
25903         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25904
25905         FID=$(lfs path2fid $DIR/$tdir/f)
25906         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25907         # rmfid should fail
25908         cnt=$(ls -1 $DIR/$tdir | wc -l)
25909         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25910
25911         chmod a+rw $DIR/$tdir
25912         ls -la $DIR/$tdir
25913         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25914         # rmfid should fail
25915         cnt=$(ls -1 $DIR/$tdir | wc -l)
25916         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25917
25918         rm -f $DIR/$tdir/f
25919         $RUNAS touch $DIR/$tdir/f
25920         FID=$(lfs path2fid $DIR/$tdir/f)
25921         echo "rmfid as root"
25922         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25923         cnt=$(ls -1 $DIR/$tdir | wc -l)
25924         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25925
25926         rm -f $DIR/$tdir/f
25927         $RUNAS touch $DIR/$tdir/f
25928         cnt=$(ls -1 $DIR/$tdir | wc -l)
25929         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25930         FID=$(lfs path2fid $DIR/$tdir/f)
25931         # rmfid w/o user_fid2path mount option should fail
25932         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25933         cnt=$(ls -1 $DIR/$tdir | wc -l)
25934         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25935
25936         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25937         stack_trap "rmdir $tmpdir"
25938         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25939                 error "failed to mount client'"
25940         stack_trap "umount_client $tmpdir"
25941
25942         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25943         # rmfid should succeed
25944         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25945         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25946
25947         # rmfid shouldn't allow to remove files due to dir's permission
25948         chmod a+rwx $tmpdir/$tdir
25949         touch $tmpdir/$tdir/f
25950         ls -la $tmpdir/$tdir
25951         FID=$(lfs path2fid $tmpdir/$tdir/f)
25952         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25953         return 0
25954 }
25955 run_test 421f "rmfid checks permissions"
25956
25957 test_421g() {
25958         local cnt
25959         local FIDS
25960
25961         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25962         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25963                 skip "Need MDS version at least 2.12.54"
25964
25965         mkdir -p $DIR/$tdir
25966         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25967         createmany -o $DIR/$tdir/striped_dir/f 512
25968         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25969         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25970
25971         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25972                 sed "s/[/][^:]*://g")
25973
25974         rm -f $DIR/$tdir/striped_dir/f1*
25975         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25976         removed=$((512 - cnt))
25977
25978         # few files have been just removed, so we expect
25979         # rmfid to fail on their fids
25980         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25981         [ $removed != $errors ] && error "$errors != $removed"
25982
25983         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25984         rm -rf $DIR/$tdir
25985         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25986 }
25987 run_test 421g "rmfid to return errors properly"
25988
25989 test_422() {
25990         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25991         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25992         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25993         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25994         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25995
25996         local amc=$(at_max_get client)
25997         local amo=$(at_max_get mds1)
25998         local timeout=`lctl get_param -n timeout`
25999
26000         at_max_set 0 client
26001         at_max_set 0 mds1
26002
26003 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26004         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26005                         fail_val=$(((2*timeout + 10)*1000))
26006         touch $DIR/$tdir/d3/file &
26007         sleep 2
26008 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26009         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26010                         fail_val=$((2*timeout + 5))
26011         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26012         local pid=$!
26013         sleep 1
26014         kill -9 $pid
26015         sleep $((2 * timeout))
26016         echo kill $pid
26017         kill -9 $pid
26018         lctl mark touch
26019         touch $DIR/$tdir/d2/file3
26020         touch $DIR/$tdir/d2/file4
26021         touch $DIR/$tdir/d2/file5
26022
26023         wait
26024         at_max_set $amc client
26025         at_max_set $amo mds1
26026
26027         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26028         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26029                 error "Watchdog is always throttled"
26030 }
26031 run_test 422 "kill a process with RPC in progress"
26032
26033 stat_test() {
26034     df -h $MOUNT &
26035     df -h $MOUNT &
26036     df -h $MOUNT &
26037     df -h $MOUNT &
26038     df -h $MOUNT &
26039     df -h $MOUNT &
26040 }
26041
26042 test_423() {
26043     local _stats
26044     # ensure statfs cache is expired
26045     sleep 2;
26046
26047     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26048     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26049
26050     return 0
26051 }
26052 run_test 423 "statfs should return a right data"
26053
26054 test_424() {
26055 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26056         $LCTL set_param fail_loc=0x80000522
26057         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26058         rm -f $DIR/$tfile
26059 }
26060 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26061
26062 test_425() {
26063         test_mkdir -c -1 $DIR/$tdir
26064         $LFS setstripe -c -1 $DIR/$tdir
26065
26066         lru_resize_disable "" 100
26067         stack_trap "lru_resize_enable" EXIT
26068
26069         sleep 5
26070
26071         for i in $(seq $((MDSCOUNT * 125))); do
26072                 local t=$DIR/$tdir/$tfile_$i
26073
26074                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26075                         error_noexit "Create file $t"
26076         done
26077         stack_trap "rm -rf $DIR/$tdir" EXIT
26078
26079         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26080                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26081                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26082
26083                 [ $lock_count -le $lru_size ] ||
26084                         error "osc lock count $lock_count > lru size $lru_size"
26085         done
26086
26087         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26088                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26089                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26090
26091                 [ $lock_count -le $lru_size ] ||
26092                         error "mdc lock count $lock_count > lru size $lru_size"
26093         done
26094 }
26095 run_test 425 "lock count should not exceed lru size"
26096
26097 test_426() {
26098         splice-test -r $DIR/$tfile
26099         splice-test -rd $DIR/$tfile
26100         splice-test $DIR/$tfile
26101         splice-test -d $DIR/$tfile
26102 }
26103 run_test 426 "splice test on Lustre"
26104
26105 test_427() {
26106         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26107         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26108                 skip "Need MDS version at least 2.12.4"
26109         local log
26110
26111         mkdir $DIR/$tdir
26112         mkdir $DIR/$tdir/1
26113         mkdir $DIR/$tdir/2
26114         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26115         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26116
26117         $LFS getdirstripe $DIR/$tdir/1/dir
26118
26119         #first setfattr for creating updatelog
26120         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26121
26122 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26123         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26124         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26125         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26126
26127         sleep 2
26128         fail mds2
26129         wait_recovery_complete mds2 $((2*TIMEOUT))
26130
26131         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26132         echo $log | grep "get update log failed" &&
26133                 error "update log corruption is detected" || true
26134 }
26135 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26136
26137 test_428() {
26138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26139         local cache_limit=$CACHE_MAX
26140
26141         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26142         $LCTL set_param -n llite.*.max_cached_mb=64
26143
26144         mkdir $DIR/$tdir
26145         $LFS setstripe -c 1 $DIR/$tdir
26146         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26147         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26148         #test write
26149         for f in $(seq 4); do
26150                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26151         done
26152         wait
26153
26154         cancel_lru_locks osc
26155         # Test read
26156         for f in $(seq 4); do
26157                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26158         done
26159         wait
26160 }
26161 run_test 428 "large block size IO should not hang"
26162
26163 test_429() { # LU-7915 / LU-10948
26164         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26165         local testfile=$DIR/$tfile
26166         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26167         local new_flag=1
26168         local first_rpc
26169         local second_rpc
26170         local third_rpc
26171
26172         $LCTL get_param $ll_opencache_threshold_count ||
26173                 skip "client does not have opencache parameter"
26174
26175         set_opencache $new_flag
26176         stack_trap "restore_opencache"
26177         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26178                 error "enable opencache failed"
26179         touch $testfile
26180         # drop MDC DLM locks
26181         cancel_lru_locks mdc
26182         # clear MDC RPC stats counters
26183         $LCTL set_param $mdc_rpcstats=clear
26184
26185         # According to the current implementation, we need to run 3 times
26186         # open & close file to verify if opencache is enabled correctly.
26187         # 1st, RPCs are sent for lookup/open and open handle is released on
26188         #      close finally.
26189         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26190         #      so open handle won't be released thereafter.
26191         # 3rd, No RPC is sent out.
26192         $MULTIOP $testfile oc || error "multiop failed"
26193         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26194         echo "1st: $first_rpc RPCs in flight"
26195
26196         $MULTIOP $testfile oc || error "multiop failed"
26197         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26198         echo "2nd: $second_rpc RPCs in flight"
26199
26200         $MULTIOP $testfile oc || error "multiop failed"
26201         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26202         echo "3rd: $third_rpc RPCs in flight"
26203
26204         #verify no MDC RPC is sent
26205         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26206 }
26207 run_test 429 "verify if opencache flag on client side does work"
26208
26209 lseek_test_430() {
26210         local offset
26211         local file=$1
26212
26213         # data at [200K, 400K)
26214         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26215                 error "256K->512K dd fails"
26216         # data at [2M, 3M)
26217         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26218                 error "2M->3M dd fails"
26219         # data at [4M, 5M)
26220         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26221                 error "4M->5M dd fails"
26222         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26223         # start at first component hole #1
26224         printf "Seeking hole from 1000 ... "
26225         offset=$(lseek_test -l 1000 $file)
26226         echo $offset
26227         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26228         printf "Seeking data from 1000 ... "
26229         offset=$(lseek_test -d 1000 $file)
26230         echo $offset
26231         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26232
26233         # start at first component data block
26234         printf "Seeking hole from 300000 ... "
26235         offset=$(lseek_test -l 300000 $file)
26236         echo $offset
26237         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26238         printf "Seeking data from 300000 ... "
26239         offset=$(lseek_test -d 300000 $file)
26240         echo $offset
26241         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26242
26243         # start at the first component but beyond end of object size
26244         printf "Seeking hole from 1000000 ... "
26245         offset=$(lseek_test -l 1000000 $file)
26246         echo $offset
26247         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26248         printf "Seeking data from 1000000 ... "
26249         offset=$(lseek_test -d 1000000 $file)
26250         echo $offset
26251         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26252
26253         # start at second component stripe 2 (empty file)
26254         printf "Seeking hole from 1500000 ... "
26255         offset=$(lseek_test -l 1500000 $file)
26256         echo $offset
26257         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26258         printf "Seeking data from 1500000 ... "
26259         offset=$(lseek_test -d 1500000 $file)
26260         echo $offset
26261         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26262
26263         # start at second component stripe 1 (all data)
26264         printf "Seeking hole from 3000000 ... "
26265         offset=$(lseek_test -l 3000000 $file)
26266         echo $offset
26267         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26268         printf "Seeking data from 3000000 ... "
26269         offset=$(lseek_test -d 3000000 $file)
26270         echo $offset
26271         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26272
26273         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26274                 error "2nd dd fails"
26275         echo "Add data block at 640K...1280K"
26276
26277         # start at before new data block, in hole
26278         printf "Seeking hole from 600000 ... "
26279         offset=$(lseek_test -l 600000 $file)
26280         echo $offset
26281         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26282         printf "Seeking data from 600000 ... "
26283         offset=$(lseek_test -d 600000 $file)
26284         echo $offset
26285         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26286
26287         # start at the first component new data block
26288         printf "Seeking hole from 1000000 ... "
26289         offset=$(lseek_test -l 1000000 $file)
26290         echo $offset
26291         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26292         printf "Seeking data from 1000000 ... "
26293         offset=$(lseek_test -d 1000000 $file)
26294         echo $offset
26295         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26296
26297         # start at second component stripe 2, new data
26298         printf "Seeking hole from 1200000 ... "
26299         offset=$(lseek_test -l 1200000 $file)
26300         echo $offset
26301         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26302         printf "Seeking data from 1200000 ... "
26303         offset=$(lseek_test -d 1200000 $file)
26304         echo $offset
26305         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26306
26307         # start beyond file end
26308         printf "Using offset > filesize ... "
26309         lseek_test -l 4000000 $file && error "lseek should fail"
26310         printf "Using offset > filesize ... "
26311         lseek_test -d 4000000 $file && error "lseek should fail"
26312
26313         printf "Done\n\n"
26314 }
26315
26316 test_430a() {
26317         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26318                 skip "MDT does not support SEEK_HOLE"
26319
26320         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26321                 skip "OST does not support SEEK_HOLE"
26322
26323         local file=$DIR/$tdir/$tfile
26324
26325         mkdir -p $DIR/$tdir
26326
26327         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26328         # OST stripe #1 will have continuous data at [1M, 3M)
26329         # OST stripe #2 is empty
26330         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26331         lseek_test_430 $file
26332         rm $file
26333         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26334         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26335         lseek_test_430 $file
26336         rm $file
26337         $LFS setstripe -c2 -S 512K $file
26338         echo "Two stripes, stripe size 512K"
26339         lseek_test_430 $file
26340         rm $file
26341         # FLR with stale mirror
26342         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26343                        -N -c2 -S 1M $file
26344         echo "Mirrored file:"
26345         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26346         echo "Plain 2 stripes 1M"
26347         lseek_test_430 $file
26348         rm $file
26349 }
26350 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26351
26352 test_430b() {
26353         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26354                 skip "OST does not support SEEK_HOLE"
26355
26356         local offset
26357         local file=$DIR/$tdir/$tfile
26358
26359         mkdir -p $DIR/$tdir
26360         # Empty layout lseek should fail
26361         $MCREATE $file
26362         # seek from 0
26363         printf "Seeking hole from 0 ... "
26364         lseek_test -l 0 $file && error "lseek should fail"
26365         printf "Seeking data from 0 ... "
26366         lseek_test -d 0 $file && error "lseek should fail"
26367         rm $file
26368
26369         # 1M-hole file
26370         $LFS setstripe -E 1M -c2 -E eof $file
26371         $TRUNCATE $file 1048576
26372         printf "Seeking hole from 1000000 ... "
26373         offset=$(lseek_test -l 1000000 $file)
26374         echo $offset
26375         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26376         printf "Seeking data from 1000000 ... "
26377         lseek_test -d 1000000 $file && error "lseek should fail"
26378         rm $file
26379
26380         # full component followed by non-inited one
26381         $LFS setstripe -E 1M -c2 -E eof $file
26382         dd if=/dev/urandom of=$file bs=1M count=1
26383         printf "Seeking hole from 1000000 ... "
26384         offset=$(lseek_test -l 1000000 $file)
26385         echo $offset
26386         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26387         printf "Seeking hole from 1048576 ... "
26388         lseek_test -l 1048576 $file && error "lseek should fail"
26389         # init second component and truncate back
26390         echo "123" >> $file
26391         $TRUNCATE $file 1048576
26392         printf "Seeking hole from 1000000 ... "
26393         offset=$(lseek_test -l 1000000 $file)
26394         echo $offset
26395         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26396         printf "Seeking hole from 1048576 ... "
26397         lseek_test -l 1048576 $file && error "lseek should fail"
26398         # boundary checks for big values
26399         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26400         offset=$(lseek_test -d 0 $file.10g)
26401         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26402         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26403         offset=$(lseek_test -d 0 $file.100g)
26404         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26405         return 0
26406 }
26407 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26408
26409 test_430c() {
26410         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26411                 skip "OST does not support SEEK_HOLE"
26412
26413         local file=$DIR/$tdir/$tfile
26414         local start
26415
26416         mkdir -p $DIR/$tdir
26417         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26418
26419         # cp version 8.33+ prefers lseek over fiemap
26420         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26421                 start=$SECONDS
26422                 time cp $file /dev/null
26423                 (( SECONDS - start < 5 )) ||
26424                         error "cp: too long runtime $((SECONDS - start))"
26425
26426         fi
26427         # tar version 1.29+ supports SEEK_HOLE/DATA
26428         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26429                 start=$SECONDS
26430                 time tar cS $file - | cat > /dev/null
26431                 (( SECONDS - start < 5 )) ||
26432                         error "tar: too long runtime $((SECONDS - start))"
26433         fi
26434 }
26435 run_test 430c "lseek: external tools check"
26436
26437 test_431() { # LU-14187
26438         local file=$DIR/$tdir/$tfile
26439
26440         mkdir -p $DIR/$tdir
26441         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26442         dd if=/dev/urandom of=$file bs=4k count=1
26443         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26444         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26445         #define OBD_FAIL_OST_RESTART_IO 0x251
26446         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26447         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26448         cp $file $file.0
26449         cancel_lru_locks
26450         sync_all_data
26451         echo 3 > /proc/sys/vm/drop_caches
26452         diff  $file $file.0 || error "data diff"
26453 }
26454 run_test 431 "Restart transaction for IO"
26455
26456 cleanup_test_432() {
26457         do_facet mgs $LCTL nodemap_activate 0
26458         wait_nm_sync active
26459 }
26460
26461 test_432() {
26462         local tmpdir=$TMP/dir432
26463
26464         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26465                 skip "Need MDS version at least 2.14.52"
26466
26467         stack_trap cleanup_test_432 EXIT
26468         mkdir $DIR/$tdir
26469         mkdir $tmpdir
26470
26471         do_facet mgs $LCTL nodemap_activate 1
26472         wait_nm_sync active
26473         do_facet mgs $LCTL nodemap_modify --name default \
26474                 --property admin --value 1
26475         do_facet mgs $LCTL nodemap_modify --name default \
26476                 --property trusted --value 1
26477         cancel_lru_locks mdc
26478         wait_nm_sync default admin_nodemap
26479         wait_nm_sync default trusted_nodemap
26480
26481         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26482                grep -ci "Operation not permitted") -ne 0 ]; then
26483                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26484         fi
26485 }
26486 run_test 432 "mv dir from outside Lustre"
26487
26488 prep_801() {
26489         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26490         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26491                 skip "Need server version at least 2.9.55"
26492
26493         start_full_debug_logging
26494 }
26495
26496 post_801() {
26497         stop_full_debug_logging
26498 }
26499
26500 barrier_stat() {
26501         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26502                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26503                            awk '/The barrier for/ { print $7 }')
26504                 echo $st
26505         else
26506                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26507                 echo \'$st\'
26508         fi
26509 }
26510
26511 barrier_expired() {
26512         local expired
26513
26514         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26515                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26516                           awk '/will be expired/ { print $7 }')
26517         else
26518                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26519         fi
26520
26521         echo $expired
26522 }
26523
26524 test_801a() {
26525         prep_801
26526
26527         echo "Start barrier_freeze at: $(date)"
26528         #define OBD_FAIL_BARRIER_DELAY          0x2202
26529         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26530         # Do not reduce barrier time - See LU-11873
26531         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26532
26533         sleep 2
26534         local b_status=$(barrier_stat)
26535         echo "Got barrier status at: $(date)"
26536         [ "$b_status" = "'freezing_p1'" ] ||
26537                 error "(1) unexpected barrier status $b_status"
26538
26539         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26540         wait
26541         b_status=$(barrier_stat)
26542         [ "$b_status" = "'frozen'" ] ||
26543                 error "(2) unexpected barrier status $b_status"
26544
26545         local expired=$(barrier_expired)
26546         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26547         sleep $((expired + 3))
26548
26549         b_status=$(barrier_stat)
26550         [ "$b_status" = "'expired'" ] ||
26551                 error "(3) unexpected barrier status $b_status"
26552
26553         # Do not reduce barrier time - See LU-11873
26554         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26555                 error "(4) fail to freeze barrier"
26556
26557         b_status=$(barrier_stat)
26558         [ "$b_status" = "'frozen'" ] ||
26559                 error "(5) unexpected barrier status $b_status"
26560
26561         echo "Start barrier_thaw at: $(date)"
26562         #define OBD_FAIL_BARRIER_DELAY          0x2202
26563         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26564         do_facet mgs $LCTL barrier_thaw $FSNAME &
26565
26566         sleep 2
26567         b_status=$(barrier_stat)
26568         echo "Got barrier status at: $(date)"
26569         [ "$b_status" = "'thawing'" ] ||
26570                 error "(6) unexpected barrier status $b_status"
26571
26572         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26573         wait
26574         b_status=$(barrier_stat)
26575         [ "$b_status" = "'thawed'" ] ||
26576                 error "(7) unexpected barrier status $b_status"
26577
26578         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26579         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26580         do_facet mgs $LCTL barrier_freeze $FSNAME
26581
26582         b_status=$(barrier_stat)
26583         [ "$b_status" = "'failed'" ] ||
26584                 error "(8) unexpected barrier status $b_status"
26585
26586         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26587         do_facet mgs $LCTL barrier_thaw $FSNAME
26588
26589         post_801
26590 }
26591 run_test 801a "write barrier user interfaces and stat machine"
26592
26593 test_801b() {
26594         prep_801
26595
26596         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26597         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26598         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26599         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26600         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26601
26602         cancel_lru_locks mdc
26603
26604         # 180 seconds should be long enough
26605         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26606
26607         local b_status=$(barrier_stat)
26608         [ "$b_status" = "'frozen'" ] ||
26609                 error "(6) unexpected barrier status $b_status"
26610
26611         mkdir $DIR/$tdir/d0/d10 &
26612         mkdir_pid=$!
26613
26614         touch $DIR/$tdir/d1/f13 &
26615         touch_pid=$!
26616
26617         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26618         ln_pid=$!
26619
26620         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26621         mv_pid=$!
26622
26623         rm -f $DIR/$tdir/d4/f12 &
26624         rm_pid=$!
26625
26626         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26627
26628         # To guarantee taht the 'stat' is not blocked
26629         b_status=$(barrier_stat)
26630         [ "$b_status" = "'frozen'" ] ||
26631                 error "(8) unexpected barrier status $b_status"
26632
26633         # let above commands to run at background
26634         sleep 5
26635
26636         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26637         ps -p $touch_pid || error "(10) touch should be blocked"
26638         ps -p $ln_pid || error "(11) link should be blocked"
26639         ps -p $mv_pid || error "(12) rename should be blocked"
26640         ps -p $rm_pid || error "(13) unlink should be blocked"
26641
26642         b_status=$(barrier_stat)
26643         [ "$b_status" = "'frozen'" ] ||
26644                 error "(14) unexpected barrier status $b_status"
26645
26646         do_facet mgs $LCTL barrier_thaw $FSNAME
26647         b_status=$(barrier_stat)
26648         [ "$b_status" = "'thawed'" ] ||
26649                 error "(15) unexpected barrier status $b_status"
26650
26651         wait $mkdir_pid || error "(16) mkdir should succeed"
26652         wait $touch_pid || error "(17) touch should succeed"
26653         wait $ln_pid || error "(18) link should succeed"
26654         wait $mv_pid || error "(19) rename should succeed"
26655         wait $rm_pid || error "(20) unlink should succeed"
26656
26657         post_801
26658 }
26659 run_test 801b "modification will be blocked by write barrier"
26660
26661 test_801c() {
26662         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26663
26664         prep_801
26665
26666         stop mds2 || error "(1) Fail to stop mds2"
26667
26668         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26669
26670         local b_status=$(barrier_stat)
26671         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26672                 do_facet mgs $LCTL barrier_thaw $FSNAME
26673                 error "(2) unexpected barrier status $b_status"
26674         }
26675
26676         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26677                 error "(3) Fail to rescan barrier bitmap"
26678
26679         # Do not reduce barrier time - See LU-11873
26680         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26681
26682         b_status=$(barrier_stat)
26683         [ "$b_status" = "'frozen'" ] ||
26684                 error "(4) unexpected barrier status $b_status"
26685
26686         do_facet mgs $LCTL barrier_thaw $FSNAME
26687         b_status=$(barrier_stat)
26688         [ "$b_status" = "'thawed'" ] ||
26689                 error "(5) unexpected barrier status $b_status"
26690
26691         local devname=$(mdsdevname 2)
26692
26693         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26694
26695         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26696                 error "(7) Fail to rescan barrier bitmap"
26697
26698         post_801
26699 }
26700 run_test 801c "rescan barrier bitmap"
26701
26702 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26703 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26704 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26705 saved_MOUNT_OPTS=$MOUNT_OPTS
26706
26707 cleanup_802a() {
26708         trap 0
26709
26710         stopall
26711         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26712         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26713         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26714         MOUNT_OPTS=$saved_MOUNT_OPTS
26715         setupall
26716 }
26717
26718 test_802a() {
26719         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26720         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26721         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26722                 skip "Need server version at least 2.9.55"
26723
26724         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26725
26726         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26727
26728         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26729                 error "(2) Fail to copy"
26730
26731         trap cleanup_802a EXIT
26732
26733         # sync by force before remount as readonly
26734         sync; sync_all_data; sleep 3; sync_all_data
26735
26736         stopall
26737
26738         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26739         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26740         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26741
26742         echo "Mount the server as read only"
26743         setupall server_only || error "(3) Fail to start servers"
26744
26745         echo "Mount client without ro should fail"
26746         mount_client $MOUNT &&
26747                 error "(4) Mount client without 'ro' should fail"
26748
26749         echo "Mount client with ro should succeed"
26750         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26751         mount_client $MOUNT ||
26752                 error "(5) Mount client with 'ro' should succeed"
26753
26754         echo "Modify should be refused"
26755         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26756
26757         echo "Read should be allowed"
26758         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26759                 error "(7) Read should succeed under ro mode"
26760
26761         cleanup_802a
26762 }
26763 run_test 802a "simulate readonly device"
26764
26765 test_802b() {
26766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26767         remote_mds_nodsh && skip "remote MDS with nodsh"
26768
26769         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26770                 skip "readonly option not available"
26771
26772         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26773
26774         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26775                 error "(2) Fail to copy"
26776
26777         # write back all cached data before setting MDT to readonly
26778         cancel_lru_locks
26779         sync_all_data
26780
26781         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26782         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26783
26784         echo "Modify should be refused"
26785         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26786
26787         echo "Read should be allowed"
26788         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26789                 error "(7) Read should succeed under ro mode"
26790
26791         # disable readonly
26792         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26793 }
26794 run_test 802b "be able to set MDTs to readonly"
26795
26796 test_803a() {
26797         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26798         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26799                 skip "MDS needs to be newer than 2.10.54"
26800
26801         mkdir_on_mdt0 $DIR/$tdir
26802         # Create some objects on all MDTs to trigger related logs objects
26803         for idx in $(seq $MDSCOUNT); do
26804                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26805                         $DIR/$tdir/dir${idx} ||
26806                         error "Fail to create $DIR/$tdir/dir${idx}"
26807         done
26808
26809         sync; sleep 3
26810         wait_delete_completed # ensure old test cleanups are finished
26811         echo "before create:"
26812         $LFS df -i $MOUNT
26813         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26814
26815         for i in {1..10}; do
26816                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26817                         error "Fail to create $DIR/$tdir/foo$i"
26818         done
26819
26820         sync; sleep 3
26821         echo "after create:"
26822         $LFS df -i $MOUNT
26823         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26824
26825         # allow for an llog to be cleaned up during the test
26826         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26827                 error "before ($before_used) + 10 > after ($after_used)"
26828
26829         for i in {1..10}; do
26830                 rm -rf $DIR/$tdir/foo$i ||
26831                         error "Fail to remove $DIR/$tdir/foo$i"
26832         done
26833
26834         sleep 3 # avoid MDT return cached statfs
26835         wait_delete_completed
26836         echo "after unlink:"
26837         $LFS df -i $MOUNT
26838         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26839
26840         # allow for an llog to be created during the test
26841         [ $after_used -le $((before_used + 1)) ] ||
26842                 error "after ($after_used) > before ($before_used) + 1"
26843 }
26844 run_test 803a "verify agent object for remote object"
26845
26846 test_803b() {
26847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26848         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26849                 skip "MDS needs to be newer than 2.13.56"
26850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26851
26852         for i in $(seq 0 $((MDSCOUNT - 1))); do
26853                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26854         done
26855
26856         local before=0
26857         local after=0
26858
26859         local tmp
26860
26861         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26862         for i in $(seq 0 $((MDSCOUNT - 1))); do
26863                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26864                         awk '/getattr/ { print $2 }')
26865                 before=$((before + tmp))
26866         done
26867         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26868         for i in $(seq 0 $((MDSCOUNT - 1))); do
26869                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26870                         awk '/getattr/ { print $2 }')
26871                 after=$((after + tmp))
26872         done
26873
26874         [ $before -eq $after ] || error "getattr count $before != $after"
26875 }
26876 run_test 803b "remote object can getattr from cache"
26877
26878 test_804() {
26879         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26880         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26881                 skip "MDS needs to be newer than 2.10.54"
26882         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26883
26884         mkdir -p $DIR/$tdir
26885         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26886                 error "Fail to create $DIR/$tdir/dir0"
26887
26888         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26889         local dev=$(mdsdevname 2)
26890
26891         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26892                 grep ${fid} || error "NOT found agent entry for dir0"
26893
26894         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26895                 error "Fail to create $DIR/$tdir/dir1"
26896
26897         touch $DIR/$tdir/dir1/foo0 ||
26898                 error "Fail to create $DIR/$tdir/dir1/foo0"
26899         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26900         local rc=0
26901
26902         for idx in $(seq $MDSCOUNT); do
26903                 dev=$(mdsdevname $idx)
26904                 do_facet mds${idx} \
26905                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26906                         grep ${fid} && rc=$idx
26907         done
26908
26909         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26910                 error "Fail to rename foo0 to foo1"
26911         if [ $rc -eq 0 ]; then
26912                 for idx in $(seq $MDSCOUNT); do
26913                         dev=$(mdsdevname $idx)
26914                         do_facet mds${idx} \
26915                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26916                         grep ${fid} && rc=$idx
26917                 done
26918         fi
26919
26920         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26921                 error "Fail to rename foo1 to foo2"
26922         if [ $rc -eq 0 ]; then
26923                 for idx in $(seq $MDSCOUNT); do
26924                         dev=$(mdsdevname $idx)
26925                         do_facet mds${idx} \
26926                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26927                         grep ${fid} && rc=$idx
26928                 done
26929         fi
26930
26931         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26932
26933         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26934                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26935         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26936                 error "Fail to rename foo2 to foo0"
26937         unlink $DIR/$tdir/dir1/foo0 ||
26938                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26939         rm -rf $DIR/$tdir/dir0 ||
26940                 error "Fail to rm $DIR/$tdir/dir0"
26941
26942         for idx in $(seq $MDSCOUNT); do
26943                 dev=$(mdsdevname $idx)
26944                 rc=0
26945
26946                 stop mds${idx}
26947                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26948                         rc=$?
26949                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26950                         error "mount mds$idx failed"
26951                 df $MOUNT > /dev/null 2>&1
26952
26953                 # e2fsck should not return error
26954                 [ $rc -eq 0 ] ||
26955                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26956         done
26957 }
26958 run_test 804 "verify agent entry for remote entry"
26959
26960 cleanup_805() {
26961         do_facet $SINGLEMDS zfs set quota=$old $fsset
26962         unlinkmany $DIR/$tdir/f- 1000000
26963         trap 0
26964 }
26965
26966 test_805() {
26967         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26968         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26969         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26970                 skip "netfree not implemented before 0.7"
26971         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26972                 skip "Need MDS version at least 2.10.57"
26973
26974         local fsset
26975         local freekb
26976         local usedkb
26977         local old
26978         local quota
26979         local pref="osd-zfs.$FSNAME-MDT0000."
26980
26981         # limit available space on MDS dataset to meet nospace issue
26982         # quickly. then ZFS 0.7.2 can use reserved space if asked
26983         # properly (using netfree flag in osd_declare_destroy()
26984         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26985         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26986                 gawk '{print $3}')
26987         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26988         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26989         let "usedkb=usedkb-freekb"
26990         let "freekb=freekb/2"
26991         if let "freekb > 5000"; then
26992                 let "freekb=5000"
26993         fi
26994         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26995         trap cleanup_805 EXIT
26996         mkdir_on_mdt0 $DIR/$tdir
26997         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26998                 error "Can't set PFL layout"
26999         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27000         rm -rf $DIR/$tdir || error "not able to remove"
27001         do_facet $SINGLEMDS zfs set quota=$old $fsset
27002         trap 0
27003 }
27004 run_test 805 "ZFS can remove from full fs"
27005
27006 # Size-on-MDS test
27007 check_lsom_data()
27008 {
27009         local file=$1
27010         local expect=$(stat -c %s $file)
27011
27012         check_lsom_size $1 $expect
27013
27014         local blocks=$($LFS getsom -b $file)
27015         expect=$(stat -c %b $file)
27016         [[ $blocks == $expect ]] ||
27017                 error "$file expected blocks: $expect, got: $blocks"
27018 }
27019
27020 check_lsom_size()
27021 {
27022         local size
27023         local expect=$2
27024
27025         cancel_lru_locks mdc
27026
27027         size=$($LFS getsom -s $1)
27028         [[ $size == $expect ]] ||
27029                 error "$file expected size: $expect, got: $size"
27030 }
27031
27032 test_806() {
27033         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27034                 skip "Need MDS version at least 2.11.52"
27035
27036         local bs=1048576
27037
27038         touch $DIR/$tfile || error "touch $tfile failed"
27039
27040         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27041         save_lustre_params client "llite.*.xattr_cache" > $save
27042         lctl set_param llite.*.xattr_cache=0
27043         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27044
27045         # single-threaded write
27046         echo "Test SOM for single-threaded write"
27047         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27048                 error "write $tfile failed"
27049         check_lsom_size $DIR/$tfile $bs
27050
27051         local num=32
27052         local size=$(($num * $bs))
27053         local offset=0
27054         local i
27055
27056         echo "Test SOM for single client multi-threaded($num) write"
27057         $TRUNCATE $DIR/$tfile 0
27058         for ((i = 0; i < $num; i++)); do
27059                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27060                 local pids[$i]=$!
27061                 offset=$((offset + $bs))
27062         done
27063         for (( i=0; i < $num; i++ )); do
27064                 wait ${pids[$i]}
27065         done
27066         check_lsom_size $DIR/$tfile $size
27067
27068         $TRUNCATE $DIR/$tfile 0
27069         for ((i = 0; i < $num; i++)); do
27070                 offset=$((offset - $bs))
27071                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27072                 local pids[$i]=$!
27073         done
27074         for (( i=0; i < $num; i++ )); do
27075                 wait ${pids[$i]}
27076         done
27077         check_lsom_size $DIR/$tfile $size
27078
27079         # multi-client writes
27080         num=$(get_node_count ${CLIENTS//,/ })
27081         size=$(($num * $bs))
27082         offset=0
27083         i=0
27084
27085         echo "Test SOM for multi-client ($num) writes"
27086         $TRUNCATE $DIR/$tfile 0
27087         for client in ${CLIENTS//,/ }; do
27088                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27089                 local pids[$i]=$!
27090                 i=$((i + 1))
27091                 offset=$((offset + $bs))
27092         done
27093         for (( i=0; i < $num; i++ )); do
27094                 wait ${pids[$i]}
27095         done
27096         check_lsom_size $DIR/$tfile $offset
27097
27098         i=0
27099         $TRUNCATE $DIR/$tfile 0
27100         for client in ${CLIENTS//,/ }; do
27101                 offset=$((offset - $bs))
27102                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27103                 local pids[$i]=$!
27104                 i=$((i + 1))
27105         done
27106         for (( i=0; i < $num; i++ )); do
27107                 wait ${pids[$i]}
27108         done
27109         check_lsom_size $DIR/$tfile $size
27110
27111         # verify truncate
27112         echo "Test SOM for truncate"
27113         $TRUNCATE $DIR/$tfile 1048576
27114         check_lsom_size $DIR/$tfile 1048576
27115         $TRUNCATE $DIR/$tfile 1234
27116         check_lsom_size $DIR/$tfile 1234
27117
27118         # verify SOM blocks count
27119         echo "Verify SOM block count"
27120         $TRUNCATE $DIR/$tfile 0
27121         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27122                 error "failed to write file $tfile"
27123         check_lsom_data $DIR/$tfile
27124 }
27125 run_test 806 "Verify Lazy Size on MDS"
27126
27127 test_807() {
27128         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27129         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27130                 skip "Need MDS version at least 2.11.52"
27131
27132         # Registration step
27133         changelog_register || error "changelog_register failed"
27134         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27135         changelog_users $SINGLEMDS | grep -q $cl_user ||
27136                 error "User $cl_user not found in changelog_users"
27137
27138         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27139         save_lustre_params client "llite.*.xattr_cache" > $save
27140         lctl set_param llite.*.xattr_cache=0
27141         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27142
27143         rm -rf $DIR/$tdir || error "rm $tdir failed"
27144         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27145         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27146         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27147         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27148                 error "truncate $tdir/trunc failed"
27149
27150         local bs=1048576
27151         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27152                 error "write $tfile failed"
27153
27154         # multi-client wirtes
27155         local num=$(get_node_count ${CLIENTS//,/ })
27156         local offset=0
27157         local i=0
27158
27159         echo "Test SOM for multi-client ($num) writes"
27160         touch $DIR/$tfile || error "touch $tfile failed"
27161         $TRUNCATE $DIR/$tfile 0
27162         for client in ${CLIENTS//,/ }; do
27163                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27164                 local pids[$i]=$!
27165                 i=$((i + 1))
27166                 offset=$((offset + $bs))
27167         done
27168         for (( i=0; i < $num; i++ )); do
27169                 wait ${pids[$i]}
27170         done
27171
27172         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27173         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27174         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27175         check_lsom_data $DIR/$tdir/trunc
27176         check_lsom_data $DIR/$tdir/single_dd
27177         check_lsom_data $DIR/$tfile
27178
27179         rm -rf $DIR/$tdir
27180         # Deregistration step
27181         changelog_deregister || error "changelog_deregister failed"
27182 }
27183 run_test 807 "verify LSOM syncing tool"
27184
27185 check_som_nologged()
27186 {
27187         local lines=$($LFS changelog $FSNAME-MDT0000 |
27188                 grep 'x=trusted.som' | wc -l)
27189         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27190 }
27191
27192 test_808() {
27193         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27194                 skip "Need MDS version at least 2.11.55"
27195
27196         # Registration step
27197         changelog_register || error "changelog_register failed"
27198
27199         touch $DIR/$tfile || error "touch $tfile failed"
27200         check_som_nologged
27201
27202         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27203                 error "write $tfile failed"
27204         check_som_nologged
27205
27206         $TRUNCATE $DIR/$tfile 1234
27207         check_som_nologged
27208
27209         $TRUNCATE $DIR/$tfile 1048576
27210         check_som_nologged
27211
27212         # Deregistration step
27213         changelog_deregister || error "changelog_deregister failed"
27214 }
27215 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27216
27217 check_som_nodata()
27218 {
27219         $LFS getsom $1
27220         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27221 }
27222
27223 test_809() {
27224         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27225                 skip "Need MDS version at least 2.11.56"
27226
27227         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27228                 error "failed to create DoM-only file $DIR/$tfile"
27229         touch $DIR/$tfile || error "touch $tfile failed"
27230         check_som_nodata $DIR/$tfile
27231
27232         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27233                 error "write $tfile failed"
27234         check_som_nodata $DIR/$tfile
27235
27236         $TRUNCATE $DIR/$tfile 1234
27237         check_som_nodata $DIR/$tfile
27238
27239         $TRUNCATE $DIR/$tfile 4097
27240         check_som_nodata $DIR/$file
27241 }
27242 run_test 809 "Verify no SOM xattr store for DoM-only files"
27243
27244 test_810() {
27245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27246         $GSS && skip_env "could not run with gss"
27247         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27248                 skip "OST < 2.12.58 doesn't align checksum"
27249
27250         set_checksums 1
27251         stack_trap "set_checksums $ORIG_CSUM" EXIT
27252         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27253
27254         local csum
27255         local before
27256         local after
27257         for csum in $CKSUM_TYPES; do
27258                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27259                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27260                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27261                         eval set -- $i
27262                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27263                         before=$(md5sum $DIR/$tfile)
27264                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27265                         after=$(md5sum $DIR/$tfile)
27266                         [ "$before" == "$after" ] ||
27267                                 error "$csum: $before != $after bs=$1 seek=$2"
27268                 done
27269         done
27270 }
27271 run_test 810 "partial page writes on ZFS (LU-11663)"
27272
27273 test_812a() {
27274         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27275                 skip "OST < 2.12.51 doesn't support this fail_loc"
27276
27277         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27278         # ensure ost1 is connected
27279         stat $DIR/$tfile >/dev/null || error "can't stat"
27280         wait_osc_import_state client ost1 FULL
27281         # no locks, no reqs to let the connection idle
27282         cancel_lru_locks osc
27283
27284         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27285 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27286         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27287         wait_osc_import_state client ost1 CONNECTING
27288         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27289
27290         stat $DIR/$tfile >/dev/null || error "can't stat file"
27291 }
27292 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27293
27294 test_812b() { # LU-12378
27295         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27296                 skip "OST < 2.12.51 doesn't support this fail_loc"
27297
27298         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27299         # ensure ost1 is connected
27300         stat $DIR/$tfile >/dev/null || error "can't stat"
27301         wait_osc_import_state client ost1 FULL
27302         # no locks, no reqs to let the connection idle
27303         cancel_lru_locks osc
27304
27305         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27306 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27307         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27308         wait_osc_import_state client ost1 CONNECTING
27309         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27310
27311         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27312         wait_osc_import_state client ost1 IDLE
27313 }
27314 run_test 812b "do not drop no resend request for idle connect"
27315
27316 test_812c() {
27317         local old
27318
27319         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27320
27321         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27322         $LFS getstripe $DIR/$tfile
27323         $LCTL set_param osc.*.idle_timeout=10
27324         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27325         # ensure ost1 is connected
27326         stat $DIR/$tfile >/dev/null || error "can't stat"
27327         wait_osc_import_state client ost1 FULL
27328         # no locks, no reqs to let the connection idle
27329         cancel_lru_locks osc
27330
27331 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27332         $LCTL set_param fail_loc=0x80000533
27333         sleep 15
27334         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27335 }
27336 run_test 812c "idle import vs lock enqueue race"
27337
27338 test_813() {
27339         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27340         [ -z "$file_heat_sav" ] && skip "no file heat support"
27341
27342         local readsample
27343         local writesample
27344         local readbyte
27345         local writebyte
27346         local readsample1
27347         local writesample1
27348         local readbyte1
27349         local writebyte1
27350
27351         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27352         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27353
27354         $LCTL set_param -n llite.*.file_heat=1
27355         echo "Turn on file heat"
27356         echo "Period second: $period_second, Decay percentage: $decay_pct"
27357
27358         echo "QQQQ" > $DIR/$tfile
27359         echo "QQQQ" > $DIR/$tfile
27360         echo "QQQQ" > $DIR/$tfile
27361         cat $DIR/$tfile > /dev/null
27362         cat $DIR/$tfile > /dev/null
27363         cat $DIR/$tfile > /dev/null
27364         cat $DIR/$tfile > /dev/null
27365
27366         local out=$($LFS heat_get $DIR/$tfile)
27367
27368         $LFS heat_get $DIR/$tfile
27369         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27370         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27371         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27372         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27373
27374         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27375         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27376         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27377         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27378
27379         sleep $((period_second + 3))
27380         echo "Sleep $((period_second + 3)) seconds..."
27381         # The recursion formula to calculate the heat of the file f is as
27382         # follow:
27383         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27384         # Where Hi is the heat value in the period between time points i*I and
27385         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27386         # to the weight of Ci.
27387         out=$($LFS heat_get $DIR/$tfile)
27388         $LFS heat_get $DIR/$tfile
27389         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27390         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27391         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27392         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27393
27394         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27395                 error "read sample ($readsample) is wrong"
27396         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27397                 error "write sample ($writesample) is wrong"
27398         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27399                 error "read bytes ($readbyte) is wrong"
27400         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27401                 error "write bytes ($writebyte) is wrong"
27402
27403         echo "QQQQ" > $DIR/$tfile
27404         echo "QQQQ" > $DIR/$tfile
27405         echo "QQQQ" > $DIR/$tfile
27406         cat $DIR/$tfile > /dev/null
27407         cat $DIR/$tfile > /dev/null
27408         cat $DIR/$tfile > /dev/null
27409         cat $DIR/$tfile > /dev/null
27410
27411         sleep $((period_second + 3))
27412         echo "Sleep $((period_second + 3)) seconds..."
27413
27414         out=$($LFS heat_get $DIR/$tfile)
27415         $LFS heat_get $DIR/$tfile
27416         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27417         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27418         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27419         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27420
27421         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27422                 4 * $decay_pct) / 100") -eq 1 ] ||
27423                 error "read sample ($readsample1) is wrong"
27424         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27425                 3 * $decay_pct) / 100") -eq 1 ] ||
27426                 error "write sample ($writesample1) is wrong"
27427         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27428                 20 * $decay_pct) / 100") -eq 1 ] ||
27429                 error "read bytes ($readbyte1) is wrong"
27430         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27431                 15 * $decay_pct) / 100") -eq 1 ] ||
27432                 error "write bytes ($writebyte1) is wrong"
27433
27434         echo "Turn off file heat for the file $DIR/$tfile"
27435         $LFS heat_set -o $DIR/$tfile
27436
27437         echo "QQQQ" > $DIR/$tfile
27438         echo "QQQQ" > $DIR/$tfile
27439         echo "QQQQ" > $DIR/$tfile
27440         cat $DIR/$tfile > /dev/null
27441         cat $DIR/$tfile > /dev/null
27442         cat $DIR/$tfile > /dev/null
27443         cat $DIR/$tfile > /dev/null
27444
27445         out=$($LFS heat_get $DIR/$tfile)
27446         $LFS heat_get $DIR/$tfile
27447         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27448         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27449         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27450         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27451
27452         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27453         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27454         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27455         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27456
27457         echo "Trun on file heat for the file $DIR/$tfile"
27458         $LFS heat_set -O $DIR/$tfile
27459
27460         echo "QQQQ" > $DIR/$tfile
27461         echo "QQQQ" > $DIR/$tfile
27462         echo "QQQQ" > $DIR/$tfile
27463         cat $DIR/$tfile > /dev/null
27464         cat $DIR/$tfile > /dev/null
27465         cat $DIR/$tfile > /dev/null
27466         cat $DIR/$tfile > /dev/null
27467
27468         out=$($LFS heat_get $DIR/$tfile)
27469         $LFS heat_get $DIR/$tfile
27470         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27471         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27472         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27473         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27474
27475         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27476         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27477         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27478         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27479
27480         $LFS heat_set -c $DIR/$tfile
27481         $LCTL set_param -n llite.*.file_heat=0
27482         echo "Turn off file heat support for the Lustre filesystem"
27483
27484         echo "QQQQ" > $DIR/$tfile
27485         echo "QQQQ" > $DIR/$tfile
27486         echo "QQQQ" > $DIR/$tfile
27487         cat $DIR/$tfile > /dev/null
27488         cat $DIR/$tfile > /dev/null
27489         cat $DIR/$tfile > /dev/null
27490         cat $DIR/$tfile > /dev/null
27491
27492         out=$($LFS heat_get $DIR/$tfile)
27493         $LFS heat_get $DIR/$tfile
27494         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27495         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27496         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27497         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27498
27499         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27500         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27501         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27502         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27503
27504         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27505         rm -f $DIR/$tfile
27506 }
27507 run_test 813 "File heat verfication"
27508
27509 test_814()
27510 {
27511         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27512         echo -n y >> $DIR/$tfile
27513         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27514         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27515 }
27516 run_test 814 "sparse cp works as expected (LU-12361)"
27517
27518 test_815()
27519 {
27520         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27521         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27522 }
27523 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27524
27525 test_816() {
27526         local ost1_imp=$(get_osc_import_name client ost1)
27527         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27528                          cut -d'.' -f2)
27529
27530         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27531         # ensure ost1 is connected
27532
27533         stat $DIR/$tfile >/dev/null || error "can't stat"
27534         wait_osc_import_state client ost1 FULL
27535         # no locks, no reqs to let the connection idle
27536         cancel_lru_locks osc
27537         lru_resize_disable osc
27538         local before
27539         local now
27540         before=$($LCTL get_param -n \
27541                  ldlm.namespaces.$imp_name.lru_size)
27542
27543         wait_osc_import_state client ost1 IDLE
27544         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27545         now=$($LCTL get_param -n \
27546               ldlm.namespaces.$imp_name.lru_size)
27547         [ $before == $now ] || error "lru_size changed $before != $now"
27548 }
27549 run_test 816 "do not reset lru_resize on idle reconnect"
27550
27551 cleanup_817() {
27552         umount $tmpdir
27553         exportfs -u localhost:$DIR/nfsexp
27554         rm -rf $DIR/nfsexp
27555 }
27556
27557 test_817() {
27558         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27559
27560         mkdir -p $DIR/nfsexp
27561         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27562                 error "failed to export nfs"
27563
27564         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27565         stack_trap cleanup_817 EXIT
27566
27567         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27568                 error "failed to mount nfs to $tmpdir"
27569
27570         cp /bin/true $tmpdir
27571         $DIR/nfsexp/true || error "failed to execute 'true' command"
27572 }
27573 run_test 817 "nfsd won't cache write lock for exec file"
27574
27575 test_818() {
27576         test_mkdir -i0 -c1 $DIR/$tdir
27577         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27578         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27579         stop $SINGLEMDS
27580
27581         # restore osp-syn threads
27582         stack_trap "fail $SINGLEMDS"
27583
27584         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27585         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27586         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27587                 error "start $SINGLEMDS failed"
27588         rm -rf $DIR/$tdir
27589
27590         local testid=$(echo $TESTNAME | tr '_' ' ')
27591
27592         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27593                 grep "run LFSCK" || error "run LFSCK is not suggested"
27594 }
27595 run_test 818 "unlink with failed llog"
27596
27597 test_819a() {
27598         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27599         cancel_lru_locks osc
27600         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27601         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27602         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27603         rm -f $TDIR/$tfile
27604 }
27605 run_test 819a "too big niobuf in read"
27606
27607 test_819b() {
27608         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27609         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27610         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27611         cancel_lru_locks osc
27612         sleep 1
27613         rm -f $TDIR/$tfile
27614 }
27615 run_test 819b "too big niobuf in write"
27616
27617
27618 function test_820_start_ost() {
27619         sleep 5
27620
27621         for num in $(seq $OSTCOUNT); do
27622                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27623         done
27624 }
27625
27626 test_820() {
27627         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27628
27629         mkdir $DIR/$tdir
27630         umount_client $MOUNT || error "umount failed"
27631         for num in $(seq $OSTCOUNT); do
27632                 stop ost$num
27633         done
27634
27635         # mount client with no active OSTs
27636         # so that the client can't initialize max LOV EA size
27637         # from OSC notifications
27638         mount_client $MOUNT || error "mount failed"
27639         # delay OST starting to keep this 0 max EA size for a while
27640         test_820_start_ost &
27641
27642         # create a directory on MDS2
27643         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27644                 error "Failed to create directory"
27645         # open intent should update default EA size
27646         # see mdc_update_max_ea_from_body()
27647         # notice this is the very first RPC to MDS2
27648         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27649         ret=$?
27650         echo $out
27651         # With SSK, this situation can lead to -EPERM being returned.
27652         # In that case, simply retry.
27653         if [ $ret -ne 0 ] && $SHARED_KEY; then
27654                 if echo "$out" | grep -q "not permitted"; then
27655                         cp /etc/services $DIR/$tdir/mds2
27656                         ret=$?
27657                 fi
27658         fi
27659         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27660 }
27661 run_test 820 "update max EA from open intent"
27662
27663 test_822() {
27664         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27665
27666         save_lustre_params mds1 \
27667                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27668         do_facet $SINGLEMDS "$LCTL set_param -n \
27669                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27670         do_facet $SINGLEMDS "$LCTL set_param -n \
27671                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27672
27673         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27674         local maxage=$(do_facet mds1 $LCTL get_param -n \
27675                        osp.$FSNAME-OST0000*MDT0000.maxage)
27676         sleep $((maxage + 1))
27677
27678         #define OBD_FAIL_NET_ERROR_RPC          0x532
27679         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27680
27681         stack_trap "restore_lustre_params < $p; rm $p"
27682
27683         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27684                       osp.$FSNAME-OST0000*MDT0000.create_count")
27685         for i in $(seq 1 $count); do
27686                 touch $DIR/$tfile.${i} || error "touch failed"
27687         done
27688 }
27689 run_test 822 "test precreate failure"
27690
27691 test_823() {
27692         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27693         local OST_MAX_PRECREATE=20000
27694
27695         save_lustre_params mds1 \
27696                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27697         do_facet $SINGLEMDS "$LCTL set_param -n \
27698                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27699         do_facet $SINGLEMDS "$LCTL set_param -n \
27700                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27701
27702         stack_trap "restore_lustre_params < $p; rm $p"
27703
27704         do_facet $SINGLEMDS "$LCTL set_param -n \
27705                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27706
27707         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27708                       osp.$FSNAME-OST0000*MDT0000.create_count")
27709         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27710                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27711         local expect_count=$(((($max/2)/256) * 256))
27712
27713         log "setting create_count to 100200:"
27714         log " -result- count: $count with max: $max, expecting: $expect_count"
27715
27716         [[ $count -eq expect_count ]] ||
27717                 error "Create count not set to max precreate."
27718 }
27719 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27720
27721 test_831() {
27722         local sync_changes=$(do_facet $SINGLEMDS \
27723                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27724
27725         [ "$sync_changes" -gt 100 ] &&
27726                 skip "Sync changes $sync_changes > 100 already"
27727
27728         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27729
27730         $LFS mkdir -i 0 $DIR/$tdir
27731         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27732
27733         save_lustre_params mds1 \
27734                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27735         save_lustre_params mds1 \
27736                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27737
27738         do_facet mds1 "$LCTL set_param -n \
27739                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27740                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27741         stack_trap "restore_lustre_params < $p" EXIT
27742
27743         createmany -o $DIR/$tdir/f- 1000
27744         unlinkmany $DIR/$tdir/f- 1000 &
27745         local UNLINK_PID=$!
27746
27747         while sleep 1; do
27748                 sync_changes=$(do_facet mds1 \
27749                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27750                 # the check in the code is racy, fail the test
27751                 # if the value above the limit by 10.
27752                 [ $sync_changes -gt 110 ] && {
27753                         kill -2 $UNLINK_PID
27754                         wait
27755                         error "osp changes throttling failed, $sync_changes>110"
27756                 }
27757                 kill -0 $UNLINK_PID 2> /dev/null || break
27758         done
27759         wait
27760 }
27761 run_test 831 "throttling unlink/setattr queuing on OSP"
27762
27763 #
27764 # tests that do cleanup/setup should be run at the end
27765 #
27766
27767 test_900() {
27768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27769         local ls
27770
27771         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27772         $LCTL set_param fail_loc=0x903
27773
27774         cancel_lru_locks MGC
27775
27776         FAIL_ON_ERROR=true cleanup
27777         FAIL_ON_ERROR=true setup
27778 }
27779 run_test 900 "umount should not race with any mgc requeue thread"
27780
27781 # LUS-6253/LU-11185
27782 test_901() {
27783         local oldc
27784         local newc
27785         local olds
27786         local news
27787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27788
27789         # some get_param have a bug to handle dot in param name
27790         cancel_lru_locks MGC
27791         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27792         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27793         umount_client $MOUNT || error "umount failed"
27794         mount_client $MOUNT || error "mount failed"
27795         cancel_lru_locks MGC
27796         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27797         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27798
27799         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27800         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27801
27802         return 0
27803 }
27804 run_test 901 "don't leak a mgc lock on client umount"
27805
27806 # LU-13377
27807 test_902() {
27808         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27809                 skip "client does not have LU-13377 fix"
27810         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27811         $LCTL set_param fail_loc=0x1415
27812         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27813         cancel_lru_locks osc
27814         rm -f $DIR/$tfile
27815 }
27816 run_test 902 "test short write doesn't hang lustre"
27817
27818 # LU-14711
27819 test_903() {
27820         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27821         echo "blah" > $DIR/${tfile}-2
27822         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27823         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27824         $LCTL set_param fail_loc=0x417 fail_val=20
27825
27826         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27827         sleep 1 # To start the destroy
27828         wait_destroy_complete 150 || error "Destroy taking too long"
27829         cat $DIR/$tfile > /dev/null || error "Evicted"
27830 }
27831 run_test 903 "Test long page discard does not cause evictions"
27832
27833 complete $SECONDS
27834 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27835 check_and_cleanup_lustre
27836 if [ "$I_MOUNTED" != "yes" ]; then
27837         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27838 fi
27839 exit_status