Whamcloud - gitweb
3039059c0a0b4f5c558321af278a679e8f3d3d2b
[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 rc=0
1188         trap 0
1189         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1190
1191         local start=$SECONDS
1192         rm -rf $DIR/$tdir
1193         rc=$?
1194         wait_delete_completed
1195         echo "cleanup time $((SECONDS - start))"
1196         return $rc
1197 }
1198
1199 max_pages_per_rpc() {
1200         local mdtname="$(printf "MDT%04x" ${1:-0})"
1201         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1202 }
1203
1204 test_24v() {
1205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1206
1207         local nrfiles=${COUNT:-100000}
1208         local fname="$DIR/$tdir/$tfile"
1209
1210         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1211         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1212
1213         test_mkdir "$(dirname $fname)"
1214         # assume MDT0000 has the fewest inodes
1215         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1216         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1217         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1218
1219         trap simple_cleanup_common EXIT
1220
1221         createmany -m "$fname" $nrfiles
1222
1223         cancel_lru_locks mdc
1224         lctl set_param mdc.*.stats clear
1225
1226         # was previously test_24D: LU-6101
1227         # readdir() returns correct number of entries after cursor reload
1228         local num_ls=$(ls $DIR/$tdir | wc -l)
1229         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1230         local num_all=$(ls -a $DIR/$tdir | wc -l)
1231         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1232                 [ $num_all -ne $((nrfiles + 2)) ]; then
1233                         error "Expected $nrfiles files, got $num_ls " \
1234                                 "($num_uniq unique $num_all .&..)"
1235         fi
1236         # LU-5 large readdir
1237         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1238         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1239         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1240         # take into account of overhead in lu_dirpage header and end mark in
1241         # each page, plus one in rpc_num calculation.
1242         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1243         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1244         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1245         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1246         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1247         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1248         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1249         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1250                 error "large readdir doesn't take effect: " \
1251                       "$mds_readpage should be about $rpc_max"
1252
1253         simple_cleanup_common
1254 }
1255 run_test 24v "list large directory (test hash collision, b=17560)"
1256
1257 test_24w() { # bug21506
1258         SZ1=234852
1259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1260         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1261         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1262         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1263         [[ "$SZ1" -eq "$SZ2" ]] ||
1264                 error "Error reading at the end of the file $tfile"
1265 }
1266 run_test 24w "Reading a file larger than 4Gb"
1267
1268 test_24x() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1272                 skip "Need MDS version at least 2.7.56"
1273
1274         local MDTIDX=1
1275         local remote_dir=$DIR/$tdir/remote_dir
1276
1277         test_mkdir $DIR/$tdir
1278         $LFS mkdir -i $MDTIDX $remote_dir ||
1279                 error "create remote directory failed"
1280
1281         test_mkdir $DIR/$tdir/src_dir
1282         touch $DIR/$tdir/src_file
1283         test_mkdir $remote_dir/tgt_dir
1284         touch $remote_dir/tgt_file
1285
1286         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1287                 error "rename dir cross MDT failed!"
1288
1289         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1290                 error "rename file cross MDT failed!"
1291
1292         touch $DIR/$tdir/ln_file
1293         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1294                 error "ln file cross MDT failed"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24x "cross MDT rename/link"
1299
1300 test_24y() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1303
1304         local remote_dir=$DIR/$tdir/remote_dir
1305         local mdtidx=1
1306
1307         test_mkdir $DIR/$tdir
1308         $LFS mkdir -i $mdtidx $remote_dir ||
1309                 error "create remote directory failed"
1310
1311         test_mkdir $remote_dir/src_dir
1312         touch $remote_dir/src_file
1313         test_mkdir $remote_dir/tgt_dir
1314         touch $remote_dir/tgt_file
1315
1316         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1317                 error "rename subdir in the same remote dir failed!"
1318
1319         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1320                 error "rename files in the same remote dir failed!"
1321
1322         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1323                 error "link files in the same remote dir failed!"
1324
1325         rm -rf $DIR/$tdir || error "Can not delete directories"
1326 }
1327 run_test 24y "rename/link on the same dir should succeed"
1328
1329 test_24z() {
1330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1331         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1332                 skip "Need MDS version at least 2.12.51"
1333
1334         local index
1335
1336         for index in 0 1; do
1337                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1338                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1339         done
1340
1341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1344         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1345
1346         local mdts=$(comma_list $(mdts_nodes))
1347
1348         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1349         stack_trap "do_nodes $mdts $LCTL \
1350                 set_param mdt.*.enable_remote_rename=1" EXIT
1351
1352         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1353
1354         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1355         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1356 }
1357 run_test 24z "cross-MDT rename is done as cp"
1358
1359 test_24A() { # LU-3182
1360         local NFILES=5000
1361
1362         rm -rf $DIR/$tdir
1363         test_mkdir $DIR/$tdir
1364         trap simple_cleanup_common EXIT
1365         createmany -m $DIR/$tdir/$tfile $NFILES
1366         local t=$(ls $DIR/$tdir | wc -l)
1367         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1368         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1369         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1370            [ $v -ne $((NFILES + 2)) ] ; then
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372         fi
1373
1374         simple_cleanup_common || error "Can not delete directories"
1375 }
1376 run_test 24A "readdir() returns correct number of entries."
1377
1378 test_24B() { # LU-4805
1379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1380
1381         local count
1382
1383         test_mkdir $DIR/$tdir
1384         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1385                 error "create striped dir failed"
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 2 ] || error "Expected 2, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/a
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 3 ] || error "Expected 3, got $count"
1394
1395         touch $DIR/$tdir/striped_dir/.f
1396
1397         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1398         [ $count -eq 4 ] || error "Expected 4, got $count"
1399
1400         rm -rf $DIR/$tdir || error "Can not delete directories"
1401 }
1402 run_test 24B "readdir for striped dir return correct number of entries"
1403
1404 test_24C() {
1405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1406
1407         mkdir $DIR/$tdir
1408         mkdir $DIR/$tdir/d0
1409         mkdir $DIR/$tdir/d1
1410
1411         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1412                 error "create striped dir failed"
1413
1414         cd $DIR/$tdir/d0/striped_dir
1415
1416         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1417         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1418         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d0_ino" = "$parent_ino" ] ||
1421                 error ".. wrong, expect $d0_ino, get $parent_ino"
1422
1423         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1424                 error "mv striped dir failed"
1425
1426         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1427
1428         [ "$d1_ino" = "$parent_ino" ] ||
1429                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1430 }
1431 run_test 24C "check .. in striped dir"
1432
1433 test_24E() {
1434         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1436
1437         mkdir -p $DIR/$tdir
1438         mkdir $DIR/$tdir/src_dir
1439         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1440                 error "create remote source failed"
1441
1442         touch $DIR/$tdir/src_dir/src_child/a
1443
1444         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1445                 error "create remote target dir failed"
1446
1447         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "create remote target child failed"
1449
1450         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1451                 error "rename dir cross MDT failed!"
1452
1453         find $DIR/$tdir
1454
1455         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1456                 error "src_child still exists after rename"
1457
1458         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1459                 error "missing file(a) after rename"
1460
1461         rm -rf $DIR/$tdir || error "Can not delete directories"
1462 }
1463 run_test 24E "cross MDT rename/link"
1464
1465 test_24F () {
1466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1467
1468         local repeats=1000
1469         [ "$SLOW" = "no" ] && repeats=100
1470
1471         mkdir -p $DIR/$tdir
1472
1473         echo "$repeats repeats"
1474         for ((i = 0; i < repeats; i++)); do
1475                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1476                 touch $DIR/$tdir/test/a || error "touch fails"
1477                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1478                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1479         done
1480
1481         true
1482 }
1483 run_test 24F "hash order vs readdir (LU-11330)"
1484
1485 test_24G () {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487
1488         local ino1
1489         local ino2
1490
1491         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1492         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1493         touch $DIR/$tdir-0/f1 || error "touch f1"
1494         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1495         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1496         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1497         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1498         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1499 }
1500 run_test 24G "migrate symlink in rename"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27d() {
1724         test_mkdir $DIR/$tdir
1725         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1726                 error "setstripe failed"
1727         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1729 }
1730 run_test 27d "create file with default settings"
1731
1732 test_27e() {
1733         # LU-5839 adds check for existed layout before setting it
1734         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1735                 skip "Need MDS version at least 2.7.56"
1736
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741 }
1742 run_test 27e "setstripe existing file (should return error)"
1743
1744 test_27f() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1747                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1749                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1751         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1752 }
1753 run_test 27f "setstripe with bad stripe size (should return error)"
1754
1755 test_27g() {
1756         test_mkdir $DIR/$tdir
1757         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1758         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1759                 error "$DIR/$tdir/$tfile has object"
1760 }
1761 run_test 27g "$LFS getstripe with no objects"
1762
1763 test_27ga() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1767         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1768         local rc=$?
1769         (( rc == 2 )) || error "getstripe did not return ENOENT"
1770 }
1771 run_test 27ga "$LFS getstripe with missing file (should return error)"
1772
1773 test_27i() {
1774         test_mkdir $DIR/$tdir
1775         touch $DIR/$tdir/$tfile || error "touch failed"
1776         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1777                 error "missing objects"
1778 }
1779 run_test 27i "$LFS getstripe with some objects"
1780
1781 test_27j() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1784                 error "setstripe failed" || true
1785 }
1786 run_test 27j "setstripe with bad stripe offset (should return error)"
1787
1788 test_27k() { # bug 2844
1789         test_mkdir $DIR/$tdir
1790         local file=$DIR/$tdir/$tfile
1791         local ll_max_blksize=$((4 * 1024 * 1024))
1792         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1793         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1795         dd if=/dev/zero of=$file bs=4k count=1
1796         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1797         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1798 }
1799 run_test 27k "limit i_blksize for broken user apps"
1800
1801 test_27l() {
1802         mcreate $DIR/$tfile || error "creating file"
1803         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1804                 error "setstripe should have failed" || true
1805 }
1806 run_test 27l "check setstripe permissions (should return error)"
1807
1808 test_27m() {
1809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1810
1811         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1812                 skip_env "multiple clients -- skipping"
1813
1814         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1815                    head -n1)
1816         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1817                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1818         fi
1819         trap simple_cleanup_common EXIT
1820         test_mkdir $DIR/$tdir
1821         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1822         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1823                 error "dd should fill OST0"
1824         i=2
1825         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1826                 i=$((i + 1))
1827                 [ $i -gt 256 ] && break
1828         done
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it"
1834         i=$((i + 1))
1835         touch $DIR/$tdir/$tfile.$i
1836         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1837             awk '{print $1}'| grep -w "0") ] &&
1838                 error "OST0 was full but new created file still use it"
1839         simple_cleanup_common
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 test_27n() {
1864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1866         remote_mds_nodsh && skip "remote MDS with nodsh"
1867         remote_ost_nodsh && skip "remote OST with nodsh"
1868
1869         reset_enospc
1870         rm -f $DIR/$tdir/$tfile
1871         exhaust_precreations 0 0x80000215
1872         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1873         touch $DIR/$tdir/$tfile || error "touch failed"
1874         $LFS getstripe $DIR/$tdir/$tfile
1875         reset_enospc
1876 }
1877 run_test 27n "create file with some full OSTs"
1878
1879 test_27o() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_all_precreations 0x215
1888
1889         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1890
1891         reset_enospc
1892         rm -rf $DIR/$tdir/*
1893 }
1894 run_test 27o "create file with all full OSTs (should error)"
1895
1896 function create_and_checktime() {
1897         local fname=$1
1898         local loops=$2
1899         local i
1900
1901         for ((i=0; i < $loops; i++)); do
1902                 local start=$SECONDS
1903                 multiop $fname-$i Oc
1904                 ((SECONDS-start < TIMEOUT)) ||
1905                         error "creation took " $((SECONDS-$start)) && return 1
1906         done
1907 }
1908
1909 test_27oo() {
1910         local mdts=$(comma_list $(mdts_nodes))
1911
1912         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1913                 skip "Need MDS version at least 2.13.57"
1914
1915         local f0=$DIR/${tfile}-0
1916         local f1=$DIR/${tfile}-1
1917
1918         wait_delete_completed
1919
1920         # refill precreated objects
1921         $LFS setstripe -i0 -c1 $f0
1922
1923         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1924         # force QoS allocation policy
1925         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1926         stack_trap "do_nodes $mdts $LCTL set_param \
1927                 lov.*.qos_threshold_rr=$saved" EXIT
1928         sleep_maxage
1929
1930         # one OST is unavailable, but still have few objects preallocated
1931         stop ost1
1932         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1933                 rm -rf $f1 $DIR/$tdir*" EXIT
1934
1935         for ((i=0; i < 7; i++)); do
1936                 mkdir $DIR/$tdir$i || error "can't create dir"
1937                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1938                         error "can't set striping"
1939         done
1940         for ((i=0; i < 7; i++)); do
1941                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1942         done
1943         wait
1944 }
1945 run_test 27oo "don't let few threads to reserve too many objects"
1946
1947 test_27p() {
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         reset_enospc
1954         rm -f $DIR/$tdir/$tfile
1955         test_mkdir $DIR/$tdir
1956
1957         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1958         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1959         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1960
1961         exhaust_precreations 0 0x80000215
1962         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1963         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1964         $LFS getstripe $DIR/$tdir/$tfile
1965
1966         reset_enospc
1967 }
1968 run_test 27p "append to a truncated file with some full OSTs"
1969
1970 test_27q() {
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1973         remote_mds_nodsh && skip "remote MDS with nodsh"
1974         remote_ost_nodsh && skip "remote OST with nodsh"
1975
1976         reset_enospc
1977         rm -f $DIR/$tdir/$tfile
1978
1979         mkdir_on_mdt0 $DIR/$tdir
1980         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1981         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1982                 error "truncate $DIR/$tdir/$tfile failed"
1983         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1984
1985         exhaust_all_precreations 0x215
1986
1987         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1988         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1989
1990         reset_enospc
1991 }
1992 run_test 27q "append to truncated file with all OSTs full (should error)"
1993
1994 test_27r() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         exhaust_precreations 0 0x80000215
2003
2004         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2005
2006         reset_enospc
2007 }
2008 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2009
2010 test_27s() { # bug 10725
2011         test_mkdir $DIR/$tdir
2012         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2013         local stripe_count=0
2014         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2015         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2016                 error "stripe width >= 2^32 succeeded" || true
2017
2018 }
2019 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2020
2021 test_27t() { # bug 10864
2022         WDIR=$(pwd)
2023         WLFS=$(which lfs)
2024         cd $DIR
2025         touch $tfile
2026         $WLFS getstripe $tfile
2027         cd $WDIR
2028 }
2029 run_test 27t "check that utils parse path correctly"
2030
2031 test_27u() { # bug 4900
2032         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2033         remote_mds_nodsh && skip "remote MDS with nodsh"
2034
2035         local index
2036         local list=$(comma_list $(mdts_nodes))
2037
2038 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2039         do_nodes $list $LCTL set_param fail_loc=0x139
2040         test_mkdir -p $DIR/$tdir
2041         trap simple_cleanup_common EXIT
2042         createmany -o $DIR/$tdir/t- 1000
2043         do_nodes $list $LCTL set_param fail_loc=0
2044
2045         TLOG=$TMP/$tfile.getstripe
2046         $LFS getstripe $DIR/$tdir > $TLOG
2047         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2048         unlinkmany $DIR/$tdir/t- 1000
2049         trap 0
2050         [[ $OBJS -gt 0 ]] &&
2051                 error "$OBJS objects created on OST-0. See $TLOG" ||
2052                 rm -f $TLOG
2053 }
2054 run_test 27u "skip object creation on OSC w/o objects"
2055
2056 test_27v() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060         remote_ost_nodsh && skip "remote OST with nodsh"
2061
2062         exhaust_all_precreations 0x215
2063         reset_enospc
2064
2065         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2066
2067         touch $DIR/$tdir/$tfile
2068         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2069         # all except ost1
2070         for (( i=1; i < OSTCOUNT; i++ )); do
2071                 do_facet ost$i lctl set_param fail_loc=0x705
2072         done
2073         local START=`date +%s`
2074         createmany -o $DIR/$tdir/$tfile 32
2075
2076         local FINISH=`date +%s`
2077         local TIMEOUT=`lctl get_param -n timeout`
2078         local PROCESS=$((FINISH - START))
2079         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2080                error "$FINISH - $START >= $TIMEOUT / 2"
2081         sleep $((TIMEOUT / 2 - PROCESS))
2082         reset_enospc
2083 }
2084 run_test 27v "skip object creation on slow OST"
2085
2086 test_27w() { # bug 10997
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2089         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2090                 error "stripe size $size != 65536" || true
2091         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2092                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2093 }
2094 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2095
2096 test_27wa() {
2097         [[ $OSTCOUNT -lt 2 ]] &&
2098                 skip_env "skipping multiple stripe count/offset test"
2099
2100         test_mkdir $DIR/$tdir
2101         for i in $(seq 1 $OSTCOUNT); do
2102                 offset=$((i - 1))
2103                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2104                         error "setstripe -c $i -i $offset failed"
2105                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2106                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2107                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2108                 [ $index -ne $offset ] &&
2109                         error "stripe offset $index != $offset" || true
2110         done
2111 }
2112 run_test 27wa "check $LFS setstripe -c -i options"
2113
2114 test_27x() {
2115         remote_ost_nodsh && skip "remote OST with nodsh"
2116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2118
2119         OFFSET=$(($OSTCOUNT - 1))
2120         OSTIDX=0
2121         local OST=$(ostname_from_index $OSTIDX)
2122
2123         test_mkdir $DIR/$tdir
2124         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2126         sleep_maxage
2127         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2128         for i in $(seq 0 $OFFSET); do
2129                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2130                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2131                 error "OST0 was degraded but new created file still use it"
2132         done
2133         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2134 }
2135 run_test 27x "create files while OST0 is degraded"
2136
2137 test_27y() {
2138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2139         remote_mds_nodsh && skip "remote MDS with nodsh"
2140         remote_ost_nodsh && skip "remote OST with nodsh"
2141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2142
2143         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2144         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2145                 osp.$mdtosc.prealloc_last_id)
2146         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2147                 osp.$mdtosc.prealloc_next_id)
2148         local fcount=$((last_id - next_id))
2149         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2150         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2151
2152         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2153                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2154         local OST_DEACTIVE_IDX=-1
2155         local OSC
2156         local OSTIDX
2157         local OST
2158
2159         for OSC in $MDS_OSCS; do
2160                 OST=$(osc_to_ost $OSC)
2161                 OSTIDX=$(index_from_ostuuid $OST)
2162                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2163                         OST_DEACTIVE_IDX=$OSTIDX
2164                 fi
2165                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2166                         echo $OSC "is Deactivated:"
2167                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2168                 fi
2169         done
2170
2171         OSTIDX=$(index_from_ostuuid $OST)
2172         test_mkdir $DIR/$tdir
2173         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=1
2182                 fi
2183         done
2184
2185         sleep_maxage
2186         createmany -o $DIR/$tdir/$tfile $fcount
2187
2188         for OSC in $MDS_OSCS; do
2189                 OST=$(osc_to_ost $OSC)
2190                 OSTIDX=$(index_from_ostuuid $OST)
2191                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2192                         echo $OST "is recovered from degraded:"
2193                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2194                                                 obdfilter.$OST.degraded=0
2195                 else
2196                         do_facet $SINGLEMDS lctl --device %$OSC activate
2197                 fi
2198         done
2199
2200         # all osp devices get activated, hence -1 stripe count restored
2201         local stripe_count=0
2202
2203         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2204         # devices get activated.
2205         sleep_maxage
2206         $LFS setstripe -c -1 $DIR/$tfile
2207         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2208         rm -f $DIR/$tfile
2209         [ $stripe_count -ne $OSTCOUNT ] &&
2210                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2211         return 0
2212 }
2213 run_test 27y "create files while OST0 is degraded and the rest inactive"
2214
2215 check_seq_oid()
2216 {
2217         log "check file $1"
2218
2219         lmm_count=$($LFS getstripe -c $1)
2220         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2221         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2222
2223         local old_ifs="$IFS"
2224         IFS=$'[:]'
2225         fid=($($LFS path2fid $1))
2226         IFS="$old_ifs"
2227
2228         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2229         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2230
2231         # compare lmm_seq and lu_fid->f_seq
2232         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2233         # compare lmm_object_id and lu_fid->oid
2234         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2235
2236         # check the trusted.fid attribute of the OST objects of the file
2237         local have_obdidx=false
2238         local stripe_nr=0
2239         $LFS getstripe $1 | while read obdidx oid hex seq; do
2240                 # skip lines up to and including "obdidx"
2241                 [ -z "$obdidx" ] && break
2242                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2243                 $have_obdidx || continue
2244
2245                 local ost=$((obdidx + 1))
2246                 local dev=$(ostdevname $ost)
2247                 local oid_hex
2248
2249                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2250
2251                 seq=$(echo $seq | sed -e "s/^0x//g")
2252                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2253                         oid_hex=$(echo $oid)
2254                 else
2255                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2256                 fi
2257                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2258
2259                 local ff=""
2260                 #
2261                 # Don't unmount/remount the OSTs if we don't need to do that.
2262                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2263                 # update too, until that use mount/ll_decode_filter_fid/mount.
2264                 # Re-enable when debugfs will understand new filter_fid.
2265                 #
2266                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2267                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2268                                 $dev 2>/dev/null" | grep "parent=")
2269                 fi
2270                 if [ -z "$ff" ]; then
2271                         stop ost$ost
2272                         mount_fstype ost$ost
2273                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2274                                 $(facet_mntpt ost$ost)/$obj_file)
2275                         unmount_fstype ost$ost
2276                         start ost$ost $dev $OST_MOUNT_OPTS
2277                         clients_up
2278                 fi
2279
2280                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2281
2282                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2283
2284                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2285                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2286                 #
2287                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2288                 #       stripe_size=1048576 component_id=1 component_start=0 \
2289                 #       component_end=33554432
2290                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2291                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2292                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2293                 local ff_pstripe
2294                 if grep -q 'stripe=' <<<$ff; then
2295                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2296                 else
2297                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2298                         # into f_ver in this case.  See comment on ff_parent.
2299                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2300                 fi
2301
2302                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2303                 [ $ff_pseq = $lmm_seq ] ||
2304                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2305                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2306                 [ $ff_poid = $lmm_oid ] ||
2307                         error "FF parent OID $ff_poid != $lmm_oid"
2308                 (($ff_pstripe == $stripe_nr)) ||
2309                         error "FF stripe $ff_pstripe != $stripe_nr"
2310
2311                 stripe_nr=$((stripe_nr + 1))
2312                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2313                         continue
2314                 if grep -q 'stripe_count=' <<<$ff; then
2315                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2316                                             -e 's/ .*//' <<<$ff)
2317                         [ $lmm_count = $ff_scnt ] ||
2318                                 error "FF stripe count $lmm_count != $ff_scnt"
2319                 fi
2320         done
2321 }
2322
2323 test_27z() {
2324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2325         remote_ost_nodsh && skip "remote OST with nodsh"
2326
2327         test_mkdir $DIR/$tdir
2328         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2329                 { error "setstripe -c -1 failed"; return 1; }
2330         # We need to send a write to every object to get parent FID info set.
2331         # This _should_ also work for setattr, but does not currently.
2332         # touch $DIR/$tdir/$tfile-1 ||
2333         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2334                 { error "dd $tfile-1 failed"; return 2; }
2335         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2336                 { error "setstripe -c -1 failed"; return 3; }
2337         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2338                 { error "dd $tfile-2 failed"; return 4; }
2339
2340         # make sure write RPCs have been sent to OSTs
2341         sync; sleep 5; sync
2342
2343         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2344         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2345 }
2346 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2347
2348 test_27A() { # b=19102
2349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2350
2351         save_layout_restore_at_exit $MOUNT
2352         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2353         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2354                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2355         local default_size=$($LFS getstripe -S $MOUNT)
2356         local default_offset=$($LFS getstripe -i $MOUNT)
2357         local dsize=$(do_facet $SINGLEMDS \
2358                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2359         [ $default_size -eq $dsize ] ||
2360                 error "stripe size $default_size != $dsize"
2361         [ $default_offset -eq -1 ] ||
2362                 error "stripe offset $default_offset != -1"
2363 }
2364 run_test 27A "check filesystem-wide default LOV EA values"
2365
2366 test_27B() { # LU-2523
2367         test_mkdir $DIR/$tdir
2368         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2369         touch $DIR/$tdir/f0
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # rename f0 onto f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2375                 $DIR/$tdir/f0
2376
2377         rm -f $DIR/$tdir/f1
2378         # open f1 with O_LOV_DELAY_CREATE
2379         # unlink f1
2380         # call setstripe ioctl on open file descriptor for f1
2381         # close
2382         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2383
2384         # Allow multiop to fail in imitation of NFS's busted semantics.
2385         true
2386 }
2387 run_test 27B "call setstripe on open unlinked file/rename victim"
2388
2389 # 27C family tests full striping and overstriping
2390 test_27Ca() { #LU-2871
2391         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2392
2393         declare -a ost_idx
2394         local index
2395         local found
2396         local i
2397         local j
2398
2399         test_mkdir $DIR/$tdir
2400         cd $DIR/$tdir
2401         for i in $(seq 0 $((OSTCOUNT - 1))); do
2402                 # set stripe across all OSTs starting from OST$i
2403                 $LFS setstripe -i $i -c -1 $tfile$i
2404                 # get striping information
2405                 ost_idx=($($LFS getstripe $tfile$i |
2406                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2407                 echo ${ost_idx[@]}
2408
2409                 # check the layout
2410                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2411                         error "${#ost_idx[@]} != $OSTCOUNT"
2412
2413                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2414                         found=0
2415                         for j in $(echo ${ost_idx[@]}); do
2416                                 if [ $index -eq $j ]; then
2417                                         found=1
2418                                         break
2419                                 fi
2420                         done
2421                         [ $found = 1 ] ||
2422                                 error "Can not find $index in ${ost_idx[@]}"
2423                 done
2424         done
2425 }
2426 run_test 27Ca "check full striping across all OSTs"
2427
2428 test_27Cb() {
2429         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2430                 skip "server does not support overstriping"
2431         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2432                 skip_env "too many osts, skipping"
2433
2434         test_mkdir -p $DIR/$tdir
2435         local setcount=$(($OSTCOUNT * 2))
2436         [ $setcount -lt 160 ] || large_xattr_enabled ||
2437                 skip_env "ea_inode feature disabled"
2438
2439         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2440                 error "setstripe failed"
2441
2442         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2443         [ $count -eq $setcount ] ||
2444                 error "stripe count $count, should be $setcount"
2445
2446         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2447                 error "overstriped should be set in pattern"
2448
2449         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2450                 error "dd failed"
2451 }
2452 run_test 27Cb "more stripes than OSTs with -C"
2453
2454 test_27Cc() {
2455         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2456                 skip "server does not support overstriping"
2457         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2458
2459         test_mkdir -p $DIR/$tdir
2460         local setcount=$(($OSTCOUNT - 1))
2461
2462         [ $setcount -lt 160 ] || large_xattr_enabled ||
2463                 skip_env "ea_inode feature disabled"
2464
2465         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2466                 error "setstripe failed"
2467
2468         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2469         [ $count -eq $setcount ] ||
2470                 error "stripe count $count, should be $setcount"
2471
2472         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2473                 error "overstriped should not be set in pattern"
2474
2475         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2476                 error "dd failed"
2477 }
2478 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2479
2480 test_27Cd() {
2481         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2482                 skip "server does not support overstriping"
2483         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2484         large_xattr_enabled || skip_env "ea_inode feature disabled"
2485
2486         test_mkdir -p $DIR/$tdir
2487         local setcount=$LOV_MAX_STRIPE_COUNT
2488
2489         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2490                 error "setstripe failed"
2491
2492         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2493         [ $count -eq $setcount ] ||
2494                 error "stripe count $count, should be $setcount"
2495
2496         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2497                 error "overstriped should be set in pattern"
2498
2499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2500                 error "dd failed"
2501
2502         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2503 }
2504 run_test 27Cd "test maximum stripe count"
2505
2506 test_27Ce() {
2507         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2508                 skip "server does not support overstriping"
2509         test_mkdir -p $DIR/$tdir
2510
2511         pool_add $TESTNAME || error "Pool creation failed"
2512         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2513
2514         local setcount=8
2515
2516         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2517                 error "setstripe failed"
2518
2519         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2520         [ $count -eq $setcount ] ||
2521                 error "stripe count $count, should be $setcount"
2522
2523         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2524                 error "overstriped should be set in pattern"
2525
2526         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2527                 error "dd failed"
2528
2529         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2530 }
2531 run_test 27Ce "test pool with overstriping"
2532
2533 test_27Cf() {
2534         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2535                 skip "server does not support overstriping"
2536         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2537                 skip_env "too many osts, skipping"
2538
2539         test_mkdir -p $DIR/$tdir
2540
2541         local setcount=$(($OSTCOUNT * 2))
2542         [ $setcount -lt 160 ] || large_xattr_enabled ||
2543                 skip_env "ea_inode feature disabled"
2544
2545         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2546                 error "setstripe failed"
2547
2548         echo 1 > $DIR/$tdir/$tfile
2549
2550         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2551         [ $count -eq $setcount ] ||
2552                 error "stripe count $count, should be $setcount"
2553
2554         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2555                 error "overstriped should be set in pattern"
2556
2557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2558                 error "dd failed"
2559
2560         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2561 }
2562 run_test 27Cf "test default inheritance with overstriping"
2563
2564 test_27D() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2567         remote_mds_nodsh && skip "remote MDS with nodsh"
2568
2569         local POOL=${POOL:-testpool}
2570         local first_ost=0
2571         local last_ost=$(($OSTCOUNT - 1))
2572         local ost_step=1
2573         local ost_list=$(seq $first_ost $ost_step $last_ost)
2574         local ost_range="$first_ost $last_ost $ost_step"
2575
2576         test_mkdir $DIR/$tdir
2577         pool_add $POOL || error "pool_add failed"
2578         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2579
2580         local skip27D
2581         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2582                 skip27D+="-s 29"
2583         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2584                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2585                         skip27D+=" -s 30,31"
2586         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2587           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2588                 skip27D+=" -s 32,33"
2589         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2590                 skip27D+=" -s 34"
2591         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2592                 error "llapi_layout_test failed"
2593
2594         destroy_test_pools || error "destroy test pools failed"
2595 }
2596 run_test 27D "validate llapi_layout API"
2597
2598 # Verify that default_easize is increased from its initial value after
2599 # accessing a widely striped file.
2600 test_27E() {
2601         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2602         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2603                 skip "client does not have LU-3338 fix"
2604
2605         # 72 bytes is the minimum space required to store striping
2606         # information for a file striped across one OST:
2607         # (sizeof(struct lov_user_md_v3) +
2608         #  sizeof(struct lov_user_ost_data_v1))
2609         local min_easize=72
2610         $LCTL set_param -n llite.*.default_easize $min_easize ||
2611                 error "lctl set_param failed"
2612         local easize=$($LCTL get_param -n llite.*.default_easize)
2613
2614         [ $easize -eq $min_easize ] ||
2615                 error "failed to set default_easize"
2616
2617         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2618                 error "setstripe failed"
2619         # In order to ensure stat() call actually talks to MDS we need to
2620         # do something drastic to this file to shake off all lock, e.g.
2621         # rename it (kills lookup lock forcing cache cleaning)
2622         mv $DIR/$tfile $DIR/${tfile}-1
2623         ls -l $DIR/${tfile}-1
2624         rm $DIR/${tfile}-1
2625
2626         easize=$($LCTL get_param -n llite.*.default_easize)
2627
2628         [ $easize -gt $min_easize ] ||
2629                 error "default_easize not updated"
2630 }
2631 run_test 27E "check that default extended attribute size properly increases"
2632
2633 test_27F() { # LU-5346/LU-7975
2634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2635         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2636         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2637                 skip "Need MDS version at least 2.8.51"
2638         remote_ost_nodsh && skip "remote OST with nodsh"
2639
2640         test_mkdir $DIR/$tdir
2641         rm -f $DIR/$tdir/f0
2642         $LFS setstripe -c 2 $DIR/$tdir
2643
2644         # stop all OSTs to reproduce situation for LU-7975 ticket
2645         for num in $(seq $OSTCOUNT); do
2646                 stop ost$num
2647         done
2648
2649         # open/create f0 with O_LOV_DELAY_CREATE
2650         # truncate f0 to a non-0 size
2651         # close
2652         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2653
2654         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2655         # open/write it again to force delayed layout creation
2656         cat /etc/hosts > $DIR/$tdir/f0 &
2657         catpid=$!
2658
2659         # restart OSTs
2660         for num in $(seq $OSTCOUNT); do
2661                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2662                         error "ost$num failed to start"
2663         done
2664
2665         wait $catpid || error "cat failed"
2666
2667         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2668         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2669                 error "wrong stripecount"
2670
2671 }
2672 run_test 27F "Client resend delayed layout creation with non-zero size"
2673
2674 test_27G() { #LU-10629
2675         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2676                 skip "Need MDS version at least 2.11.51"
2677         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2678         remote_mds_nodsh && skip "remote MDS with nodsh"
2679         local POOL=${POOL:-testpool}
2680         local ostrange="0 0 1"
2681
2682         test_mkdir $DIR/$tdir
2683         touch $DIR/$tdir/$tfile.nopool
2684         pool_add $POOL || error "pool_add failed"
2685         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2686         $LFS setstripe -p $POOL $DIR/$tdir
2687
2688         local pool=$($LFS getstripe -p $DIR/$tdir)
2689
2690         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2691         touch $DIR/$tdir/$tfile.default
2692         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2693         $LFS find $DIR/$tdir -type f --pool $POOL
2694         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2695         [[ "$found" == "2" ]] ||
2696                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2697
2698         $LFS setstripe -d $DIR/$tdir
2699
2700         pool=$($LFS getstripe -p -d $DIR/$tdir)
2701
2702         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2703 }
2704 run_test 27G "Clear OST pool from stripe"
2705
2706 test_27H() {
2707         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2708                 skip "Need MDS version newer than 2.11.54"
2709         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2710         test_mkdir $DIR/$tdir
2711         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2712         touch $DIR/$tdir/$tfile
2713         $LFS getstripe -c $DIR/$tdir/$tfile
2714         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2715                 error "two-stripe file doesn't have two stripes"
2716
2717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2718         $LFS getstripe -y $DIR/$tdir/$tfile
2719         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2720              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2721                 error "expected l_ost_idx: [02]$ not matched"
2722
2723         # make sure ost list has been cleared
2724         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2725         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2726                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2727         touch $DIR/$tdir/f3
2728         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2729 }
2730 run_test 27H "Set specific OSTs stripe"
2731
2732 test_27I() {
2733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2735         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2736                 skip "Need MDS version newer than 2.12.52"
2737         local pool=$TESTNAME
2738         local ostrange="1 1 1"
2739
2740         save_layout_restore_at_exit $MOUNT
2741         $LFS setstripe -c 2 -i 0 $MOUNT
2742         pool_add $pool || error "pool_add failed"
2743         pool_add_targets $pool $ostrange ||
2744                 error "pool_add_targets failed"
2745         test_mkdir $DIR/$tdir
2746         $LFS setstripe -p $pool $DIR/$tdir
2747         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2748         $LFS getstripe $DIR/$tdir/$tfile
2749 }
2750 run_test 27I "check that root dir striping does not break parent dir one"
2751
2752 test_27J() {
2753         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2754                 skip "Need MDS version newer than 2.12.51"
2755
2756         test_mkdir $DIR/$tdir
2757         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2758         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2759
2760         # create foreign file (raw way)
2761         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2762                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2763
2764         ! $LFS setstripe --foreign --flags foo \
2765                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2766                         error "creating $tfile with '--flags foo' should fail"
2767
2768         ! $LFS setstripe --foreign --flags 0xffffffff \
2769                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2770                         error "creating $tfile w/ 0xffffffff flags should fail"
2771
2772         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2773                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2774
2775         # verify foreign file (raw way)
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2779         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2780                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2781         parse_foreign_file -f $DIR/$tdir/$tfile |
2782                 grep "lov_foreign_size: 73" ||
2783                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2784         parse_foreign_file -f $DIR/$tdir/$tfile |
2785                 grep "lov_foreign_type: 1" ||
2786                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2787         parse_foreign_file -f $DIR/$tdir/$tfile |
2788                 grep "lov_foreign_flags: 0x0000DA08" ||
2789                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2790         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_value: 0x" |
2792                 sed -e 's/lov_foreign_value: 0x//')
2793         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2794         [[ $lov = ${lov2// /} ]] ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2796
2797         # create foreign file (lfs + API)
2798         $LFS setstripe --foreign=none --flags 0xda08 \
2799                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2800                 error "$DIR/$tdir/${tfile}2: create failed"
2801
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_magic:.*0x0BD70BD0" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2805         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2806         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2808         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2809                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2810         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2811                 grep "lfm_flags:.*0x0000DA08" ||
2812                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2813         $LFS getstripe $DIR/$tdir/${tfile}2 |
2814                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2815                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2816
2817         # modify striping should fail
2818         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2819                 error "$DIR/$tdir/$tfile: setstripe should fail"
2820         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2821                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2822
2823         # R/W should fail
2824         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2825         cat $DIR/$tdir/${tfile}2 &&
2826                 error "$DIR/$tdir/${tfile}2: read should fail"
2827         cat /etc/passwd > $DIR/$tdir/$tfile &&
2828                 error "$DIR/$tdir/$tfile: write should fail"
2829         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2830                 error "$DIR/$tdir/${tfile}2: write should fail"
2831
2832         # chmod should work
2833         chmod 222 $DIR/$tdir/$tfile ||
2834                 error "$DIR/$tdir/$tfile: chmod failed"
2835         chmod 222 $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: chmod failed"
2837
2838         # chown should work
2839         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2840                 error "$DIR/$tdir/$tfile: chown failed"
2841         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2842                 error "$DIR/$tdir/${tfile}2: chown failed"
2843
2844         # rename should work
2845         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2846                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2847         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2848                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2849
2850         #remove foreign file
2851         rm $DIR/$tdir/${tfile}.new ||
2852                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2853         rm $DIR/$tdir/${tfile}2.new ||
2854                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2855 }
2856 run_test 27J "basic ops on file with foreign LOV"
2857
2858 test_27K() {
2859         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2860                 skip "Need MDS version newer than 2.12.49"
2861
2862         test_mkdir $DIR/$tdir
2863         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2864         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2865
2866         # create foreign dir (raw way)
2867         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2868                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2869
2870         ! $LFS setdirstripe --foreign --flags foo \
2871                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2872                         error "creating $tdir with '--flags foo' should fail"
2873
2874         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2875                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2876                         error "creating $tdir w/ 0xffffffff flags should fail"
2877
2878         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2879                 error "create_foreign_dir FAILED"
2880
2881         # verify foreign dir (raw way)
2882         parse_foreign_dir -d $DIR/$tdir/$tdir |
2883                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2884                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2885         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2886                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2887         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2888                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2889         parse_foreign_dir -d $DIR/$tdir/$tdir |
2890                 grep "lmv_foreign_flags: 55813$" ||
2891                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2892         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_value: 0x" |
2894                 sed 's/lmv_foreign_value: 0x//')
2895         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2896                 sed 's/ //g')
2897         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2898
2899         # create foreign dir (lfs + API)
2900         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2901                 $DIR/$tdir/${tdir}2 ||
2902                 error "$DIR/$tdir/${tdir}2: create failed"
2903
2904         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2905                 grep "lfm_magic:.*0x0CD50CD0" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2907         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2908         # - sizeof(lfm_type) - sizeof(lfm_flags)
2909         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2911         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2913         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2914                 grep "lfm_flags:.*0x0000DA05" ||
2915                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2916         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2917                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2918                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2919
2920         # file create in dir should fail
2921         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2922         touch $DIR/$tdir/${tdir}2/$tfile &&
2923                 "$DIR/${tdir}2: file create should fail"
2924
2925         # chmod should work
2926         chmod 777 $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chmod failed"
2928         chmod 777 $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chmod failed"
2930
2931         # chown should work
2932         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2933                 error "$DIR/$tdir: chown failed"
2934         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2935                 error "$DIR/${tdir}2: chown failed"
2936
2937         # rename should work
2938         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2940         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2942
2943         #remove foreign dir
2944         rmdir $DIR/$tdir/${tdir}.new ||
2945                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2946         rmdir $DIR/$tdir/${tdir}2.new ||
2947                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2948 }
2949 run_test 27K "basic ops on dir with foreign LMV"
2950
2951 test_27L() {
2952         remote_mds_nodsh && skip "remote MDS with nodsh"
2953
2954         local POOL=${POOL:-$TESTNAME}
2955
2956         pool_add $POOL || error "pool_add failed"
2957
2958         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2959                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2960                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2961 }
2962 run_test 27L "lfs pool_list gives correct pool name"
2963
2964 test_27M() {
2965         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2966                 skip "Need MDS version >= than 2.12.57"
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2969
2970         test_mkdir $DIR/$tdir
2971
2972         # Set default striping on directory
2973         local setcount=4
2974         local stripe_opt
2975
2976         # if we run against a 2.12 server which lacks overstring support
2977         # then the connect_flag will not report overstriping, even if client
2978         # is 2.14+
2979         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2980                 stripe_opt="-C $setcount"
2981         elif (( $OSTCOUNT >= $setcount )); then
2982                 stripe_opt="-c $setcount"
2983         else
2984                 skip "server does not support overstriping"
2985         fi
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         # Capture existing append_stripe_count setting for restore
2994         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2995         local mdts=$(comma_list $(mdts_nodes))
2996         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3076         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3077
3078         # Create the pool
3079         pool_add $TESTNAME || error "pool creation failed"
3080         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3081
3082         echo 1 >> $DIR/$tdir/${tfile}.10_append
3083
3084         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3085         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3086
3087         # Check that count is still correct
3088         appendcount=1
3089         echo 1 >> $DIR/$tdir/${tfile}.11_append
3090         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3091         [ $count -eq $appendcount ] ||
3092                 error "(11) stripe count $count, should be $appendcount for append"
3093
3094         # Disable O_APPEND stripe count, verify pool works separately
3095         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.12_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3100         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3101
3102         # Remove pool setting, verify it's not applied
3103         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3104
3105         echo 1 >> $DIR/$tdir/${tfile}.13_append
3106
3107         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3108         [ "$pool" = "" ] || error "(13) pool found: $pool"
3109 }
3110 run_test 27M "test O_APPEND striping"
3111
3112 test_27N() {
3113         combined_mgs_mds && skip "needs separate MGS/MDT"
3114
3115         pool_add $TESTNAME || error "pool_add failed"
3116         do_facet mgs "$LCTL pool_list $FSNAME" |
3117                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3118                 error "lctl pool_list on MGS failed"
3119 }
3120 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3121
3122 clean_foreign_symlink() {
3123         trap 0
3124         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3125         for i in $DIR/$tdir/* ; do
3126                 $LFS unlink_foreign $i || true
3127         done
3128 }
3129
3130 test_27O() {
3131         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3132                 skip "Need MDS version newer than 2.12.51"
3133
3134         test_mkdir $DIR/$tdir
3135         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3136         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3137
3138         trap clean_foreign_symlink EXIT
3139
3140         # enable foreign_symlink behaviour
3141         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3142
3143         # foreign symlink LOV format is a partial path by default
3144
3145         # create foreign file (lfs + API)
3146         $LFS setstripe --foreign=symlink --flags 0xda05 \
3147                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3148                 error "$DIR/$tdir/${tfile}: create failed"
3149
3150         $LFS getstripe -v $DIR/$tdir/${tfile} |
3151                 grep "lfm_magic:.*0x0BD70BD0" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3153         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} |
3156                 grep "lfm_flags:.*0x0000DA05" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3158         $LFS getstripe $DIR/$tdir/${tfile} |
3159                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3161
3162         # modify striping should fail
3163         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3164                 error "$DIR/$tdir/$tfile: setstripe should fail"
3165
3166         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3167         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3168         cat /etc/passwd > $DIR/$tdir/$tfile &&
3169                 error "$DIR/$tdir/$tfile: write should fail"
3170
3171         # rename should succeed
3172         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3173                 error "$DIR/$tdir/$tfile: rename has failed"
3174
3175         #remove foreign_symlink file should fail
3176         rm $DIR/$tdir/${tfile}.new &&
3177                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3178
3179         #test fake symlink
3180         mkdir /tmp/${uuid1} ||
3181                 error "/tmp/${uuid1}: mkdir has failed"
3182         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3183                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3184         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3185         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3187         #read should succeed now
3188         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3189                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3190         #write should succeed now
3191         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3193         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3195         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3196                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3197
3198         #check that getstripe still works
3199         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3201
3202         # chmod should still succeed
3203         chmod 644 $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3205
3206         # chown should still succeed
3207         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3208                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3209
3210         # rename should still succeed
3211         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3213
3214         #remove foreign_symlink file should still fail
3215         rm $DIR/$tdir/${tfile} &&
3216                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3217
3218         #use special ioctl() to unlink foreign_symlink file
3219         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3220                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3221
3222 }
3223 run_test 27O "basic ops on foreign file of symlink type"
3224
3225 test_27P() {
3226         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3227                 skip "Need MDS version newer than 2.12.49"
3228
3229         test_mkdir $DIR/$tdir
3230         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3231         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3232
3233         trap clean_foreign_symlink EXIT
3234
3235         # enable foreign_symlink behaviour
3236         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3237
3238         # foreign symlink LMV format is a partial path by default
3239
3240         # create foreign dir (lfs + API)
3241         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3242                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3243                 error "$DIR/$tdir/${tdir}: create failed"
3244
3245         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3246                 grep "lfm_magic:.*0x0CD50CD0" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3251                 grep "lfm_flags:.*0x0000DA05" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3253         $LFS getdirstripe $DIR/$tdir/${tdir} |
3254                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3256
3257         # file create in dir should fail
3258         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3259         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3260
3261         # rename should succeed
3262         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3263                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3264
3265         #remove foreign_symlink dir should fail
3266         rmdir $DIR/$tdir/${tdir}.new &&
3267                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3268
3269         #test fake symlink
3270         mkdir -p /tmp/${uuid1}/${uuid2} ||
3271                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3272         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3273                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3274         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3275         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3277         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3278                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3279
3280         #check that getstripe fails now that foreign_symlink enabled
3281         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3282                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3283
3284         # file create in dir should work now
3285         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3286                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3287         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3289         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3290                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3291
3292         # chmod should still succeed
3293         chmod 755 $DIR/$tdir/${tdir}.new ||
3294                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3295
3296         # chown should still succeed
3297         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3298                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3299
3300         # rename should still succeed
3301         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3303
3304         #remove foreign_symlink dir should still fail
3305         rmdir $DIR/$tdir/${tdir} &&
3306                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3307
3308         #use special ioctl() to unlink foreign_symlink file
3309         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3310                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3311
3312         #created file should still exist
3313         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3314                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3315         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3317 }
3318 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3319
3320 test_27Q() {
3321         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3322         stack_trap "rm -f $TMP/$tfile*"
3323
3324         test_mkdir $DIR/$tdir-1
3325         test_mkdir $DIR/$tdir-2
3326
3327         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3328         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3329
3330         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3331         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3334         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3335
3336         # Create some bad symlinks and ensure that we don't loop
3337         # forever or something. These should return ELOOP (40) and
3338         # ENOENT (2) but I don't want to test for that because there's
3339         # always some weirdo architecture that needs to ruin
3340         # everything by defining these error numbers differently.
3341
3342         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3343         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3344
3345         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3346         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3347
3348         return 0
3349 }
3350 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3351
3352 test_27R() {
3353         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3354                 skip "need MDS 2.14.55 or later"
3355         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3356
3357         local testdir="$DIR/$tdir"
3358         test_mkdir -p $testdir
3359         stack_trap "rm -rf $testdir"
3360         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3361
3362         local f1="$testdir/f1"
3363         touch $f1 || error "failed to touch $f1"
3364         local count=$($LFS getstripe -c $f1)
3365         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3366
3367         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3368         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3369
3370         local maxcount=$(($OSTCOUNT - 1))
3371         local mdts=$(comma_list $(mdts_nodes))
3372         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3373         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3374
3375         local f2="$testdir/f2"
3376         touch $f2 || error "failed to touch $f2"
3377         local count=$($LFS getstripe -c $f2)
3378         (( $count == $maxcount )) || error "wrong stripe count"
3379 }
3380 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3381
3382 # createtest also checks that device nodes are created and
3383 # then visible correctly (#2091)
3384 test_28() { # bug 2091
3385         test_mkdir $DIR/d28
3386         $CREATETEST $DIR/d28/ct || error "createtest failed"
3387 }
3388 run_test 28 "create/mknod/mkdir with bad file types ============"
3389
3390 test_29() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3394                 disable_opencache
3395                 stack_trap "restore_opencache"
3396         }
3397
3398         sync; sleep 1; sync # flush out any dirty pages from previous tests
3399         cancel_lru_locks
3400         test_mkdir $DIR/d29
3401         touch $DIR/d29/foo
3402         log 'first d29'
3403         ls -l $DIR/d29
3404
3405         declare -i LOCKCOUNTORIG=0
3406         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3407                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3408         done
3409         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3410
3411         declare -i LOCKUNUSEDCOUNTORIG=0
3412         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3413                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3414         done
3415
3416         log 'second d29'
3417         ls -l $DIR/d29
3418         log 'done'
3419
3420         declare -i LOCKCOUNTCURRENT=0
3421         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3422                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3423         done
3424
3425         declare -i LOCKUNUSEDCOUNTCURRENT=0
3426         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3427                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3428         done
3429
3430         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3431                 $LCTL set_param -n ldlm.dump_namespaces ""
3432                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3433                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3434                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3435                 return 2
3436         fi
3437         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3438                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3439                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3440                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3441                 return 3
3442         fi
3443 }
3444 run_test 29 "IT_GETATTR regression  ============================"
3445
3446 test_30a() { # was test_30
3447         cp $(which ls) $DIR || cp /bin/ls $DIR
3448         $DIR/ls / || error "Can't execute binary from lustre"
3449         rm $DIR/ls
3450 }
3451 run_test 30a "execute binary from Lustre (execve) =============="
3452
3453 test_30b() {
3454         cp `which ls` $DIR || cp /bin/ls $DIR
3455         chmod go+rx $DIR/ls
3456         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3457         rm $DIR/ls
3458 }
3459 run_test 30b "execute binary from Lustre as non-root ==========="
3460
3461 test_30c() { # b=22376
3462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3463
3464         cp $(which ls) $DIR || cp /bin/ls $DIR
3465         chmod a-rw $DIR/ls
3466         cancel_lru_locks mdc
3467         cancel_lru_locks osc
3468         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3469         rm -f $DIR/ls
3470 }
3471 run_test 30c "execute binary from Lustre without read perms ===="
3472
3473 test_30d() {
3474         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3475
3476         for i in {1..10}; do
3477                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3478                 local PID=$!
3479                 sleep 1
3480                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3481                 wait $PID || error "executing dd from Lustre failed"
3482                 rm -f $DIR/$tfile
3483         done
3484
3485         rm -f $DIR/dd
3486 }
3487 run_test 30d "execute binary from Lustre while clear locks"
3488
3489 test_31a() {
3490         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3491         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3492 }
3493 run_test 31a "open-unlink file =================================="
3494
3495 test_31b() {
3496         touch $DIR/f31 || error "touch $DIR/f31 failed"
3497         ln $DIR/f31 $DIR/f31b || error "ln failed"
3498         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3499         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3500 }
3501 run_test 31b "unlink file with multiple links while open ======="
3502
3503 test_31c() {
3504         touch $DIR/f31 || error "touch $DIR/f31 failed"
3505         ln $DIR/f31 $DIR/f31c || error "ln failed"
3506         multiop_bg_pause $DIR/f31 O_uc ||
3507                 error "multiop_bg_pause for $DIR/f31 failed"
3508         MULTIPID=$!
3509         $MULTIOP $DIR/f31c Ouc
3510         kill -USR1 $MULTIPID
3511         wait $MULTIPID
3512 }
3513 run_test 31c "open-unlink file with multiple links ============="
3514
3515 test_31d() {
3516         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3517         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3518 }
3519 run_test 31d "remove of open directory ========================="
3520
3521 test_31e() { # bug 2904
3522         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3523 }
3524 run_test 31e "remove of open non-empty directory ==============="
3525
3526 test_31f() { # bug 4554
3527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3528
3529         set -vx
3530         test_mkdir $DIR/d31f
3531         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3532         cp /etc/hosts $DIR/d31f
3533         ls -l $DIR/d31f
3534         $LFS getstripe $DIR/d31f/hosts
3535         multiop_bg_pause $DIR/d31f D_c || return 1
3536         MULTIPID=$!
3537
3538         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3539         test_mkdir $DIR/d31f
3540         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3541         cp /etc/hosts $DIR/d31f
3542         ls -l $DIR/d31f
3543         $LFS getstripe $DIR/d31f/hosts
3544         multiop_bg_pause $DIR/d31f D_c || return 1
3545         MULTIPID2=$!
3546
3547         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3548         wait $MULTIPID || error "first opendir $MULTIPID failed"
3549
3550         sleep 6
3551
3552         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3553         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3554         set +vx
3555 }
3556 run_test 31f "remove of open directory with open-unlink file ==="
3557
3558 test_31g() {
3559         echo "-- cross directory link --"
3560         test_mkdir -c1 $DIR/${tdir}ga
3561         test_mkdir -c1 $DIR/${tdir}gb
3562         touch $DIR/${tdir}ga/f
3563         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3564         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3565         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3566         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3567         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3568 }
3569 run_test 31g "cross directory link==============="
3570
3571 test_31h() {
3572         echo "-- cross directory link --"
3573         test_mkdir -c1 $DIR/${tdir}
3574         test_mkdir -c1 $DIR/${tdir}/dir
3575         touch $DIR/${tdir}/f
3576         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3577         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3578         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3579         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3580         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3581 }
3582 run_test 31h "cross directory link under child==============="
3583
3584 test_31i() {
3585         echo "-- cross directory link --"
3586         test_mkdir -c1 $DIR/$tdir
3587         test_mkdir -c1 $DIR/$tdir/dir
3588         touch $DIR/$tdir/dir/f
3589         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3590         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3591         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3592         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3593         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3594 }
3595 run_test 31i "cross directory link under parent==============="
3596
3597 test_31j() {
3598         test_mkdir -c1 -p $DIR/$tdir
3599         test_mkdir -c1 -p $DIR/$tdir/dir1
3600         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3601         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3602         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3603         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3604         return 0
3605 }
3606 run_test 31j "link for directory==============="
3607
3608 test_31k() {
3609         test_mkdir -c1 -p $DIR/$tdir
3610         touch $DIR/$tdir/s
3611         touch $DIR/$tdir/exist
3612         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3613         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3614         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3615         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3616         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3617         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3618         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3619         return 0
3620 }
3621 run_test 31k "link to file: the same, non-existing, dir==============="
3622
3623 test_31m() {
3624         mkdir $DIR/d31m
3625         touch $DIR/d31m/s
3626         mkdir $DIR/d31m2
3627         touch $DIR/d31m2/exist
3628         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3629         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3630         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3631         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3632         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3633         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3634         return 0
3635 }
3636 run_test 31m "link to file: the same, non-existing, dir==============="
3637
3638 test_31n() {
3639         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3640         nlink=$(stat --format=%h $DIR/$tfile)
3641         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3642         local fd=$(free_fd)
3643         local cmd="exec $fd<$DIR/$tfile"
3644         eval $cmd
3645         cmd="exec $fd<&-"
3646         trap "eval $cmd" EXIT
3647         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3648         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3649         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3650         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3651         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3652         eval $cmd
3653 }
3654 run_test 31n "check link count of unlinked file"
3655
3656 link_one() {
3657         local tempfile=$(mktemp $1_XXXXXX)
3658         mlink $tempfile $1 2> /dev/null &&
3659                 echo "$BASHPID: link $tempfile to $1 succeeded"
3660         munlink $tempfile
3661 }
3662
3663 test_31o() { # LU-2901
3664         test_mkdir $DIR/$tdir
3665         for LOOP in $(seq 100); do
3666                 rm -f $DIR/$tdir/$tfile*
3667                 for THREAD in $(seq 8); do
3668                         link_one $DIR/$tdir/$tfile.$LOOP &
3669                 done
3670                 wait
3671                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3672                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3673                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3674                         break || true
3675         done
3676 }
3677 run_test 31o "duplicate hard links with same filename"
3678
3679 test_31p() {
3680         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3681
3682         test_mkdir $DIR/$tdir
3683         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3684         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3685
3686         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3687                 error "open unlink test1 failed"
3688         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3689                 error "open unlink test2 failed"
3690
3691         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3692                 error "test1 still exists"
3693         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3694                 error "test2 still exists"
3695 }
3696 run_test 31p "remove of open striped directory"
3697
3698 test_31q() {
3699         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3700
3701         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3702         index=$($LFS getdirstripe -i $DIR/$tdir)
3703         [ $index -eq 3 ] || error "first stripe index $index != 3"
3704         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3705         [ $index -eq 1 ] || error "second stripe index $index != 1"
3706
3707         # when "-c <stripe_count>" is set, the number of MDTs specified after
3708         # "-i" should equal to the stripe count
3709         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3710 }
3711 run_test 31q "create striped directory on specific MDTs"
3712
3713 #LU-14949
3714 test_31r() {
3715         touch $DIR/$tfile.target
3716         touch $DIR/$tfile.source
3717
3718         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3719         $LCTL set_param fail_loc=0x1419 fail_val=3
3720         cat $DIR/$tfile.target &
3721         CATPID=$!
3722
3723         # Guarantee open is waiting before we get here
3724         sleep 1
3725         mv $DIR/$tfile.source $DIR/$tfile.target
3726
3727         wait $CATPID
3728         RC=$?
3729         if [[ $RC -ne 0 ]]; then
3730                 error "open with cat failed, rc=$RC"
3731         fi
3732 }
3733 run_test 31r "open-rename(replace) race"
3734
3735 cleanup_test32_mount() {
3736         local rc=0
3737         trap 0
3738         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3739         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3740         losetup -d $loopdev || true
3741         rm -rf $DIR/$tdir
3742         return $rc
3743 }
3744
3745 test_32a() {
3746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3747
3748         echo "== more mountpoints and symlinks ================="
3749         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3750         trap cleanup_test32_mount EXIT
3751         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3752         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3753                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3754         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3755                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3756         cleanup_test32_mount
3757 }
3758 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3759
3760 test_32b() {
3761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3762
3763         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3764         trap cleanup_test32_mount EXIT
3765         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3766         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3767                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3768         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3769                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3770         cleanup_test32_mount
3771 }
3772 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3773
3774 test_32c() {
3775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3776
3777         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3778         trap cleanup_test32_mount EXIT
3779         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3780         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3781                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3782         test_mkdir -p $DIR/$tdir/d2/test_dir
3783         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3784                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3785         cleanup_test32_mount
3786 }
3787 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3788
3789 test_32d() {
3790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3791
3792         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3793         trap cleanup_test32_mount EXIT
3794         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3795         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3796                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3797         test_mkdir -p $DIR/$tdir/d2/test_dir
3798         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3799                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3800         cleanup_test32_mount
3801 }
3802 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3803
3804 test_32e() {
3805         rm -fr $DIR/$tdir
3806         test_mkdir -p $DIR/$tdir/tmp
3807         local tmp_dir=$DIR/$tdir/tmp
3808         ln -s $DIR/$tdir $tmp_dir/symlink11
3809         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3810         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3811         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3812 }
3813 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3814
3815 test_32f() {
3816         rm -fr $DIR/$tdir
3817         test_mkdir -p $DIR/$tdir/tmp
3818         local tmp_dir=$DIR/$tdir/tmp
3819         ln -s $DIR/$tdir $tmp_dir/symlink11
3820         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3821         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3822         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3823 }
3824 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3825
3826 test_32g() {
3827         local tmp_dir=$DIR/$tdir/tmp
3828         test_mkdir -p $tmp_dir
3829         test_mkdir $DIR/${tdir}2
3830         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3831         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3832         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3833         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3834         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3835         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3836 }
3837 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3838
3839 test_32h() {
3840         rm -fr $DIR/$tdir $DIR/${tdir}2
3841         tmp_dir=$DIR/$tdir/tmp
3842         test_mkdir -p $tmp_dir
3843         test_mkdir $DIR/${tdir}2
3844         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3845         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3846         ls $tmp_dir/symlink12 || error "listing symlink12"
3847         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3848 }
3849 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3850
3851 test_32i() {
3852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3853
3854         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3855         trap cleanup_test32_mount EXIT
3856         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3857         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3858                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3859         touch $DIR/$tdir/test_file
3860         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3861                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3862         cleanup_test32_mount
3863 }
3864 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3865
3866 test_32j() {
3867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3868
3869         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3870         trap cleanup_test32_mount EXIT
3871         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3872         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3873                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3874         touch $DIR/$tdir/test_file
3875         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3876                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3877         cleanup_test32_mount
3878 }
3879 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3880
3881 test_32k() {
3882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3883
3884         rm -fr $DIR/$tdir
3885         trap cleanup_test32_mount EXIT
3886         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3887         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3888                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3889         test_mkdir -p $DIR/$tdir/d2
3890         touch $DIR/$tdir/d2/test_file || error "touch failed"
3891         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3892                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3893         cleanup_test32_mount
3894 }
3895 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3896
3897 test_32l() {
3898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3899
3900         rm -fr $DIR/$tdir
3901         trap cleanup_test32_mount EXIT
3902         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3903         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3904                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3905         test_mkdir -p $DIR/$tdir/d2
3906         touch $DIR/$tdir/d2/test_file || error "touch failed"
3907         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3908                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3909         cleanup_test32_mount
3910 }
3911 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3912
3913 test_32m() {
3914         rm -fr $DIR/d32m
3915         test_mkdir -p $DIR/d32m/tmp
3916         TMP_DIR=$DIR/d32m/tmp
3917         ln -s $DIR $TMP_DIR/symlink11
3918         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3919         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3920                 error "symlink11 not a link"
3921         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3922                 error "symlink01 not a link"
3923 }
3924 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3925
3926 test_32n() {
3927         rm -fr $DIR/d32n
3928         test_mkdir -p $DIR/d32n/tmp
3929         TMP_DIR=$DIR/d32n/tmp
3930         ln -s $DIR $TMP_DIR/symlink11
3931         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3932         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3933         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3934 }
3935 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3936
3937 test_32o() {
3938         touch $DIR/$tfile
3939         test_mkdir -p $DIR/d32o/tmp
3940         TMP_DIR=$DIR/d32o/tmp
3941         ln -s $DIR/$tfile $TMP_DIR/symlink12
3942         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3943         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3944                 error "symlink12 not a link"
3945         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3946         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3947                 error "$DIR/d32o/tmp/symlink12 not file type"
3948         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3949                 error "$DIR/d32o/symlink02 not file type"
3950 }
3951 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3952
3953 test_32p() {
3954         log 32p_1
3955         rm -fr $DIR/d32p
3956         log 32p_2
3957         rm -f $DIR/$tfile
3958         log 32p_3
3959         touch $DIR/$tfile
3960         log 32p_4
3961         test_mkdir -p $DIR/d32p/tmp
3962         log 32p_5
3963         TMP_DIR=$DIR/d32p/tmp
3964         log 32p_6
3965         ln -s $DIR/$tfile $TMP_DIR/symlink12
3966         log 32p_7
3967         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3968         log 32p_8
3969         cat $DIR/d32p/tmp/symlink12 ||
3970                 error "Can't open $DIR/d32p/tmp/symlink12"
3971         log 32p_9
3972         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3973         log 32p_10
3974 }
3975 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3976
3977 test_32q() {
3978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3979
3980         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3981         trap cleanup_test32_mount EXIT
3982         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3983         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3984         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3985                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3986         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3987         cleanup_test32_mount
3988 }
3989 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3990
3991 test_32r() {
3992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3993
3994         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3995         trap cleanup_test32_mount EXIT
3996         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3997         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3998         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3999                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4000         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4001         cleanup_test32_mount
4002 }
4003 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4004
4005 test_33aa() {
4006         rm -f $DIR/$tfile
4007         touch $DIR/$tfile
4008         chmod 444 $DIR/$tfile
4009         chown $RUNAS_ID $DIR/$tfile
4010         log 33_1
4011         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4012         log 33_2
4013 }
4014 run_test 33aa "write file with mode 444 (should return error)"
4015
4016 test_33a() {
4017         rm -fr $DIR/$tdir
4018         test_mkdir $DIR/$tdir
4019         chown $RUNAS_ID $DIR/$tdir
4020         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4021                 error "$RUNAS create $tdir/$tfile failed"
4022         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4023                 error "open RDWR" || true
4024 }
4025 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4026
4027 test_33b() {
4028         rm -fr $DIR/$tdir
4029         test_mkdir $DIR/$tdir
4030         chown $RUNAS_ID $DIR/$tdir
4031         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4032 }
4033 run_test 33b "test open file with malformed flags (No panic)"
4034
4035 test_33c() {
4036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4037         remote_ost_nodsh && skip "remote OST with nodsh"
4038
4039         local ostnum
4040         local ostname
4041         local write_bytes
4042         local all_zeros
4043
4044         all_zeros=true
4045         test_mkdir $DIR/$tdir
4046         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4047
4048         sync
4049         for ostnum in $(seq $OSTCOUNT); do
4050                 # test-framework's OST numbering is one-based, while Lustre's
4051                 # is zero-based
4052                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4053                 # check if at least some write_bytes stats are counted
4054                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4055                               obdfilter.$ostname.stats |
4056                               awk '/^write_bytes/ {print $7}' )
4057                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4058                 if (( ${write_bytes:-0} > 0 )); then
4059                         all_zeros=false
4060                         break
4061                 fi
4062         done
4063
4064         $all_zeros || return 0
4065
4066         # Write four bytes
4067         echo foo > $DIR/$tdir/bar
4068         # Really write them
4069         sync
4070
4071         # Total up write_bytes after writing.  We'd better find non-zeros.
4072         for ostnum in $(seq $OSTCOUNT); do
4073                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4074                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4075                               obdfilter/$ostname/stats |
4076                               awk '/^write_bytes/ {print $7}' )
4077                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4078                 if (( ${write_bytes:-0} > 0 )); then
4079                         all_zeros=false
4080                         break
4081                 fi
4082         done
4083
4084         if $all_zeros; then
4085                 for ostnum in $(seq $OSTCOUNT); do
4086                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4087                         echo "Check write_bytes is in obdfilter.*.stats:"
4088                         do_facet ost$ostnum lctl get_param -n \
4089                                 obdfilter.$ostname.stats
4090                 done
4091                 error "OST not keeping write_bytes stats (b=22312)"
4092         fi
4093 }
4094 run_test 33c "test write_bytes stats"
4095
4096 test_33d() {
4097         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4099
4100         local MDTIDX=1
4101         local remote_dir=$DIR/$tdir/remote_dir
4102
4103         test_mkdir $DIR/$tdir
4104         $LFS mkdir -i $MDTIDX $remote_dir ||
4105                 error "create remote directory failed"
4106
4107         touch $remote_dir/$tfile
4108         chmod 444 $remote_dir/$tfile
4109         chown $RUNAS_ID $remote_dir/$tfile
4110
4111         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4112
4113         chown $RUNAS_ID $remote_dir
4114         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4115                                         error "create" || true
4116         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4117                                     error "open RDWR" || true
4118         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4119 }
4120 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4121
4122 test_33e() {
4123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4124
4125         mkdir $DIR/$tdir
4126
4127         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4128         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4129         mkdir $DIR/$tdir/local_dir
4130
4131         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4132         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4133         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4134
4135         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4136                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4137
4138         rmdir $DIR/$tdir/* || error "rmdir failed"
4139
4140         umask 777
4141         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4142         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4143         mkdir $DIR/$tdir/local_dir
4144
4145         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4146         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4147         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4148
4149         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4150                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4151
4152         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4153
4154         umask 000
4155         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4156         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4157         mkdir $DIR/$tdir/local_dir
4158
4159         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4160         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4161         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4162
4163         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4164                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4165 }
4166 run_test 33e "mkdir and striped directory should have same mode"
4167
4168 cleanup_33f() {
4169         trap 0
4170         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4171 }
4172
4173 test_33f() {
4174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4175         remote_mds_nodsh && skip "remote MDS with nodsh"
4176
4177         mkdir $DIR/$tdir
4178         chmod go+rwx $DIR/$tdir
4179         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4180         trap cleanup_33f EXIT
4181
4182         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4183                 error "cannot create striped directory"
4184
4185         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4186                 error "cannot create files in striped directory"
4187
4188         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4189                 error "cannot remove files in striped directory"
4190
4191         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4192                 error "cannot remove striped directory"
4193
4194         cleanup_33f
4195 }
4196 run_test 33f "nonroot user can create, access, and remove a striped directory"
4197
4198 test_33g() {
4199         mkdir -p $DIR/$tdir/dir2
4200
4201         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4202         echo $err
4203         [[ $err =~ "exists" ]] || error "Not exists error"
4204 }
4205 run_test 33g "nonroot user create already existing root created file"
4206
4207 test_33h() {
4208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4209         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4210                 skip "Need MDS version at least 2.13.50"
4211
4212         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4213                 error "mkdir $tdir failed"
4214         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4215
4216         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4217         local index2
4218
4219         for fname in $DIR/$tdir/$tfile.bak \
4220                      $DIR/$tdir/$tfile.SAV \
4221                      $DIR/$tdir/$tfile.orig \
4222                      $DIR/$tdir/$tfile~; do
4223                 touch $fname  || error "touch $fname failed"
4224                 index2=$($LFS getstripe -m $fname)
4225                 [ $index -eq $index2 ] ||
4226                         error "$fname MDT index mismatch $index != $index2"
4227         done
4228
4229         local failed=0
4230         for i in {1..250}; do
4231                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4232                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4233                         touch $fname  || error "touch $fname failed"
4234                         index2=$($LFS getstripe -m $fname)
4235                         if [[ $index != $index2 ]]; then
4236                                 failed=$((failed + 1))
4237                                 echo "$fname MDT index mismatch $index != $index2"
4238                         fi
4239                 done
4240         done
4241         echo "$failed MDT index mismatches"
4242         (( failed < 20 )) || error "MDT index mismatch $failed times"
4243
4244 }
4245 run_test 33h "temp file is located on the same MDT as target"
4246
4247 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4248 test_34a() {
4249         rm -f $DIR/f34
4250         $MCREATE $DIR/f34 || error "mcreate failed"
4251         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4252                 error "getstripe failed"
4253         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4254         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4255                 error "getstripe failed"
4256         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4257                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4258 }
4259 run_test 34a "truncate file that has not been opened ==========="
4260
4261 test_34b() {
4262         [ ! -f $DIR/f34 ] && test_34a
4263         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4264                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4265         $OPENFILE -f O_RDONLY $DIR/f34
4266         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4267                 error "getstripe failed"
4268         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4269                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4270 }
4271 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4272
4273 test_34c() {
4274         [ ! -f $DIR/f34 ] && test_34a
4275         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4276                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4277         $OPENFILE -f O_RDWR $DIR/f34
4278         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4279                 error "$LFS getstripe failed"
4280         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4281                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4282 }
4283 run_test 34c "O_RDWR opening file-with-size works =============="
4284
4285 test_34d() {
4286         [ ! -f $DIR/f34 ] && test_34a
4287         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4288                 error "dd failed"
4289         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4290                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4291         rm $DIR/f34
4292 }
4293 run_test 34d "write to sparse file ============================="
4294
4295 test_34e() {
4296         rm -f $DIR/f34e
4297         $MCREATE $DIR/f34e || error "mcreate failed"
4298         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4299         $CHECKSTAT -s 1000 $DIR/f34e ||
4300                 error "Size of $DIR/f34e not equal to 1000 bytes"
4301         $OPENFILE -f O_RDWR $DIR/f34e
4302         $CHECKSTAT -s 1000 $DIR/f34e ||
4303                 error "Size of $DIR/f34e not equal to 1000 bytes"
4304 }
4305 run_test 34e "create objects, some with size and some without =="
4306
4307 test_34f() { # bug 6242, 6243
4308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4309
4310         SIZE34F=48000
4311         rm -f $DIR/f34f
4312         $MCREATE $DIR/f34f || error "mcreate failed"
4313         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4314         dd if=$DIR/f34f of=$TMP/f34f
4315         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4316         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4317         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4318         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4319         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4320 }
4321 run_test 34f "read from a file with no objects until EOF ======="
4322
4323 test_34g() {
4324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4325
4326         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4327                 error "dd failed"
4328         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4329         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4330                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4331         cancel_lru_locks osc
4332         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4333                 error "wrong size after lock cancel"
4334
4335         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4336         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4337                 error "expanding truncate failed"
4338         cancel_lru_locks osc
4339         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4340                 error "wrong expanded size after lock cancel"
4341 }
4342 run_test 34g "truncate long file ==============================="
4343
4344 test_34h() {
4345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4346
4347         local gid=10
4348         local sz=1000
4349
4350         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4351         sync # Flush the cache so that multiop below does not block on cache
4352              # flush when getting the group lock
4353         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4354         MULTIPID=$!
4355
4356         # Since just timed wait is not good enough, let's do a sync write
4357         # that way we are sure enough time for a roundtrip + processing
4358         # passed + 2 seconds of extra margin.
4359         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4360         rm $DIR/${tfile}-1
4361         sleep 2
4362
4363         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4364                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4365                 kill -9 $MULTIPID
4366         fi
4367         wait $MULTIPID
4368         local nsz=`stat -c %s $DIR/$tfile`
4369         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4370 }
4371 run_test 34h "ftruncate file under grouplock should not block"
4372
4373 test_35a() {
4374         cp /bin/sh $DIR/f35a
4375         chmod 444 $DIR/f35a
4376         chown $RUNAS_ID $DIR/f35a
4377         $RUNAS $DIR/f35a && error || true
4378         rm $DIR/f35a
4379 }
4380 run_test 35a "exec file with mode 444 (should return and not leak)"
4381
4382 test_36a() {
4383         rm -f $DIR/f36
4384         utime $DIR/f36 || error "utime failed for MDS"
4385 }
4386 run_test 36a "MDS utime check (mknod, utime)"
4387
4388 test_36b() {
4389         echo "" > $DIR/f36
4390         utime $DIR/f36 || error "utime failed for OST"
4391 }
4392 run_test 36b "OST utime check (open, utime)"
4393
4394 test_36c() {
4395         rm -f $DIR/d36/f36
4396         test_mkdir $DIR/d36
4397         chown $RUNAS_ID $DIR/d36
4398         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4399 }
4400 run_test 36c "non-root MDS utime check (mknod, utime)"
4401
4402 test_36d() {
4403         [ ! -d $DIR/d36 ] && test_36c
4404         echo "" > $DIR/d36/f36
4405         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4406 }
4407 run_test 36d "non-root OST utime check (open, utime)"
4408
4409 test_36e() {
4410         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4411
4412         test_mkdir $DIR/$tdir
4413         touch $DIR/$tdir/$tfile
4414         $RUNAS utime $DIR/$tdir/$tfile &&
4415                 error "utime worked, expected failure" || true
4416 }
4417 run_test 36e "utime on non-owned file (should return error)"
4418
4419 subr_36fh() {
4420         local fl="$1"
4421         local LANG_SAVE=$LANG
4422         local LC_LANG_SAVE=$LC_LANG
4423         export LANG=C LC_LANG=C # for date language
4424
4425         DATESTR="Dec 20  2000"
4426         test_mkdir $DIR/$tdir
4427         lctl set_param fail_loc=$fl
4428         date; date +%s
4429         cp /etc/hosts $DIR/$tdir/$tfile
4430         sync & # write RPC generated with "current" inode timestamp, but delayed
4431         sleep 1
4432         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4433         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4434         cancel_lru_locks $OSC
4435         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4436         date; date +%s
4437         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4438                 echo "BEFORE: $LS_BEFORE" && \
4439                 echo "AFTER : $LS_AFTER" && \
4440                 echo "WANT  : $DATESTR" && \
4441                 error "$DIR/$tdir/$tfile timestamps changed" || true
4442
4443         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4444 }
4445
4446 test_36f() {
4447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4448
4449         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4450         subr_36fh "0x80000214"
4451 }
4452 run_test 36f "utime on file racing with OST BRW write =========="
4453
4454 test_36g() {
4455         remote_ost_nodsh && skip "remote OST with nodsh"
4456         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4457         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4458                 skip "Need MDS version at least 2.12.51"
4459
4460         local fmd_max_age
4461         local fmd
4462         local facet="ost1"
4463         local tgt="obdfilter"
4464
4465         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4466
4467         test_mkdir $DIR/$tdir
4468         fmd_max_age=$(do_facet $facet \
4469                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4470                 head -n 1")
4471
4472         echo "FMD max age: ${fmd_max_age}s"
4473         touch $DIR/$tdir/$tfile
4474         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4475                 gawk '{cnt=cnt+$1}  END{print cnt}')
4476         echo "FMD before: $fmd"
4477         [[ $fmd == 0 ]] &&
4478                 error "FMD wasn't create by touch"
4479         sleep $((fmd_max_age + 12))
4480         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4481                 gawk '{cnt=cnt+$1}  END{print cnt}')
4482         echo "FMD after: $fmd"
4483         [[ $fmd == 0 ]] ||
4484                 error "FMD wasn't expired by ping"
4485 }
4486 run_test 36g "FMD cache expiry ====================="
4487
4488 test_36h() {
4489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4490
4491         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4492         subr_36fh "0x80000227"
4493 }
4494 run_test 36h "utime on file racing with OST BRW write =========="
4495
4496 test_36i() {
4497         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4498
4499         test_mkdir $DIR/$tdir
4500         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4501
4502         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4503         local new_mtime=$((mtime + 200))
4504
4505         #change Modify time of striped dir
4506         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4507                         error "change mtime failed"
4508
4509         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4510
4511         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4512 }
4513 run_test 36i "change mtime on striped directory"
4514
4515 # test_37 - duplicate with tests 32q 32r
4516
4517 test_38() {
4518         local file=$DIR/$tfile
4519         touch $file
4520         openfile -f O_DIRECTORY $file
4521         local RC=$?
4522         local ENOTDIR=20
4523         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4524         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4525 }
4526 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4527
4528 test_39a() { # was test_39
4529         touch $DIR/$tfile
4530         touch $DIR/${tfile}2
4531 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4532 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4533 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4534         sleep 2
4535         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4536         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4537                 echo "mtime"
4538                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4539                 echo "atime"
4540                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4541                 echo "ctime"
4542                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4543                 error "O_TRUNC didn't change timestamps"
4544         fi
4545 }
4546 run_test 39a "mtime changed on create"
4547
4548 test_39b() {
4549         test_mkdir -c1 $DIR/$tdir
4550         cp -p /etc/passwd $DIR/$tdir/fopen
4551         cp -p /etc/passwd $DIR/$tdir/flink
4552         cp -p /etc/passwd $DIR/$tdir/funlink
4553         cp -p /etc/passwd $DIR/$tdir/frename
4554         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4555
4556         sleep 1
4557         echo "aaaaaa" >> $DIR/$tdir/fopen
4558         echo "aaaaaa" >> $DIR/$tdir/flink
4559         echo "aaaaaa" >> $DIR/$tdir/funlink
4560         echo "aaaaaa" >> $DIR/$tdir/frename
4561
4562         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4563         local link_new=`stat -c %Y $DIR/$tdir/flink`
4564         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4565         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4566
4567         cat $DIR/$tdir/fopen > /dev/null
4568         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4569         rm -f $DIR/$tdir/funlink2
4570         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4571
4572         for (( i=0; i < 2; i++ )) ; do
4573                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4574                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4575                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4576                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4577
4578                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4579                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4580                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4581                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4582
4583                 cancel_lru_locks $OSC
4584                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4585         done
4586 }
4587 run_test 39b "mtime change on open, link, unlink, rename  ======"
4588
4589 # this should be set to past
4590 TEST_39_MTIME=`date -d "1 year ago" +%s`
4591
4592 # bug 11063
4593 test_39c() {
4594         touch $DIR1/$tfile
4595         sleep 2
4596         local mtime0=`stat -c %Y $DIR1/$tfile`
4597
4598         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4599         local mtime1=`stat -c %Y $DIR1/$tfile`
4600         [ "$mtime1" = $TEST_39_MTIME ] || \
4601                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4602
4603         local d1=`date +%s`
4604         echo hello >> $DIR1/$tfile
4605         local d2=`date +%s`
4606         local mtime2=`stat -c %Y $DIR1/$tfile`
4607         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4608                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4609
4610         mv $DIR1/$tfile $DIR1/$tfile-1
4611
4612         for (( i=0; i < 2; i++ )) ; do
4613                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4614                 [ "$mtime2" = "$mtime3" ] || \
4615                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4616
4617                 cancel_lru_locks $OSC
4618                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4619         done
4620 }
4621 run_test 39c "mtime change on rename ==========================="
4622
4623 # bug 21114
4624 test_39d() {
4625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4626
4627         touch $DIR1/$tfile
4628         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4629
4630         for (( i=0; i < 2; i++ )) ; do
4631                 local mtime=`stat -c %Y $DIR1/$tfile`
4632                 [ $mtime = $TEST_39_MTIME ] || \
4633                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4634
4635                 cancel_lru_locks $OSC
4636                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4637         done
4638 }
4639 run_test 39d "create, utime, stat =============================="
4640
4641 # bug 21114
4642 test_39e() {
4643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4644
4645         touch $DIR1/$tfile
4646         local mtime1=`stat -c %Y $DIR1/$tfile`
4647
4648         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4649
4650         for (( i=0; i < 2; i++ )) ; do
4651                 local mtime2=`stat -c %Y $DIR1/$tfile`
4652                 [ $mtime2 = $TEST_39_MTIME ] || \
4653                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4654
4655                 cancel_lru_locks $OSC
4656                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4657         done
4658 }
4659 run_test 39e "create, stat, utime, stat ========================"
4660
4661 # bug 21114
4662 test_39f() {
4663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4664
4665         touch $DIR1/$tfile
4666         mtime1=`stat -c %Y $DIR1/$tfile`
4667
4668         sleep 2
4669         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4670
4671         for (( i=0; i < 2; i++ )) ; do
4672                 local mtime2=`stat -c %Y $DIR1/$tfile`
4673                 [ $mtime2 = $TEST_39_MTIME ] || \
4674                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4675
4676                 cancel_lru_locks $OSC
4677                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4678         done
4679 }
4680 run_test 39f "create, stat, sleep, utime, stat ================="
4681
4682 # bug 11063
4683 test_39g() {
4684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4685
4686         echo hello >> $DIR1/$tfile
4687         local mtime1=`stat -c %Y $DIR1/$tfile`
4688
4689         sleep 2
4690         chmod o+r $DIR1/$tfile
4691
4692         for (( i=0; i < 2; i++ )) ; do
4693                 local mtime2=`stat -c %Y $DIR1/$tfile`
4694                 [ "$mtime1" = "$mtime2" ] || \
4695                         error "lost mtime: $mtime2, should be $mtime1"
4696
4697                 cancel_lru_locks $OSC
4698                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4699         done
4700 }
4701 run_test 39g "write, chmod, stat ==============================="
4702
4703 # bug 11063
4704 test_39h() {
4705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4706
4707         touch $DIR1/$tfile
4708         sleep 1
4709
4710         local d1=`date`
4711         echo hello >> $DIR1/$tfile
4712         local mtime1=`stat -c %Y $DIR1/$tfile`
4713
4714         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4715         local d2=`date`
4716         if [ "$d1" != "$d2" ]; then
4717                 echo "write and touch not within one second"
4718         else
4719                 for (( i=0; i < 2; i++ )) ; do
4720                         local mtime2=`stat -c %Y $DIR1/$tfile`
4721                         [ "$mtime2" = $TEST_39_MTIME ] || \
4722                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4723
4724                         cancel_lru_locks $OSC
4725                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4726                 done
4727         fi
4728 }
4729 run_test 39h "write, utime within one second, stat ============="
4730
4731 test_39i() {
4732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4733
4734         touch $DIR1/$tfile
4735         sleep 1
4736
4737         echo hello >> $DIR1/$tfile
4738         local mtime1=`stat -c %Y $DIR1/$tfile`
4739
4740         mv $DIR1/$tfile $DIR1/$tfile-1
4741
4742         for (( i=0; i < 2; i++ )) ; do
4743                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4744
4745                 [ "$mtime1" = "$mtime2" ] || \
4746                         error "lost mtime: $mtime2, should be $mtime1"
4747
4748                 cancel_lru_locks $OSC
4749                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4750         done
4751 }
4752 run_test 39i "write, rename, stat =============================="
4753
4754 test_39j() {
4755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4756
4757         start_full_debug_logging
4758         touch $DIR1/$tfile
4759         sleep 1
4760
4761         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4762         lctl set_param fail_loc=0x80000412
4763         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4764                 error "multiop failed"
4765         local multipid=$!
4766         local mtime1=`stat -c %Y $DIR1/$tfile`
4767
4768         mv $DIR1/$tfile $DIR1/$tfile-1
4769
4770         kill -USR1 $multipid
4771         wait $multipid || error "multiop close failed"
4772
4773         for (( i=0; i < 2; i++ )) ; do
4774                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4775                 [ "$mtime1" = "$mtime2" ] ||
4776                         error "mtime is lost on close: $mtime2, " \
4777                               "should be $mtime1"
4778
4779                 cancel_lru_locks
4780                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4781         done
4782         lctl set_param fail_loc=0
4783         stop_full_debug_logging
4784 }
4785 run_test 39j "write, rename, close, stat ======================="
4786
4787 test_39k() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         touch $DIR1/$tfile
4791         sleep 1
4792
4793         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4794         local multipid=$!
4795         local mtime1=`stat -c %Y $DIR1/$tfile`
4796
4797         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4798
4799         kill -USR1 $multipid
4800         wait $multipid || error "multiop close failed"
4801
4802         for (( i=0; i < 2; i++ )) ; do
4803                 local mtime2=`stat -c %Y $DIR1/$tfile`
4804
4805                 [ "$mtime2" = $TEST_39_MTIME ] || \
4806                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4807
4808                 cancel_lru_locks
4809                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4810         done
4811 }
4812 run_test 39k "write, utime, close, stat ========================"
4813
4814 # this should be set to future
4815 TEST_39_ATIME=`date -d "1 year" +%s`
4816
4817 test_39l() {
4818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4819         remote_mds_nodsh && skip "remote MDS with nodsh"
4820
4821         local atime_diff=$(do_facet $SINGLEMDS \
4822                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4823         rm -rf $DIR/$tdir
4824         mkdir_on_mdt0 $DIR/$tdir
4825
4826         # test setting directory atime to future
4827         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4828         local atime=$(stat -c %X $DIR/$tdir)
4829         [ "$atime" = $TEST_39_ATIME ] ||
4830                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4831
4832         # test setting directory atime from future to now
4833         local now=$(date +%s)
4834         touch -a -d @$now $DIR/$tdir
4835
4836         atime=$(stat -c %X $DIR/$tdir)
4837         [ "$atime" -eq "$now"  ] ||
4838                 error "atime is not updated from future: $atime, $now"
4839
4840         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4841         sleep 3
4842
4843         # test setting directory atime when now > dir atime + atime_diff
4844         local d1=$(date +%s)
4845         ls $DIR/$tdir
4846         local d2=$(date +%s)
4847         cancel_lru_locks mdc
4848         atime=$(stat -c %X $DIR/$tdir)
4849         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4850                 error "atime is not updated  : $atime, should be $d2"
4851
4852         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4853         sleep 3
4854
4855         # test not setting directory atime when now < dir atime + atime_diff
4856         ls $DIR/$tdir
4857         cancel_lru_locks mdc
4858         atime=$(stat -c %X $DIR/$tdir)
4859         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4860                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4861
4862         do_facet $SINGLEMDS \
4863                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4864 }
4865 run_test 39l "directory atime update ==========================="
4866
4867 test_39m() {
4868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4869
4870         touch $DIR1/$tfile
4871         sleep 2
4872         local far_past_mtime=$(date -d "May 29 1953" +%s)
4873         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4874
4875         touch -m -d @$far_past_mtime $DIR1/$tfile
4876         touch -a -d @$far_past_atime $DIR1/$tfile
4877
4878         for (( i=0; i < 2; i++ )) ; do
4879                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4880                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4881                         error "atime or mtime set incorrectly"
4882
4883                 cancel_lru_locks $OSC
4884                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4885         done
4886 }
4887 run_test 39m "test atime and mtime before 1970"
4888
4889 test_39n() { # LU-3832
4890         remote_mds_nodsh && skip "remote MDS with nodsh"
4891
4892         local atime_diff=$(do_facet $SINGLEMDS \
4893                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4894         local atime0
4895         local atime1
4896         local atime2
4897
4898         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4899
4900         rm -rf $DIR/$tfile
4901         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4902         atime0=$(stat -c %X $DIR/$tfile)
4903
4904         sleep 5
4905         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4906         atime1=$(stat -c %X $DIR/$tfile)
4907
4908         sleep 5
4909         cancel_lru_locks mdc
4910         cancel_lru_locks osc
4911         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4912         atime2=$(stat -c %X $DIR/$tfile)
4913
4914         do_facet $SINGLEMDS \
4915                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4916
4917         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4918         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4919 }
4920 run_test 39n "check that O_NOATIME is honored"
4921
4922 test_39o() {
4923         TESTDIR=$DIR/$tdir/$tfile
4924         [ -e $TESTDIR ] && rm -rf $TESTDIR
4925         mkdir -p $TESTDIR
4926         cd $TESTDIR
4927         links1=2
4928         ls
4929         mkdir a b
4930         ls
4931         links2=$(stat -c %h .)
4932         [ $(($links1 + 2)) != $links2 ] &&
4933                 error "wrong links count $(($links1 + 2)) != $links2"
4934         rmdir b
4935         links3=$(stat -c %h .)
4936         [ $(($links1 + 1)) != $links3 ] &&
4937                 error "wrong links count $links1 != $links3"
4938         return 0
4939 }
4940 run_test 39o "directory cached attributes updated after create"
4941
4942 test_39p() {
4943         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4944
4945         local MDTIDX=1
4946         TESTDIR=$DIR/$tdir/$tdir
4947         [ -e $TESTDIR ] && rm -rf $TESTDIR
4948         test_mkdir -p $TESTDIR
4949         cd $TESTDIR
4950         links1=2
4951         ls
4952         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4953         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4954         ls
4955         links2=$(stat -c %h .)
4956         [ $(($links1 + 2)) != $links2 ] &&
4957                 error "wrong links count $(($links1 + 2)) != $links2"
4958         rmdir remote_dir2
4959         links3=$(stat -c %h .)
4960         [ $(($links1 + 1)) != $links3 ] &&
4961                 error "wrong links count $links1 != $links3"
4962         return 0
4963 }
4964 run_test 39p "remote directory cached attributes updated after create ========"
4965
4966 test_39r() {
4967         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4968                 skip "no atime update on old OST"
4969         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4970                 skip_env "ldiskfs only test"
4971         fi
4972
4973         local saved_adiff
4974         saved_adiff=$(do_facet ost1 \
4975                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4976         stack_trap "do_facet ost1 \
4977                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4978
4979         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4980
4981         $LFS setstripe -i 0 $DIR/$tfile
4982         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4983                 error "can't write initial file"
4984         cancel_lru_locks osc
4985
4986         # exceed atime_diff and access file
4987         sleep 6
4988         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4989                 error "can't udpate atime"
4990
4991         local atime_cli=$(stat -c %X $DIR/$tfile)
4992         echo "client atime: $atime_cli"
4993         # allow atime update to be written to device
4994         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4995         sleep 5
4996
4997         local ostdev=$(ostdevname 1)
4998         local fid=($(lfs getstripe -y $DIR/$tfile |
4999                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5000         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5001         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5002
5003         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5004         local atime_ost=$(do_facet ost1 "$cmd" |&
5005                           awk -F'[: ]' '/atime:/ { print $4 }')
5006         (( atime_cli == atime_ost )) ||
5007                 error "atime on client $atime_cli != ost $atime_ost"
5008 }
5009 run_test 39r "lazy atime update on OST"
5010
5011 test_39q() { # LU-8041
5012         local testdir=$DIR/$tdir
5013         mkdir -p $testdir
5014         multiop_bg_pause $testdir D_c || error "multiop failed"
5015         local multipid=$!
5016         cancel_lru_locks mdc
5017         kill -USR1 $multipid
5018         local atime=$(stat -c %X $testdir)
5019         [ "$atime" -ne 0 ] || error "atime is zero"
5020 }
5021 run_test 39q "close won't zero out atime"
5022
5023 test_40() {
5024         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5025         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5026                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5027         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5028                 error "$tfile is not 4096 bytes in size"
5029 }
5030 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5031
5032 test_41() {
5033         # bug 1553
5034         small_write $DIR/f41 18
5035 }
5036 run_test 41 "test small file write + fstat ====================="
5037
5038 count_ost_writes() {
5039         lctl get_param -n ${OSC}.*.stats |
5040                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5041                         END { printf("%0.0f", writes) }'
5042 }
5043
5044 # decent default
5045 WRITEBACK_SAVE=500
5046 DIRTY_RATIO_SAVE=40
5047 MAX_DIRTY_RATIO=50
5048 BG_DIRTY_RATIO_SAVE=10
5049 MAX_BG_DIRTY_RATIO=25
5050
5051 start_writeback() {
5052         trap 0
5053         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5054         # dirty_ratio, dirty_background_ratio
5055         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5056                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5057                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5058                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5059         else
5060                 # if file not here, we are a 2.4 kernel
5061                 kill -CONT `pidof kupdated`
5062         fi
5063 }
5064
5065 stop_writeback() {
5066         # setup the trap first, so someone cannot exit the test at the
5067         # exact wrong time and mess up a machine
5068         trap start_writeback EXIT
5069         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5070         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5071                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5072                 sysctl -w vm.dirty_writeback_centisecs=0
5073                 sysctl -w vm.dirty_writeback_centisecs=0
5074                 # save and increase /proc/sys/vm/dirty_ratio
5075                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5076                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5077                 # save and increase /proc/sys/vm/dirty_background_ratio
5078                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5079                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5080         else
5081                 # if file not here, we are a 2.4 kernel
5082                 kill -STOP `pidof kupdated`
5083         fi
5084 }
5085
5086 # ensure that all stripes have some grant before we test client-side cache
5087 setup_test42() {
5088         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5089                 dd if=/dev/zero of=$i bs=4k count=1
5090                 rm $i
5091         done
5092 }
5093
5094 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5095 # file truncation, and file removal.
5096 test_42a() {
5097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5098
5099         setup_test42
5100         cancel_lru_locks $OSC
5101         stop_writeback
5102         sync; sleep 1; sync # just to be safe
5103         BEFOREWRITES=`count_ost_writes`
5104         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5105         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5106         AFTERWRITES=`count_ost_writes`
5107         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5108                 error "$BEFOREWRITES < $AFTERWRITES"
5109         start_writeback
5110 }
5111 run_test 42a "ensure that we don't flush on close"
5112
5113 test_42b() {
5114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5115
5116         setup_test42
5117         cancel_lru_locks $OSC
5118         stop_writeback
5119         sync
5120         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5121         BEFOREWRITES=$(count_ost_writes)
5122         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5123         AFTERWRITES=$(count_ost_writes)
5124         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5125                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5126         fi
5127         BEFOREWRITES=$(count_ost_writes)
5128         sync || error "sync: $?"
5129         AFTERWRITES=$(count_ost_writes)
5130         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5131                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5132         fi
5133         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5134         start_writeback
5135         return 0
5136 }
5137 run_test 42b "test destroy of file with cached dirty data ======"
5138
5139 # if these tests just want to test the effect of truncation,
5140 # they have to be very careful.  consider:
5141 # - the first open gets a {0,EOF}PR lock
5142 # - the first write conflicts and gets a {0, count-1}PW
5143 # - the rest of the writes are under {count,EOF}PW
5144 # - the open for truncate tries to match a {0,EOF}PR
5145 #   for the filesize and cancels the PWs.
5146 # any number of fixes (don't get {0,EOF} on open, match
5147 # composite locks, do smarter file size management) fix
5148 # this, but for now we want these tests to verify that
5149 # the cancellation with truncate intent works, so we
5150 # start the file with a full-file pw lock to match against
5151 # until the truncate.
5152 trunc_test() {
5153         test=$1
5154         file=$DIR/$test
5155         offset=$2
5156         cancel_lru_locks $OSC
5157         stop_writeback
5158         # prime the file with 0,EOF PW to match
5159         touch $file
5160         $TRUNCATE $file 0
5161         sync; sync
5162         # now the real test..
5163         dd if=/dev/zero of=$file bs=1024 count=100
5164         BEFOREWRITES=`count_ost_writes`
5165         $TRUNCATE $file $offset
5166         cancel_lru_locks $OSC
5167         AFTERWRITES=`count_ost_writes`
5168         start_writeback
5169 }
5170
5171 test_42c() {
5172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5173
5174         trunc_test 42c 1024
5175         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5176                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5177         rm $file
5178 }
5179 run_test 42c "test partial truncate of file with cached dirty data"
5180
5181 test_42d() {
5182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5183
5184         trunc_test 42d 0
5185         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5186                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5187         rm $file
5188 }
5189 run_test 42d "test complete truncate of file with cached dirty data"
5190
5191 test_42e() { # bug22074
5192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5193
5194         local TDIR=$DIR/${tdir}e
5195         local pages=16 # hardcoded 16 pages, don't change it.
5196         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5197         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5198         local max_dirty_mb
5199         local warmup_files
5200
5201         test_mkdir $DIR/${tdir}e
5202         $LFS setstripe -c 1 $TDIR
5203         createmany -o $TDIR/f $files
5204
5205         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5206
5207         # we assume that with $OSTCOUNT files, at least one of them will
5208         # be allocated on OST0.
5209         warmup_files=$((OSTCOUNT * max_dirty_mb))
5210         createmany -o $TDIR/w $warmup_files
5211
5212         # write a large amount of data into one file and sync, to get good
5213         # avail_grant number from OST.
5214         for ((i=0; i<$warmup_files; i++)); do
5215                 idx=$($LFS getstripe -i $TDIR/w$i)
5216                 [ $idx -ne 0 ] && continue
5217                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5218                 break
5219         done
5220         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5221         sync
5222         $LCTL get_param $proc_osc0/cur_dirty_bytes
5223         $LCTL get_param $proc_osc0/cur_grant_bytes
5224
5225         # create as much dirty pages as we can while not to trigger the actual
5226         # RPCs directly. but depends on the env, VFS may trigger flush during this
5227         # period, hopefully we are good.
5228         for ((i=0; i<$warmup_files; i++)); do
5229                 idx=$($LFS getstripe -i $TDIR/w$i)
5230                 [ $idx -ne 0 ] && continue
5231                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5232         done
5233         $LCTL get_param $proc_osc0/cur_dirty_bytes
5234         $LCTL get_param $proc_osc0/cur_grant_bytes
5235
5236         # perform the real test
5237         $LCTL set_param $proc_osc0/rpc_stats 0
5238         for ((;i<$files; i++)); do
5239                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5240                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5241         done
5242         sync
5243         $LCTL get_param $proc_osc0/rpc_stats
5244
5245         local percent=0
5246         local have_ppr=false
5247         $LCTL get_param $proc_osc0/rpc_stats |
5248                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5249                         # skip lines until we are at the RPC histogram data
5250                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5251                         $have_ppr || continue
5252
5253                         # we only want the percent stat for < 16 pages
5254                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5255
5256                         percent=$((percent + WPCT))
5257                         if [[ $percent -gt 15 ]]; then
5258                                 error "less than 16-pages write RPCs" \
5259                                       "$percent% > 15%"
5260                                 break
5261                         fi
5262                 done
5263         rm -rf $TDIR
5264 }
5265 run_test 42e "verify sub-RPC writes are not done synchronously"
5266
5267 test_43A() { # was test_43
5268         test_mkdir $DIR/$tdir
5269         cp -p /bin/ls $DIR/$tdir/$tfile
5270         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5271         pid=$!
5272         # give multiop a chance to open
5273         sleep 1
5274
5275         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5276         kill -USR1 $pid
5277         # Wait for multiop to exit
5278         wait $pid
5279 }
5280 run_test 43A "execution of file opened for write should return -ETXTBSY"
5281
5282 test_43a() {
5283         test_mkdir $DIR/$tdir
5284         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5285         $DIR/$tdir/sleep 60 &
5286         SLEEP_PID=$!
5287         # Make sure exec of $tdir/sleep wins race with truncate
5288         sleep 1
5289         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5290         kill $SLEEP_PID
5291 }
5292 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5293
5294 test_43b() {
5295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5296
5297         test_mkdir $DIR/$tdir
5298         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5299         $DIR/$tdir/sleep 60 &
5300         SLEEP_PID=$!
5301         # Make sure exec of $tdir/sleep wins race with truncate
5302         sleep 1
5303         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5304         kill $SLEEP_PID
5305 }
5306 run_test 43b "truncate of file being executed should return -ETXTBSY"
5307
5308 test_43c() {
5309         local testdir="$DIR/$tdir"
5310         test_mkdir $testdir
5311         cp $SHELL $testdir/
5312         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5313                 ( cd $testdir && md5sum -c )
5314 }
5315 run_test 43c "md5sum of copy into lustre"
5316
5317 test_44A() { # was test_44
5318         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5319
5320         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5321         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5322 }
5323 run_test 44A "zero length read from a sparse stripe"
5324
5325 test_44a() {
5326         local nstripe=$($LFS getstripe -c -d $DIR)
5327         [ -z "$nstripe" ] && skip "can't get stripe info"
5328         [[ $nstripe -gt $OSTCOUNT ]] &&
5329                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5330
5331         local stride=$($LFS getstripe -S -d $DIR)
5332         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5333                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5334         fi
5335
5336         OFFSETS="0 $((stride/2)) $((stride-1))"
5337         for offset in $OFFSETS; do
5338                 for i in $(seq 0 $((nstripe-1))); do
5339                         local GLOBALOFFSETS=""
5340                         # size in Bytes
5341                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5342                         local myfn=$DIR/d44a-$size
5343                         echo "--------writing $myfn at $size"
5344                         ll_sparseness_write $myfn $size ||
5345                                 error "ll_sparseness_write"
5346                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5347                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5348                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5349
5350                         for j in $(seq 0 $((nstripe-1))); do
5351                                 # size in Bytes
5352                                 size=$((((j + $nstripe )*$stride + $offset)))
5353                                 ll_sparseness_write $myfn $size ||
5354                                         error "ll_sparseness_write"
5355                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5356                         done
5357                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5358                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5359                         rm -f $myfn
5360                 done
5361         done
5362 }
5363 run_test 44a "test sparse pwrite ==============================="
5364
5365 dirty_osc_total() {
5366         tot=0
5367         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5368                 tot=$(($tot + $d))
5369         done
5370         echo $tot
5371 }
5372 do_dirty_record() {
5373         before=`dirty_osc_total`
5374         echo executing "\"$*\""
5375         eval $*
5376         after=`dirty_osc_total`
5377         echo before $before, after $after
5378 }
5379 test_45() {
5380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5381
5382         f="$DIR/f45"
5383         # Obtain grants from OST if it supports it
5384         echo blah > ${f}_grant
5385         stop_writeback
5386         sync
5387         do_dirty_record "echo blah > $f"
5388         [[ $before -eq $after ]] && error "write wasn't cached"
5389         do_dirty_record "> $f"
5390         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5391         do_dirty_record "echo blah > $f"
5392         [[ $before -eq $after ]] && error "write wasn't cached"
5393         do_dirty_record "sync"
5394         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5395         do_dirty_record "echo blah > $f"
5396         [[ $before -eq $after ]] && error "write wasn't cached"
5397         do_dirty_record "cancel_lru_locks osc"
5398         [[ $before -gt $after ]] ||
5399                 error "lock cancellation didn't lower dirty count"
5400         start_writeback
5401 }
5402 run_test 45 "osc io page accounting ============================"
5403
5404 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5405 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5406 # objects offset and an assert hit when an rpc was built with 1023's mapped
5407 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5408 test_46() {
5409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5410
5411         f="$DIR/f46"
5412         stop_writeback
5413         sync
5414         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5415         sync
5416         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5417         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5418         sync
5419         start_writeback
5420 }
5421 run_test 46 "dirtying a previously written page ================"
5422
5423 # test_47 is removed "Device nodes check" is moved to test_28
5424
5425 test_48a() { # bug 2399
5426         [ "$mds1_FSTYPE" = "zfs" ] &&
5427         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5428                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5429
5430         test_mkdir $DIR/$tdir
5431         cd $DIR/$tdir
5432         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5433         test_mkdir $DIR/$tdir
5434         touch foo || error "'touch foo' failed after recreating cwd"
5435         test_mkdir bar
5436         touch .foo || error "'touch .foo' failed after recreating cwd"
5437         test_mkdir .bar
5438         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5439         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5440         cd . || error "'cd .' failed after recreating cwd"
5441         mkdir . && error "'mkdir .' worked after recreating cwd"
5442         rmdir . && error "'rmdir .' worked after recreating cwd"
5443         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5444         cd .. || error "'cd ..' failed after recreating cwd"
5445 }
5446 run_test 48a "Access renamed working dir (should return errors)="
5447
5448 test_48b() { # bug 2399
5449         rm -rf $DIR/$tdir
5450         test_mkdir $DIR/$tdir
5451         cd $DIR/$tdir
5452         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5453         touch foo && error "'touch foo' worked after removing cwd"
5454         mkdir foo && error "'mkdir foo' worked after removing cwd"
5455         touch .foo && error "'touch .foo' worked after removing cwd"
5456         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5457         ls . > /dev/null && error "'ls .' worked after removing cwd"
5458         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5459         mkdir . && error "'mkdir .' worked after removing cwd"
5460         rmdir . && error "'rmdir .' worked after removing cwd"
5461         ln -s . foo && error "'ln -s .' worked after removing cwd"
5462         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5463 }
5464 run_test 48b "Access removed working dir (should return errors)="
5465
5466 test_48c() { # bug 2350
5467         #lctl set_param debug=-1
5468         #set -vx
5469         rm -rf $DIR/$tdir
5470         test_mkdir -p $DIR/$tdir/dir
5471         cd $DIR/$tdir/dir
5472         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5473         $TRACE touch foo && error "touch foo worked after removing cwd"
5474         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5475         touch .foo && error "touch .foo worked after removing cwd"
5476         mkdir .foo && error "mkdir .foo worked after removing cwd"
5477         $TRACE ls . && error "'ls .' worked after removing cwd"
5478         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5479         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5480         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5481         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5482         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5483 }
5484 run_test 48c "Access removed working subdir (should return errors)"
5485
5486 test_48d() { # bug 2350
5487         #lctl set_param debug=-1
5488         #set -vx
5489         rm -rf $DIR/$tdir
5490         test_mkdir -p $DIR/$tdir/dir
5491         cd $DIR/$tdir/dir
5492         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5493         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5494         $TRACE touch foo && error "'touch foo' worked after removing parent"
5495         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5496         touch .foo && error "'touch .foo' worked after removing parent"
5497         mkdir .foo && error "mkdir .foo worked after removing parent"
5498         $TRACE ls . && error "'ls .' worked after removing parent"
5499         $TRACE ls .. && error "'ls ..' worked after removing parent"
5500         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5501         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5502         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5503         true
5504 }
5505 run_test 48d "Access removed parent subdir (should return errors)"
5506
5507 test_48e() { # bug 4134
5508         #lctl set_param debug=-1
5509         #set -vx
5510         rm -rf $DIR/$tdir
5511         test_mkdir -p $DIR/$tdir/dir
5512         cd $DIR/$tdir/dir
5513         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5514         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5515         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5516         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5517         # On a buggy kernel addition of "touch foo" after cd .. will
5518         # produce kernel oops in lookup_hash_it
5519         touch ../foo && error "'cd ..' worked after recreate parent"
5520         cd $DIR
5521         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5522 }
5523 run_test 48e "Access to recreated parent subdir (should return errors)"
5524
5525 test_48f() {
5526         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5527                 skip "need MDS >= 2.13.55"
5528         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5529         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5530                 skip "needs different host for mdt1 mdt2"
5531         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5532
5533         $LFS mkdir -i0 $DIR/$tdir
5534         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5535
5536         for d in sub1 sub2 sub3; do
5537                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5538                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5539                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5540         done
5541
5542         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5543 }
5544 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5545
5546 test_49() { # LU-1030
5547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5548         remote_ost_nodsh && skip "remote OST with nodsh"
5549
5550         # get ost1 size - $FSNAME-OST0000
5551         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5552                 awk '{ print $4 }')
5553         # write 800M at maximum
5554         [[ $ost1_size -lt 2 ]] && ost1_size=2
5555         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5556
5557         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5558         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5559         local dd_pid=$!
5560
5561         # change max_pages_per_rpc while writing the file
5562         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5563         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5564         # loop until dd process exits
5565         while ps ax -opid | grep -wq $dd_pid; do
5566                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5567                 sleep $((RANDOM % 5 + 1))
5568         done
5569         # restore original max_pages_per_rpc
5570         $LCTL set_param $osc1_mppc=$orig_mppc
5571         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5572 }
5573 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5574
5575 test_50() {
5576         # bug 1485
5577         test_mkdir $DIR/$tdir
5578         cd $DIR/$tdir
5579         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5580 }
5581 run_test 50 "special situations: /proc symlinks  ==============="
5582
5583 test_51a() {    # was test_51
5584         # bug 1516 - create an empty entry right after ".." then split dir
5585         test_mkdir -c1 $DIR/$tdir
5586         touch $DIR/$tdir/foo
5587         $MCREATE $DIR/$tdir/bar
5588         rm $DIR/$tdir/foo
5589         createmany -m $DIR/$tdir/longfile 201
5590         FNUM=202
5591         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5592                 $MCREATE $DIR/$tdir/longfile$FNUM
5593                 FNUM=$(($FNUM + 1))
5594                 echo -n "+"
5595         done
5596         echo
5597         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5598 }
5599 run_test 51a "special situations: split htree with empty entry =="
5600
5601 cleanup_print_lfs_df () {
5602         trap 0
5603         $LFS df
5604         $LFS df -i
5605 }
5606
5607 test_51b() {
5608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5609
5610         local dir=$DIR/$tdir
5611         local nrdirs=$((65536 + 100))
5612
5613         # cleanup the directory
5614         rm -fr $dir
5615
5616         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5617
5618         $LFS df
5619         $LFS df -i
5620         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5621         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5622         [[ $numfree -lt $nrdirs ]] &&
5623                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5624
5625         # need to check free space for the directories as well
5626         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5627         numfree=$(( blkfree / $(fs_inode_ksize) ))
5628         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5629
5630         trap cleanup_print_lfs_df EXIT
5631
5632         # create files
5633         createmany -d $dir/d $nrdirs || {
5634                 unlinkmany $dir/d $nrdirs
5635                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5636         }
5637
5638         # really created :
5639         nrdirs=$(ls -U $dir | wc -l)
5640
5641         # unlink all but 100 subdirectories, then check it still works
5642         local left=100
5643         local delete=$((nrdirs - left))
5644
5645         $LFS df
5646         $LFS df -i
5647
5648         # for ldiskfs the nlink count should be 1, but this is OSD specific
5649         # and so this is listed for informational purposes only
5650         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5651         unlinkmany -d $dir/d $delete ||
5652                 error "unlink of first $delete subdirs failed"
5653
5654         echo "nlink between: $(stat -c %h $dir)"
5655         local found=$(ls -U $dir | wc -l)
5656         [ $found -ne $left ] &&
5657                 error "can't find subdirs: found only $found, expected $left"
5658
5659         unlinkmany -d $dir/d $delete $left ||
5660                 error "unlink of second $left subdirs failed"
5661         # regardless of whether the backing filesystem tracks nlink accurately
5662         # or not, the nlink count shouldn't be more than "." and ".." here
5663         local after=$(stat -c %h $dir)
5664         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5665                 echo "nlink after: $after"
5666
5667         cleanup_print_lfs_df
5668 }
5669 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5670
5671 test_51d() {
5672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5673         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5674         local qos_old
5675
5676         test_mkdir $DIR/$tdir
5677         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5678
5679         qos_old=$(do_facet mds1 \
5680                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5681         do_nodes $(comma_list $(mdts_nodes)) \
5682                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5683         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5684                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5685
5686         createmany -o $DIR/$tdir/t- 1000
5687         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5688         for ((n = 0; n < $OSTCOUNT; n++)); do
5689                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5690                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5691                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5692                             '($1 == '$n') { objs += 1 } \
5693                             END { printf("%0.0f", objs) }')
5694                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5695         done
5696         unlinkmany $DIR/$tdir/t- 1000
5697
5698         nlast=0
5699         for ((n = 0; n < $OSTCOUNT; n++)); do
5700                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5701                         { $LFS df && $LFS df -i &&
5702                         error "OST $n has fewer objects vs. OST $nlast" \
5703                               " (${objs[$n]} < ${objs[$nlast]}"; }
5704                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5705                         { $LFS df && $LFS df -i &&
5706                         error "OST $n has fewer objects vs. OST $nlast" \
5707                               " (${objs[$n]} < ${objs[$nlast]}"; }
5708
5709                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5710                         { $LFS df && $LFS df -i &&
5711                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5712                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5713                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5714                         { $LFS df && $LFS df -i &&
5715                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5716                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5717                 nlast=$n
5718         done
5719 }
5720 run_test 51d "check object distribution"
5721
5722 test_51e() {
5723         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5724                 skip_env "ldiskfs only test"
5725         fi
5726
5727         test_mkdir -c1 $DIR/$tdir
5728         test_mkdir -c1 $DIR/$tdir/d0
5729
5730         touch $DIR/$tdir/d0/foo
5731         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5732                 error "file exceed 65000 nlink limit!"
5733         unlinkmany $DIR/$tdir/d0/f- 65001
5734         return 0
5735 }
5736 run_test 51e "check file nlink limit"
5737
5738 test_51f() {
5739         test_mkdir $DIR/$tdir
5740
5741         local max=100000
5742         local ulimit_old=$(ulimit -n)
5743         local spare=20 # number of spare fd's for scripts/libraries, etc.
5744         local mdt=$($LFS getstripe -m $DIR/$tdir)
5745         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5746
5747         echo "MDT$mdt numfree=$numfree, max=$max"
5748         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5749         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5750                 while ! ulimit -n $((numfree + spare)); do
5751                         numfree=$((numfree * 3 / 4))
5752                 done
5753                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5754         else
5755                 echo "left ulimit at $ulimit_old"
5756         fi
5757
5758         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5759                 unlinkmany $DIR/$tdir/f $numfree
5760                 error "create+open $numfree files in $DIR/$tdir failed"
5761         }
5762         ulimit -n $ulimit_old
5763
5764         # if createmany exits at 120s there will be fewer than $numfree files
5765         unlinkmany $DIR/$tdir/f $numfree || true
5766 }
5767 run_test 51f "check many open files limit"
5768
5769 test_52a() {
5770         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5771         test_mkdir $DIR/$tdir
5772         touch $DIR/$tdir/foo
5773         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5774         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5775         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5776         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5777         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5778                                         error "link worked"
5779         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5780         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5781         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5782                                                      error "lsattr"
5783         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5784         cp -r $DIR/$tdir $TMP/
5785         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5786 }
5787 run_test 52a "append-only flag test (should return errors)"
5788
5789 test_52b() {
5790         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5791         test_mkdir $DIR/$tdir
5792         touch $DIR/$tdir/foo
5793         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5794         cat test > $DIR/$tdir/foo && error "cat test worked"
5795         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5796         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5797         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5798                                         error "link worked"
5799         echo foo >> $DIR/$tdir/foo && error "echo worked"
5800         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5801         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5802         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5803         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5804                                                         error "lsattr"
5805         chattr -i $DIR/$tdir/foo || error "chattr failed"
5806
5807         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5808 }
5809 run_test 52b "immutable flag test (should return errors) ======="
5810
5811 test_53() {
5812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5813         remote_mds_nodsh && skip "remote MDS with nodsh"
5814         remote_ost_nodsh && skip "remote OST with nodsh"
5815
5816         local param
5817         local param_seq
5818         local ostname
5819         local mds_last
5820         local mds_last_seq
5821         local ost_last
5822         local ost_last_seq
5823         local ost_last_id
5824         local ostnum
5825         local node
5826         local found=false
5827         local support_last_seq=true
5828
5829         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5830                 support_last_seq=false
5831
5832         # only test MDT0000
5833         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5834         local value
5835         for value in $(do_facet $SINGLEMDS \
5836                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5837                 param=$(echo ${value[0]} | cut -d "=" -f1)
5838                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5839
5840                 if $support_last_seq; then
5841                         param_seq=$(echo $param |
5842                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5843                         mds_last_seq=$(do_facet $SINGLEMDS \
5844                                        $LCTL get_param -n $param_seq)
5845                 fi
5846                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5847
5848                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5849                 node=$(facet_active_host ost$((ostnum+1)))
5850                 param="obdfilter.$ostname.last_id"
5851                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5852                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5853                         ost_last_id=$ost_last
5854
5855                         if $support_last_seq; then
5856                                 ost_last_id=$(echo $ost_last |
5857                                               awk -F':' '{print $2}' |
5858                                               sed -e "s/^0x//g")
5859                                 ost_last_seq=$(echo $ost_last |
5860                                                awk -F':' '{print $1}')
5861                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5862                         fi
5863
5864                         if [[ $ost_last_id != $mds_last ]]; then
5865                                 error "$ost_last_id != $mds_last"
5866                         else
5867                                 found=true
5868                                 break
5869                         fi
5870                 done
5871         done
5872         $found || error "can not match last_seq/last_id for $mdtosc"
5873         return 0
5874 }
5875 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5876
5877 test_54a() {
5878         perl -MSocket -e ';' || skip "no Socket perl module installed"
5879
5880         $SOCKETSERVER $DIR/socket ||
5881                 error "$SOCKETSERVER $DIR/socket failed: $?"
5882         $SOCKETCLIENT $DIR/socket ||
5883                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5884         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5885 }
5886 run_test 54a "unix domain socket test =========================="
5887
5888 test_54b() {
5889         f="$DIR/f54b"
5890         mknod $f c 1 3
5891         chmod 0666 $f
5892         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5893 }
5894 run_test 54b "char device works in lustre ======================"
5895
5896 find_loop_dev() {
5897         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5898         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5899         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5900
5901         for i in $(seq 3 7); do
5902                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5903                 LOOPDEV=$LOOPBASE$i
5904                 LOOPNUM=$i
5905                 break
5906         done
5907 }
5908
5909 cleanup_54c() {
5910         local rc=0
5911         loopdev="$DIR/loop54c"
5912
5913         trap 0
5914         $UMOUNT $DIR/$tdir || rc=$?
5915         losetup -d $loopdev || true
5916         losetup -d $LOOPDEV || true
5917         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5918         return $rc
5919 }
5920
5921 test_54c() {
5922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5923
5924         loopdev="$DIR/loop54c"
5925
5926         find_loop_dev
5927         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5928         trap cleanup_54c EXIT
5929         mknod $loopdev b 7 $LOOPNUM
5930         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5931         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5932         losetup $loopdev $DIR/$tfile ||
5933                 error "can't set up $loopdev for $DIR/$tfile"
5934         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5935         test_mkdir $DIR/$tdir
5936         mount -t ext2 $loopdev $DIR/$tdir ||
5937                 error "error mounting $loopdev on $DIR/$tdir"
5938         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5939                 error "dd write"
5940         df $DIR/$tdir
5941         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5942                 error "dd read"
5943         cleanup_54c
5944 }
5945 run_test 54c "block device works in lustre ====================="
5946
5947 test_54d() {
5948         f="$DIR/f54d"
5949         string="aaaaaa"
5950         mknod $f p
5951         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5952 }
5953 run_test 54d "fifo device works in lustre ======================"
5954
5955 test_54e() {
5956         f="$DIR/f54e"
5957         string="aaaaaa"
5958         cp -aL /dev/console $f
5959         echo $string > $f || error "echo $string to $f failed"
5960 }
5961 run_test 54e "console/tty device works in lustre ======================"
5962
5963 test_56a() {
5964         local numfiles=3
5965         local numdirs=2
5966         local dir=$DIR/$tdir
5967
5968         rm -rf $dir
5969         test_mkdir -p $dir/dir
5970         for i in $(seq $numfiles); do
5971                 touch $dir/file$i
5972                 touch $dir/dir/file$i
5973         done
5974
5975         local numcomp=$($LFS getstripe --component-count $dir)
5976
5977         [[ $numcomp == 0 ]] && numcomp=1
5978
5979         # test lfs getstripe with --recursive
5980         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5981
5982         [[ $filenum -eq $((numfiles * 2)) ]] ||
5983                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5984         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5985         [[ $filenum -eq $numfiles ]] ||
5986                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5987         echo "$LFS getstripe showed obdidx or l_ost_idx"
5988
5989         # test lfs getstripe with file instead of dir
5990         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5991         [[ $filenum -eq 1 ]] ||
5992                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5993         echo "$LFS getstripe file1 passed"
5994
5995         #test lfs getstripe with --verbose
5996         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5997         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5998                 error "$LFS getstripe --verbose $dir: "\
5999                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6000         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6001                 error "$LFS getstripe $dir: showed lmm_magic"
6002
6003         #test lfs getstripe with -v prints lmm_fid
6004         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6005         local countfids=$((numdirs + numfiles * numcomp))
6006         [[ $filenum -eq $countfids ]] ||
6007                 error "$LFS getstripe -v $dir: "\
6008                       "got $filenum want $countfids lmm_fid"
6009         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6010                 error "$LFS getstripe $dir: showed lmm_fid by default"
6011         echo "$LFS getstripe --verbose passed"
6012
6013         #check for FID information
6014         local fid1=$($LFS getstripe --fid $dir/file1)
6015         local fid2=$($LFS getstripe --verbose $dir/file1 |
6016                      awk '/lmm_fid: / { print $2; exit; }')
6017         local fid3=$($LFS path2fid $dir/file1)
6018
6019         [ "$fid1" != "$fid2" ] &&
6020                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6021         [ "$fid1" != "$fid3" ] &&
6022                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6023         echo "$LFS getstripe --fid passed"
6024
6025         #test lfs getstripe with --obd
6026         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6027                 error "$LFS getstripe --obd wrong_uuid: should return error"
6028
6029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6030
6031         local ostidx=1
6032         local obduuid=$(ostuuid_from_index $ostidx)
6033         local found=$($LFS getstripe -r --obd $obduuid $dir |
6034                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6035
6036         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6037         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6038                 ((filenum--))
6039         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6040                 ((filenum--))
6041
6042         [[ $found -eq $filenum ]] ||
6043                 error "$LFS getstripe --obd: found $found expect $filenum"
6044         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6045                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6046                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6047                 error "$LFS getstripe --obd: should not show file on other obd"
6048         echo "$LFS getstripe --obd passed"
6049 }
6050 run_test 56a "check $LFS getstripe"
6051
6052 test_56b() {
6053         local dir=$DIR/$tdir
6054         local numdirs=3
6055
6056         test_mkdir $dir
6057         for i in $(seq $numdirs); do
6058                 test_mkdir $dir/dir$i
6059         done
6060
6061         # test lfs getdirstripe default mode is non-recursion, which is
6062         # different from lfs getstripe
6063         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6064
6065         [[ $dircnt -eq 1 ]] ||
6066                 error "$LFS getdirstripe: found $dircnt, not 1"
6067         dircnt=$($LFS getdirstripe --recursive $dir |
6068                 grep -c lmv_stripe_count)
6069         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6070                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6071 }
6072 run_test 56b "check $LFS getdirstripe"
6073
6074 test_56c() {
6075         remote_ost_nodsh && skip "remote OST with nodsh"
6076
6077         local ost_idx=0
6078         local ost_name=$(ostname_from_index $ost_idx)
6079         local old_status=$(ost_dev_status $ost_idx)
6080         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6081
6082         [[ -z "$old_status" ]] ||
6083                 skip_env "OST $ost_name is in $old_status status"
6084
6085         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6086         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6087                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6088         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6089                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6090                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6091         fi
6092
6093         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6094                 error "$LFS df -v showing inactive devices"
6095         sleep_maxage
6096
6097         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6098
6099         [[ "$new_status" =~ "D" ]] ||
6100                 error "$ost_name status is '$new_status', missing 'D'"
6101         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6102                 [[ "$new_status" =~ "N" ]] ||
6103                         error "$ost_name status is '$new_status', missing 'N'"
6104         fi
6105         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6106                 [[ "$new_status" =~ "f" ]] ||
6107                         error "$ost_name status is '$new_status', missing 'f'"
6108         fi
6109
6110         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6111         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6112                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6113         [[ -z "$p" ]] && restore_lustre_params < $p || true
6114         sleep_maxage
6115
6116         new_status=$(ost_dev_status $ost_idx)
6117         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6118                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6119         # can't check 'f' as devices may actually be on flash
6120 }
6121 run_test 56c "check 'lfs df' showing device status"
6122
6123 test_56d() {
6124         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6125         local osts=$($LFS df -v $MOUNT | grep -c OST)
6126
6127         $LFS df $MOUNT
6128
6129         (( mdts == MDSCOUNT )) ||
6130                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6131         (( osts == OSTCOUNT )) ||
6132                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6133 }
6134 run_test 56d "'lfs df -v' prints only configured devices"
6135
6136 test_56e() {
6137         err_enoent=2 # No such file or directory
6138         err_eopnotsupp=95 # Operation not supported
6139
6140         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6141         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6142
6143         # Check for handling of path not exists
6144         output=$($LFS df $enoent_mnt 2>&1)
6145         ret=$?
6146
6147         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6148         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6149                 error "expect failure $err_enoent, not $ret"
6150
6151         # Check for handling of non-Lustre FS
6152         output=$($LFS df $notsup_mnt)
6153         ret=$?
6154
6155         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6156         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6157                 error "expect success $err_eopnotsupp, not $ret"
6158
6159         # Check for multiple LustreFS argument
6160         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6161         ret=$?
6162
6163         [[ $output -eq 3 && $ret -eq 0 ]] ||
6164                 error "expect success 3, not $output, rc = $ret"
6165
6166         # Check for correct non-Lustre FS handling among multiple
6167         # LustreFS argument
6168         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6169                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6170         ret=$?
6171
6172         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6173                 error "expect success 2, not $output, rc = $ret"
6174 }
6175 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6176
6177 NUMFILES=3
6178 NUMDIRS=3
6179 setup_56() {
6180         local local_tdir="$1"
6181         local local_numfiles="$2"
6182         local local_numdirs="$3"
6183         local dir_params="$4"
6184         local dir_stripe_params="$5"
6185
6186         if [ ! -d "$local_tdir" ] ; then
6187                 test_mkdir -p $dir_stripe_params $local_tdir
6188                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6189                 for i in $(seq $local_numfiles) ; do
6190                         touch $local_tdir/file$i
6191                 done
6192                 for i in $(seq $local_numdirs) ; do
6193                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6194                         for j in $(seq $local_numfiles) ; do
6195                                 touch $local_tdir/dir$i/file$j
6196                         done
6197                 done
6198         fi
6199 }
6200
6201 setup_56_special() {
6202         local local_tdir=$1
6203         local local_numfiles=$2
6204         local local_numdirs=$3
6205
6206         setup_56 $local_tdir $local_numfiles $local_numdirs
6207
6208         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6209                 for i in $(seq $local_numfiles) ; do
6210                         mknod $local_tdir/loop${i}b b 7 $i
6211                         mknod $local_tdir/null${i}c c 1 3
6212                         ln -s $local_tdir/file1 $local_tdir/link${i}
6213                 done
6214                 for i in $(seq $local_numdirs) ; do
6215                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6216                         mknod $local_tdir/dir$i/null${i}c c 1 3
6217                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6218                 done
6219         fi
6220 }
6221
6222 test_56g() {
6223         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6224         local expected=$(($NUMDIRS + 2))
6225
6226         setup_56 $dir $NUMFILES $NUMDIRS
6227
6228         # test lfs find with -name
6229         for i in $(seq $NUMFILES) ; do
6230                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6231
6232                 [ $nums -eq $expected ] ||
6233                         error "lfs find -name '*$i' $dir wrong: "\
6234                               "found $nums, expected $expected"
6235         done
6236 }
6237 run_test 56g "check lfs find -name"
6238
6239 test_56h() {
6240         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6241         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6242
6243         setup_56 $dir $NUMFILES $NUMDIRS
6244
6245         # test lfs find with ! -name
6246         for i in $(seq $NUMFILES) ; do
6247                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6248
6249                 [ $nums -eq $expected ] ||
6250                         error "lfs find ! -name '*$i' $dir wrong: "\
6251                               "found $nums, expected $expected"
6252         done
6253 }
6254 run_test 56h "check lfs find ! -name"
6255
6256 test_56i() {
6257         local dir=$DIR/$tdir
6258
6259         test_mkdir $dir
6260
6261         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6262         local out=$($cmd)
6263
6264         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6265 }
6266 run_test 56i "check 'lfs find -ost UUID' skips directories"
6267
6268 test_56j() {
6269         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6270
6271         setup_56_special $dir $NUMFILES $NUMDIRS
6272
6273         local expected=$((NUMDIRS + 1))
6274         local cmd="$LFS find -type d $dir"
6275         local nums=$($cmd | wc -l)
6276
6277         [ $nums -eq $expected ] ||
6278                 error "'$cmd' wrong: found $nums, expected $expected"
6279 }
6280 run_test 56j "check lfs find -type d"
6281
6282 test_56k() {
6283         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6284
6285         setup_56_special $dir $NUMFILES $NUMDIRS
6286
6287         local expected=$(((NUMDIRS + 1) * NUMFILES))
6288         local cmd="$LFS find -type f $dir"
6289         local nums=$($cmd | wc -l)
6290
6291         [ $nums -eq $expected ] ||
6292                 error "'$cmd' wrong: found $nums, expected $expected"
6293 }
6294 run_test 56k "check lfs find -type f"
6295
6296 test_56l() {
6297         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6298
6299         setup_56_special $dir $NUMFILES $NUMDIRS
6300
6301         local expected=$((NUMDIRS + NUMFILES))
6302         local cmd="$LFS find -type b $dir"
6303         local nums=$($cmd | wc -l)
6304
6305         [ $nums -eq $expected ] ||
6306                 error "'$cmd' wrong: found $nums, expected $expected"
6307 }
6308 run_test 56l "check lfs find -type b"
6309
6310 test_56m() {
6311         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6312
6313         setup_56_special $dir $NUMFILES $NUMDIRS
6314
6315         local expected=$((NUMDIRS + NUMFILES))
6316         local cmd="$LFS find -type c $dir"
6317         local nums=$($cmd | wc -l)
6318         [ $nums -eq $expected ] ||
6319                 error "'$cmd' wrong: found $nums, expected $expected"
6320 }
6321 run_test 56m "check lfs find -type c"
6322
6323 test_56n() {
6324         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6325         setup_56_special $dir $NUMFILES $NUMDIRS
6326
6327         local expected=$((NUMDIRS + NUMFILES))
6328         local cmd="$LFS find -type l $dir"
6329         local nums=$($cmd | wc -l)
6330
6331         [ $nums -eq $expected ] ||
6332                 error "'$cmd' wrong: found $nums, expected $expected"
6333 }
6334 run_test 56n "check lfs find -type l"
6335
6336 test_56o() {
6337         local dir=$DIR/$tdir
6338
6339         setup_56 $dir $NUMFILES $NUMDIRS
6340         utime $dir/file1 > /dev/null || error "utime (1)"
6341         utime $dir/file2 > /dev/null || error "utime (2)"
6342         utime $dir/dir1 > /dev/null || error "utime (3)"
6343         utime $dir/dir2 > /dev/null || error "utime (4)"
6344         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6345         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6346
6347         local expected=4
6348         local nums=$($LFS find -mtime +0 $dir | wc -l)
6349
6350         [ $nums -eq $expected ] ||
6351                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6352
6353         expected=12
6354         cmd="$LFS find -mtime 0 $dir"
6355         nums=$($cmd | wc -l)
6356         [ $nums -eq $expected ] ||
6357                 error "'$cmd' wrong: found $nums, expected $expected"
6358 }
6359 run_test 56o "check lfs find -mtime for old files"
6360
6361 test_56ob() {
6362         local dir=$DIR/$tdir
6363         local expected=1
6364         local count=0
6365
6366         # just to make sure there is something that won't be found
6367         test_mkdir $dir
6368         touch $dir/$tfile.now
6369
6370         for age in year week day hour min; do
6371                 count=$((count + 1))
6372
6373                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6374                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6375                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6376
6377                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6378                 local nums=$($cmd | wc -l)
6379                 [ $nums -eq $expected ] ||
6380                         error "'$cmd' wrong: found $nums, expected $expected"
6381
6382                 cmd="$LFS find $dir -atime $count${age:0:1}"
6383                 nums=$($cmd | wc -l)
6384                 [ $nums -eq $expected ] ||
6385                         error "'$cmd' wrong: found $nums, expected $expected"
6386         done
6387
6388         sleep 2
6389         cmd="$LFS find $dir -ctime +1s -type f"
6390         nums=$($cmd | wc -l)
6391         (( $nums == $count * 2 + 1)) ||
6392                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6393 }
6394 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6395
6396 test_newerXY_base() {
6397         local x=$1
6398         local y=$2
6399         local dir=$DIR/$tdir
6400         local ref
6401         local negref
6402
6403         if [ $y == "t" ]; then
6404                 if [ $x == "b" ]; then
6405                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6406                 else
6407                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6408                 fi
6409         else
6410                 ref=$DIR/$tfile.newer.$x$y
6411                 touch $ref || error "touch $ref failed"
6412         fi
6413
6414         echo "before = $ref"
6415         sleep 2
6416         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6417         sleep 2
6418         if [ $y == "t" ]; then
6419                 if [ $x == "b" ]; then
6420                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6421                 else
6422                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6423                 fi
6424         else
6425                 negref=$DIR/$tfile.negnewer.$x$y
6426                 touch $negref || error "touch $negref failed"
6427         fi
6428
6429         echo "after = $negref"
6430         local cmd="$LFS find $dir -newer$x$y $ref"
6431         local nums=$(eval $cmd | wc -l)
6432         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6433
6434         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6435                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6436
6437         cmd="$LFS find $dir ! -newer$x$y $negref"
6438         nums=$(eval $cmd | wc -l)
6439         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6440                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6441
6442         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6443         nums=$(eval $cmd | wc -l)
6444         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6445                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6446
6447         rm -rf $DIR/*
6448 }
6449
6450 test_56oc() {
6451         test_newerXY_base "a" "a"
6452         test_newerXY_base "a" "m"
6453         test_newerXY_base "a" "c"
6454         test_newerXY_base "m" "a"
6455         test_newerXY_base "m" "m"
6456         test_newerXY_base "m" "c"
6457         test_newerXY_base "c" "a"
6458         test_newerXY_base "c" "m"
6459         test_newerXY_base "c" "c"
6460
6461         [[ -n "$sles_version" ]] &&
6462                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6463
6464         test_newerXY_base "a" "t"
6465         test_newerXY_base "m" "t"
6466         test_newerXY_base "c" "t"
6467
6468         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6469            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6470                 ! btime_supported && echo "btime unsupported" && return 0
6471
6472         test_newerXY_base "b" "b"
6473         test_newerXY_base "b" "t"
6474 }
6475 run_test 56oc "check lfs find -newerXY work"
6476
6477 btime_supported() {
6478         local dir=$DIR/$tdir
6479         local rc
6480
6481         mkdir -p $dir
6482         touch $dir/$tfile
6483         $LFS find $dir -btime -1d -type f
6484         rc=$?
6485         rm -rf $dir
6486         return $rc
6487 }
6488
6489 test_56od() {
6490         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6491                 ! btime_supported && skip "btime unsupported on MDS"
6492
6493         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6494                 ! btime_supported && skip "btime unsupported on clients"
6495
6496         local dir=$DIR/$tdir
6497         local ref=$DIR/$tfile.ref
6498         local negref=$DIR/$tfile.negref
6499
6500         mkdir $dir || error "mkdir $dir failed"
6501         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6502         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6503         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6504         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6505         touch $ref || error "touch $ref failed"
6506         # sleep 3 seconds at least
6507         sleep 3
6508
6509         local before=$(do_facet mds1 date +%s)
6510         local skew=$(($(date +%s) - before + 1))
6511
6512         if (( skew < 0 && skew > -5 )); then
6513                 sleep $((0 - skew + 1))
6514                 skew=0
6515         fi
6516
6517         # Set the dir stripe params to limit files all on MDT0,
6518         # otherwise we need to calc the max clock skew between
6519         # the client and MDTs.
6520         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6521         sleep 2
6522         touch $negref || error "touch $negref failed"
6523
6524         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6525         local nums=$($cmd | wc -l)
6526         local expected=$(((NUMFILES + 1) * NUMDIRS))
6527
6528         [ $nums -eq $expected ] ||
6529                 error "'$cmd' wrong: found $nums, expected $expected"
6530
6531         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6532         nums=$($cmd | wc -l)
6533         expected=$((NUMFILES + 1))
6534         [ $nums -eq $expected ] ||
6535                 error "'$cmd' wrong: found $nums, expected $expected"
6536
6537         [ $skew -lt 0 ] && return
6538
6539         local after=$(do_facet mds1 date +%s)
6540         local age=$((after - before + 1 + skew))
6541
6542         cmd="$LFS find $dir -btime -${age}s -type f"
6543         nums=$($cmd | wc -l)
6544         expected=$(((NUMFILES + 1) * NUMDIRS))
6545
6546         echo "Clock skew between client and server: $skew, age:$age"
6547         [ $nums -eq $expected ] ||
6548                 error "'$cmd' wrong: found $nums, expected $expected"
6549
6550         expected=$(($NUMDIRS + 1))
6551         cmd="$LFS find $dir -btime -${age}s -type d"
6552         nums=$($cmd | wc -l)
6553         [ $nums -eq $expected ] ||
6554                 error "'$cmd' wrong: found $nums, expected $expected"
6555         rm -f $ref $negref || error "Failed to remove $ref $negref"
6556 }
6557 run_test 56od "check lfs find -btime with units"
6558
6559 test_56p() {
6560         [ $RUNAS_ID -eq $UID ] &&
6561                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6562
6563         local dir=$DIR/$tdir
6564
6565         setup_56 $dir $NUMFILES $NUMDIRS
6566         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6567
6568         local expected=$NUMFILES
6569         local cmd="$LFS find -uid $RUNAS_ID $dir"
6570         local nums=$($cmd | wc -l)
6571
6572         [ $nums -eq $expected ] ||
6573                 error "'$cmd' wrong: found $nums, expected $expected"
6574
6575         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6576         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6577         nums=$($cmd | wc -l)
6578         [ $nums -eq $expected ] ||
6579                 error "'$cmd' wrong: found $nums, expected $expected"
6580 }
6581 run_test 56p "check lfs find -uid and ! -uid"
6582
6583 test_56q() {
6584         [ $RUNAS_ID -eq $UID ] &&
6585                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6586
6587         local dir=$DIR/$tdir
6588
6589         setup_56 $dir $NUMFILES $NUMDIRS
6590         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6591
6592         local expected=$NUMFILES
6593         local cmd="$LFS find -gid $RUNAS_GID $dir"
6594         local nums=$($cmd | wc -l)
6595
6596         [ $nums -eq $expected ] ||
6597                 error "'$cmd' wrong: found $nums, expected $expected"
6598
6599         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6600         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6601         nums=$($cmd | wc -l)
6602         [ $nums -eq $expected ] ||
6603                 error "'$cmd' wrong: found $nums, expected $expected"
6604 }
6605 run_test 56q "check lfs find -gid and ! -gid"
6606
6607 test_56r() {
6608         local dir=$DIR/$tdir
6609
6610         setup_56 $dir $NUMFILES $NUMDIRS
6611
6612         local expected=12
6613         local cmd="$LFS find -size 0 -type f -lazy $dir"
6614         local nums=$($cmd | wc -l)
6615
6616         [ $nums -eq $expected ] ||
6617                 error "'$cmd' wrong: found $nums, expected $expected"
6618         cmd="$LFS find -size 0 -type f $dir"
6619         nums=$($cmd | wc -l)
6620         [ $nums -eq $expected ] ||
6621                 error "'$cmd' wrong: found $nums, expected $expected"
6622
6623         expected=0
6624         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6625         nums=$($cmd | wc -l)
6626         [ $nums -eq $expected ] ||
6627                 error "'$cmd' wrong: found $nums, expected $expected"
6628         cmd="$LFS find ! -size 0 -type f $dir"
6629         nums=$($cmd | wc -l)
6630         [ $nums -eq $expected ] ||
6631                 error "'$cmd' wrong: found $nums, expected $expected"
6632
6633         echo "test" > $dir/$tfile
6634         echo "test2" > $dir/$tfile.2 && sync
6635         expected=1
6636         cmd="$LFS find -size 5 -type f -lazy $dir"
6637         nums=$($cmd | wc -l)
6638         [ $nums -eq $expected ] ||
6639                 error "'$cmd' wrong: found $nums, expected $expected"
6640         cmd="$LFS find -size 5 -type f $dir"
6641         nums=$($cmd | wc -l)
6642         [ $nums -eq $expected ] ||
6643                 error "'$cmd' wrong: found $nums, expected $expected"
6644
6645         expected=1
6646         cmd="$LFS find -size +5 -type f -lazy $dir"
6647         nums=$($cmd | wc -l)
6648         [ $nums -eq $expected ] ||
6649                 error "'$cmd' wrong: found $nums, expected $expected"
6650         cmd="$LFS find -size +5 -type f $dir"
6651         nums=$($cmd | wc -l)
6652         [ $nums -eq $expected ] ||
6653                 error "'$cmd' wrong: found $nums, expected $expected"
6654
6655         expected=2
6656         cmd="$LFS find -size +0 -type f -lazy $dir"
6657         nums=$($cmd | wc -l)
6658         [ $nums -eq $expected ] ||
6659                 error "'$cmd' wrong: found $nums, expected $expected"
6660         cmd="$LFS find -size +0 -type f $dir"
6661         nums=$($cmd | wc -l)
6662         [ $nums -eq $expected ] ||
6663                 error "'$cmd' wrong: found $nums, expected $expected"
6664
6665         expected=2
6666         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6667         nums=$($cmd | wc -l)
6668         [ $nums -eq $expected ] ||
6669                 error "'$cmd' wrong: found $nums, expected $expected"
6670         cmd="$LFS find ! -size -5 -type f $dir"
6671         nums=$($cmd | wc -l)
6672         [ $nums -eq $expected ] ||
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674
6675         expected=12
6676         cmd="$LFS find -size -5 -type f -lazy $dir"
6677         nums=$($cmd | wc -l)
6678         [ $nums -eq $expected ] ||
6679                 error "'$cmd' wrong: found $nums, expected $expected"
6680         cmd="$LFS find -size -5 -type f $dir"
6681         nums=$($cmd | wc -l)
6682         [ $nums -eq $expected ] ||
6683                 error "'$cmd' wrong: found $nums, expected $expected"
6684 }
6685 run_test 56r "check lfs find -size works"
6686
6687 test_56ra_sub() {
6688         local expected=$1
6689         local glimpses=$2
6690         local cmd="$3"
6691
6692         cancel_lru_locks $OSC
6693
6694         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6695         local nums=$($cmd | wc -l)
6696
6697         [ $nums -eq $expected ] ||
6698                 error "'$cmd' wrong: found $nums, expected $expected"
6699
6700         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6701
6702         if (( rpcs_before + glimpses != rpcs_after )); then
6703                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6704                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6705
6706                 if [[ $glimpses == 0 ]]; then
6707                         error "'$cmd' should not send glimpse RPCs to OST"
6708                 else
6709                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6710                 fi
6711         fi
6712 }
6713
6714 test_56ra() {
6715         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6716                 skip "MDS < 2.12.58 doesn't return LSOM data"
6717         local dir=$DIR/$tdir
6718         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6719
6720         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6721
6722         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6723         $LCTL set_param -n llite.*.statahead_agl=0
6724         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6725
6726         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6727         # open and close all files to ensure LSOM is updated
6728         cancel_lru_locks $OSC
6729         find $dir -type f | xargs cat > /dev/null
6730
6731         #   expect_found  glimpse_rpcs  command_to_run
6732         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6733         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6734         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6735         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6736
6737         echo "test" > $dir/$tfile
6738         echo "test2" > $dir/$tfile.2 && sync
6739         cancel_lru_locks $OSC
6740         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6741
6742         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6743         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6744         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6745         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6746
6747         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6748         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6749         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6750         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6751         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6752         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6753 }
6754 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6755
6756 test_56rb() {
6757         local dir=$DIR/$tdir
6758         local tmp=$TMP/$tfile.log
6759         local mdt_idx;
6760
6761         test_mkdir -p $dir || error "failed to mkdir $dir"
6762         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6763                 error "failed to setstripe $dir/$tfile"
6764         mdt_idx=$($LFS getdirstripe -i $dir)
6765         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6766
6767         stack_trap "rm -f $tmp" EXIT
6768         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6769         ! grep -q obd_uuid $tmp ||
6770                 error "failed to find --size +100K --ost 0 $dir"
6771         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6772         ! grep -q obd_uuid $tmp ||
6773                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6774 }
6775 run_test 56rb "check lfs find --size --ost/--mdt works"
6776
6777 test_56rc() {
6778         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6779         local dir=$DIR/$tdir
6780         local found
6781
6782         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6783         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6784         (( $MDSCOUNT > 2 )) &&
6785                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6786         mkdir $dir/$tdir-{1..10}
6787         touch $dir/$tfile-{1..10}
6788
6789         found=$($LFS find $dir --mdt-count 2 | wc -l)
6790         expect=11
6791         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6792
6793         found=$($LFS find $dir -T +1 | wc -l)
6794         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6795         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6796
6797         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6798         expect=11
6799         (( $found == $expect )) || error "found $found all_char, expect $expect"
6800
6801         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6802         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6803         (( $found == $expect )) || error "found $found all_char, expect $expect"
6804 }
6805 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6806
6807 test_56s() { # LU-611 #LU-9369
6808         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6809
6810         local dir=$DIR/$tdir
6811         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6812
6813         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6814         for i in $(seq $NUMDIRS); do
6815                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6816         done
6817
6818         local expected=$NUMDIRS
6819         local cmd="$LFS find -c $OSTCOUNT $dir"
6820         local nums=$($cmd | wc -l)
6821
6822         [ $nums -eq $expected ] || {
6823                 $LFS getstripe -R $dir
6824                 error "'$cmd' wrong: found $nums, expected $expected"
6825         }
6826
6827         expected=$((NUMDIRS + onestripe))
6828         cmd="$LFS find -stripe-count +0 -type f $dir"
6829         nums=$($cmd | wc -l)
6830         [ $nums -eq $expected ] || {
6831                 $LFS getstripe -R $dir
6832                 error "'$cmd' wrong: found $nums, expected $expected"
6833         }
6834
6835         expected=$onestripe
6836         cmd="$LFS find -stripe-count 1 -type f $dir"
6837         nums=$($cmd | wc -l)
6838         [ $nums -eq $expected ] || {
6839                 $LFS getstripe -R $dir
6840                 error "'$cmd' wrong: found $nums, expected $expected"
6841         }
6842
6843         cmd="$LFS find -stripe-count -2 -type f $dir"
6844         nums=$($cmd | wc -l)
6845         [ $nums -eq $expected ] || {
6846                 $LFS getstripe -R $dir
6847                 error "'$cmd' wrong: found $nums, expected $expected"
6848         }
6849
6850         expected=0
6851         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6852         nums=$($cmd | wc -l)
6853         [ $nums -eq $expected ] || {
6854                 $LFS getstripe -R $dir
6855                 error "'$cmd' wrong: found $nums, expected $expected"
6856         }
6857 }
6858 run_test 56s "check lfs find -stripe-count works"
6859
6860 test_56t() { # LU-611 #LU-9369
6861         local dir=$DIR/$tdir
6862
6863         setup_56 $dir 0 $NUMDIRS
6864         for i in $(seq $NUMDIRS); do
6865                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6866         done
6867
6868         local expected=$NUMDIRS
6869         local cmd="$LFS find -S 8M $dir"
6870         local nums=$($cmd | wc -l)
6871
6872         [ $nums -eq $expected ] || {
6873                 $LFS getstripe -R $dir
6874                 error "'$cmd' wrong: found $nums, expected $expected"
6875         }
6876         rm -rf $dir
6877
6878         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6879
6880         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6881
6882         expected=$(((NUMDIRS + 1) * NUMFILES))
6883         cmd="$LFS find -stripe-size 512k -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         cmd="$LFS find -stripe-size +320k -type f $dir"
6889         nums=$($cmd | wc -l)
6890         [ $nums -eq $expected ] ||
6891                 error "'$cmd' wrong: found $nums, expected $expected"
6892
6893         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6894         cmd="$LFS find -stripe-size +200k -type f $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898
6899         cmd="$LFS find -stripe-size -640k -type f $dir"
6900         nums=$($cmd | wc -l)
6901         [ $nums -eq $expected ] ||
6902                 error "'$cmd' wrong: found $nums, expected $expected"
6903
6904         expected=4
6905         cmd="$LFS find -stripe-size 256k -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         cmd="$LFS find -stripe-size -320k -type f $dir"
6911         nums=$($cmd | wc -l)
6912         [ $nums -eq $expected ] ||
6913                 error "'$cmd' wrong: found $nums, expected $expected"
6914
6915         expected=0
6916         cmd="$LFS find -stripe-size 1024k -type f $dir"
6917         nums=$($cmd | wc -l)
6918         [ $nums -eq $expected ] ||
6919                 error "'$cmd' wrong: found $nums, expected $expected"
6920 }
6921 run_test 56t "check lfs find -stripe-size works"
6922
6923 test_56u() { # LU-611
6924         local dir=$DIR/$tdir
6925
6926         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6927
6928         if [[ $OSTCOUNT -gt 1 ]]; then
6929                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6930                 onestripe=4
6931         else
6932                 onestripe=0
6933         fi
6934
6935         local expected=$(((NUMDIRS + 1) * NUMFILES))
6936         local cmd="$LFS find -stripe-index 0 -type f $dir"
6937         local nums=$($cmd | wc -l)
6938
6939         [ $nums -eq $expected ] ||
6940                 error "'$cmd' wrong: found $nums, expected $expected"
6941
6942         expected=$onestripe
6943         cmd="$LFS find -stripe-index 1 -type f $dir"
6944         nums=$($cmd | wc -l)
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6949         nums=$($cmd | wc -l)
6950         [ $nums -eq $expected ] ||
6951                 error "'$cmd' wrong: found $nums, expected $expected"
6952
6953         expected=0
6954         # This should produce an error and not return any files
6955         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6956         nums=$($cmd 2>/dev/null | wc -l)
6957         [ $nums -eq $expected ] ||
6958                 error "'$cmd' wrong: found $nums, expected $expected"
6959
6960         if [[ $OSTCOUNT -gt 1 ]]; then
6961                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6962                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6963                 nums=$($cmd | wc -l)
6964                 [ $nums -eq $expected ] ||
6965                         error "'$cmd' wrong: found $nums, expected $expected"
6966         fi
6967 }
6968 run_test 56u "check lfs find -stripe-index works"
6969
6970 test_56v() {
6971         local mdt_idx=0
6972         local dir=$DIR/$tdir
6973
6974         setup_56 $dir $NUMFILES $NUMDIRS
6975
6976         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6977         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6978
6979         for file in $($LFS find -m $UUID $dir); do
6980                 file_midx=$($LFS getstripe -m $file)
6981                 [ $file_midx -eq $mdt_idx ] ||
6982                         error "lfs find -m $UUID != getstripe -m $file_midx"
6983         done
6984 }
6985 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6986
6987 test_56w() {
6988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6990
6991         local dir=$DIR/$tdir
6992
6993         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6994
6995         local stripe_size=$($LFS getstripe -S -d $dir) ||
6996                 error "$LFS getstripe -S -d $dir failed"
6997         stripe_size=${stripe_size%% *}
6998
6999         local file_size=$((stripe_size * OSTCOUNT))
7000         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7001         local required_space=$((file_num * file_size))
7002         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7003                            head -n1)
7004         [[ $free_space -le $((required_space / 1024)) ]] &&
7005                 skip_env "need $required_space, have $free_space kbytes"
7006
7007         local dd_bs=65536
7008         local dd_count=$((file_size / dd_bs))
7009
7010         # write data into the files
7011         local i
7012         local j
7013         local file
7014
7015         for i in $(seq $NUMFILES); do
7016                 file=$dir/file$i
7017                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7018                         error "write data into $file failed"
7019         done
7020         for i in $(seq $NUMDIRS); do
7021                 for j in $(seq $NUMFILES); do
7022                         file=$dir/dir$i/file$j
7023                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7024                                 error "write data into $file failed"
7025                 done
7026         done
7027
7028         # $LFS_MIGRATE will fail if hard link migration is unsupported
7029         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7030                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7031                         error "creating links to $dir/dir1/file1 failed"
7032         fi
7033
7034         local expected=-1
7035
7036         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7037
7038         # lfs_migrate file
7039         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7040
7041         echo "$cmd"
7042         eval $cmd || error "$cmd failed"
7043
7044         check_stripe_count $dir/file1 $expected
7045
7046         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7047         then
7048                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7049                 # OST 1 if it is on OST 0. This file is small enough to
7050                 # be on only one stripe.
7051                 file=$dir/migr_1_ost
7052                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7053                         error "write data into $file failed"
7054                 local obdidx=$($LFS getstripe -i $file)
7055                 local oldmd5=$(md5sum $file)
7056                 local newobdidx=0
7057
7058                 [[ $obdidx -eq 0 ]] && newobdidx=1
7059                 cmd="$LFS migrate -i $newobdidx $file"
7060                 echo $cmd
7061                 eval $cmd || error "$cmd failed"
7062
7063                 local realobdix=$($LFS getstripe -i $file)
7064                 local newmd5=$(md5sum $file)
7065
7066                 [[ $newobdidx -ne $realobdix ]] &&
7067                         error "new OST is different (was=$obdidx, "\
7068                               "wanted=$newobdidx, got=$realobdix)"
7069                 [[ "$oldmd5" != "$newmd5" ]] &&
7070                         error "md5sum differ: $oldmd5, $newmd5"
7071         fi
7072
7073         # lfs_migrate dir
7074         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7075         echo "$cmd"
7076         eval $cmd || error "$cmd failed"
7077
7078         for j in $(seq $NUMFILES); do
7079                 check_stripe_count $dir/dir1/file$j $expected
7080         done
7081
7082         # lfs_migrate works with lfs find
7083         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7084              $LFS_MIGRATE -y -c $expected"
7085         echo "$cmd"
7086         eval $cmd || error "$cmd failed"
7087
7088         for i in $(seq 2 $NUMFILES); do
7089                 check_stripe_count $dir/file$i $expected
7090         done
7091         for i in $(seq 2 $NUMDIRS); do
7092                 for j in $(seq $NUMFILES); do
7093                 check_stripe_count $dir/dir$i/file$j $expected
7094                 done
7095         done
7096 }
7097 run_test 56w "check lfs_migrate -c stripe_count works"
7098
7099 test_56wb() {
7100         local file1=$DIR/$tdir/file1
7101         local create_pool=false
7102         local initial_pool=$($LFS getstripe -p $DIR)
7103         local pool_list=()
7104         local pool=""
7105
7106         echo -n "Creating test dir..."
7107         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7108         echo "done."
7109
7110         echo -n "Creating test file..."
7111         touch $file1 || error "cannot create file"
7112         echo "done."
7113
7114         echo -n "Detecting existing pools..."
7115         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7116
7117         if [ ${#pool_list[@]} -gt 0 ]; then
7118                 echo "${pool_list[@]}"
7119                 for thispool in "${pool_list[@]}"; do
7120                         if [[ -z "$initial_pool" ||
7121                               "$initial_pool" != "$thispool" ]]; then
7122                                 pool="$thispool"
7123                                 echo "Using existing pool '$pool'"
7124                                 break
7125                         fi
7126                 done
7127         else
7128                 echo "none detected."
7129         fi
7130         if [ -z "$pool" ]; then
7131                 pool=${POOL:-testpool}
7132                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7133                 echo -n "Creating pool '$pool'..."
7134                 create_pool=true
7135                 pool_add $pool &> /dev/null ||
7136                         error "pool_add failed"
7137                 echo "done."
7138
7139                 echo -n "Adding target to pool..."
7140                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7141                         error "pool_add_targets failed"
7142                 echo "done."
7143         fi
7144
7145         echo -n "Setting pool using -p option..."
7146         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7147                 error "migrate failed rc = $?"
7148         echo "done."
7149
7150         echo -n "Verifying test file is in pool after migrating..."
7151         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7152                 error "file was not migrated to pool $pool"
7153         echo "done."
7154
7155         echo -n "Removing test file from pool '$pool'..."
7156         # "lfs migrate $file" won't remove the file from the pool
7157         # until some striping information is changed.
7158         $LFS migrate -c 1 $file1 &> /dev/null ||
7159                 error "cannot remove from pool"
7160         [ "$($LFS getstripe -p $file1)" ] &&
7161                 error "pool still set"
7162         echo "done."
7163
7164         echo -n "Setting pool using --pool option..."
7165         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7166                 error "migrate failed rc = $?"
7167         echo "done."
7168
7169         # Clean up
7170         rm -f $file1
7171         if $create_pool; then
7172                 destroy_test_pools 2> /dev/null ||
7173                         error "destroy test pools failed"
7174         fi
7175 }
7176 run_test 56wb "check lfs_migrate pool support"
7177
7178 test_56wc() {
7179         local file1="$DIR/$tdir/file1"
7180         local parent_ssize
7181         local parent_scount
7182         local cur_ssize
7183         local cur_scount
7184         local orig_ssize
7185
7186         echo -n "Creating test dir..."
7187         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7188         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7189                 error "cannot set stripe by '-S 1M -c 1'"
7190         echo "done"
7191
7192         echo -n "Setting initial stripe for test file..."
7193         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7194                 error "cannot set stripe"
7195         cur_ssize=$($LFS getstripe -S "$file1")
7196         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7197         echo "done."
7198
7199         # File currently set to -S 512K -c 1
7200
7201         # Ensure -c and -S options are rejected when -R is set
7202         echo -n "Verifying incompatible options are detected..."
7203         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7204                 error "incompatible -c and -R options not detected"
7205         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7206                 error "incompatible -S and -R options not detected"
7207         echo "done."
7208
7209         # Ensure unrecognized options are passed through to 'lfs migrate'
7210         echo -n "Verifying -S option is passed through to lfs migrate..."
7211         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7212                 error "migration failed"
7213         cur_ssize=$($LFS getstripe -S "$file1")
7214         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7215         echo "done."
7216
7217         # File currently set to -S 1M -c 1
7218
7219         # Ensure long options are supported
7220         echo -n "Verifying long options supported..."
7221         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7222                 error "long option without argument not supported"
7223         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7224                 error "long option with argument not supported"
7225         cur_ssize=$($LFS getstripe -S "$file1")
7226         [ $cur_ssize -eq 524288 ] ||
7227                 error "migrate --stripe-size $cur_ssize != 524288"
7228         echo "done."
7229
7230         # File currently set to -S 512K -c 1
7231
7232         if [ "$OSTCOUNT" -gt 1 ]; then
7233                 echo -n "Verifying explicit stripe count can be set..."
7234                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7235                         error "migrate failed"
7236                 cur_scount=$($LFS getstripe -c "$file1")
7237                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7238                 echo "done."
7239         fi
7240
7241         # File currently set to -S 512K -c 1 or -S 512K -c 2
7242
7243         # Ensure parent striping is used if -R is set, and no stripe
7244         # count or size is specified
7245         echo -n "Setting stripe for parent directory..."
7246         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7247                 error "cannot set stripe '-S 2M -c 1'"
7248         echo "done."
7249
7250         echo -n "Verifying restripe option uses parent stripe settings..."
7251         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7252         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7253         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7254                 error "migrate failed"
7255         cur_ssize=$($LFS getstripe -S "$file1")
7256         [ $cur_ssize -eq $parent_ssize ] ||
7257                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7258         cur_scount=$($LFS getstripe -c "$file1")
7259         [ $cur_scount -eq $parent_scount ] ||
7260                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7261         echo "done."
7262
7263         # File currently set to -S 1M -c 1
7264
7265         # Ensure striping is preserved if -R is not set, and no stripe
7266         # count or size is specified
7267         echo -n "Verifying striping size preserved when not specified..."
7268         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7269         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7270                 error "cannot set stripe on parent directory"
7271         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7272                 error "migrate failed"
7273         cur_ssize=$($LFS getstripe -S "$file1")
7274         [ $cur_ssize -eq $orig_ssize ] ||
7275                 error "migrate by default $cur_ssize != $orig_ssize"
7276         echo "done."
7277
7278         # Ensure file name properly detected when final option has no argument
7279         echo -n "Verifying file name properly detected..."
7280         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7281                 error "file name interpreted as option argument"
7282         echo "done."
7283
7284         # Clean up
7285         rm -f "$file1"
7286 }
7287 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7288
7289 test_56wd() {
7290         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7291
7292         local file1=$DIR/$tdir/file1
7293
7294         echo -n "Creating test dir..."
7295         test_mkdir $DIR/$tdir || error "cannot create dir"
7296         echo "done."
7297
7298         echo -n "Creating test file..."
7299         touch $file1
7300         echo "done."
7301
7302         # Ensure 'lfs migrate' will fail by using a non-existent option,
7303         # and make sure rsync is not called to recover
7304         echo -n "Make sure --no-rsync option works..."
7305         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7306                 grep -q 'refusing to fall back to rsync' ||
7307                 error "rsync was called with --no-rsync set"
7308         echo "done."
7309
7310         # Ensure rsync is called without trying 'lfs migrate' first
7311         echo -n "Make sure --rsync option works..."
7312         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7313                 grep -q 'falling back to rsync' &&
7314                 error "lfs migrate was called with --rsync set"
7315         echo "done."
7316
7317         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7318         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7319                 grep -q 'at the same time' ||
7320                 error "--rsync and --no-rsync accepted concurrently"
7321         echo "done."
7322
7323         # Clean up
7324         rm -f $file1
7325 }
7326 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7327
7328 test_56we() {
7329         local td=$DIR/$tdir
7330         local tf=$td/$tfile
7331
7332         test_mkdir $td || error "cannot create $td"
7333         touch $tf || error "cannot touch $tf"
7334
7335         echo -n "Make sure --non-direct|-D works..."
7336         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7337                 grep -q "lfs migrate --non-direct" ||
7338                 error "--non-direct option cannot work correctly"
7339         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7340                 grep -q "lfs migrate -D" ||
7341                 error "-D option cannot work correctly"
7342         echo "done."
7343 }
7344 run_test 56we "check lfs_migrate --non-direct|-D support"
7345
7346 test_56x() {
7347         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7348         check_swap_layouts_support
7349
7350         local dir=$DIR/$tdir
7351         local ref1=/etc/passwd
7352         local file1=$dir/file1
7353
7354         test_mkdir $dir || error "creating dir $dir"
7355         $LFS setstripe -c 2 $file1
7356         cp $ref1 $file1
7357         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7358         stripe=$($LFS getstripe -c $file1)
7359         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7360         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7361
7362         # clean up
7363         rm -f $file1
7364 }
7365 run_test 56x "lfs migration support"
7366
7367 test_56xa() {
7368         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7369         check_swap_layouts_support
7370
7371         local dir=$DIR/$tdir/$testnum
7372
7373         test_mkdir -p $dir
7374
7375         local ref1=/etc/passwd
7376         local file1=$dir/file1
7377
7378         $LFS setstripe -c 2 $file1
7379         cp $ref1 $file1
7380         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7381
7382         local stripe=$($LFS getstripe -c $file1)
7383
7384         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7385         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7386
7387         # clean up
7388         rm -f $file1
7389 }
7390 run_test 56xa "lfs migration --block support"
7391
7392 check_migrate_links() {
7393         local dir="$1"
7394         local file1="$dir/file1"
7395         local begin="$2"
7396         local count="$3"
7397         local runas="$4"
7398         local total_count=$(($begin + $count - 1))
7399         local symlink_count=10
7400         local uniq_count=10
7401
7402         if [ ! -f "$file1" ]; then
7403                 echo -n "creating initial file..."
7404                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7405                         error "cannot setstripe initial file"
7406                 echo "done"
7407
7408                 echo -n "creating symlinks..."
7409                 for s in $(seq 1 $symlink_count); do
7410                         ln -s "$file1" "$dir/slink$s" ||
7411                                 error "cannot create symlinks"
7412                 done
7413                 echo "done"
7414
7415                 echo -n "creating nonlinked files..."
7416                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7417                         error "cannot create nonlinked files"
7418                 echo "done"
7419         fi
7420
7421         # create hard links
7422         if [ ! -f "$dir/file$total_count" ]; then
7423                 echo -n "creating hard links $begin:$total_count..."
7424                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7425                         /dev/null || error "cannot create hard links"
7426                 echo "done"
7427         fi
7428
7429         echo -n "checking number of hard links listed in xattrs..."
7430         local fid=$($LFS getstripe -F "$file1")
7431         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7432
7433         echo "${#paths[*]}"
7434         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7435                         skip "hard link list has unexpected size, skipping test"
7436         fi
7437         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7438                         error "link names should exceed xattrs size"
7439         fi
7440
7441         echo -n "migrating files..."
7442         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7443         local rc=$?
7444         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7445         echo "done"
7446
7447         # make sure all links have been properly migrated
7448         echo -n "verifying files..."
7449         fid=$($LFS getstripe -F "$file1") ||
7450                 error "cannot get fid for file $file1"
7451         for i in $(seq 2 $total_count); do
7452                 local fid2=$($LFS getstripe -F $dir/file$i)
7453
7454                 [ "$fid2" == "$fid" ] ||
7455                         error "migrated hard link has mismatched FID"
7456         done
7457
7458         # make sure hard links were properly detected, and migration was
7459         # performed only once for the entire link set; nonlinked files should
7460         # also be migrated
7461         local actual=$(grep -c 'done' <<< "$migrate_out")
7462         local expected=$(($uniq_count + 1))
7463
7464         [ "$actual" -eq  "$expected" ] ||
7465                 error "hard links individually migrated ($actual != $expected)"
7466
7467         # make sure the correct number of hard links are present
7468         local hardlinks=$(stat -c '%h' "$file1")
7469
7470         [ $hardlinks -eq $total_count ] ||
7471                 error "num hard links $hardlinks != $total_count"
7472         echo "done"
7473
7474         return 0
7475 }
7476
7477 test_56xb() {
7478         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7479                 skip "Need MDS version at least 2.10.55"
7480
7481         local dir="$DIR/$tdir"
7482
7483         test_mkdir "$dir" || error "cannot create dir $dir"
7484
7485         echo "testing lfs migrate mode when all links fit within xattrs"
7486         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7487
7488         echo "testing rsync mode when all links fit within xattrs"
7489         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7490
7491         echo "testing lfs migrate mode when all links do not fit within xattrs"
7492         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7493
7494         echo "testing rsync mode when all links do not fit within xattrs"
7495         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7496
7497         chown -R $RUNAS_ID $dir
7498         echo "testing non-root lfs migrate mode when not all links are in xattr"
7499         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7500
7501         # clean up
7502         rm -rf $dir
7503 }
7504 run_test 56xb "lfs migration hard link support"
7505
7506 test_56xc() {
7507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7508
7509         local dir="$DIR/$tdir"
7510
7511         test_mkdir "$dir" || error "cannot create dir $dir"
7512
7513         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7514         echo -n "Setting initial stripe for 20MB test file..."
7515         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7516                 error "cannot setstripe 20MB file"
7517         echo "done"
7518         echo -n "Sizing 20MB test file..."
7519         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7520         echo "done"
7521         echo -n "Verifying small file autostripe count is 1..."
7522         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7523                 error "cannot migrate 20MB file"
7524         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7525                 error "cannot get stripe for $dir/20mb"
7526         [ $stripe_count -eq 1 ] ||
7527                 error "unexpected stripe count $stripe_count for 20MB file"
7528         rm -f "$dir/20mb"
7529         echo "done"
7530
7531         # Test 2: File is small enough to fit within the available space on
7532         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7533         # have at least an additional 1KB for each desired stripe for test 3
7534         echo -n "Setting stripe for 1GB test file..."
7535         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7536         echo "done"
7537         echo -n "Sizing 1GB test file..."
7538         # File size is 1GB + 3KB
7539         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7540         echo "done"
7541
7542         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7543         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7544         if (( avail > 524288 * OSTCOUNT )); then
7545                 echo -n "Migrating 1GB file..."
7546                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7547                         error "cannot migrate 1GB file"
7548                 echo "done"
7549                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7550                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7551                         error "cannot getstripe for 1GB file"
7552                 [ $stripe_count -eq 2 ] ||
7553                         error "unexpected stripe count $stripe_count != 2"
7554                 echo "done"
7555         fi
7556
7557         # Test 3: File is too large to fit within the available space on
7558         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7559         if [ $OSTCOUNT -ge 3 ]; then
7560                 # The required available space is calculated as
7561                 # file size (1GB + 3KB) / OST count (3).
7562                 local kb_per_ost=349526
7563
7564                 echo -n "Migrating 1GB file with limit..."
7565                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7566                         error "cannot migrate 1GB file with limit"
7567                 echo "done"
7568
7569                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7570                 echo -n "Verifying 1GB autostripe count with limited space..."
7571                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7572                         error "unexpected stripe count $stripe_count (min 3)"
7573                 echo "done"
7574         fi
7575
7576         # clean up
7577         rm -rf $dir
7578 }
7579 run_test 56xc "lfs migration autostripe"
7580
7581 test_56xd() {
7582         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7583
7584         local dir=$DIR/$tdir
7585         local f_mgrt=$dir/$tfile.mgrt
7586         local f_yaml=$dir/$tfile.yaml
7587         local f_copy=$dir/$tfile.copy
7588         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7589         local layout_copy="-c 2 -S 2M -i 1"
7590         local yamlfile=$dir/yamlfile
7591         local layout_before;
7592         local layout_after;
7593
7594         test_mkdir "$dir" || error "cannot create dir $dir"
7595         $LFS setstripe $layout_yaml $f_yaml ||
7596                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7597         $LFS getstripe --yaml $f_yaml > $yamlfile
7598         $LFS setstripe $layout_copy $f_copy ||
7599                 error "cannot setstripe $f_copy with layout $layout_copy"
7600         touch $f_mgrt
7601         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7602
7603         # 1. test option --yaml
7604         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7605                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7606         layout_before=$(get_layout_param $f_yaml)
7607         layout_after=$(get_layout_param $f_mgrt)
7608         [ "$layout_after" == "$layout_before" ] ||
7609                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7610
7611         # 2. test option --copy
7612         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7613                 error "cannot migrate $f_mgrt with --copy $f_copy"
7614         layout_before=$(get_layout_param $f_copy)
7615         layout_after=$(get_layout_param $f_mgrt)
7616         [ "$layout_after" == "$layout_before" ] ||
7617                 error "lfs_migrate --copy: $layout_after != $layout_before"
7618 }
7619 run_test 56xd "check lfs_migrate --yaml and --copy support"
7620
7621 test_56xe() {
7622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7623
7624         local dir=$DIR/$tdir
7625         local f_comp=$dir/$tfile
7626         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7627         local layout_before=""
7628         local layout_after=""
7629
7630         test_mkdir "$dir" || error "cannot create dir $dir"
7631         $LFS setstripe $layout $f_comp ||
7632                 error "cannot setstripe $f_comp with layout $layout"
7633         layout_before=$(get_layout_param $f_comp)
7634         dd if=/dev/zero of=$f_comp bs=1M count=4
7635
7636         # 1. migrate a comp layout file by lfs_migrate
7637         $LFS_MIGRATE -y $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         # 2. migrate a comp layout file by lfs migrate
7643         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7644         layout_after=$(get_layout_param $f_comp)
7645         [ "$layout_before" == "$layout_after" ] ||
7646                 error "lfs migrate: $layout_before != $layout_after"
7647 }
7648 run_test 56xe "migrate a composite layout file"
7649
7650 test_56xf() {
7651         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7652
7653         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7654                 skip "Need server version at least 2.13.53"
7655
7656         local dir=$DIR/$tdir
7657         local f_comp=$dir/$tfile
7658         local layout="-E 1M -c1 -E -1 -c2"
7659         local fid_before=""
7660         local fid_after=""
7661
7662         test_mkdir "$dir" || error "cannot create dir $dir"
7663         $LFS setstripe $layout $f_comp ||
7664                 error "cannot setstripe $f_comp with layout $layout"
7665         fid_before=$($LFS getstripe --fid $f_comp)
7666         dd if=/dev/zero of=$f_comp bs=1M count=4
7667
7668         # 1. migrate a comp layout file to a comp layout
7669         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7670         fid_after=$($LFS getstripe --fid $f_comp)
7671         [ "$fid_before" == "$fid_after" ] ||
7672                 error "comp-to-comp migrate: $fid_before != $fid_after"
7673
7674         # 2. migrate a comp layout file to a plain layout
7675         $LFS migrate -c2 $f_comp ||
7676                 error "cannot migrate $f_comp by lfs migrate"
7677         fid_after=$($LFS getstripe --fid $f_comp)
7678         [ "$fid_before" == "$fid_after" ] ||
7679                 error "comp-to-plain migrate: $fid_before != $fid_after"
7680
7681         # 3. migrate a plain layout file to a comp layout
7682         $LFS migrate $layout $f_comp ||
7683                 error "cannot migrate $f_comp by lfs migrate"
7684         fid_after=$($LFS getstripe --fid $f_comp)
7685         [ "$fid_before" == "$fid_after" ] ||
7686                 error "plain-to-comp migrate: $fid_before != $fid_after"
7687 }
7688 run_test 56xf "FID is not lost during migration of a composite layout file"
7689
7690 check_file_ost_range() {
7691         local file="$1"
7692         shift
7693         local range="$*"
7694         local -a file_range
7695         local idx
7696
7697         file_range=($($LFS getstripe -y "$file" |
7698                 awk '/l_ost_idx:/ { print $NF }'))
7699
7700         if [[ "${#file_range[@]}" = 0 ]]; then
7701                 echo "No osts found for $file"
7702                 return 1
7703         fi
7704
7705         for idx in "${file_range[@]}"; do
7706                 [[ " $range " =~ " $idx " ]] ||
7707                         return 1
7708         done
7709
7710         return 0
7711 }
7712
7713 sub_test_56xg() {
7714         local stripe_opt="$1"
7715         local pool="$2"
7716         shift 2
7717         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7718
7719         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7720                 error "Fail to migrate $tfile on $pool"
7721         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7722                 error "$tfile is not in pool $pool"
7723         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7724                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7725 }
7726
7727 test_56xg() {
7728         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7729         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7730         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7731                 skip "Need MDS version newer than 2.14.52"
7732
7733         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7734         local -a pool_ranges=("0 0" "1 1" "0 1")
7735
7736         # init pools
7737         for i in "${!pool_names[@]}"; do
7738                 pool_add ${pool_names[$i]} ||
7739                         error "pool_add failed (pool: ${pool_names[$i]})"
7740                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7741                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7742         done
7743
7744         # init the file to migrate
7745         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7746                 error "Unable to create $tfile on OST1"
7747         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7748                 error "Unable to write on $tfile"
7749
7750         echo "1. migrate $tfile on pool ${pool_names[0]}"
7751         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7752
7753         echo "2. migrate $tfile on pool ${pool_names[2]}"
7754         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7755
7756         echo "3. migrate $tfile on pool ${pool_names[1]}"
7757         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7758
7759         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7760         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7761         echo
7762
7763         # Clean pools
7764         destroy_test_pools ||
7765                 error "pool_destroy failed"
7766 }
7767 run_test 56xg "lfs migrate pool support"
7768
7769 test_56y() {
7770         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7771                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7772
7773         local res=""
7774         local dir=$DIR/$tdir
7775         local f1=$dir/file1
7776         local f2=$dir/file2
7777
7778         test_mkdir -p $dir || error "creating dir $dir"
7779         touch $f1 || error "creating std file $f1"
7780         $MULTIOP $f2 H2c || error "creating released file $f2"
7781
7782         # a directory can be raid0, so ask only for files
7783         res=$($LFS find $dir -L raid0 -type f | wc -l)
7784         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7785
7786         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7787         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7788
7789         # only files can be released, so no need to force file search
7790         res=$($LFS find $dir -L released)
7791         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7792
7793         res=$($LFS find $dir -type f \! -L released)
7794         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7795 }
7796 run_test 56y "lfs find -L raid0|released"
7797
7798 test_56z() { # LU-4824
7799         # This checks to make sure 'lfs find' continues after errors
7800         # There are two classes of errors that should be caught:
7801         # - If multiple paths are provided, all should be searched even if one
7802         #   errors out
7803         # - If errors are encountered during the search, it should not terminate
7804         #   early
7805         local dir=$DIR/$tdir
7806         local i
7807
7808         test_mkdir $dir
7809         for i in d{0..9}; do
7810                 test_mkdir $dir/$i
7811                 touch $dir/$i/$tfile
7812         done
7813         $LFS find $DIR/non_existent_dir $dir &&
7814                 error "$LFS find did not return an error"
7815         # Make a directory unsearchable. This should NOT be the last entry in
7816         # directory order.  Arbitrarily pick the 6th entry
7817         chmod 700 $($LFS find $dir -type d | sed '6!d')
7818
7819         $RUNAS $LFS find $DIR/non_existent $dir
7820         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7821
7822         # The user should be able to see 10 directories and 9 files
7823         (( count == 19 )) ||
7824                 error "$LFS find found $count != 19 entries after error"
7825 }
7826 run_test 56z "lfs find should continue after an error"
7827
7828 test_56aa() { # LU-5937
7829         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7830
7831         local dir=$DIR/$tdir
7832
7833         mkdir $dir
7834         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7835
7836         createmany -o $dir/striped_dir/${tfile}- 1024
7837         local dirs=$($LFS find --size +8k $dir/)
7838
7839         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7840 }
7841 run_test 56aa "lfs find --size under striped dir"
7842
7843 test_56ab() { # LU-10705
7844         test_mkdir $DIR/$tdir
7845         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7846         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7847         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7848         # Flush writes to ensure valid blocks.  Need to be more thorough for
7849         # ZFS, since blocks are not allocated/returned to client immediately.
7850         sync_all_data
7851         wait_zfs_commit ost1 2
7852         cancel_lru_locks osc
7853         ls -ls $DIR/$tdir
7854
7855         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7856
7857         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7858
7859         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7860         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7861
7862         rm -f $DIR/$tdir/$tfile.[123]
7863 }
7864 run_test 56ab "lfs find --blocks"
7865
7866 # LU-11188
7867 test_56aca() {
7868         local dir="$DIR/$tdir"
7869         local perms=(001 002 003 004 005 006 007
7870                      010 020 030 040 050 060 070
7871                      100 200 300 400 500 600 700
7872                      111 222 333 444 555 666 777)
7873         local perm_minus=(8 8 4 8 4 4 2
7874                           8 8 4 8 4 4 2
7875                           8 8 4 8 4 4 2
7876                           4 4 2 4 2 2 1)
7877         local perm_slash=(8  8 12  8 12 12 14
7878                           8  8 12  8 12 12 14
7879                           8  8 12  8 12 12 14
7880                          16 16 24 16 24 24 28)
7881
7882         test_mkdir "$dir"
7883         for perm in ${perms[*]}; do
7884                 touch "$dir/$tfile.$perm"
7885                 chmod $perm "$dir/$tfile.$perm"
7886         done
7887
7888         for ((i = 0; i < ${#perms[*]}; i++)); do
7889                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7890                 (( $num == 1 )) ||
7891                         error "lfs find -perm ${perms[i]}:"\
7892                               "$num != 1"
7893
7894                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7895                 (( $num == ${perm_minus[i]} )) ||
7896                         error "lfs find -perm -${perms[i]}:"\
7897                               "$num != ${perm_minus[i]}"
7898
7899                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7900                 (( $num == ${perm_slash[i]} )) ||
7901                         error "lfs find -perm /${perms[i]}:"\
7902                               "$num != ${perm_slash[i]}"
7903         done
7904 }
7905 run_test 56aca "check lfs find -perm with octal representation"
7906
7907 test_56acb() {
7908         local dir=$DIR/$tdir
7909         # p is the permission of write and execute for user, group and other
7910         # without the umask. It is used to test +wx.
7911         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7912         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7913         local symbolic=(+t  a+t u+t g+t o+t
7914                         g+s u+s o+s +s o+sr
7915                         o=r,ug+o,u+w
7916                         u+ g+ o+ a+ ugo+
7917                         u- g- o- a- ugo-
7918                         u= g= o= a= ugo=
7919                         o=r,ug+o,u+w u=r,a+u,u+w
7920                         g=r,ugo=g,u+w u+x,+X +X
7921                         u+x,u+X u+X u+x,g+X o+r,+X
7922                         u+x,go+X +wx +rwx)
7923
7924         test_mkdir $dir
7925         for perm in ${perms[*]}; do
7926                 touch "$dir/$tfile.$perm"
7927                 chmod $perm "$dir/$tfile.$perm"
7928         done
7929
7930         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7931                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7932
7933                 (( $num == 1 )) ||
7934                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7935         done
7936 }
7937 run_test 56acb "check lfs find -perm with symbolic representation"
7938
7939 test_56acc() {
7940         local dir=$DIR/$tdir
7941         local tests="17777 787 789 abcd
7942                 ug=uu ug=a ug=gu uo=ou urw
7943                 u+xg+x a=r,u+x,"
7944
7945         test_mkdir $dir
7946         for err in $tests; do
7947                 if $LFS find $dir -perm $err 2>/dev/null; then
7948                         error "lfs find -perm $err: parsing should have failed"
7949                 fi
7950         done
7951 }
7952 run_test 56acc "check parsing error for lfs find -perm"
7953
7954 test_56ba() {
7955         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7956                 skip "Need MDS version at least 2.10.50"
7957
7958         # Create composite files with one component
7959         local dir=$DIR/$tdir
7960
7961         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7962         # Create composite files with three components
7963         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7964         # Create non-composite files
7965         createmany -o $dir/${tfile}- 10
7966
7967         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7968
7969         [[ $nfiles == 10 ]] ||
7970                 error "lfs find -E 1M found $nfiles != 10 files"
7971
7972         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7973         [[ $nfiles == 25 ]] ||
7974                 error "lfs find ! -E 1M found $nfiles != 25 files"
7975
7976         # All files have a component that starts at 0
7977         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7978         [[ $nfiles == 35 ]] ||
7979                 error "lfs find --component-start 0 - $nfiles != 35 files"
7980
7981         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7982         [[ $nfiles == 15 ]] ||
7983                 error "lfs find --component-start 2M - $nfiles != 15 files"
7984
7985         # All files created here have a componenet that does not starts at 2M
7986         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7987         [[ $nfiles == 35 ]] ||
7988                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7989
7990         # Find files with a specified number of components
7991         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7992         [[ $nfiles == 15 ]] ||
7993                 error "lfs find --component-count 3 - $nfiles != 15 files"
7994
7995         # Remember non-composite files have a component count of zero
7996         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7997         [[ $nfiles == 10 ]] ||
7998                 error "lfs find --component-count 0 - $nfiles != 10 files"
7999
8000         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8001         [[ $nfiles == 20 ]] ||
8002                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8003
8004         # All files have a flag called "init"
8005         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8006         [[ $nfiles == 35 ]] ||
8007                 error "lfs find --component-flags init - $nfiles != 35 files"
8008
8009         # Multi-component files will have a component not initialized
8010         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8011         [[ $nfiles == 15 ]] ||
8012                 error "lfs find !--component-flags init - $nfiles != 15 files"
8013
8014         rm -rf $dir
8015
8016 }
8017 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8018
8019 test_56ca() {
8020         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8021                 skip "Need MDS version at least 2.10.57"
8022
8023         local td=$DIR/$tdir
8024         local tf=$td/$tfile
8025         local dir
8026         local nfiles
8027         local cmd
8028         local i
8029         local j
8030
8031         # create mirrored directories and mirrored files
8032         mkdir $td || error "mkdir $td failed"
8033         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8034         createmany -o $tf- 10 || error "create $tf- failed"
8035
8036         for i in $(seq 2); do
8037                 dir=$td/dir$i
8038                 mkdir $dir || error "mkdir $dir failed"
8039                 $LFS mirror create -N$((3 + i)) $dir ||
8040                         error "create mirrored dir $dir failed"
8041                 createmany -o $dir/$tfile- 10 ||
8042                         error "create $dir/$tfile- failed"
8043         done
8044
8045         # change the states of some mirrored files
8046         echo foo > $tf-6
8047         for i in $(seq 2); do
8048                 dir=$td/dir$i
8049                 for j in $(seq 4 9); do
8050                         echo foo > $dir/$tfile-$j
8051                 done
8052         done
8053
8054         # find mirrored files with specific mirror count
8055         cmd="$LFS find --mirror-count 3 --type f $td"
8056         nfiles=$($cmd | wc -l)
8057         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8058
8059         cmd="$LFS find ! --mirror-count 3 --type f $td"
8060         nfiles=$($cmd | wc -l)
8061         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8062
8063         cmd="$LFS find --mirror-count +2 --type f $td"
8064         nfiles=$($cmd | wc -l)
8065         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8066
8067         cmd="$LFS find --mirror-count -6 --type f $td"
8068         nfiles=$($cmd | wc -l)
8069         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8070
8071         # find mirrored files with specific file state
8072         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8073         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8074
8075         cmd="$LFS find --mirror-state=ro --type f $td"
8076         nfiles=$($cmd | wc -l)
8077         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8078
8079         cmd="$LFS find ! --mirror-state=ro --type f $td"
8080         nfiles=$($cmd | wc -l)
8081         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8082
8083         cmd="$LFS find --mirror-state=wp --type f $td"
8084         nfiles=$($cmd | wc -l)
8085         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8086
8087         cmd="$LFS find ! --mirror-state=sp --type f $td"
8088         nfiles=$($cmd | wc -l)
8089         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8090 }
8091 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8092
8093 test_56da() { # LU-14179
8094         local path=$DIR/$tdir
8095
8096         test_mkdir $path
8097         cd $path
8098
8099         local longdir=$(str_repeat 'a' 255)
8100
8101         for i in {1..15}; do
8102                 path=$path/$longdir
8103                 test_mkdir $longdir
8104                 cd $longdir
8105         done
8106
8107         local len=${#path}
8108         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8109
8110         test_mkdir $lastdir
8111         cd $lastdir
8112         # PATH_MAX-1
8113         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8114
8115         # NAME_MAX
8116         touch $(str_repeat 'f' 255)
8117
8118         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8119                 error "lfs find reported an error"
8120
8121         rm -rf $DIR/$tdir
8122 }
8123 run_test 56da "test lfs find with long paths"
8124
8125 test_57a() {
8126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8127         # note test will not do anything if MDS is not local
8128         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8129                 skip_env "ldiskfs only test"
8130         fi
8131         remote_mds_nodsh && skip "remote MDS with nodsh"
8132
8133         local MNTDEV="osd*.*MDT*.mntdev"
8134         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8135         [ -z "$DEV" ] && error "can't access $MNTDEV"
8136         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8137                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8138                         error "can't access $DEV"
8139                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8140                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8141                 rm $TMP/t57a.dump
8142         done
8143 }
8144 run_test 57a "verify MDS filesystem created with large inodes =="
8145
8146 test_57b() {
8147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8148         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8149                 skip_env "ldiskfs only test"
8150         fi
8151         remote_mds_nodsh && skip "remote MDS with nodsh"
8152
8153         local dir=$DIR/$tdir
8154         local filecount=100
8155         local file1=$dir/f1
8156         local fileN=$dir/f$filecount
8157
8158         rm -rf $dir || error "removing $dir"
8159         test_mkdir -c1 $dir
8160         local mdtidx=$($LFS getstripe -m $dir)
8161         local mdtname=MDT$(printf %04x $mdtidx)
8162         local facet=mds$((mdtidx + 1))
8163
8164         echo "mcreating $filecount files"
8165         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8166
8167         # verify that files do not have EAs yet
8168         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8169                 error "$file1 has an EA"
8170         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8171                 error "$fileN has an EA"
8172
8173         sync
8174         sleep 1
8175         df $dir  #make sure we get new statfs data
8176         local mdsfree=$(do_facet $facet \
8177                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8178         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8179         local file
8180
8181         echo "opening files to create objects/EAs"
8182         for file in $(seq -f $dir/f%g 1 $filecount); do
8183                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8184                         error "opening $file"
8185         done
8186
8187         # verify that files have EAs now
8188         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8189         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8190
8191         sleep 1  #make sure we get new statfs data
8192         df $dir
8193         local mdsfree2=$(do_facet $facet \
8194                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8195         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8196
8197         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8198                 if [ "$mdsfree" != "$mdsfree2" ]; then
8199                         error "MDC before $mdcfree != after $mdcfree2"
8200                 else
8201                         echo "MDC before $mdcfree != after $mdcfree2"
8202                         echo "unable to confirm if MDS has large inodes"
8203                 fi
8204         fi
8205         rm -rf $dir
8206 }
8207 run_test 57b "default LOV EAs are stored inside large inodes ==="
8208
8209 test_58() {
8210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8211         [ -z "$(which wiretest 2>/dev/null)" ] &&
8212                         skip_env "could not find wiretest"
8213
8214         wiretest
8215 }
8216 run_test 58 "verify cross-platform wire constants =============="
8217
8218 test_59() {
8219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8220
8221         echo "touch 130 files"
8222         createmany -o $DIR/f59- 130
8223         echo "rm 130 files"
8224         unlinkmany $DIR/f59- 130
8225         sync
8226         # wait for commitment of removal
8227         wait_delete_completed
8228 }
8229 run_test 59 "verify cancellation of llog records async ========="
8230
8231 TEST60_HEAD="test_60 run $RANDOM"
8232 test_60a() {
8233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8234         remote_mgs_nodsh && skip "remote MGS with nodsh"
8235         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8236                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8237                         skip_env "missing subtest run-llog.sh"
8238
8239         log "$TEST60_HEAD - from kernel mode"
8240         do_facet mgs "$LCTL dk > /dev/null"
8241         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8242         do_facet mgs $LCTL dk > $TMP/$tfile
8243
8244         # LU-6388: test llog_reader
8245         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8246         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8247         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8248                         skip_env "missing llog_reader"
8249         local fstype=$(facet_fstype mgs)
8250         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8251                 skip_env "Only for ldiskfs or zfs type mgs"
8252
8253         local mntpt=$(facet_mntpt mgs)
8254         local mgsdev=$(mgsdevname 1)
8255         local fid_list
8256         local fid
8257         local rec_list
8258         local rec
8259         local rec_type
8260         local obj_file
8261         local path
8262         local seq
8263         local oid
8264         local pass=true
8265
8266         #get fid and record list
8267         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8268                 tail -n 4))
8269         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8270                 tail -n 4))
8271         #remount mgs as ldiskfs or zfs type
8272         stop mgs || error "stop mgs failed"
8273         mount_fstype mgs || error "remount mgs failed"
8274         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8275                 fid=${fid_list[i]}
8276                 rec=${rec_list[i]}
8277                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8278                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8279                 oid=$((16#$oid))
8280
8281                 case $fstype in
8282                         ldiskfs )
8283                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8284                         zfs )
8285                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8286                 esac
8287                 echo "obj_file is $obj_file"
8288                 do_facet mgs $llog_reader $obj_file
8289
8290                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8291                         awk '{ print $3 }' | sed -e "s/^type=//g")
8292                 if [ $rec_type != $rec ]; then
8293                         echo "FAILED test_60a wrong record type $rec_type," \
8294                               "should be $rec"
8295                         pass=false
8296                         break
8297                 fi
8298
8299                 #check obj path if record type is LLOG_LOGID_MAGIC
8300                 if [ "$rec" == "1064553b" ]; then
8301                         path=$(do_facet mgs $llog_reader $obj_file |
8302                                 grep "path=" | awk '{ print $NF }' |
8303                                 sed -e "s/^path=//g")
8304                         if [ $obj_file != $mntpt/$path ]; then
8305                                 echo "FAILED test_60a wrong obj path" \
8306                                       "$montpt/$path, should be $obj_file"
8307                                 pass=false
8308                                 break
8309                         fi
8310                 fi
8311         done
8312         rm -f $TMP/$tfile
8313         #restart mgs before "error", otherwise it will block the next test
8314         stop mgs || error "stop mgs failed"
8315         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8316         $pass || error "test failed, see FAILED test_60a messages for specifics"
8317 }
8318 run_test 60a "llog_test run from kernel module and test llog_reader"
8319
8320 test_60b() { # bug 6411
8321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8322
8323         dmesg > $DIR/$tfile
8324         LLOG_COUNT=$(do_facet mgs dmesg |
8325                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8326                           /llog_[a-z]*.c:[0-9]/ {
8327                                 if (marker)
8328                                         from_marker++
8329                                 from_begin++
8330                           }
8331                           END {
8332                                 if (marker)
8333                                         print from_marker
8334                                 else
8335                                         print from_begin
8336                           }")
8337
8338         [[ $LLOG_COUNT -gt 120 ]] &&
8339                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8340 }
8341 run_test 60b "limit repeated messages from CERROR/CWARN"
8342
8343 test_60c() {
8344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8345
8346         echo "create 5000 files"
8347         createmany -o $DIR/f60c- 5000
8348 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8349         lctl set_param fail_loc=0x80000137
8350         unlinkmany $DIR/f60c- 5000
8351         lctl set_param fail_loc=0
8352 }
8353 run_test 60c "unlink file when mds full"
8354
8355 test_60d() {
8356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8357
8358         SAVEPRINTK=$(lctl get_param -n printk)
8359         # verify "lctl mark" is even working"
8360         MESSAGE="test message ID $RANDOM $$"
8361         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8362         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8363
8364         lctl set_param printk=0 || error "set lnet.printk failed"
8365         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8366         MESSAGE="new test message ID $RANDOM $$"
8367         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8368         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8369         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8370
8371         lctl set_param -n printk="$SAVEPRINTK"
8372 }
8373 run_test 60d "test printk console message masking"
8374
8375 test_60e() {
8376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8377         remote_mds_nodsh && skip "remote MDS with nodsh"
8378
8379         touch $DIR/$tfile
8380 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8381         do_facet mds1 lctl set_param fail_loc=0x15b
8382         rm $DIR/$tfile
8383 }
8384 run_test 60e "no space while new llog is being created"
8385
8386 test_60f() {
8387         local old_path=$($LCTL get_param -n debug_path)
8388
8389         stack_trap "$LCTL set_param debug_path=$old_path"
8390         stack_trap "rm -f $TMP/$tfile*"
8391         rm -f $TMP/$tfile* 2> /dev/null
8392         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8393         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8394         test_mkdir $DIR/$tdir
8395         # retry in case the open is cached and not released
8396         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8397                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8398                 sleep 0.1
8399         done
8400         ls $TMP/$tfile*
8401         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8402 }
8403 run_test 60f "change debug_path works"
8404
8405 test_60g() {
8406         local pid
8407         local i
8408
8409         test_mkdir -c $MDSCOUNT $DIR/$tdir
8410
8411         (
8412                 local index=0
8413                 while true; do
8414                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8415                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8416                                 2>/dev/null
8417                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8418                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8419                         index=$((index + 1))
8420                 done
8421         ) &
8422
8423         pid=$!
8424
8425         for i in {0..100}; do
8426                 # define OBD_FAIL_OSD_TXN_START    0x19a
8427                 local index=$((i % MDSCOUNT + 1))
8428
8429                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8430                         > /dev/null
8431                 sleep 0.01
8432         done
8433
8434         kill -9 $pid
8435
8436         for i in $(seq $MDSCOUNT); do
8437                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8438         done
8439
8440         mkdir $DIR/$tdir/new || error "mkdir failed"
8441         rmdir $DIR/$tdir/new || error "rmdir failed"
8442
8443         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8444                 -t namespace
8445         for i in $(seq $MDSCOUNT); do
8446                 wait_update_facet mds$i "$LCTL get_param -n \
8447                         mdd.$(facet_svc mds$i).lfsck_namespace |
8448                         awk '/^status/ { print \\\$2 }'" "completed"
8449         done
8450
8451         ls -R $DIR/$tdir || error "ls failed"
8452         rm -rf $DIR/$tdir || error "rmdir failed"
8453 }
8454 run_test 60g "transaction abort won't cause MDT hung"
8455
8456 test_60h() {
8457         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8458                 skip "Need MDS version at least 2.12.52"
8459         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8460
8461         local f
8462
8463         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8464         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8465         for fail_loc in 0x80000188 0x80000189; do
8466                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8467                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8468                         error "mkdir $dir-$fail_loc failed"
8469                 for i in {0..10}; do
8470                         # create may fail on missing stripe
8471                         echo $i > $DIR/$tdir-$fail_loc/$i
8472                 done
8473                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8474                         error "getdirstripe $tdir-$fail_loc failed"
8475                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8476                         error "migrate $tdir-$fail_loc failed"
8477                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8478                         error "getdirstripe $tdir-$fail_loc failed"
8479                 pushd $DIR/$tdir-$fail_loc
8480                 for f in *; do
8481                         echo $f | cmp $f - || error "$f data mismatch"
8482                 done
8483                 popd
8484                 rm -rf $DIR/$tdir-$fail_loc
8485         done
8486 }
8487 run_test 60h "striped directory with missing stripes can be accessed"
8488
8489 function t60i_load() {
8490         mkdir $DIR/$tdir
8491         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8492         $LCTL set_param fail_loc=0x131c fail_val=1
8493         for ((i=0; i<5000; i++)); do
8494                 touch $DIR/$tdir/f$i
8495         done
8496 }
8497
8498 test_60i() {
8499         changelog_register || error "changelog_register failed"
8500         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8501         changelog_users $SINGLEMDS | grep -q $cl_user ||
8502                 error "User $cl_user not found in changelog_users"
8503         changelog_chmask "ALL"
8504         t60i_load &
8505         local PID=$!
8506         for((i=0; i<100; i++)); do
8507                 changelog_dump >/dev/null ||
8508                         error "can't read changelog"
8509         done
8510         kill $PID
8511         wait $PID
8512         changelog_deregister || error "changelog_deregister failed"
8513         $LCTL set_param fail_loc=0
8514 }
8515 run_test 60i "llog: new record vs reader race"
8516
8517 test_61a() {
8518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8519
8520         f="$DIR/f61"
8521         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8522         cancel_lru_locks osc
8523         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8524         sync
8525 }
8526 run_test 61a "mmap() writes don't make sync hang ================"
8527
8528 test_61b() {
8529         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8530 }
8531 run_test 61b "mmap() of unstriped file is successful"
8532
8533 # bug 2330 - insufficient obd_match error checking causes LBUG
8534 test_62() {
8535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8536
8537         f="$DIR/f62"
8538         echo foo > $f
8539         cancel_lru_locks osc
8540         lctl set_param fail_loc=0x405
8541         cat $f && error "cat succeeded, expect -EIO"
8542         lctl set_param fail_loc=0
8543 }
8544 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8545 # match every page all of the time.
8546 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8547
8548 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8549 # Though this test is irrelevant anymore, it helped to reveal some
8550 # other grant bugs (LU-4482), let's keep it.
8551 test_63a() {   # was test_63
8552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8553
8554         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8555
8556         for i in `seq 10` ; do
8557                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8558                 sleep 5
8559                 kill $!
8560                 sleep 1
8561         done
8562
8563         rm -f $DIR/f63 || true
8564 }
8565 run_test 63a "Verify oig_wait interruption does not crash ======="
8566
8567 # bug 2248 - async write errors didn't return to application on sync
8568 # bug 3677 - async write errors left page locked
8569 test_63b() {
8570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8571
8572         debugsave
8573         lctl set_param debug=-1
8574
8575         # ensure we have a grant to do async writes
8576         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8577         rm $DIR/$tfile
8578
8579         sync    # sync lest earlier test intercept the fail_loc
8580
8581         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8582         lctl set_param fail_loc=0x80000406
8583         $MULTIOP $DIR/$tfile Owy && \
8584                 error "sync didn't return ENOMEM"
8585         sync; sleep 2; sync     # do a real sync this time to flush page
8586         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8587                 error "locked page left in cache after async error" || true
8588         debugrestore
8589 }
8590 run_test 63b "async write errors should be returned to fsync ==="
8591
8592 test_64a () {
8593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8594
8595         lfs df $DIR
8596         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8597 }
8598 run_test 64a "verify filter grant calculations (in kernel) ====="
8599
8600 test_64b () {
8601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8602
8603         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8604 }
8605 run_test 64b "check out-of-space detection on client"
8606
8607 test_64c() {
8608         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8609 }
8610 run_test 64c "verify grant shrink"
8611
8612 import_param() {
8613         local tgt=$1
8614         local param=$2
8615
8616         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8617 }
8618
8619 # this does exactly what osc_request.c:osc_announce_cached() does in
8620 # order to calculate max amount of grants to ask from server
8621 want_grant() {
8622         local tgt=$1
8623
8624         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8625         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8626
8627         ((rpc_in_flight++));
8628         nrpages=$((nrpages * rpc_in_flight))
8629
8630         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8631
8632         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8633
8634         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8635         local undirty=$((nrpages * PAGE_SIZE))
8636
8637         local max_extent_pages
8638         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8639         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8640         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8641         local grant_extent_tax
8642         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8643
8644         undirty=$((undirty + nrextents * grant_extent_tax))
8645
8646         echo $undirty
8647 }
8648
8649 # this is size of unit for grant allocation. It should be equal to
8650 # what tgt_grant.c:tgt_grant_chunk() calculates
8651 grant_chunk() {
8652         local tgt=$1
8653         local max_brw_size
8654         local grant_extent_tax
8655
8656         max_brw_size=$(import_param $tgt max_brw_size)
8657
8658         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8659
8660         echo $(((max_brw_size + grant_extent_tax) * 2))
8661 }
8662
8663 test_64d() {
8664         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8665                 skip "OST < 2.10.55 doesn't limit grants enough"
8666
8667         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8668
8669         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8670                 skip "no grant_param connect flag"
8671
8672         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8673
8674         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8675         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8676
8677
8678         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8679         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8680
8681         $LFS setstripe $DIR/$tfile -i 0 -c 1
8682         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8683         ddpid=$!
8684
8685         while kill -0 $ddpid; do
8686                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8687
8688                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8689                         kill $ddpid
8690                         error "cur_grant $cur_grant > $max_cur_granted"
8691                 fi
8692
8693                 sleep 1
8694         done
8695 }
8696 run_test 64d "check grant limit exceed"
8697
8698 check_grants() {
8699         local tgt=$1
8700         local expected=$2
8701         local msg=$3
8702         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8703
8704         ((cur_grants == expected)) ||
8705                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8706 }
8707
8708 round_up_p2() {
8709         echo $((($1 + $2 - 1) & ~($2 - 1)))
8710 }
8711
8712 test_64e() {
8713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8714         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8715                 skip "Need OSS version at least 2.11.56"
8716
8717         # Remount client to reset grant
8718         remount_client $MOUNT || error "failed to remount client"
8719         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8720
8721         local init_grants=$(import_param $osc_tgt initial_grant)
8722
8723         check_grants $osc_tgt $init_grants "init grants"
8724
8725         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8726         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8727         local gbs=$(import_param $osc_tgt grant_block_size)
8728
8729         # write random number of bytes from max_brw_size / 4 to max_brw_size
8730         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8731         # align for direct io
8732         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8733         # round to grant consumption unit
8734         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8735
8736         local grants=$((wb_round_up + extent_tax))
8737
8738         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8739
8740         # define OBD_FAIL_TGT_NO_GRANT 0x725
8741         # make the server not grant more back
8742         do_facet ost1 $LCTL set_param fail_loc=0x725
8743         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8744
8745         do_facet ost1 $LCTL set_param fail_loc=0
8746
8747         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8748
8749         rm -f $DIR/$tfile || error "rm failed"
8750
8751         # Remount client to reset grant
8752         remount_client $MOUNT || error "failed to remount client"
8753         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8754
8755         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8756
8757         # define OBD_FAIL_TGT_NO_GRANT 0x725
8758         # make the server not grant more back
8759         do_facet ost1 $LCTL set_param fail_loc=0x725
8760         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8761         do_facet ost1 $LCTL set_param fail_loc=0
8762
8763         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8764 }
8765 run_test 64e "check grant consumption (no grant allocation)"
8766
8767 test_64f() {
8768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8769
8770         # Remount client to reset grant
8771         remount_client $MOUNT || error "failed to remount client"
8772         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8773
8774         local init_grants=$(import_param $osc_tgt initial_grant)
8775         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8776         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8777         local gbs=$(import_param $osc_tgt grant_block_size)
8778         local chunk=$(grant_chunk $osc_tgt)
8779
8780         # write random number of bytes from max_brw_size / 4 to max_brw_size
8781         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8782         # align for direct io
8783         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8784         # round to grant consumption unit
8785         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8786
8787         local grants=$((wb_round_up + extent_tax))
8788
8789         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8790         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8791                 error "error writing to $DIR/$tfile"
8792
8793         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8794                 "direct io with grant allocation"
8795
8796         rm -f $DIR/$tfile || error "rm failed"
8797
8798         # Remount client to reset grant
8799         remount_client $MOUNT || error "failed to remount client"
8800         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8801
8802         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8803
8804         local cmd="oO_WRONLY:w${write_bytes}_yc"
8805
8806         $MULTIOP $DIR/$tfile $cmd &
8807         MULTIPID=$!
8808         sleep 1
8809
8810         check_grants $osc_tgt $((init_grants - grants)) \
8811                 "buffered io, not write rpc"
8812
8813         kill -USR1 $MULTIPID
8814         wait
8815
8816         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8817                 "buffered io, one RPC"
8818 }
8819 run_test 64f "check grant consumption (with grant allocation)"
8820
8821 test_64g() {
8822         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8823         #       skip "Need MDS version at least 2.14.54"
8824
8825         local mdts=$(comma_list $(mdts_nodes))
8826
8827         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8828                         tr '\n' ' ')
8829         stack_trap "$LCTL set_param $old"
8830
8831         # generate dirty pages and increase dirty granted on MDT
8832         stack_trap "rm -f $DIR/$tfile-*"
8833         for (( i = 0; i < 10; i++)); do
8834                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8835                         error "can't set stripe"
8836                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8837                         error "can't dd"
8838                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8839                         $LFS getstripe $DIR/$tfile-$i
8840                         error "not DoM file"
8841                 }
8842         done
8843
8844         # flush dirty pages
8845         sync
8846
8847         # wait until grant shrink reset grant dirty on MDTs
8848         for ((i = 0; i < 120; i++)); do
8849                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8850                         awk '{sum=sum+$1} END {print sum}')
8851                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8852                 echo "$grant_dirty grants, $vm_dirty pages"
8853                 (( grant_dirty + vm_dirty == 0 )) && break
8854                 (( i == 3 )) && sync &&
8855                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8856                 sleep 1
8857         done
8858
8859         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8860                 awk '{sum=sum+$1} END {print sum}')
8861         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8862 }
8863 run_test 64g "grant shrink on MDT"
8864
8865 test_64h() {
8866         local instance=$($LFS getname -i $DIR)
8867         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8868         local num_exps=$(do_facet ost1 \
8869             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8870         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8871         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8872         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8873
8874         # 10MiB is for file to be written, max_brw_size * 16 *
8875         # num_exps is space reserve so that tgt_grant_shrink() decided
8876         # to not shrink
8877         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8878         (( avail * 1024 < expect )) &&
8879                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8880
8881         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8882         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8883         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8884         $LCTL set_param osc.*OST0000*.grant_shrink=1
8885         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8886
8887         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8888         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8889
8890         # drop cache so that coming read would do rpc
8891         cancel_lru_locks osc
8892
8893         # shrink interval is set to 10, pause for 7 seconds so that
8894         # grant thread did not wake up yet but coming read entered
8895         # shrink mode for rpc (osc_should_shrink_grant())
8896         sleep 7
8897
8898         declare -a cur_grant_bytes
8899         declare -a tot_granted
8900         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8901         tot_granted[0]=$(do_facet ost1 \
8902             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8903
8904         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8905
8906         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8907         tot_granted[1]=$(do_facet ost1 \
8908             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8909
8910         # grant change should be equal on both sides
8911         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8912                 tot_granted[0] - tot_granted[1])) ||
8913                 error "grant change mismatch, "                                \
8914                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8915                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8916 }
8917 run_test 64h "grant shrink on read"
8918
8919 test_64i() {
8920         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8921                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8922
8923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8924         remote_ost_nodsh && skip "remote OSTs with nodsh"
8925
8926         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8927
8928         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8929
8930         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8931         local instance=$($LFS getname -i $DIR)
8932
8933         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8934         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8935
8936         # shrink grants and simulate rpc loss
8937         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8938         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8939         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8940
8941         fail ost1
8942
8943         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8944
8945         local testid=$(echo $TESTNAME | tr '_' ' ')
8946
8947         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8948                 grep "GRANT, real grant" &&
8949                 error "client has more grants then it owns" || true
8950 }
8951 run_test 64i "shrink on reconnect"
8952
8953 # bug 1414 - set/get directories' stripe info
8954 test_65a() {
8955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8956
8957         test_mkdir $DIR/$tdir
8958         touch $DIR/$tdir/f1
8959         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8960 }
8961 run_test 65a "directory with no stripe info"
8962
8963 test_65b() {
8964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8965
8966         test_mkdir $DIR/$tdir
8967         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8968
8969         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8970                                                 error "setstripe"
8971         touch $DIR/$tdir/f2
8972         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8973 }
8974 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8975
8976 test_65c() {
8977         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8978         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8979
8980         test_mkdir $DIR/$tdir
8981         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8982
8983         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8984                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8985         touch $DIR/$tdir/f3
8986         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8987 }
8988 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8989
8990 test_65d() {
8991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8992
8993         test_mkdir $DIR/$tdir
8994         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8995         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8996
8997         if [[ $STRIPECOUNT -le 0 ]]; then
8998                 sc=1
8999         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9000                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9001                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9002         else
9003                 sc=$(($STRIPECOUNT - 1))
9004         fi
9005         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9006         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9007         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9008                 error "lverify failed"
9009 }
9010 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9011
9012 test_65e() {
9013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9014
9015         test_mkdir $DIR/$tdir
9016
9017         $LFS setstripe $DIR/$tdir || error "setstripe"
9018         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9019                                         error "no stripe info failed"
9020         touch $DIR/$tdir/f6
9021         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9022 }
9023 run_test 65e "directory setstripe defaults"
9024
9025 test_65f() {
9026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9027
9028         test_mkdir $DIR/${tdir}f
9029         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9030                 error "setstripe succeeded" || true
9031 }
9032 run_test 65f "dir setstripe permission (should return error) ==="
9033
9034 test_65g() {
9035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9036
9037         test_mkdir $DIR/$tdir
9038         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9039
9040         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9041                 error "setstripe -S failed"
9042         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9043         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9044                 error "delete default stripe failed"
9045 }
9046 run_test 65g "directory setstripe -d"
9047
9048 test_65h() {
9049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9050
9051         test_mkdir $DIR/$tdir
9052         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9053
9054         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9055                 error "setstripe -S failed"
9056         test_mkdir $DIR/$tdir/dd1
9057         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9058                 error "stripe info inherit failed"
9059 }
9060 run_test 65h "directory stripe info inherit ===================="
9061
9062 test_65i() {
9063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9064
9065         save_layout_restore_at_exit $MOUNT
9066
9067         # bug6367: set non-default striping on root directory
9068         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9069
9070         # bug12836: getstripe on -1 default directory striping
9071         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9072
9073         # bug12836: getstripe -v on -1 default directory striping
9074         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9075
9076         # bug12836: new find on -1 default directory striping
9077         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9078 }
9079 run_test 65i "various tests to set root directory striping"
9080
9081 test_65j() { # bug6367
9082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9083
9084         sync; sleep 1
9085
9086         # if we aren't already remounting for each test, do so for this test
9087         if [ "$I_MOUNTED" = "yes" ]; then
9088                 cleanup || error "failed to unmount"
9089                 setup
9090         fi
9091
9092         save_layout_restore_at_exit $MOUNT
9093
9094         $LFS setstripe -d $MOUNT || error "setstripe failed"
9095 }
9096 run_test 65j "set default striping on root directory (bug 6367)="
9097
9098 cleanup_65k() {
9099         rm -rf $DIR/$tdir
9100         wait_delete_completed
9101         do_facet $SINGLEMDS "lctl set_param -n \
9102                 osp.$ost*MDT0000.max_create_count=$max_count"
9103         do_facet $SINGLEMDS "lctl set_param -n \
9104                 osp.$ost*MDT0000.create_count=$count"
9105         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9106         echo $INACTIVE_OSC "is Activate"
9107
9108         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9109 }
9110
9111 test_65k() { # bug11679
9112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9113         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9114         remote_mds_nodsh && skip "remote MDS with nodsh"
9115
9116         local disable_precreate=true
9117         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9118                 disable_precreate=false
9119
9120         echo "Check OST status: "
9121         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9122                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9123
9124         for OSC in $MDS_OSCS; do
9125                 echo $OSC "is active"
9126                 do_facet $SINGLEMDS lctl --device %$OSC activate
9127         done
9128
9129         for INACTIVE_OSC in $MDS_OSCS; do
9130                 local ost=$(osc_to_ost $INACTIVE_OSC)
9131                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9132                                lov.*md*.target_obd |
9133                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9134
9135                 mkdir -p $DIR/$tdir
9136                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9137                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9138
9139                 echo "Deactivate: " $INACTIVE_OSC
9140                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9141
9142                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9143                               osp.$ost*MDT0000.create_count")
9144                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9145                                   osp.$ost*MDT0000.max_create_count")
9146                 $disable_precreate &&
9147                         do_facet $SINGLEMDS "lctl set_param -n \
9148                                 osp.$ost*MDT0000.max_create_count=0"
9149
9150                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9151                         [ -f $DIR/$tdir/$idx ] && continue
9152                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9153                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9154                                 { cleanup_65k;
9155                                   error "setstripe $idx should succeed"; }
9156                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9157                 done
9158                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9159                 rmdir $DIR/$tdir
9160
9161                 do_facet $SINGLEMDS "lctl set_param -n \
9162                         osp.$ost*MDT0000.max_create_count=$max_count"
9163                 do_facet $SINGLEMDS "lctl set_param -n \
9164                         osp.$ost*MDT0000.create_count=$count"
9165                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9166                 echo $INACTIVE_OSC "is Activate"
9167
9168                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9169         done
9170 }
9171 run_test 65k "validate manual striping works properly with deactivated OSCs"
9172
9173 test_65l() { # bug 12836
9174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9175
9176         test_mkdir -p $DIR/$tdir/test_dir
9177         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9178         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9179 }
9180 run_test 65l "lfs find on -1 stripe dir ========================"
9181
9182 test_65m() {
9183         local layout=$(save_layout $MOUNT)
9184         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9185                 restore_layout $MOUNT $layout
9186                 error "setstripe should fail by non-root users"
9187         }
9188         true
9189 }
9190 run_test 65m "normal user can't set filesystem default stripe"
9191
9192 test_65n() {
9193         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9194         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9195                 skip "Need MDS version at least 2.12.50"
9196         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9197
9198         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9199         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9200         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9201
9202         save_layout_restore_at_exit $MOUNT
9203
9204         # new subdirectory under root directory should not inherit
9205         # the default layout from root
9206         local dir1=$MOUNT/$tdir-1
9207         mkdir $dir1 || error "mkdir $dir1 failed"
9208         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9209                 error "$dir1 shouldn't have LOV EA"
9210
9211         # delete the default layout on root directory
9212         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9213
9214         local dir2=$MOUNT/$tdir-2
9215         mkdir $dir2 || error "mkdir $dir2 failed"
9216         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9217                 error "$dir2 shouldn't have LOV EA"
9218
9219         # set a new striping pattern on root directory
9220         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9221         local new_def_stripe_size=$((def_stripe_size * 2))
9222         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9223                 error "set stripe size on $MOUNT failed"
9224
9225         # new file created in $dir2 should inherit the new stripe size from
9226         # the filesystem default
9227         local file2=$dir2/$tfile-2
9228         touch $file2 || error "touch $file2 failed"
9229
9230         local file2_stripe_size=$($LFS getstripe -S $file2)
9231         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9232         {
9233                 echo "file2_stripe_size: '$file2_stripe_size'"
9234                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9235                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9236         }
9237
9238         local dir3=$MOUNT/$tdir-3
9239         mkdir $dir3 || error "mkdir $dir3 failed"
9240         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9241         # the root layout, which is the actual default layout that will be used
9242         # when new files are created in $dir3.
9243         local dir3_layout=$(get_layout_param $dir3)
9244         local root_dir_layout=$(get_layout_param $MOUNT)
9245         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9246         {
9247                 echo "dir3_layout: '$dir3_layout'"
9248                 echo "root_dir_layout: '$root_dir_layout'"
9249                 error "$dir3 should show the default layout from $MOUNT"
9250         }
9251
9252         # set OST pool on root directory
9253         local pool=$TESTNAME
9254         pool_add $pool || error "add $pool failed"
9255         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9256                 error "add targets to $pool failed"
9257
9258         $LFS setstripe -p $pool $MOUNT ||
9259                 error "set OST pool on $MOUNT failed"
9260
9261         # new file created in $dir3 should inherit the pool from
9262         # the filesystem default
9263         local file3=$dir3/$tfile-3
9264         touch $file3 || error "touch $file3 failed"
9265
9266         local file3_pool=$($LFS getstripe -p $file3)
9267         [[ "$file3_pool" = "$pool" ]] ||
9268                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9269
9270         local dir4=$MOUNT/$tdir-4
9271         mkdir $dir4 || error "mkdir $dir4 failed"
9272         local dir4_layout=$(get_layout_param $dir4)
9273         root_dir_layout=$(get_layout_param $MOUNT)
9274         echo "$LFS getstripe -d $dir4"
9275         $LFS getstripe -d $dir4
9276         echo "$LFS getstripe -d $MOUNT"
9277         $LFS getstripe -d $MOUNT
9278         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9279         {
9280                 echo "dir4_layout: '$dir4_layout'"
9281                 echo "root_dir_layout: '$root_dir_layout'"
9282                 error "$dir4 should show the default layout from $MOUNT"
9283         }
9284
9285         # new file created in $dir4 should inherit the pool from
9286         # the filesystem default
9287         local file4=$dir4/$tfile-4
9288         touch $file4 || error "touch $file4 failed"
9289
9290         local file4_pool=$($LFS getstripe -p $file4)
9291         [[ "$file4_pool" = "$pool" ]] ||
9292                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9293
9294         # new subdirectory under non-root directory should inherit
9295         # the default layout from its parent directory
9296         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9297                 error "set directory layout on $dir4 failed"
9298
9299         local dir5=$dir4/$tdir-5
9300         mkdir $dir5 || error "mkdir $dir5 failed"
9301
9302         dir4_layout=$(get_layout_param $dir4)
9303         local dir5_layout=$(get_layout_param $dir5)
9304         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9305         {
9306                 echo "dir4_layout: '$dir4_layout'"
9307                 echo "dir5_layout: '$dir5_layout'"
9308                 error "$dir5 should inherit the default layout from $dir4"
9309         }
9310
9311         # though subdir under ROOT doesn't inherit default layout, but
9312         # its sub dir/file should be created with default layout.
9313         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9314         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9315                 skip "Need MDS version at least 2.12.59"
9316
9317         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9318         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9319         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9320
9321         if [ $default_lmv_hash == "none" ]; then
9322                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9323         else
9324                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9325                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9326         fi
9327
9328         $LFS setdirstripe -D -c 2 $MOUNT ||
9329                 error "setdirstripe -D -c 2 failed"
9330         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9331         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9332         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9333 }
9334 run_test 65n "don't inherit default layout from root for new subdirectories"
9335
9336 # bug 2543 - update blocks count on client
9337 test_66() {
9338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9339
9340         COUNT=${COUNT:-8}
9341         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9342         sync; sync_all_data; sync; sync_all_data
9343         cancel_lru_locks osc
9344         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9345         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9346 }
9347 run_test 66 "update inode blocks count on client ==============="
9348
9349 meminfo() {
9350         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9351 }
9352
9353 swap_used() {
9354         swapon -s | awk '($1 == "'$1'") { print $4 }'
9355 }
9356
9357 # bug5265, obdfilter oa2dentry return -ENOENT
9358 # #define OBD_FAIL_SRV_ENOENT 0x217
9359 test_69() {
9360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9361         remote_ost_nodsh && skip "remote OST with nodsh"
9362
9363         f="$DIR/$tfile"
9364         $LFS setstripe -c 1 -i 0 $f
9365
9366         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9367
9368         do_facet ost1 lctl set_param fail_loc=0x217
9369         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9370         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9371
9372         do_facet ost1 lctl set_param fail_loc=0
9373         $DIRECTIO write $f 0 2 || error "write error"
9374
9375         cancel_lru_locks osc
9376         $DIRECTIO read $f 0 1 || error "read error"
9377
9378         do_facet ost1 lctl set_param fail_loc=0x217
9379         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9380
9381         do_facet ost1 lctl set_param fail_loc=0
9382         rm -f $f
9383 }
9384 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9385
9386 test_71() {
9387         test_mkdir $DIR/$tdir
9388         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9389         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9390 }
9391 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9392
9393 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9395         [ "$RUNAS_ID" = "$UID" ] &&
9396                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9397         # Check that testing environment is properly set up. Skip if not
9398         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9399                 skip_env "User $RUNAS_ID does not exist - skipping"
9400
9401         touch $DIR/$tfile
9402         chmod 777 $DIR/$tfile
9403         chmod ug+s $DIR/$tfile
9404         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9405                 error "$RUNAS dd $DIR/$tfile failed"
9406         # See if we are still setuid/sgid
9407         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9408                 error "S/gid is not dropped on write"
9409         # Now test that MDS is updated too
9410         cancel_lru_locks mdc
9411         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9412                 error "S/gid is not dropped on MDS"
9413         rm -f $DIR/$tfile
9414 }
9415 run_test 72a "Test that remove suid works properly (bug5695) ===="
9416
9417 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9418         local perm
9419
9420         [ "$RUNAS_ID" = "$UID" ] &&
9421                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9422         [ "$RUNAS_ID" -eq 0 ] &&
9423                 skip_env "RUNAS_ID = 0 -- skipping"
9424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9425         # Check that testing environment is properly set up. Skip if not
9426         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9427                 skip_env "User $RUNAS_ID does not exist - skipping"
9428
9429         touch $DIR/${tfile}-f{g,u}
9430         test_mkdir $DIR/${tfile}-dg
9431         test_mkdir $DIR/${tfile}-du
9432         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9433         chmod g+s $DIR/${tfile}-{f,d}g
9434         chmod u+s $DIR/${tfile}-{f,d}u
9435         for perm in 777 2777 4777; do
9436                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9437                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9438                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9439                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9440         done
9441         true
9442 }
9443 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9444
9445 # bug 3462 - multiple simultaneous MDC requests
9446 test_73() {
9447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9448
9449         test_mkdir $DIR/d73-1
9450         test_mkdir $DIR/d73-2
9451         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9452         pid1=$!
9453
9454         lctl set_param fail_loc=0x80000129
9455         $MULTIOP $DIR/d73-1/f73-2 Oc &
9456         sleep 1
9457         lctl set_param fail_loc=0
9458
9459         $MULTIOP $DIR/d73-2/f73-3 Oc &
9460         pid3=$!
9461
9462         kill -USR1 $pid1
9463         wait $pid1 || return 1
9464
9465         sleep 25
9466
9467         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9468         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9469         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9470
9471         rm -rf $DIR/d73-*
9472 }
9473 run_test 73 "multiple MDC requests (should not deadlock)"
9474
9475 test_74a() { # bug 6149, 6184
9476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9477
9478         touch $DIR/f74a
9479         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9480         #
9481         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9482         # will spin in a tight reconnection loop
9483         $LCTL set_param fail_loc=0x8000030e
9484         # get any lock that won't be difficult - lookup works.
9485         ls $DIR/f74a
9486         $LCTL set_param fail_loc=0
9487         rm -f $DIR/f74a
9488         true
9489 }
9490 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9491
9492 test_74b() { # bug 13310
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494
9495         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9496         #
9497         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9498         # will spin in a tight reconnection loop
9499         $LCTL set_param fail_loc=0x8000030e
9500         # get a "difficult" lock
9501         touch $DIR/f74b
9502         $LCTL set_param fail_loc=0
9503         rm -f $DIR/f74b
9504         true
9505 }
9506 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9507
9508 test_74c() {
9509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9510
9511         #define OBD_FAIL_LDLM_NEW_LOCK
9512         $LCTL set_param fail_loc=0x319
9513         touch $DIR/$tfile && error "touch successful"
9514         $LCTL set_param fail_loc=0
9515         true
9516 }
9517 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9518
9519 slab_lic=/sys/kernel/slab/lustre_inode_cache
9520 num_objects() {
9521         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9522         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9523                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9524 }
9525
9526 test_76a() { # Now for b=20433, added originally in b=1443
9527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9528
9529         cancel_lru_locks osc
9530         # there may be some slab objects cached per core
9531         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9532         local before=$(num_objects)
9533         local count=$((512 * cpus))
9534         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9535         local margin=$((count / 10))
9536         if [[ -f $slab_lic/aliases ]]; then
9537                 local aliases=$(cat $slab_lic/aliases)
9538                 (( aliases > 0 )) && margin=$((margin * aliases))
9539         fi
9540
9541         echo "before slab objects: $before"
9542         for i in $(seq $count); do
9543                 touch $DIR/$tfile
9544                 rm -f $DIR/$tfile
9545         done
9546         cancel_lru_locks osc
9547         local after=$(num_objects)
9548         echo "created: $count, after slab objects: $after"
9549         # shared slab counts are not very accurate, allow significant margin
9550         # the main goal is that the cache growth is not permanently > $count
9551         while (( after > before + margin )); do
9552                 sleep 1
9553                 after=$(num_objects)
9554                 wait=$((wait + 1))
9555                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9556                 if (( wait > 60 )); then
9557                         error "inode slab grew from $before+$margin to $after"
9558                 fi
9559         done
9560 }
9561 run_test 76a "confirm clients recycle inodes properly ===="
9562
9563 test_76b() {
9564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9565         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9566
9567         local count=512
9568         local before=$(num_objects)
9569
9570         for i in $(seq $count); do
9571                 mkdir $DIR/$tdir
9572                 rmdir $DIR/$tdir
9573         done
9574
9575         local after=$(num_objects)
9576         local wait=0
9577
9578         while (( after > before )); do
9579                 sleep 1
9580                 after=$(num_objects)
9581                 wait=$((wait + 1))
9582                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9583                 if (( wait > 60 )); then
9584                         error "inode slab grew from $before to $after"
9585                 fi
9586         done
9587
9588         echo "slab objects before: $before, after: $after"
9589 }
9590 run_test 76b "confirm clients recycle directory inodes properly ===="
9591
9592 export ORIG_CSUM=""
9593 set_checksums()
9594 {
9595         # Note: in sptlrpc modes which enable its own bulk checksum, the
9596         # original crc32_le bulk checksum will be automatically disabled,
9597         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9598         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9599         # In this case set_checksums() will not be no-op, because sptlrpc
9600         # bulk checksum will be enabled all through the test.
9601
9602         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9603         lctl set_param -n osc.*.checksums $1
9604         return 0
9605 }
9606
9607 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9608                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9609 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9610                              tr -d [] | head -n1)}
9611 set_checksum_type()
9612 {
9613         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9614         rc=$?
9615         log "set checksum type to $1, rc = $rc"
9616         return $rc
9617 }
9618
9619 get_osc_checksum_type()
9620 {
9621         # arugment 1: OST name, like OST0000
9622         ost=$1
9623         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9624                         sed 's/.*\[\(.*\)\].*/\1/g')
9625         rc=$?
9626         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9627         echo $checksum_type
9628 }
9629
9630 F77_TMP=$TMP/f77-temp
9631 F77SZ=8
9632 setup_f77() {
9633         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9634                 error "error writing to $F77_TMP"
9635 }
9636
9637 test_77a() { # bug 10889
9638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9639         $GSS && skip_env "could not run with gss"
9640
9641         [ ! -f $F77_TMP ] && setup_f77
9642         set_checksums 1
9643         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9644         set_checksums 0
9645         rm -f $DIR/$tfile
9646 }
9647 run_test 77a "normal checksum read/write operation"
9648
9649 test_77b() { # bug 10889
9650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9651         $GSS && skip_env "could not run with gss"
9652
9653         [ ! -f $F77_TMP ] && setup_f77
9654         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9655         $LCTL set_param fail_loc=0x80000409
9656         set_checksums 1
9657
9658         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9659                 error "dd error: $?"
9660         $LCTL set_param fail_loc=0
9661
9662         for algo in $CKSUM_TYPES; do
9663                 cancel_lru_locks osc
9664                 set_checksum_type $algo
9665                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9666                 $LCTL set_param fail_loc=0x80000408
9667                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9668                 $LCTL set_param fail_loc=0
9669         done
9670         set_checksums 0
9671         set_checksum_type $ORIG_CSUM_TYPE
9672         rm -f $DIR/$tfile
9673 }
9674 run_test 77b "checksum error on client write, read"
9675
9676 cleanup_77c() {
9677         trap 0
9678         set_checksums 0
9679         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9680         $check_ost &&
9681                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9682         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9683         $check_ost && [ -n "$ost_file_prefix" ] &&
9684                 do_facet ost1 rm -f ${ost_file_prefix}\*
9685 }
9686
9687 test_77c() {
9688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9689         $GSS && skip_env "could not run with gss"
9690         remote_ost_nodsh && skip "remote OST with nodsh"
9691
9692         local bad1
9693         local osc_file_prefix
9694         local osc_file
9695         local check_ost=false
9696         local ost_file_prefix
9697         local ost_file
9698         local orig_cksum
9699         local dump_cksum
9700         local fid
9701
9702         # ensure corruption will occur on first OSS/OST
9703         $LFS setstripe -i 0 $DIR/$tfile
9704
9705         [ ! -f $F77_TMP ] && setup_f77
9706         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9707                 error "dd write error: $?"
9708         fid=$($LFS path2fid $DIR/$tfile)
9709
9710         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9711         then
9712                 check_ost=true
9713                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9714                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9715         else
9716                 echo "OSS do not support bulk pages dump upon error"
9717         fi
9718
9719         osc_file_prefix=$($LCTL get_param -n debug_path)
9720         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9721
9722         trap cleanup_77c EXIT
9723
9724         set_checksums 1
9725         # enable bulk pages dump upon error on Client
9726         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9727         # enable bulk pages dump upon error on OSS
9728         $check_ost &&
9729                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9730
9731         # flush Client cache to allow next read to reach OSS
9732         cancel_lru_locks osc
9733
9734         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9735         $LCTL set_param fail_loc=0x80000408
9736         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9737         $LCTL set_param fail_loc=0
9738
9739         rm -f $DIR/$tfile
9740
9741         # check cksum dump on Client
9742         osc_file=$(ls ${osc_file_prefix}*)
9743         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9744         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9745         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9746         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9747         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9748                      cksum)
9749         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9750         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9751                 error "dump content does not match on Client"
9752
9753         $check_ost || skip "No need to check cksum dump on OSS"
9754
9755         # check cksum dump on OSS
9756         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9757         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9758         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9759         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9760         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9761                 error "dump content does not match on OSS"
9762
9763         cleanup_77c
9764 }
9765 run_test 77c "checksum error on client read with debug"
9766
9767 test_77d() { # bug 10889
9768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9769         $GSS && skip_env "could not run with gss"
9770
9771         stack_trap "rm -f $DIR/$tfile"
9772         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9773         $LCTL set_param fail_loc=0x80000409
9774         set_checksums 1
9775         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9776                 error "direct write: rc=$?"
9777         $LCTL set_param fail_loc=0
9778         set_checksums 0
9779
9780         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9781         $LCTL set_param fail_loc=0x80000408
9782         set_checksums 1
9783         cancel_lru_locks osc
9784         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9785                 error "direct read: rc=$?"
9786         $LCTL set_param fail_loc=0
9787         set_checksums 0
9788 }
9789 run_test 77d "checksum error on OST direct write, read"
9790
9791 test_77f() { # bug 10889
9792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9793         $GSS && skip_env "could not run with gss"
9794
9795         set_checksums 1
9796         stack_trap "rm -f $DIR/$tfile"
9797         for algo in $CKSUM_TYPES; do
9798                 cancel_lru_locks osc
9799                 set_checksum_type $algo
9800                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9801                 $LCTL set_param fail_loc=0x409
9802                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9803                         error "direct write succeeded"
9804                 $LCTL set_param fail_loc=0
9805         done
9806         set_checksum_type $ORIG_CSUM_TYPE
9807         set_checksums 0
9808 }
9809 run_test 77f "repeat checksum error on write (expect error)"
9810
9811 test_77g() { # bug 10889
9812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9813         $GSS && skip_env "could not run with gss"
9814         remote_ost_nodsh && skip "remote OST with nodsh"
9815
9816         [ ! -f $F77_TMP ] && setup_f77
9817
9818         local file=$DIR/$tfile
9819         stack_trap "rm -f $file" EXIT
9820
9821         $LFS setstripe -c 1 -i 0 $file
9822         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9823         do_facet ost1 lctl set_param fail_loc=0x8000021a
9824         set_checksums 1
9825         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9826                 error "write error: rc=$?"
9827         do_facet ost1 lctl set_param fail_loc=0
9828         set_checksums 0
9829
9830         cancel_lru_locks osc
9831         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9832         do_facet ost1 lctl set_param fail_loc=0x8000021b
9833         set_checksums 1
9834         cmp $F77_TMP $file || error "file compare failed"
9835         do_facet ost1 lctl set_param fail_loc=0
9836         set_checksums 0
9837 }
9838 run_test 77g "checksum error on OST write, read"
9839
9840 test_77k() { # LU-10906
9841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9842         $GSS && skip_env "could not run with gss"
9843
9844         local cksum_param="osc.$FSNAME*.checksums"
9845         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9846         local checksum
9847         local i
9848
9849         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9850         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9851         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9852
9853         for i in 0 1; do
9854                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9855                         error "failed to set checksum=$i on MGS"
9856                 wait_update $HOSTNAME "$get_checksum" $i
9857                 #remount
9858                 echo "remount client, checksum should be $i"
9859                 remount_client $MOUNT || error "failed to remount client"
9860                 checksum=$(eval $get_checksum)
9861                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9862         done
9863         # remove persistent param to avoid races with checksum mountopt below
9864         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9865                 error "failed to delete checksum on MGS"
9866
9867         for opt in "checksum" "nochecksum"; do
9868                 #remount with mount option
9869                 echo "remount client with option $opt, checksum should be $i"
9870                 umount_client $MOUNT || error "failed to umount client"
9871                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9872                         error "failed to mount client with option '$opt'"
9873                 checksum=$(eval $get_checksum)
9874                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9875                 i=$((i - 1))
9876         done
9877
9878         remount_client $MOUNT || error "failed to remount client"
9879 }
9880 run_test 77k "enable/disable checksum correctly"
9881
9882 test_77l() {
9883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9884         $GSS && skip_env "could not run with gss"
9885
9886         set_checksums 1
9887         stack_trap "set_checksums $ORIG_CSUM" EXIT
9888         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9889
9890         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9891
9892         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9893         for algo in $CKSUM_TYPES; do
9894                 set_checksum_type $algo || error "fail to set checksum type $algo"
9895                 osc_algo=$(get_osc_checksum_type OST0000)
9896                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9897
9898                 # no locks, no reqs to let the connection idle
9899                 cancel_lru_locks osc
9900                 lru_resize_disable osc
9901                 wait_osc_import_state client ost1 IDLE
9902
9903                 # ensure ost1 is connected
9904                 stat $DIR/$tfile >/dev/null || error "can't stat"
9905                 wait_osc_import_state client ost1 FULL
9906
9907                 osc_algo=$(get_osc_checksum_type OST0000)
9908                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9909         done
9910         return 0
9911 }
9912 run_test 77l "preferred checksum type is remembered after reconnected"
9913
9914 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9915 rm -f $F77_TMP
9916 unset F77_TMP
9917
9918 test_77m() {
9919         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9920                 skip "Need at least version 2.14.52"
9921         local param=checksum_speed
9922
9923         $LCTL get_param $param || error "reading $param failed"
9924
9925         csum_speeds=$($LCTL get_param -n $param)
9926
9927         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9928                 error "known checksum types are missing"
9929 }
9930 run_test 77m "Verify checksum_speed is correctly read"
9931
9932 check_filefrag_77n() {
9933         local nr_ext=0
9934         local starts=()
9935         local ends=()
9936
9937         while read extidx a b start end rest; do
9938                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9939                         nr_ext=$(( $nr_ext + 1 ))
9940                         starts+=( ${start%..} )
9941                         ends+=( ${end%:} )
9942                 fi
9943         done < <( filefrag -sv $1 )
9944
9945         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9946         return 1
9947 }
9948
9949 test_77n() {
9950         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9951
9952         touch $DIR/$tfile
9953         $TRUNCATE $DIR/$tfile 0
9954         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9955         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9956         check_filefrag_77n $DIR/$tfile ||
9957                 skip "$tfile blocks not contiguous around hole"
9958
9959         set_checksums 1
9960         stack_trap "set_checksums $ORIG_CSUM" EXIT
9961         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9962         stack_trap "rm -f $DIR/$tfile"
9963
9964         for algo in $CKSUM_TYPES; do
9965                 if [[ "$algo" =~ ^t10 ]]; then
9966                         set_checksum_type $algo ||
9967                                 error "fail to set checksum type $algo"
9968                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9969                                 error "fail to read $tfile with $algo"
9970                 fi
9971         done
9972         rm -f $DIR/$tfile
9973         return 0
9974 }
9975 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9976
9977 test_77o() {
9978         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
9979                 skip "Need at least version 2.14.54"
9980         local ofd=obdfilter
9981         local mdt=mdt
9982
9983         # print OST checksum_type
9984         echo "$ofd.$FSNAME-*.checksum_type:"
9985         do_nodes $(comma_list $(osts_nodes)) \
9986                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
9987
9988         # print MDT checksum_type
9989         echo "$mdt.$FSNAME-*.checksum_type:"
9990         do_nodes $(comma_list $(mdts_nodes)) \
9991                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
9992
9993         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
9994                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
9995
9996         (( $o_count == $OSTCOUNT )) ||
9997                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
9998
9999         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10000                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10001
10002         (( $m_count == $MDSCOUNT )) ||
10003                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10004 }
10005 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10006
10007 cleanup_test_78() {
10008         trap 0
10009         rm -f $DIR/$tfile
10010 }
10011
10012 test_78() { # bug 10901
10013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10014         remote_ost || skip_env "local OST"
10015
10016         NSEQ=5
10017         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10018         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10019         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10020         echo "MemTotal: $MEMTOTAL"
10021
10022         # reserve 256MB of memory for the kernel and other running processes,
10023         # and then take 1/2 of the remaining memory for the read/write buffers.
10024         if [ $MEMTOTAL -gt 512 ] ;then
10025                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10026         else
10027                 # for those poor memory-starved high-end clusters...
10028                 MEMTOTAL=$((MEMTOTAL / 2))
10029         fi
10030         echo "Mem to use for directio: $MEMTOTAL"
10031
10032         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10033         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10034         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10035         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10036                 head -n1)
10037         echo "Smallest OST: $SMALLESTOST"
10038         [[ $SMALLESTOST -lt 10240 ]] &&
10039                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10040
10041         trap cleanup_test_78 EXIT
10042
10043         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10044                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10045
10046         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10047         echo "File size: $F78SIZE"
10048         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10049         for i in $(seq 1 $NSEQ); do
10050                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10051                 echo directIO rdwr round $i of $NSEQ
10052                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10053         done
10054
10055         cleanup_test_78
10056 }
10057 run_test 78 "handle large O_DIRECT writes correctly ============"
10058
10059 test_79() { # bug 12743
10060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10061
10062         wait_delete_completed
10063
10064         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10065         BKFREE=$(calc_osc_kbytes kbytesfree)
10066         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10067
10068         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10069         DFTOTAL=`echo $STRING | cut -d, -f1`
10070         DFUSED=`echo $STRING  | cut -d, -f2`
10071         DFAVAIL=`echo $STRING | cut -d, -f3`
10072         DFFREE=$(($DFTOTAL - $DFUSED))
10073
10074         ALLOWANCE=$((64 * $OSTCOUNT))
10075
10076         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10077            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10078                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10079         fi
10080         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10081            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10082                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10083         fi
10084         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10085            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10086                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10087         fi
10088 }
10089 run_test 79 "df report consistency check ======================="
10090
10091 test_80() { # bug 10718
10092         remote_ost_nodsh && skip "remote OST with nodsh"
10093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10094
10095         # relax strong synchronous semantics for slow backends like ZFS
10096         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10097                 local soc="obdfilter.*.sync_lock_cancel"
10098                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10099
10100                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10101                 if [ -z "$save" ]; then
10102                         soc="obdfilter.*.sync_on_lock_cancel"
10103                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10104                 fi
10105
10106                 if [ "$save" != "never" ]; then
10107                         local hosts=$(comma_list $(osts_nodes))
10108
10109                         do_nodes $hosts $LCTL set_param $soc=never
10110                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10111                 fi
10112         fi
10113
10114         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10115         sync; sleep 1; sync
10116         local before=$(date +%s)
10117         cancel_lru_locks osc
10118         local after=$(date +%s)
10119         local diff=$((after - before))
10120         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10121
10122         rm -f $DIR/$tfile
10123 }
10124 run_test 80 "Page eviction is equally fast at high offsets too"
10125
10126 test_81a() { # LU-456
10127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10128         remote_ost_nodsh && skip "remote OST with nodsh"
10129
10130         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10131         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10132         do_facet ost1 lctl set_param fail_loc=0x80000228
10133
10134         # write should trigger a retry and success
10135         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10136         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10137         RC=$?
10138         if [ $RC -ne 0 ] ; then
10139                 error "write should success, but failed for $RC"
10140         fi
10141 }
10142 run_test 81a "OST should retry write when get -ENOSPC ==============="
10143
10144 test_81b() { # LU-456
10145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10146         remote_ost_nodsh && skip "remote OST with nodsh"
10147
10148         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10149         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10150         do_facet ost1 lctl set_param fail_loc=0x228
10151
10152         # write should retry several times and return -ENOSPC finally
10153         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10154         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10155         RC=$?
10156         ENOSPC=28
10157         if [ $RC -ne $ENOSPC ] ; then
10158                 error "dd should fail for -ENOSPC, but succeed."
10159         fi
10160 }
10161 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10162
10163 test_99() {
10164         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10165
10166         test_mkdir $DIR/$tdir.cvsroot
10167         chown $RUNAS_ID $DIR/$tdir.cvsroot
10168
10169         cd $TMP
10170         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10171
10172         cd /etc/init.d
10173         # some versions of cvs import exit(1) when asked to import links or
10174         # files they can't read.  ignore those files.
10175         local toignore=$(find . -type l -printf '-I %f\n' -o \
10176                          ! -perm /4 -printf '-I %f\n')
10177         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10178                 $tdir.reposname vtag rtag
10179
10180         cd $DIR
10181         test_mkdir $DIR/$tdir.reposname
10182         chown $RUNAS_ID $DIR/$tdir.reposname
10183         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10184
10185         cd $DIR/$tdir.reposname
10186         $RUNAS touch foo99
10187         $RUNAS cvs add -m 'addmsg' foo99
10188         $RUNAS cvs update
10189         $RUNAS cvs commit -m 'nomsg' foo99
10190         rm -fr $DIR/$tdir.cvsroot
10191 }
10192 run_test 99 "cvs strange file/directory operations"
10193
10194 test_100() {
10195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10196         [[ "$NETTYPE" =~ tcp ]] ||
10197                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10198         remote_ost_nodsh && skip "remote OST with nodsh"
10199         remote_mds_nodsh && skip "remote MDS with nodsh"
10200         remote_servers ||
10201                 skip "useless for local single node setup"
10202
10203         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10204                 [ "$PROT" != "tcp" ] && continue
10205                 RPORT=$(echo $REMOTE | cut -d: -f2)
10206                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10207
10208                 rc=0
10209                 LPORT=`echo $LOCAL | cut -d: -f2`
10210                 if [ $LPORT -ge 1024 ]; then
10211                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10212                         netstat -tna
10213                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10214                 fi
10215         done
10216         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10217 }
10218 run_test 100 "check local port using privileged port ==========="
10219
10220 function get_named_value()
10221 {
10222     local tag=$1
10223
10224     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10225 }
10226
10227 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10228                    awk '/^max_cached_mb/ { print $2 }')
10229
10230 cleanup_101a() {
10231         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10232         trap 0
10233 }
10234
10235 test_101a() {
10236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10237
10238         local s
10239         local discard
10240         local nreads=10000
10241         local cache_limit=32
10242
10243         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10244         trap cleanup_101a EXIT
10245         $LCTL set_param -n llite.*.read_ahead_stats=0
10246         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10247
10248         #
10249         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10250         #
10251         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10252         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10253
10254         discard=0
10255         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10256                    get_named_value 'read.but.discarded'); do
10257                         discard=$(($discard + $s))
10258         done
10259         cleanup_101a
10260
10261         $LCTL get_param osc.*-osc*.rpc_stats
10262         $LCTL get_param llite.*.read_ahead_stats
10263
10264         # Discard is generally zero, but sometimes a few random reads line up
10265         # and trigger larger readahead, which is wasted & leads to discards.
10266         if [[ $(($discard)) -gt $nreads ]]; then
10267                 error "too many ($discard) discarded pages"
10268         fi
10269         rm -f $DIR/$tfile || true
10270 }
10271 run_test 101a "check read-ahead for random reads"
10272
10273 setup_test101bc() {
10274         test_mkdir $DIR/$tdir
10275         local ssize=$1
10276         local FILE_LENGTH=$2
10277         STRIPE_OFFSET=0
10278
10279         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10280
10281         local list=$(comma_list $(osts_nodes))
10282         set_osd_param $list '' read_cache_enable 0
10283         set_osd_param $list '' writethrough_cache_enable 0
10284
10285         trap cleanup_test101bc EXIT
10286         # prepare the read-ahead file
10287         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10288
10289         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10290                                 count=$FILE_SIZE_MB 2> /dev/null
10291
10292 }
10293
10294 cleanup_test101bc() {
10295         trap 0
10296         rm -rf $DIR/$tdir
10297         rm -f $DIR/$tfile
10298
10299         local list=$(comma_list $(osts_nodes))
10300         set_osd_param $list '' read_cache_enable 1
10301         set_osd_param $list '' writethrough_cache_enable 1
10302 }
10303
10304 calc_total() {
10305         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10306 }
10307
10308 ra_check_101() {
10309         local READ_SIZE=$1
10310         local STRIPE_SIZE=$2
10311         local FILE_LENGTH=$3
10312         local RA_INC=1048576
10313         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10314         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10315                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10316         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10317                   get_named_value 'read.but.discarded' | calc_total)
10318         if [[ $DISCARD -gt $discard_limit ]]; then
10319                 $LCTL get_param llite.*.read_ahead_stats
10320                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10321         else
10322                 echo "Read-ahead success for size ${READ_SIZE}"
10323         fi
10324 }
10325
10326 test_101b() {
10327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10328         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10329
10330         local STRIPE_SIZE=1048576
10331         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10332
10333         if [ $SLOW == "yes" ]; then
10334                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10335         else
10336                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10337         fi
10338
10339         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10340
10341         # prepare the read-ahead file
10342         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10343         cancel_lru_locks osc
10344         for BIDX in 2 4 8 16 32 64 128 256
10345         do
10346                 local BSIZE=$((BIDX*4096))
10347                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10348                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10349                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10350                 $LCTL set_param -n llite.*.read_ahead_stats=0
10351                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10352                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10353                 cancel_lru_locks osc
10354                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10355         done
10356         cleanup_test101bc
10357         true
10358 }
10359 run_test 101b "check stride-io mode read-ahead ================="
10360
10361 test_101c() {
10362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10363
10364         local STRIPE_SIZE=1048576
10365         local FILE_LENGTH=$((STRIPE_SIZE*100))
10366         local nreads=10000
10367         local rsize=65536
10368         local osc_rpc_stats
10369
10370         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10371
10372         cancel_lru_locks osc
10373         $LCTL set_param osc.*.rpc_stats=0
10374         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10375         $LCTL get_param osc.*.rpc_stats
10376         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10377                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10378                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10379                 local size
10380
10381                 if [ $lines -le 20 ]; then
10382                         echo "continue debug"
10383                         continue
10384                 fi
10385                 for size in 1 2 4 8; do
10386                         local rpc=$(echo "$stats" |
10387                                     awk '($1 == "'$size':") {print $2; exit; }')
10388                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10389                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10390                 done
10391                 echo "$osc_rpc_stats check passed!"
10392         done
10393         cleanup_test101bc
10394         true
10395 }
10396 run_test 101c "check stripe_size aligned read-ahead"
10397
10398 test_101d() {
10399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10400
10401         local file=$DIR/$tfile
10402         local sz_MB=${FILESIZE_101d:-80}
10403         local ra_MB=${READAHEAD_MB:-40}
10404
10405         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10406         [ $free_MB -lt $sz_MB ] &&
10407                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10408
10409         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10410         $LFS setstripe -c -1 $file || error "setstripe failed"
10411
10412         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10413         echo Cancel LRU locks on lustre client to flush the client cache
10414         cancel_lru_locks osc
10415
10416         echo Disable read-ahead
10417         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10418         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10419         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10420         $LCTL get_param -n llite.*.max_read_ahead_mb
10421
10422         echo "Reading the test file $file with read-ahead disabled"
10423         local sz_KB=$((sz_MB * 1024 / 4))
10424         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10425         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10426         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10427                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10428
10429         echo "Cancel LRU locks on lustre client to flush the client cache"
10430         cancel_lru_locks osc
10431         echo Enable read-ahead with ${ra_MB}MB
10432         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10433
10434         echo "Reading the test file $file with read-ahead enabled"
10435         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10436                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10437
10438         echo "read-ahead disabled time read $raOFF"
10439         echo "read-ahead enabled time read $raON"
10440
10441         rm -f $file
10442         wait_delete_completed
10443
10444         # use awk for this check instead of bash because it handles decimals
10445         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10446                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10447 }
10448 run_test 101d "file read with and without read-ahead enabled"
10449
10450 test_101e() {
10451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10452
10453         local file=$DIR/$tfile
10454         local size_KB=500  #KB
10455         local count=100
10456         local bsize=1024
10457
10458         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10459         local need_KB=$((count * size_KB))
10460         [[ $free_KB -le $need_KB ]] &&
10461                 skip_env "Need free space $need_KB, have $free_KB"
10462
10463         echo "Creating $count ${size_KB}K test files"
10464         for ((i = 0; i < $count; i++)); do
10465                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10466         done
10467
10468         echo "Cancel LRU locks on lustre client to flush the client cache"
10469         cancel_lru_locks $OSC
10470
10471         echo "Reset readahead stats"
10472         $LCTL set_param -n llite.*.read_ahead_stats=0
10473
10474         for ((i = 0; i < $count; i++)); do
10475                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10476         done
10477
10478         $LCTL get_param llite.*.max_cached_mb
10479         $LCTL get_param llite.*.read_ahead_stats
10480         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10481                      get_named_value 'misses' | calc_total)
10482
10483         for ((i = 0; i < $count; i++)); do
10484                 rm -rf $file.$i 2>/dev/null
10485         done
10486
10487         #10000 means 20% reads are missing in readahead
10488         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10489 }
10490 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10491
10492 test_101f() {
10493         which iozone || skip_env "no iozone installed"
10494
10495         local old_debug=$($LCTL get_param debug)
10496         old_debug=${old_debug#*=}
10497         $LCTL set_param debug="reada mmap"
10498
10499         # create a test file
10500         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10501
10502         echo Cancel LRU locks on lustre client to flush the client cache
10503         cancel_lru_locks osc
10504
10505         echo Reset readahead stats
10506         $LCTL set_param -n llite.*.read_ahead_stats=0
10507
10508         echo mmap read the file with small block size
10509         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10510                 > /dev/null 2>&1
10511
10512         echo checking missing pages
10513         $LCTL get_param llite.*.read_ahead_stats
10514         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10515                         get_named_value 'misses' | calc_total)
10516
10517         $LCTL set_param debug="$old_debug"
10518         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10519         rm -f $DIR/$tfile
10520 }
10521 run_test 101f "check mmap read performance"
10522
10523 test_101g_brw_size_test() {
10524         local mb=$1
10525         local pages=$((mb * 1048576 / PAGE_SIZE))
10526         local file=$DIR/$tfile
10527
10528         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10529                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10530         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10531                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10532                         return 2
10533         done
10534
10535         stack_trap "rm -f $file" EXIT
10536         $LCTL set_param -n osc.*.rpc_stats=0
10537
10538         # 10 RPCs should be enough for the test
10539         local count=10
10540         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10541                 { error "dd write ${mb} MB blocks failed"; return 3; }
10542         cancel_lru_locks osc
10543         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10544                 { error "dd write ${mb} MB blocks failed"; return 4; }
10545
10546         # calculate number of full-sized read and write RPCs
10547         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10548                 sed -n '/pages per rpc/,/^$/p' |
10549                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10550                 END { print reads,writes }'))
10551         # allow one extra full-sized read RPC for async readahead
10552         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10553                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10554         [[ ${rpcs[1]} == $count ]] ||
10555                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10556 }
10557
10558 test_101g() {
10559         remote_ost_nodsh && skip "remote OST with nodsh"
10560
10561         local rpcs
10562         local osts=$(get_facets OST)
10563         local list=$(comma_list $(osts_nodes))
10564         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10565         local brw_size="obdfilter.*.brw_size"
10566
10567         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10568
10569         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10570
10571         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10572                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10573                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10574            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10575                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10576                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10577
10578                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10579                         suffix="M"
10580
10581                 if [[ $orig_mb -lt 16 ]]; then
10582                         save_lustre_params $osts "$brw_size" > $p
10583                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10584                                 error "set 16MB RPC size failed"
10585
10586                         echo "remount client to enable new RPC size"
10587                         remount_client $MOUNT || error "remount_client failed"
10588                 fi
10589
10590                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10591                 # should be able to set brw_size=12, but no rpc_stats for that
10592                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10593         fi
10594
10595         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10596
10597         if [[ $orig_mb -lt 16 ]]; then
10598                 restore_lustre_params < $p
10599                 remount_client $MOUNT || error "remount_client restore failed"
10600         fi
10601
10602         rm -f $p $DIR/$tfile
10603 }
10604 run_test 101g "Big bulk(4/16 MiB) readahead"
10605
10606 test_101h() {
10607         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10608
10609         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10610                 error "dd 70M file failed"
10611         echo Cancel LRU locks on lustre client to flush the client cache
10612         cancel_lru_locks osc
10613
10614         echo "Reset readahead stats"
10615         $LCTL set_param -n llite.*.read_ahead_stats 0
10616
10617         echo "Read 10M of data but cross 64M bundary"
10618         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10619         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10620                      get_named_value 'misses' | calc_total)
10621         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10622         rm -f $p $DIR/$tfile
10623 }
10624 run_test 101h "Readahead should cover current read window"
10625
10626 test_101i() {
10627         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10628                 error "dd 10M file failed"
10629
10630         local max_per_file_mb=$($LCTL get_param -n \
10631                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10632         cancel_lru_locks osc
10633         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10634         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10635                 error "set max_read_ahead_per_file_mb to 1 failed"
10636
10637         echo "Reset readahead stats"
10638         $LCTL set_param llite.*.read_ahead_stats=0
10639
10640         dd if=$DIR/$tfile of=/dev/null bs=2M
10641
10642         $LCTL get_param llite.*.read_ahead_stats
10643         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10644                      awk '/misses/ { print $2 }')
10645         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10646         rm -f $DIR/$tfile
10647 }
10648 run_test 101i "allow current readahead to exceed reservation"
10649
10650 test_101j() {
10651         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10652                 error "setstripe $DIR/$tfile failed"
10653         local file_size=$((1048576 * 16))
10654         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10655         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10656
10657         echo Disable read-ahead
10658         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10659
10660         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10661         for blk in $PAGE_SIZE 1048576 $file_size; do
10662                 cancel_lru_locks osc
10663                 echo "Reset readahead stats"
10664                 $LCTL set_param -n llite.*.read_ahead_stats=0
10665                 local count=$(($file_size / $blk))
10666                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10667                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10668                              get_named_value 'failed.to.fast.read' | calc_total)
10669                 $LCTL get_param -n llite.*.read_ahead_stats
10670                 [ $miss -eq $count ] || error "expected $count got $miss"
10671         done
10672
10673         rm -f $p $DIR/$tfile
10674 }
10675 run_test 101j "A complete read block should be submitted when no RA"
10676
10677 setup_test102() {
10678         test_mkdir $DIR/$tdir
10679         chown $RUNAS_ID $DIR/$tdir
10680         STRIPE_SIZE=65536
10681         STRIPE_OFFSET=1
10682         STRIPE_COUNT=$OSTCOUNT
10683         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10684
10685         trap cleanup_test102 EXIT
10686         cd $DIR
10687         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10688         cd $DIR/$tdir
10689         for num in 1 2 3 4; do
10690                 for count in $(seq 1 $STRIPE_COUNT); do
10691                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10692                                 local size=`expr $STRIPE_SIZE \* $num`
10693                                 local file=file"$num-$idx-$count"
10694                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10695                         done
10696                 done
10697         done
10698
10699         cd $DIR
10700         $1 tar cf $TMP/f102.tar $tdir --xattrs
10701 }
10702
10703 cleanup_test102() {
10704         trap 0
10705         rm -f $TMP/f102.tar
10706         rm -rf $DIR/d0.sanity/d102
10707 }
10708
10709 test_102a() {
10710         [ "$UID" != 0 ] && skip "must run as root"
10711         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10712                 skip_env "must have user_xattr"
10713
10714         [ -z "$(which setfattr 2>/dev/null)" ] &&
10715                 skip_env "could not find setfattr"
10716
10717         local testfile=$DIR/$tfile
10718
10719         touch $testfile
10720         echo "set/get xattr..."
10721         setfattr -n trusted.name1 -v value1 $testfile ||
10722                 error "setfattr -n trusted.name1=value1 $testfile failed"
10723         getfattr -n trusted.name1 $testfile 2> /dev/null |
10724           grep "trusted.name1=.value1" ||
10725                 error "$testfile missing trusted.name1=value1"
10726
10727         setfattr -n user.author1 -v author1 $testfile ||
10728                 error "setfattr -n user.author1=author1 $testfile failed"
10729         getfattr -n user.author1 $testfile 2> /dev/null |
10730           grep "user.author1=.author1" ||
10731                 error "$testfile missing trusted.author1=author1"
10732
10733         echo "listxattr..."
10734         setfattr -n trusted.name2 -v value2 $testfile ||
10735                 error "$testfile unable to set trusted.name2"
10736         setfattr -n trusted.name3 -v value3 $testfile ||
10737                 error "$testfile unable to set trusted.name3"
10738         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10739             grep "trusted.name" | wc -l) -eq 3 ] ||
10740                 error "$testfile missing 3 trusted.name xattrs"
10741
10742         setfattr -n user.author2 -v author2 $testfile ||
10743                 error "$testfile unable to set user.author2"
10744         setfattr -n user.author3 -v author3 $testfile ||
10745                 error "$testfile unable to set user.author3"
10746         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10747             grep "user.author" | wc -l) -eq 3 ] ||
10748                 error "$testfile missing 3 user.author xattrs"
10749
10750         echo "remove xattr..."
10751         setfattr -x trusted.name1 $testfile ||
10752                 error "$testfile error deleting trusted.name1"
10753         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10754                 error "$testfile did not delete trusted.name1 xattr"
10755
10756         setfattr -x user.author1 $testfile ||
10757                 error "$testfile error deleting user.author1"
10758         echo "set lustre special xattr ..."
10759         $LFS setstripe -c1 $testfile
10760         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10761                 awk -F "=" '/trusted.lov/ { print $2 }' )
10762         setfattr -n "trusted.lov" -v $lovea $testfile ||
10763                 error "$testfile doesn't ignore setting trusted.lov again"
10764         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10765                 error "$testfile allow setting invalid trusted.lov"
10766         rm -f $testfile
10767 }
10768 run_test 102a "user xattr test =================================="
10769
10770 check_102b_layout() {
10771         local layout="$*"
10772         local testfile=$DIR/$tfile
10773
10774         echo "test layout '$layout'"
10775         $LFS setstripe $layout $testfile || error "setstripe failed"
10776         $LFS getstripe -y $testfile
10777
10778         echo "get/set/list trusted.lov xattr ..." # b=10930
10779         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10780         [[ "$value" =~ "trusted.lov" ]] ||
10781                 error "can't get trusted.lov from $testfile"
10782         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10783                 error "getstripe failed"
10784
10785         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10786
10787         value=$(cut -d= -f2 <<<$value)
10788         # LU-13168: truncated xattr should fail if short lov_user_md header
10789         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10790                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10791         for len in $lens; do
10792                 echo "setfattr $len $testfile.2"
10793                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10794                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10795         done
10796         local stripe_size=$($LFS getstripe -S $testfile.2)
10797         local stripe_count=$($LFS getstripe -c $testfile.2)
10798         [[ $stripe_size -eq 65536 ]] ||
10799                 error "stripe size $stripe_size != 65536"
10800         [[ $stripe_count -eq $stripe_count_orig ]] ||
10801                 error "stripe count $stripe_count != $stripe_count_orig"
10802         rm $testfile $testfile.2
10803 }
10804
10805 test_102b() {
10806         [ -z "$(which setfattr 2>/dev/null)" ] &&
10807                 skip_env "could not find setfattr"
10808         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10809
10810         # check plain layout
10811         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10812
10813         # and also check composite layout
10814         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10815
10816 }
10817 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10818
10819 test_102c() {
10820         [ -z "$(which setfattr 2>/dev/null)" ] &&
10821                 skip_env "could not find setfattr"
10822         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10823
10824         # b10930: get/set/list lustre.lov xattr
10825         echo "get/set/list lustre.lov xattr ..."
10826         test_mkdir $DIR/$tdir
10827         chown $RUNAS_ID $DIR/$tdir
10828         local testfile=$DIR/$tdir/$tfile
10829         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10830                 error "setstripe failed"
10831         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10832                 error "getstripe failed"
10833         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10834         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10835
10836         local testfile2=${testfile}2
10837         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10838                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10839
10840         $RUNAS $MCREATE $testfile2
10841         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10842         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10843         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10844         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10845         [ $stripe_count -eq $STRIPECOUNT ] ||
10846                 error "stripe count $stripe_count != $STRIPECOUNT"
10847 }
10848 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10849
10850 compare_stripe_info1() {
10851         local stripe_index_all_zero=true
10852
10853         for num in 1 2 3 4; do
10854                 for count in $(seq 1 $STRIPE_COUNT); do
10855                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10856                                 local size=$((STRIPE_SIZE * num))
10857                                 local file=file"$num-$offset-$count"
10858                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10859                                 [[ $stripe_size -ne $size ]] &&
10860                                     error "$file: size $stripe_size != $size"
10861                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10862                                 # allow fewer stripes to be created, ORI-601
10863                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10864                                     error "$file: count $stripe_count != $count"
10865                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10866                                 [[ $stripe_index -ne 0 ]] &&
10867                                         stripe_index_all_zero=false
10868                         done
10869                 done
10870         done
10871         $stripe_index_all_zero &&
10872                 error "all files are being extracted starting from OST index 0"
10873         return 0
10874 }
10875
10876 have_xattrs_include() {
10877         tar --help | grep -q xattrs-include &&
10878                 echo --xattrs-include="lustre.*"
10879 }
10880
10881 test_102d() {
10882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10883         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10884
10885         XINC=$(have_xattrs_include)
10886         setup_test102
10887         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10888         cd $DIR/$tdir/$tdir
10889         compare_stripe_info1
10890 }
10891 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10892
10893 test_102f() {
10894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10895         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10896
10897         XINC=$(have_xattrs_include)
10898         setup_test102
10899         test_mkdir $DIR/$tdir.restore
10900         cd $DIR
10901         tar cf - --xattrs $tdir | tar xf - \
10902                 -C $DIR/$tdir.restore --xattrs $XINC
10903         cd $DIR/$tdir.restore/$tdir
10904         compare_stripe_info1
10905 }
10906 run_test 102f "tar copy files, not keep osts"
10907
10908 grow_xattr() {
10909         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10910                 skip "must have user_xattr"
10911         [ -z "$(which setfattr 2>/dev/null)" ] &&
10912                 skip_env "could not find setfattr"
10913         [ -z "$(which getfattr 2>/dev/null)" ] &&
10914                 skip_env "could not find getfattr"
10915
10916         local xsize=${1:-1024}  # in bytes
10917         local file=$DIR/$tfile
10918         local value="$(generate_string $xsize)"
10919         local xbig=trusted.big
10920         local toobig=$2
10921
10922         touch $file
10923         log "save $xbig on $file"
10924         if [ -z "$toobig" ]
10925         then
10926                 setfattr -n $xbig -v $value $file ||
10927                         error "saving $xbig on $file failed"
10928         else
10929                 setfattr -n $xbig -v $value $file &&
10930                         error "saving $xbig on $file succeeded"
10931                 return 0
10932         fi
10933
10934         local orig=$(get_xattr_value $xbig $file)
10935         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10936
10937         local xsml=trusted.sml
10938         log "save $xsml on $file"
10939         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10940
10941         local new=$(get_xattr_value $xbig $file)
10942         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10943
10944         log "grow $xsml on $file"
10945         setfattr -n $xsml -v "$value" $file ||
10946                 error "growing $xsml on $file failed"
10947
10948         new=$(get_xattr_value $xbig $file)
10949         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10950         log "$xbig still valid after growing $xsml"
10951
10952         rm -f $file
10953 }
10954
10955 test_102h() { # bug 15777
10956         grow_xattr 1024
10957 }
10958 run_test 102h "grow xattr from inside inode to external block"
10959
10960 test_102ha() {
10961         large_xattr_enabled || skip_env "ea_inode feature disabled"
10962
10963         echo "setting xattr of max xattr size: $(max_xattr_size)"
10964         grow_xattr $(max_xattr_size)
10965
10966         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10967         echo "This should fail:"
10968         grow_xattr $(($(max_xattr_size) + 10)) 1
10969 }
10970 run_test 102ha "grow xattr from inside inode to external inode"
10971
10972 test_102i() { # bug 17038
10973         [ -z "$(which getfattr 2>/dev/null)" ] &&
10974                 skip "could not find getfattr"
10975
10976         touch $DIR/$tfile
10977         ln -s $DIR/$tfile $DIR/${tfile}link
10978         getfattr -n trusted.lov $DIR/$tfile ||
10979                 error "lgetxattr on $DIR/$tfile failed"
10980         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10981                 grep -i "no such attr" ||
10982                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10983         rm -f $DIR/$tfile $DIR/${tfile}link
10984 }
10985 run_test 102i "lgetxattr test on symbolic link ============"
10986
10987 test_102j() {
10988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10989         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10990
10991         XINC=$(have_xattrs_include)
10992         setup_test102 "$RUNAS"
10993         chown $RUNAS_ID $DIR/$tdir
10994         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10995         cd $DIR/$tdir/$tdir
10996         compare_stripe_info1 "$RUNAS"
10997 }
10998 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10999
11000 test_102k() {
11001         [ -z "$(which setfattr 2>/dev/null)" ] &&
11002                 skip "could not find setfattr"
11003
11004         touch $DIR/$tfile
11005         # b22187 just check that does not crash for regular file.
11006         setfattr -n trusted.lov $DIR/$tfile
11007         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11008         local test_kdir=$DIR/$tdir
11009         test_mkdir $test_kdir
11010         local default_size=$($LFS getstripe -S $test_kdir)
11011         local default_count=$($LFS getstripe -c $test_kdir)
11012         local default_offset=$($LFS getstripe -i $test_kdir)
11013         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11014                 error 'dir setstripe failed'
11015         setfattr -n trusted.lov $test_kdir
11016         local stripe_size=$($LFS getstripe -S $test_kdir)
11017         local stripe_count=$($LFS getstripe -c $test_kdir)
11018         local stripe_offset=$($LFS getstripe -i $test_kdir)
11019         [ $stripe_size -eq $default_size ] ||
11020                 error "stripe size $stripe_size != $default_size"
11021         [ $stripe_count -eq $default_count ] ||
11022                 error "stripe count $stripe_count != $default_count"
11023         [ $stripe_offset -eq $default_offset ] ||
11024                 error "stripe offset $stripe_offset != $default_offset"
11025         rm -rf $DIR/$tfile $test_kdir
11026 }
11027 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11028
11029 test_102l() {
11030         [ -z "$(which getfattr 2>/dev/null)" ] &&
11031                 skip "could not find getfattr"
11032
11033         # LU-532 trusted. xattr is invisible to non-root
11034         local testfile=$DIR/$tfile
11035
11036         touch $testfile
11037
11038         echo "listxattr as user..."
11039         chown $RUNAS_ID $testfile
11040         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11041             grep -q "trusted" &&
11042                 error "$testfile trusted xattrs are user visible"
11043
11044         return 0;
11045 }
11046 run_test 102l "listxattr size test =================================="
11047
11048 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11049         local path=$DIR/$tfile
11050         touch $path
11051
11052         listxattr_size_check $path || error "listattr_size_check $path failed"
11053 }
11054 run_test 102m "Ensure listxattr fails on small bufffer ========"
11055
11056 cleanup_test102
11057
11058 getxattr() { # getxattr path name
11059         # Return the base64 encoding of the value of xattr name on path.
11060         local path=$1
11061         local name=$2
11062
11063         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11064         # file: $path
11065         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11066         #
11067         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11068
11069         getfattr --absolute-names --encoding=base64 --name=$name $path |
11070                 awk -F= -v name=$name '$1 == name {
11071                         print substr($0, index($0, "=") + 1);
11072         }'
11073 }
11074
11075 test_102n() { # LU-4101 mdt: protect internal xattrs
11076         [ -z "$(which setfattr 2>/dev/null)" ] &&
11077                 skip "could not find setfattr"
11078         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11079         then
11080                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11081         fi
11082
11083         local file0=$DIR/$tfile.0
11084         local file1=$DIR/$tfile.1
11085         local xattr0=$TMP/$tfile.0
11086         local xattr1=$TMP/$tfile.1
11087         local namelist="lov lma lmv link fid version som hsm"
11088         local name
11089         local value
11090
11091         rm -rf $file0 $file1 $xattr0 $xattr1
11092         touch $file0 $file1
11093
11094         # Get 'before' xattrs of $file1.
11095         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11096
11097         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11098                 namelist+=" lfsck_namespace"
11099         for name in $namelist; do
11100                 # Try to copy xattr from $file0 to $file1.
11101                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11102
11103                 setfattr --name=trusted.$name --value="$value" $file1 ||
11104                         error "setxattr 'trusted.$name' failed"
11105
11106                 # Try to set a garbage xattr.
11107                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11108
11109                 if [[ x$name == "xlov" ]]; then
11110                         setfattr --name=trusted.lov --value="$value" $file1 &&
11111                         error "setxattr invalid 'trusted.lov' success"
11112                 else
11113                         setfattr --name=trusted.$name --value="$value" $file1 ||
11114                                 error "setxattr invalid 'trusted.$name' failed"
11115                 fi
11116
11117                 # Try to remove the xattr from $file1. We don't care if this
11118                 # appears to succeed or fail, we just don't want there to be
11119                 # any changes or crashes.
11120                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11121         done
11122
11123         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11124         then
11125                 name="lfsck_ns"
11126                 # Try to copy xattr from $file0 to $file1.
11127                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11128
11129                 setfattr --name=trusted.$name --value="$value" $file1 ||
11130                         error "setxattr 'trusted.$name' failed"
11131
11132                 # Try to set a garbage xattr.
11133                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11134
11135                 setfattr --name=trusted.$name --value="$value" $file1 ||
11136                         error "setxattr 'trusted.$name' failed"
11137
11138                 # Try to remove the xattr from $file1. We don't care if this
11139                 # appears to succeed or fail, we just don't want there to be
11140                 # any changes or crashes.
11141                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11142         fi
11143
11144         # Get 'after' xattrs of file1.
11145         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11146
11147         if ! diff $xattr0 $xattr1; then
11148                 error "before and after xattrs of '$file1' differ"
11149         fi
11150
11151         rm -rf $file0 $file1 $xattr0 $xattr1
11152
11153         return 0
11154 }
11155 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11156
11157 test_102p() { # LU-4703 setxattr did not check ownership
11158         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11159                 skip "MDS needs to be at least 2.5.56"
11160
11161         local testfile=$DIR/$tfile
11162
11163         touch $testfile
11164
11165         echo "setfacl as user..."
11166         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11167         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11168
11169         echo "setfattr as user..."
11170         setfacl -m "u:$RUNAS_ID:---" $testfile
11171         $RUNAS setfattr -x system.posix_acl_access $testfile
11172         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11173 }
11174 run_test 102p "check setxattr(2) correctly fails without permission"
11175
11176 test_102q() {
11177         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11178                 skip "MDS needs to be at least 2.6.92"
11179
11180         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11181 }
11182 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11183
11184 test_102r() {
11185         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11186                 skip "MDS needs to be at least 2.6.93"
11187
11188         touch $DIR/$tfile || error "touch"
11189         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11190         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11191         rm $DIR/$tfile || error "rm"
11192
11193         #normal directory
11194         mkdir -p $DIR/$tdir || error "mkdir"
11195         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11196         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11197         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11198                 error "$testfile error deleting user.author1"
11199         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11200                 grep "user.$(basename $tdir)" &&
11201                 error "$tdir did not delete user.$(basename $tdir)"
11202         rmdir $DIR/$tdir || error "rmdir"
11203
11204         #striped directory
11205         test_mkdir $DIR/$tdir
11206         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11207         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11208         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11209                 error "$testfile error deleting user.author1"
11210         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11211                 grep "user.$(basename $tdir)" &&
11212                 error "$tdir did not delete user.$(basename $tdir)"
11213         rmdir $DIR/$tdir || error "rm striped dir"
11214 }
11215 run_test 102r "set EAs with empty values"
11216
11217 test_102s() {
11218         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11219                 skip "MDS needs to be at least 2.11.52"
11220
11221         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11222
11223         save_lustre_params client "llite.*.xattr_cache" > $save
11224
11225         for cache in 0 1; do
11226                 lctl set_param llite.*.xattr_cache=$cache
11227
11228                 rm -f $DIR/$tfile
11229                 touch $DIR/$tfile || error "touch"
11230                 for prefix in lustre security system trusted user; do
11231                         # Note getxattr() may fail with 'Operation not
11232                         # supported' or 'No such attribute' depending
11233                         # on prefix and cache.
11234                         getfattr -n $prefix.n102s $DIR/$tfile &&
11235                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11236                 done
11237         done
11238
11239         restore_lustre_params < $save
11240 }
11241 run_test 102s "getting nonexistent xattrs should fail"
11242
11243 test_102t() {
11244         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11245                 skip "MDS needs to be at least 2.11.52"
11246
11247         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11248
11249         save_lustre_params client "llite.*.xattr_cache" > $save
11250
11251         for cache in 0 1; do
11252                 lctl set_param llite.*.xattr_cache=$cache
11253
11254                 for buf_size in 0 256; do
11255                         rm -f $DIR/$tfile
11256                         touch $DIR/$tfile || error "touch"
11257                         setfattr -n user.multiop $DIR/$tfile
11258                         $MULTIOP $DIR/$tfile oa$buf_size ||
11259                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11260                 done
11261         done
11262
11263         restore_lustre_params < $save
11264 }
11265 run_test 102t "zero length xattr values handled correctly"
11266
11267 run_acl_subtest()
11268 {
11269     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11270     return $?
11271 }
11272
11273 test_103a() {
11274         [ "$UID" != 0 ] && skip "must run as root"
11275         $GSS && skip_env "could not run under gss"
11276         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11277                 skip_env "must have acl enabled"
11278         [ -z "$(which setfacl 2>/dev/null)" ] &&
11279                 skip_env "could not find setfacl"
11280         remote_mds_nodsh && skip "remote MDS with nodsh"
11281
11282         gpasswd -a daemon bin                           # LU-5641
11283         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11284
11285         declare -a identity_old
11286
11287         for num in $(seq $MDSCOUNT); do
11288                 switch_identity $num true || identity_old[$num]=$?
11289         done
11290
11291         SAVE_UMASK=$(umask)
11292         umask 0022
11293         mkdir -p $DIR/$tdir
11294         cd $DIR/$tdir
11295
11296         echo "performing cp ..."
11297         run_acl_subtest cp || error "run_acl_subtest cp failed"
11298         echo "performing getfacl-noacl..."
11299         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11300         echo "performing misc..."
11301         run_acl_subtest misc || error  "misc test failed"
11302         echo "performing permissions..."
11303         run_acl_subtest permissions || error "permissions failed"
11304         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11305         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11306                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11307                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11308         then
11309                 echo "performing permissions xattr..."
11310                 run_acl_subtest permissions_xattr ||
11311                         error "permissions_xattr failed"
11312         fi
11313         echo "performing setfacl..."
11314         run_acl_subtest setfacl || error  "setfacl test failed"
11315
11316         # inheritance test got from HP
11317         echo "performing inheritance..."
11318         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11319         chmod +x make-tree || error "chmod +x failed"
11320         run_acl_subtest inheritance || error "inheritance test failed"
11321         rm -f make-tree
11322
11323         echo "LU-974 ignore umask when acl is enabled..."
11324         run_acl_subtest 974 || error "LU-974 umask test failed"
11325         if [ $MDSCOUNT -ge 2 ]; then
11326                 run_acl_subtest 974_remote ||
11327                         error "LU-974 umask test failed under remote dir"
11328         fi
11329
11330         echo "LU-2561 newly created file is same size as directory..."
11331         if [ "$mds1_FSTYPE" != "zfs" ]; then
11332                 run_acl_subtest 2561 || error "LU-2561 test failed"
11333         else
11334                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11335         fi
11336
11337         run_acl_subtest 4924 || error "LU-4924 test failed"
11338
11339         cd $SAVE_PWD
11340         umask $SAVE_UMASK
11341
11342         for num in $(seq $MDSCOUNT); do
11343                 if [ "${identity_old[$num]}" = 1 ]; then
11344                         switch_identity $num false || identity_old[$num]=$?
11345                 fi
11346         done
11347 }
11348 run_test 103a "acl test"
11349
11350 test_103b() {
11351         declare -a pids
11352         local U
11353
11354         for U in {0..511}; do
11355                 {
11356                 local O=$(printf "%04o" $U)
11357
11358                 umask $(printf "%04o" $((511 ^ $O)))
11359                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11360                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11361
11362                 (( $S == ($O & 0666) )) ||
11363                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11364
11365                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11366                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11367                 (( $S == ($O & 0666) )) ||
11368                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11369
11370                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11371                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11372                 (( $S == ($O & 0666) )) ||
11373                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11374                 rm -f $DIR/$tfile.[smp]$0
11375                 } &
11376                 local pid=$!
11377
11378                 # limit the concurrently running threads to 64. LU-11878
11379                 local idx=$((U % 64))
11380                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11381                 pids[idx]=$pid
11382         done
11383         wait
11384 }
11385 run_test 103b "umask lfs setstripe"
11386
11387 test_103c() {
11388         mkdir -p $DIR/$tdir
11389         cp -rp $DIR/$tdir $DIR/$tdir.bak
11390
11391         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11392                 error "$DIR/$tdir shouldn't contain default ACL"
11393         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11394                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11395         true
11396 }
11397 run_test 103c "'cp -rp' won't set empty acl"
11398
11399 test_103e() {
11400         local numacl
11401         local fileacl
11402         local saved_debug=$($LCTL get_param -n debug)
11403
11404         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11405                 skip "MDS needs to be at least 2.14.0"
11406
11407         large_xattr_enabled || skip_env "ea_inode feature disabled"
11408
11409         mkdir -p $DIR/$tdir
11410         # add big LOV EA to cause reply buffer overflow earlier
11411         $LFS setstripe -C 1000 $DIR/$tdir
11412         lctl set_param mdc.*-mdc*.stats=clear
11413
11414         $LCTL set_param debug=0
11415         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11416         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11417
11418         # add a large number of default ACLs (expect 8000+ for 2.13+)
11419         for U in {2..7000}; do
11420                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11421                         error "Able to add just $U default ACLs"
11422         done
11423         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11424         echo "$numacl default ACLs created"
11425
11426         stat $DIR/$tdir || error "Cannot stat directory"
11427         # check file creation
11428         touch $DIR/$tdir/$tfile ||
11429                 error "failed to create $tfile with $numacl default ACLs"
11430         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11431         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11432         echo "$fileacl ACLs were inherited"
11433         (( $fileacl == $numacl )) ||
11434                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11435         # check that new ACLs creation adds new ACLs to inherited ACLs
11436         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11437                 error "Cannot set new ACL"
11438         numacl=$((numacl + 1))
11439         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11440         (( $fileacl == $numacl )) ||
11441                 error "failed to add new ACL: $fileacl != $numacl as expected"
11442         # adds more ACLs to a file to reach their maximum at 8000+
11443         numacl=0
11444         for U in {20000..25000}; do
11445                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11446                 numacl=$((numacl + 1))
11447         done
11448         echo "Added $numacl more ACLs to the file"
11449         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11450         echo "Total $fileacl ACLs in file"
11451         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11452         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11453         rmdir $DIR/$tdir || error "Cannot remove directory"
11454 }
11455 run_test 103e "inheritance of big amount of default ACLs"
11456
11457 test_103f() {
11458         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11459                 skip "MDS needs to be at least 2.14.51"
11460
11461         large_xattr_enabled || skip_env "ea_inode feature disabled"
11462
11463         # enable changelog to consume more internal MDD buffers
11464         changelog_register
11465
11466         mkdir -p $DIR/$tdir
11467         # add big LOV EA
11468         $LFS setstripe -C 1000 $DIR/$tdir
11469         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11470         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11471         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11472         rmdir $DIR/$tdir || error "Cannot remove directory"
11473 }
11474 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11475
11476 test_104a() {
11477         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11478
11479         touch $DIR/$tfile
11480         lfs df || error "lfs df failed"
11481         lfs df -ih || error "lfs df -ih failed"
11482         lfs df -h $DIR || error "lfs df -h $DIR failed"
11483         lfs df -i $DIR || error "lfs df -i $DIR failed"
11484         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11485         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11486
11487         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11488         lctl --device %$OSC deactivate
11489         lfs df || error "lfs df with deactivated OSC failed"
11490         lctl --device %$OSC activate
11491         # wait the osc back to normal
11492         wait_osc_import_ready client ost
11493
11494         lfs df || error "lfs df with reactivated OSC failed"
11495         rm -f $DIR/$tfile
11496 }
11497 run_test 104a "lfs df [-ih] [path] test ========================="
11498
11499 test_104b() {
11500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11501         [ $RUNAS_ID -eq $UID ] &&
11502                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11503
11504         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11505                         grep "Permission denied" | wc -l)))
11506         if [ $denied_cnt -ne 0 ]; then
11507                 error "lfs check servers test failed"
11508         fi
11509 }
11510 run_test 104b "$RUNAS lfs check servers test ===================="
11511
11512 #
11513 # Verify $1 is within range of $2.
11514 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11515 # $1 is <= 2% of $2. Else Fail.
11516 #
11517 value_in_range() {
11518         # Strip all units (M, G, T)
11519         actual=$(echo $1 | tr -d A-Z)
11520         expect=$(echo $2 | tr -d A-Z)
11521
11522         expect_lo=$(($expect * 98 / 100)) # 2% below
11523         expect_hi=$(($expect * 102 / 100)) # 2% above
11524
11525         # permit 2% drift above and below
11526         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11527 }
11528
11529 test_104c() {
11530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11531         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11532
11533         local ost_param="osd-zfs.$FSNAME-OST0000."
11534         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11535         local ofacets=$(get_facets OST)
11536         local mfacets=$(get_facets MDS)
11537         local saved_ost_blocks=
11538         local saved_mdt_blocks=
11539
11540         echo "Before recordsize change"
11541         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11542         df=($(df -h | grep "/mnt/lustre"$))
11543
11544         # For checking.
11545         echo "lfs output : ${lfs_df[*]}"
11546         echo "df  output : ${df[*]}"
11547
11548         for facet in ${ofacets//,/ }; do
11549                 if [ -z $saved_ost_blocks ]; then
11550                         saved_ost_blocks=$(do_facet $facet \
11551                                 lctl get_param -n $ost_param.blocksize)
11552                         echo "OST Blocksize: $saved_ost_blocks"
11553                 fi
11554                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11555                 do_facet $facet zfs set recordsize=32768 $ost
11556         done
11557
11558         # BS too small. Sufficient for functional testing.
11559         for facet in ${mfacets//,/ }; do
11560                 if [ -z $saved_mdt_blocks ]; then
11561                         saved_mdt_blocks=$(do_facet $facet \
11562                                 lctl get_param -n $mdt_param.blocksize)
11563                         echo "MDT Blocksize: $saved_mdt_blocks"
11564                 fi
11565                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11566                 do_facet $facet zfs set recordsize=32768 $mdt
11567         done
11568
11569         # Give new values chance to reflect change
11570         sleep 2
11571
11572         echo "After recordsize change"
11573         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11574         df_after=($(df -h | grep "/mnt/lustre"$))
11575
11576         # For checking.
11577         echo "lfs output : ${lfs_df_after[*]}"
11578         echo "df  output : ${df_after[*]}"
11579
11580         # Verify lfs df
11581         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11582                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11583         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11584                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11585         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11586                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11587
11588         # Verify df
11589         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11590                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11591         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11592                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11593         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11594                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11595
11596         # Restore MDT recordize back to original
11597         for facet in ${mfacets//,/ }; do
11598                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11599                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11600         done
11601
11602         # Restore OST recordize back to original
11603         for facet in ${ofacets//,/ }; do
11604                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11605                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11606         done
11607
11608         return 0
11609 }
11610 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11611
11612 test_105a() {
11613         # doesn't work on 2.4 kernels
11614         touch $DIR/$tfile
11615         if $(flock_is_enabled); then
11616                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11617         else
11618                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11619         fi
11620         rm -f $DIR/$tfile
11621 }
11622 run_test 105a "flock when mounted without -o flock test ========"
11623
11624 test_105b() {
11625         touch $DIR/$tfile
11626         if $(flock_is_enabled); then
11627                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11628         else
11629                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11630         fi
11631         rm -f $DIR/$tfile
11632 }
11633 run_test 105b "fcntl when mounted without -o flock test ========"
11634
11635 test_105c() {
11636         touch $DIR/$tfile
11637         if $(flock_is_enabled); then
11638                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11639         else
11640                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11641         fi
11642         rm -f $DIR/$tfile
11643 }
11644 run_test 105c "lockf when mounted without -o flock test"
11645
11646 test_105d() { # bug 15924
11647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11648
11649         test_mkdir $DIR/$tdir
11650         flock_is_enabled || skip_env "mount w/o flock enabled"
11651         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11652         $LCTL set_param fail_loc=0x80000315
11653         flocks_test 2 $DIR/$tdir
11654 }
11655 run_test 105d "flock race (should not freeze) ========"
11656
11657 test_105e() { # bug 22660 && 22040
11658         flock_is_enabled || skip_env "mount w/o flock enabled"
11659
11660         touch $DIR/$tfile
11661         flocks_test 3 $DIR/$tfile
11662 }
11663 run_test 105e "Two conflicting flocks from same process"
11664
11665 test_106() { #bug 10921
11666         test_mkdir $DIR/$tdir
11667         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11668         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11669 }
11670 run_test 106 "attempt exec of dir followed by chown of that dir"
11671
11672 test_107() {
11673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11674
11675         CDIR=`pwd`
11676         local file=core
11677
11678         cd $DIR
11679         rm -f $file
11680
11681         local save_pattern=$(sysctl -n kernel.core_pattern)
11682         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11683         sysctl -w kernel.core_pattern=$file
11684         sysctl -w kernel.core_uses_pid=0
11685
11686         ulimit -c unlimited
11687         sleep 60 &
11688         SLEEPPID=$!
11689
11690         sleep 1
11691
11692         kill -s 11 $SLEEPPID
11693         wait $SLEEPPID
11694         if [ -e $file ]; then
11695                 size=`stat -c%s $file`
11696                 [ $size -eq 0 ] && error "Fail to create core file $file"
11697         else
11698                 error "Fail to create core file $file"
11699         fi
11700         rm -f $file
11701         sysctl -w kernel.core_pattern=$save_pattern
11702         sysctl -w kernel.core_uses_pid=$save_uses_pid
11703         cd $CDIR
11704 }
11705 run_test 107 "Coredump on SIG"
11706
11707 test_110() {
11708         test_mkdir $DIR/$tdir
11709         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11710         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11711                 error "mkdir with 256 char should fail, but did not"
11712         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11713                 error "create with 255 char failed"
11714         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11715                 error "create with 256 char should fail, but did not"
11716
11717         ls -l $DIR/$tdir
11718         rm -rf $DIR/$tdir
11719 }
11720 run_test 110 "filename length checking"
11721
11722 #
11723 # Purpose: To verify dynamic thread (OSS) creation.
11724 #
11725 test_115() {
11726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11727         remote_ost_nodsh && skip "remote OST with nodsh"
11728
11729         # Lustre does not stop service threads once they are started.
11730         # Reset number of running threads to default.
11731         stopall
11732         setupall
11733
11734         local OSTIO_pre
11735         local save_params="$TMP/sanity-$TESTNAME.parameters"
11736
11737         # Get ll_ost_io count before I/O
11738         OSTIO_pre=$(do_facet ost1 \
11739                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11740         # Exit if lustre is not running (ll_ost_io not running).
11741         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11742
11743         echo "Starting with $OSTIO_pre threads"
11744         local thread_max=$((OSTIO_pre * 2))
11745         local rpc_in_flight=$((thread_max * 2))
11746         # Number of I/O Process proposed to be started.
11747         local nfiles
11748         local facets=$(get_facets OST)
11749
11750         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11751         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11752
11753         # Set in_flight to $rpc_in_flight
11754         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11755                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11756         nfiles=${rpc_in_flight}
11757         # Set ost thread_max to $thread_max
11758         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11759
11760         # 5 Minutes should be sufficient for max number of OSS
11761         # threads(thread_max) to be created.
11762         local timeout=300
11763
11764         # Start I/O.
11765         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11766         test_mkdir $DIR/$tdir
11767         for i in $(seq $nfiles); do
11768                 local file=$DIR/$tdir/${tfile}-$i
11769                 $LFS setstripe -c -1 -i 0 $file
11770                 ($WTL $file $timeout)&
11771         done
11772
11773         # I/O Started - Wait for thread_started to reach thread_max or report
11774         # error if thread_started is more than thread_max.
11775         echo "Waiting for thread_started to reach thread_max"
11776         local thread_started=0
11777         local end_time=$((SECONDS + timeout))
11778
11779         while [ $SECONDS -le $end_time ] ; do
11780                 echo -n "."
11781                 # Get ost i/o thread_started count.
11782                 thread_started=$(do_facet ost1 \
11783                         "$LCTL get_param \
11784                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11785                 # Break out if thread_started is equal/greater than thread_max
11786                 if [[ $thread_started -ge $thread_max ]]; then
11787                         echo ll_ost_io thread_started $thread_started, \
11788                                 equal/greater than thread_max $thread_max
11789                         break
11790                 fi
11791                 sleep 1
11792         done
11793
11794         # Cleanup - We have the numbers, Kill i/o jobs if running.
11795         jobcount=($(jobs -p))
11796         for i in $(seq 0 $((${#jobcount[@]}-1)))
11797         do
11798                 kill -9 ${jobcount[$i]}
11799                 if [ $? -ne 0 ] ; then
11800                         echo Warning: \
11801                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11802                 fi
11803         done
11804
11805         # Cleanup files left by WTL binary.
11806         for i in $(seq $nfiles); do
11807                 local file=$DIR/$tdir/${tfile}-$i
11808                 rm -rf $file
11809                 if [ $? -ne 0 ] ; then
11810                         echo "Warning: Failed to delete file $file"
11811                 fi
11812         done
11813
11814         restore_lustre_params <$save_params
11815         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11816
11817         # Error out if no new thread has started or Thread started is greater
11818         # than thread max.
11819         if [[ $thread_started -le $OSTIO_pre ||
11820                         $thread_started -gt $thread_max ]]; then
11821                 error "ll_ost_io: thread_started $thread_started" \
11822                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11823                       "No new thread started or thread started greater " \
11824                       "than thread_max."
11825         fi
11826 }
11827 run_test 115 "verify dynamic thread creation===================="
11828
11829 free_min_max () {
11830         wait_delete_completed
11831         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11832         echo "OST kbytes available: ${AVAIL[@]}"
11833         MAXV=${AVAIL[0]}
11834         MAXI=0
11835         MINV=${AVAIL[0]}
11836         MINI=0
11837         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11838                 #echo OST $i: ${AVAIL[i]}kb
11839                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11840                         MAXV=${AVAIL[i]}
11841                         MAXI=$i
11842                 fi
11843                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11844                         MINV=${AVAIL[i]}
11845                         MINI=$i
11846                 fi
11847         done
11848         echo "Min free space: OST $MINI: $MINV"
11849         echo "Max free space: OST $MAXI: $MAXV"
11850 }
11851
11852 test_116a() { # was previously test_116()
11853         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11855         remote_mds_nodsh && skip "remote MDS with nodsh"
11856
11857         echo -n "Free space priority "
11858         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11859                 head -n1
11860         declare -a AVAIL
11861         free_min_max
11862
11863         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11864         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11865         trap simple_cleanup_common EXIT
11866
11867         # Check if we need to generate uneven OSTs
11868         test_mkdir -p $DIR/$tdir/OST${MINI}
11869         local FILL=$((MINV / 4))
11870         local DIFF=$((MAXV - MINV))
11871         local DIFF2=$((DIFF * 100 / MINV))
11872
11873         local threshold=$(do_facet $SINGLEMDS \
11874                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11875         threshold=${threshold%%%}
11876         echo -n "Check for uneven OSTs: "
11877         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11878
11879         if [[ $DIFF2 -gt $threshold ]]; then
11880                 echo "ok"
11881                 echo "Don't need to fill OST$MINI"
11882         else
11883                 # generate uneven OSTs. Write 2% over the QOS threshold value
11884                 echo "no"
11885                 DIFF=$((threshold - DIFF2 + 2))
11886                 DIFF2=$((MINV * DIFF / 100))
11887                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11888                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11889                         error "setstripe failed"
11890                 DIFF=$((DIFF2 / 2048))
11891                 i=0
11892                 while [ $i -lt $DIFF ]; do
11893                         i=$((i + 1))
11894                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11895                                 bs=2M count=1 2>/dev/null
11896                         echo -n .
11897                 done
11898                 echo .
11899                 sync
11900                 sleep_maxage
11901                 free_min_max
11902         fi
11903
11904         DIFF=$((MAXV - MINV))
11905         DIFF2=$((DIFF * 100 / MINV))
11906         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11907         if [ $DIFF2 -gt $threshold ]; then
11908                 echo "ok"
11909         else
11910                 echo "failed - QOS mode won't be used"
11911                 simple_cleanup_common
11912                 skip "QOS imbalance criteria not met"
11913         fi
11914
11915         MINI1=$MINI
11916         MINV1=$MINV
11917         MAXI1=$MAXI
11918         MAXV1=$MAXV
11919
11920         # now fill using QOS
11921         $LFS setstripe -c 1 $DIR/$tdir
11922         FILL=$((FILL / 200))
11923         if [ $FILL -gt 600 ]; then
11924                 FILL=600
11925         fi
11926         echo "writing $FILL files to QOS-assigned OSTs"
11927         i=0
11928         while [ $i -lt $FILL ]; do
11929                 i=$((i + 1))
11930                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11931                         count=1 2>/dev/null
11932                 echo -n .
11933         done
11934         echo "wrote $i 200k files"
11935         sync
11936         sleep_maxage
11937
11938         echo "Note: free space may not be updated, so measurements might be off"
11939         free_min_max
11940         DIFF2=$((MAXV - MINV))
11941         echo "free space delta: orig $DIFF final $DIFF2"
11942         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11943         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11944         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11945         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11946         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11947         if [[ $DIFF -gt 0 ]]; then
11948                 FILL=$((DIFF2 * 100 / DIFF - 100))
11949                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11950         fi
11951
11952         # Figure out which files were written where
11953         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11954                awk '/'$MINI1': / {print $2; exit}')
11955         echo $UUID
11956         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11957         echo "$MINC files created on smaller OST $MINI1"
11958         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11959                awk '/'$MAXI1': / {print $2; exit}')
11960         echo $UUID
11961         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11962         echo "$MAXC files created on larger OST $MAXI1"
11963         if [[ $MINC -gt 0 ]]; then
11964                 FILL=$((MAXC * 100 / MINC - 100))
11965                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11966         fi
11967         [[ $MAXC -gt $MINC ]] ||
11968                 error_ignore LU-9 "stripe QOS didn't balance free space"
11969         simple_cleanup_common
11970 }
11971 run_test 116a "stripe QOS: free space balance ==================="
11972
11973 test_116b() { # LU-2093
11974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11975         remote_mds_nodsh && skip "remote MDS with nodsh"
11976
11977 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11978         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11979                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11980         [ -z "$old_rr" ] && skip "no QOS"
11981         do_facet $SINGLEMDS lctl set_param \
11982                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11983         mkdir -p $DIR/$tdir
11984         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11985         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11986         do_facet $SINGLEMDS lctl set_param fail_loc=0
11987         rm -rf $DIR/$tdir
11988         do_facet $SINGLEMDS lctl set_param \
11989                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11990 }
11991 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11992
11993 test_117() # bug 10891
11994 {
11995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11996
11997         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11998         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11999         lctl set_param fail_loc=0x21e
12000         > $DIR/$tfile || error "truncate failed"
12001         lctl set_param fail_loc=0
12002         echo "Truncate succeeded."
12003         rm -f $DIR/$tfile
12004 }
12005 run_test 117 "verify osd extend =========="
12006
12007 NO_SLOW_RESENDCOUNT=4
12008 export OLD_RESENDCOUNT=""
12009 set_resend_count () {
12010         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12011         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12012         lctl set_param -n $PROC_RESENDCOUNT $1
12013         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12014 }
12015
12016 # for reduce test_118* time (b=14842)
12017 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12018
12019 # Reset async IO behavior after error case
12020 reset_async() {
12021         FILE=$DIR/reset_async
12022
12023         # Ensure all OSCs are cleared
12024         $LFS setstripe -c -1 $FILE
12025         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12026         sync
12027         rm $FILE
12028 }
12029
12030 test_118a() #bug 11710
12031 {
12032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12033
12034         reset_async
12035
12036         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12037         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12038         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12039
12040         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12041                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12042                 return 1;
12043         fi
12044         rm -f $DIR/$tfile
12045 }
12046 run_test 118a "verify O_SYNC works =========="
12047
12048 test_118b()
12049 {
12050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12051         remote_ost_nodsh && skip "remote OST with nodsh"
12052
12053         reset_async
12054
12055         #define OBD_FAIL_SRV_ENOENT 0x217
12056         set_nodes_failloc "$(osts_nodes)" 0x217
12057         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12058         RC=$?
12059         set_nodes_failloc "$(osts_nodes)" 0
12060         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12061         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12062                     grep -c writeback)
12063
12064         if [[ $RC -eq 0 ]]; then
12065                 error "Must return error due to dropped pages, rc=$RC"
12066                 return 1;
12067         fi
12068
12069         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12070                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12071                 return 1;
12072         fi
12073
12074         echo "Dirty pages not leaked on ENOENT"
12075
12076         # Due to the above error the OSC will issue all RPCs syncronously
12077         # until a subsequent RPC completes successfully without error.
12078         $MULTIOP $DIR/$tfile Ow4096yc
12079         rm -f $DIR/$tfile
12080
12081         return 0
12082 }
12083 run_test 118b "Reclaim dirty pages on fatal error =========="
12084
12085 test_118c()
12086 {
12087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12088
12089         # for 118c, restore the original resend count, LU-1940
12090         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12091                                 set_resend_count $OLD_RESENDCOUNT
12092         remote_ost_nodsh && skip "remote OST with nodsh"
12093
12094         reset_async
12095
12096         #define OBD_FAIL_OST_EROFS               0x216
12097         set_nodes_failloc "$(osts_nodes)" 0x216
12098
12099         # multiop should block due to fsync until pages are written
12100         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12101         MULTIPID=$!
12102         sleep 1
12103
12104         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12105                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12106         fi
12107
12108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12109                     grep -c writeback)
12110         if [[ $WRITEBACK -eq 0 ]]; then
12111                 error "No page in writeback, writeback=$WRITEBACK"
12112         fi
12113
12114         set_nodes_failloc "$(osts_nodes)" 0
12115         wait $MULTIPID
12116         RC=$?
12117         if [[ $RC -ne 0 ]]; then
12118                 error "Multiop fsync failed, rc=$RC"
12119         fi
12120
12121         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12122         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12123                     grep -c writeback)
12124         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12125                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12126         fi
12127
12128         rm -f $DIR/$tfile
12129         echo "Dirty pages flushed via fsync on EROFS"
12130         return 0
12131 }
12132 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12133
12134 # continue to use small resend count to reduce test_118* time (b=14842)
12135 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12136
12137 test_118d()
12138 {
12139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12140         remote_ost_nodsh && skip "remote OST with nodsh"
12141
12142         reset_async
12143
12144         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12145         set_nodes_failloc "$(osts_nodes)" 0x214
12146         # multiop should block due to fsync until pages are written
12147         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12148         MULTIPID=$!
12149         sleep 1
12150
12151         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12152                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12153         fi
12154
12155         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12156                     grep -c writeback)
12157         if [[ $WRITEBACK -eq 0 ]]; then
12158                 error "No page in writeback, writeback=$WRITEBACK"
12159         fi
12160
12161         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12162         set_nodes_failloc "$(osts_nodes)" 0
12163
12164         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12165         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12166                     grep -c writeback)
12167         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12168                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12169         fi
12170
12171         rm -f $DIR/$tfile
12172         echo "Dirty pages gaurenteed flushed via fsync"
12173         return 0
12174 }
12175 run_test 118d "Fsync validation inject a delay of the bulk =========="
12176
12177 test_118f() {
12178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12179
12180         reset_async
12181
12182         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12183         lctl set_param fail_loc=0x8000040a
12184
12185         # Should simulate EINVAL error which is fatal
12186         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12187         RC=$?
12188         if [[ $RC -eq 0 ]]; then
12189                 error "Must return error due to dropped pages, rc=$RC"
12190         fi
12191
12192         lctl set_param fail_loc=0x0
12193
12194         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12195         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12196         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12197                     grep -c writeback)
12198         if [[ $LOCKED -ne 0 ]]; then
12199                 error "Locked pages remain in cache, locked=$LOCKED"
12200         fi
12201
12202         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12203                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12204         fi
12205
12206         rm -f $DIR/$tfile
12207         echo "No pages locked after fsync"
12208
12209         reset_async
12210         return 0
12211 }
12212 run_test 118f "Simulate unrecoverable OSC side error =========="
12213
12214 test_118g() {
12215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12216
12217         reset_async
12218
12219         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12220         lctl set_param fail_loc=0x406
12221
12222         # simulate local -ENOMEM
12223         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12224         RC=$?
12225
12226         lctl set_param fail_loc=0
12227         if [[ $RC -eq 0 ]]; then
12228                 error "Must return error due to dropped pages, rc=$RC"
12229         fi
12230
12231         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12232         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12233         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12234                         grep -c writeback)
12235         if [[ $LOCKED -ne 0 ]]; then
12236                 error "Locked pages remain in cache, locked=$LOCKED"
12237         fi
12238
12239         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12240                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12241         fi
12242
12243         rm -f $DIR/$tfile
12244         echo "No pages locked after fsync"
12245
12246         reset_async
12247         return 0
12248 }
12249 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12250
12251 test_118h() {
12252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12253         remote_ost_nodsh && skip "remote OST with nodsh"
12254
12255         reset_async
12256
12257         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12258         set_nodes_failloc "$(osts_nodes)" 0x20e
12259         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12260         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12261         RC=$?
12262
12263         set_nodes_failloc "$(osts_nodes)" 0
12264         if [[ $RC -eq 0 ]]; then
12265                 error "Must return error due to dropped pages, rc=$RC"
12266         fi
12267
12268         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12269         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12270         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12271                     grep -c writeback)
12272         if [[ $LOCKED -ne 0 ]]; then
12273                 error "Locked pages remain in cache, locked=$LOCKED"
12274         fi
12275
12276         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12277                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12278         fi
12279
12280         rm -f $DIR/$tfile
12281         echo "No pages locked after fsync"
12282
12283         return 0
12284 }
12285 run_test 118h "Verify timeout in handling recoverables errors  =========="
12286
12287 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12288
12289 test_118i() {
12290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12291         remote_ost_nodsh && skip "remote OST with nodsh"
12292
12293         reset_async
12294
12295         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12296         set_nodes_failloc "$(osts_nodes)" 0x20e
12297
12298         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12299         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12300         PID=$!
12301         sleep 5
12302         set_nodes_failloc "$(osts_nodes)" 0
12303
12304         wait $PID
12305         RC=$?
12306         if [[ $RC -ne 0 ]]; then
12307                 error "got error, but should be not, rc=$RC"
12308         fi
12309
12310         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12311         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12312         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12313         if [[ $LOCKED -ne 0 ]]; then
12314                 error "Locked pages remain in cache, locked=$LOCKED"
12315         fi
12316
12317         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12318                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12319         fi
12320
12321         rm -f $DIR/$tfile
12322         echo "No pages locked after fsync"
12323
12324         return 0
12325 }
12326 run_test 118i "Fix error before timeout in recoverable error  =========="
12327
12328 [ "$SLOW" = "no" ] && set_resend_count 4
12329
12330 test_118j() {
12331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12332         remote_ost_nodsh && skip "remote OST with nodsh"
12333
12334         reset_async
12335
12336         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12337         set_nodes_failloc "$(osts_nodes)" 0x220
12338
12339         # return -EIO from OST
12340         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12341         RC=$?
12342         set_nodes_failloc "$(osts_nodes)" 0x0
12343         if [[ $RC -eq 0 ]]; then
12344                 error "Must return error due to dropped pages, rc=$RC"
12345         fi
12346
12347         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12348         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12349         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12350         if [[ $LOCKED -ne 0 ]]; then
12351                 error "Locked pages remain in cache, locked=$LOCKED"
12352         fi
12353
12354         # in recoverable error on OST we want resend and stay until it finished
12355         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12356                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12357         fi
12358
12359         rm -f $DIR/$tfile
12360         echo "No pages locked after fsync"
12361
12362         return 0
12363 }
12364 run_test 118j "Simulate unrecoverable OST side error =========="
12365
12366 test_118k()
12367 {
12368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12369         remote_ost_nodsh && skip "remote OSTs with nodsh"
12370
12371         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12372         set_nodes_failloc "$(osts_nodes)" 0x20e
12373         test_mkdir $DIR/$tdir
12374
12375         for ((i=0;i<10;i++)); do
12376                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12377                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12378                 SLEEPPID=$!
12379                 sleep 0.500s
12380                 kill $SLEEPPID
12381                 wait $SLEEPPID
12382         done
12383
12384         set_nodes_failloc "$(osts_nodes)" 0
12385         rm -rf $DIR/$tdir
12386 }
12387 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12388
12389 test_118l() # LU-646
12390 {
12391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12392
12393         test_mkdir $DIR/$tdir
12394         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12395         rm -rf $DIR/$tdir
12396 }
12397 run_test 118l "fsync dir"
12398
12399 test_118m() # LU-3066
12400 {
12401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12402
12403         test_mkdir $DIR/$tdir
12404         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12405         rm -rf $DIR/$tdir
12406 }
12407 run_test 118m "fdatasync dir ========="
12408
12409 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12410
12411 test_118n()
12412 {
12413         local begin
12414         local end
12415
12416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12417         remote_ost_nodsh && skip "remote OSTs with nodsh"
12418
12419         # Sleep to avoid a cached response.
12420         #define OBD_STATFS_CACHE_SECONDS 1
12421         sleep 2
12422
12423         # Inject a 10 second delay in the OST_STATFS handler.
12424         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12425         set_nodes_failloc "$(osts_nodes)" 0x242
12426
12427         begin=$SECONDS
12428         stat --file-system $MOUNT > /dev/null
12429         end=$SECONDS
12430
12431         set_nodes_failloc "$(osts_nodes)" 0
12432
12433         if ((end - begin > 20)); then
12434             error "statfs took $((end - begin)) seconds, expected 10"
12435         fi
12436 }
12437 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12438
12439 test_119a() # bug 11737
12440 {
12441         BSIZE=$((512 * 1024))
12442         directio write $DIR/$tfile 0 1 $BSIZE
12443         # We ask to read two blocks, which is more than a file size.
12444         # directio will indicate an error when requested and actual
12445         # sizes aren't equeal (a normal situation in this case) and
12446         # print actual read amount.
12447         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12448         if [ "$NOB" != "$BSIZE" ]; then
12449                 error "read $NOB bytes instead of $BSIZE"
12450         fi
12451         rm -f $DIR/$tfile
12452 }
12453 run_test 119a "Short directIO read must return actual read amount"
12454
12455 test_119b() # bug 11737
12456 {
12457         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12458
12459         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12460         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12461         sync
12462         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12463                 error "direct read failed"
12464         rm -f $DIR/$tfile
12465 }
12466 run_test 119b "Sparse directIO read must return actual read amount"
12467
12468 test_119c() # bug 13099
12469 {
12470         BSIZE=1048576
12471         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12472         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12473         rm -f $DIR/$tfile
12474 }
12475 run_test 119c "Testing for direct read hitting hole"
12476
12477 test_119d() # bug 15950
12478 {
12479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12480
12481         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12482         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12483         BSIZE=1048576
12484         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12485         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12486         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12487         lctl set_param fail_loc=0x40d
12488         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12489         pid_dio=$!
12490         sleep 1
12491         cat $DIR/$tfile > /dev/null &
12492         lctl set_param fail_loc=0
12493         pid_reads=$!
12494         wait $pid_dio
12495         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12496         sleep 2
12497         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12498         error "the read rpcs have not completed in 2s"
12499         rm -f $DIR/$tfile
12500         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12501 }
12502 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12503
12504 test_120a() {
12505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12506         remote_mds_nodsh && skip "remote MDS with nodsh"
12507         test_mkdir -i0 -c1 $DIR/$tdir
12508         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12509                 skip_env "no early lock cancel on server"
12510
12511         lru_resize_disable mdc
12512         lru_resize_disable osc
12513         cancel_lru_locks mdc
12514         # asynchronous object destroy at MDT could cause bl ast to client
12515         cancel_lru_locks osc
12516
12517         stat $DIR/$tdir > /dev/null
12518         can1=$(do_facet mds1 \
12519                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12520                awk '/ldlm_cancel/ {print $2}')
12521         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12522                awk '/ldlm_bl_callback/ {print $2}')
12523         test_mkdir -i0 -c1 $DIR/$tdir/d1
12524         can2=$(do_facet mds1 \
12525                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12526                awk '/ldlm_cancel/ {print $2}')
12527         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12528                awk '/ldlm_bl_callback/ {print $2}')
12529         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12530         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12531         lru_resize_enable mdc
12532         lru_resize_enable osc
12533 }
12534 run_test 120a "Early Lock Cancel: mkdir test"
12535
12536 test_120b() {
12537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12538         remote_mds_nodsh && skip "remote MDS with nodsh"
12539         test_mkdir $DIR/$tdir
12540         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12541                 skip_env "no early lock cancel on server"
12542
12543         lru_resize_disable mdc
12544         lru_resize_disable osc
12545         cancel_lru_locks mdc
12546         stat $DIR/$tdir > /dev/null
12547         can1=$(do_facet $SINGLEMDS \
12548                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12549                awk '/ldlm_cancel/ {print $2}')
12550         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12551                awk '/ldlm_bl_callback/ {print $2}')
12552         touch $DIR/$tdir/f1
12553         can2=$(do_facet $SINGLEMDS \
12554                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12555                awk '/ldlm_cancel/ {print $2}')
12556         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12557                awk '/ldlm_bl_callback/ {print $2}')
12558         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12559         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12560         lru_resize_enable mdc
12561         lru_resize_enable osc
12562 }
12563 run_test 120b "Early Lock Cancel: create test"
12564
12565 test_120c() {
12566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12567         remote_mds_nodsh && skip "remote MDS with nodsh"
12568         test_mkdir -i0 -c1 $DIR/$tdir
12569         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12570                 skip "no early lock cancel on server"
12571
12572         lru_resize_disable mdc
12573         lru_resize_disable osc
12574         test_mkdir -i0 -c1 $DIR/$tdir/d1
12575         test_mkdir -i0 -c1 $DIR/$tdir/d2
12576         touch $DIR/$tdir/d1/f1
12577         cancel_lru_locks mdc
12578         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12579         can1=$(do_facet mds1 \
12580                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12581                awk '/ldlm_cancel/ {print $2}')
12582         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12583                awk '/ldlm_bl_callback/ {print $2}')
12584         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12585         can2=$(do_facet mds1 \
12586                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12587                awk '/ldlm_cancel/ {print $2}')
12588         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12589                awk '/ldlm_bl_callback/ {print $2}')
12590         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12591         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12592         lru_resize_enable mdc
12593         lru_resize_enable osc
12594 }
12595 run_test 120c "Early Lock Cancel: link test"
12596
12597 test_120d() {
12598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12599         remote_mds_nodsh && skip "remote MDS with nodsh"
12600         test_mkdir -i0 -c1 $DIR/$tdir
12601         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12602                 skip_env "no early lock cancel on server"
12603
12604         lru_resize_disable mdc
12605         lru_resize_disable osc
12606         touch $DIR/$tdir
12607         cancel_lru_locks mdc
12608         stat $DIR/$tdir > /dev/null
12609         can1=$(do_facet mds1 \
12610                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12611                awk '/ldlm_cancel/ {print $2}')
12612         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12613                awk '/ldlm_bl_callback/ {print $2}')
12614         chmod a+x $DIR/$tdir
12615         can2=$(do_facet mds1 \
12616                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12617                awk '/ldlm_cancel/ {print $2}')
12618         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12619                awk '/ldlm_bl_callback/ {print $2}')
12620         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12621         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12622         lru_resize_enable mdc
12623         lru_resize_enable osc
12624 }
12625 run_test 120d "Early Lock Cancel: setattr test"
12626
12627 test_120e() {
12628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12629         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12630                 skip_env "no early lock cancel on server"
12631         remote_mds_nodsh && skip "remote MDS with nodsh"
12632
12633         local dlmtrace_set=false
12634
12635         test_mkdir -i0 -c1 $DIR/$tdir
12636         lru_resize_disable mdc
12637         lru_resize_disable osc
12638         ! $LCTL get_param debug | grep -q dlmtrace &&
12639                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12640         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12641         cancel_lru_locks mdc
12642         cancel_lru_locks osc
12643         dd if=$DIR/$tdir/f1 of=/dev/null
12644         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12645         # XXX client can not do early lock cancel of OST lock
12646         # during unlink (LU-4206), so cancel osc lock now.
12647         sleep 2
12648         cancel_lru_locks osc
12649         can1=$(do_facet mds1 \
12650                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12651                awk '/ldlm_cancel/ {print $2}')
12652         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12653                awk '/ldlm_bl_callback/ {print $2}')
12654         unlink $DIR/$tdir/f1
12655         sleep 5
12656         can2=$(do_facet mds1 \
12657                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12658                awk '/ldlm_cancel/ {print $2}')
12659         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12660                awk '/ldlm_bl_callback/ {print $2}')
12661         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12662                 $LCTL dk $TMP/cancel.debug.txt
12663         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12664                 $LCTL dk $TMP/blocking.debug.txt
12665         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12666         lru_resize_enable mdc
12667         lru_resize_enable osc
12668 }
12669 run_test 120e "Early Lock Cancel: unlink test"
12670
12671 test_120f() {
12672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12673         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12674                 skip_env "no early lock cancel on server"
12675         remote_mds_nodsh && skip "remote MDS with nodsh"
12676
12677         test_mkdir -i0 -c1 $DIR/$tdir
12678         lru_resize_disable mdc
12679         lru_resize_disable osc
12680         test_mkdir -i0 -c1 $DIR/$tdir/d1
12681         test_mkdir -i0 -c1 $DIR/$tdir/d2
12682         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12683         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12684         cancel_lru_locks mdc
12685         cancel_lru_locks osc
12686         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12687         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12688         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12689         # XXX client can not do early lock cancel of OST lock
12690         # during rename (LU-4206), so cancel osc lock now.
12691         sleep 2
12692         cancel_lru_locks osc
12693         can1=$(do_facet mds1 \
12694                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12695                awk '/ldlm_cancel/ {print $2}')
12696         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12697                awk '/ldlm_bl_callback/ {print $2}')
12698         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12699         sleep 5
12700         can2=$(do_facet mds1 \
12701                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12702                awk '/ldlm_cancel/ {print $2}')
12703         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12704                awk '/ldlm_bl_callback/ {print $2}')
12705         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12706         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12707         lru_resize_enable mdc
12708         lru_resize_enable osc
12709 }
12710 run_test 120f "Early Lock Cancel: rename test"
12711
12712 test_120g() {
12713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12714         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12715                 skip_env "no early lock cancel on server"
12716         remote_mds_nodsh && skip "remote MDS with nodsh"
12717
12718         lru_resize_disable mdc
12719         lru_resize_disable osc
12720         count=10000
12721         echo create $count files
12722         test_mkdir $DIR/$tdir
12723         cancel_lru_locks mdc
12724         cancel_lru_locks osc
12725         t0=$(date +%s)
12726
12727         can0=$(do_facet $SINGLEMDS \
12728                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12729                awk '/ldlm_cancel/ {print $2}')
12730         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12731                awk '/ldlm_bl_callback/ {print $2}')
12732         createmany -o $DIR/$tdir/f $count
12733         sync
12734         can1=$(do_facet $SINGLEMDS \
12735                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12736                awk '/ldlm_cancel/ {print $2}')
12737         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12738                awk '/ldlm_bl_callback/ {print $2}')
12739         t1=$(date +%s)
12740         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12741         echo rm $count files
12742         rm -r $DIR/$tdir
12743         sync
12744         can2=$(do_facet $SINGLEMDS \
12745                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12746                awk '/ldlm_cancel/ {print $2}')
12747         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12748                awk '/ldlm_bl_callback/ {print $2}')
12749         t2=$(date +%s)
12750         echo total: $count removes in $((t2-t1))
12751         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12752         sleep 2
12753         # wait for commitment of removal
12754         lru_resize_enable mdc
12755         lru_resize_enable osc
12756 }
12757 run_test 120g "Early Lock Cancel: performance test"
12758
12759 test_121() { #bug #10589
12760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12761
12762         rm -rf $DIR/$tfile
12763         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12764 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12765         lctl set_param fail_loc=0x310
12766         cancel_lru_locks osc > /dev/null
12767         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12768         lctl set_param fail_loc=0
12769         [[ $reads -eq $writes ]] ||
12770                 error "read $reads blocks, must be $writes blocks"
12771 }
12772 run_test 121 "read cancel race ========="
12773
12774 test_123a_base() { # was test 123, statahead(bug 11401)
12775         local lsx="$1"
12776
12777         SLOWOK=0
12778         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12779                 log "testing UP system. Performance may be lower than expected."
12780                 SLOWOK=1
12781         fi
12782
12783         rm -rf $DIR/$tdir
12784         test_mkdir $DIR/$tdir
12785         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12786         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12787         MULT=10
12788         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12789                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12790
12791                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12792                 lctl set_param -n llite.*.statahead_max 0
12793                 lctl get_param llite.*.statahead_max
12794                 cancel_lru_locks mdc
12795                 cancel_lru_locks osc
12796                 stime=$(date +%s)
12797                 time $lsx $DIR/$tdir | wc -l
12798                 etime=$(date +%s)
12799                 delta=$((etime - stime))
12800                 log "$lsx $i files without statahead: $delta sec"
12801                 lctl set_param llite.*.statahead_max=$max
12802
12803                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12804                         grep "statahead wrong:" | awk '{print $3}')
12805                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12806                 cancel_lru_locks mdc
12807                 cancel_lru_locks osc
12808                 stime=$(date +%s)
12809                 time $lsx $DIR/$tdir | wc -l
12810                 etime=$(date +%s)
12811                 delta_sa=$((etime - stime))
12812                 log "$lsx $i files with statahead: $delta_sa sec"
12813                 lctl get_param -n llite.*.statahead_stats
12814                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12815                         grep "statahead wrong:" | awk '{print $3}')
12816
12817                 [[ $swrong -lt $ewrong ]] &&
12818                         log "statahead was stopped, maybe too many locks held!"
12819                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12820
12821                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12822                         max=$(lctl get_param -n llite.*.statahead_max |
12823                                 head -n 1)
12824                         lctl set_param -n llite.*.statahead_max 0
12825                         lctl get_param llite.*.statahead_max
12826                         cancel_lru_locks mdc
12827                         cancel_lru_locks osc
12828                         stime=$(date +%s)
12829                         time $lsx $DIR/$tdir | wc -l
12830                         etime=$(date +%s)
12831                         delta=$((etime - stime))
12832                         log "$lsx $i files again without statahead: $delta sec"
12833                         lctl set_param llite.*.statahead_max=$max
12834                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12835                                 if [  $SLOWOK -eq 0 ]; then
12836                                         error "$lsx $i files is slower with statahead!"
12837                                 else
12838                                         log "$lsx $i files is slower with statahead!"
12839                                 fi
12840                                 break
12841                         fi
12842                 fi
12843
12844                 [ $delta -gt 20 ] && break
12845                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12846                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12847         done
12848         log "$lsx done"
12849
12850         stime=$(date +%s)
12851         rm -r $DIR/$tdir
12852         sync
12853         etime=$(date +%s)
12854         delta=$((etime - stime))
12855         log "rm -r $DIR/$tdir/: $delta seconds"
12856         log "rm done"
12857         lctl get_param -n llite.*.statahead_stats
12858 }
12859
12860 test_123aa() {
12861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12862
12863         test_123a_base "ls -l"
12864 }
12865 run_test 123aa "verify statahead work"
12866
12867 test_123ab() {
12868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12869
12870         statx_supported || skip_env "Test must be statx() syscall supported"
12871
12872         test_123a_base "$STATX -l"
12873 }
12874 run_test 123ab "verify statahead work by using statx"
12875
12876 test_123ac() {
12877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12878
12879         statx_supported || skip_env "Test must be statx() syscall supported"
12880
12881         local rpcs_before
12882         local rpcs_after
12883         local agl_before
12884         local agl_after
12885
12886         cancel_lru_locks $OSC
12887         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12888         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12889                 awk '/agl.total:/ {print $3}')
12890         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12891         test_123a_base "$STATX --cached=always -D"
12892         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12893                 awk '/agl.total:/ {print $3}')
12894         [ $agl_before -eq $agl_after ] ||
12895                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12896         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12897         [ $rpcs_after -eq $rpcs_before ] ||
12898                 error "$STATX should not send glimpse RPCs to $OSC"
12899 }
12900 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12901
12902 test_123b () { # statahead(bug 15027)
12903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12904
12905         test_mkdir $DIR/$tdir
12906         createmany -o $DIR/$tdir/$tfile-%d 1000
12907
12908         cancel_lru_locks mdc
12909         cancel_lru_locks osc
12910
12911 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12912         lctl set_param fail_loc=0x80000803
12913         ls -lR $DIR/$tdir > /dev/null
12914         log "ls done"
12915         lctl set_param fail_loc=0x0
12916         lctl get_param -n llite.*.statahead_stats
12917         rm -r $DIR/$tdir
12918         sync
12919
12920 }
12921 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12922
12923 test_123c() {
12924         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12925
12926         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12927         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12928         touch $DIR/$tdir.1/{1..3}
12929         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12930
12931         remount_client $MOUNT
12932
12933         $MULTIOP $DIR/$tdir.0 Q
12934
12935         # let statahead to complete
12936         ls -l $DIR/$tdir.0 > /dev/null
12937
12938         testid=$(echo $TESTNAME | tr '_' ' ')
12939         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12940                 error "statahead warning" || true
12941 }
12942 run_test 123c "Can not initialize inode warning on DNE statahead"
12943
12944 test_124a() {
12945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12946         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12947                 skip_env "no lru resize on server"
12948
12949         local NR=2000
12950
12951         test_mkdir $DIR/$tdir
12952
12953         log "create $NR files at $DIR/$tdir"
12954         createmany -o $DIR/$tdir/f $NR ||
12955                 error "failed to create $NR files in $DIR/$tdir"
12956
12957         cancel_lru_locks mdc
12958         ls -l $DIR/$tdir > /dev/null
12959
12960         local NSDIR=""
12961         local LRU_SIZE=0
12962         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12963                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12964                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12965                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12966                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12967                         log "NSDIR=$NSDIR"
12968                         log "NS=$(basename $NSDIR)"
12969                         break
12970                 fi
12971         done
12972
12973         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12974                 skip "Not enough cached locks created!"
12975         fi
12976         log "LRU=$LRU_SIZE"
12977
12978         local SLEEP=30
12979
12980         # We know that lru resize allows one client to hold $LIMIT locks
12981         # for 10h. After that locks begin to be killed by client.
12982         local MAX_HRS=10
12983         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12984         log "LIMIT=$LIMIT"
12985         if [ $LIMIT -lt $LRU_SIZE ]; then
12986                 skip "Limit is too small $LIMIT"
12987         fi
12988
12989         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12990         # killing locks. Some time was spent for creating locks. This means
12991         # that up to the moment of sleep finish we must have killed some of
12992         # them (10-100 locks). This depends on how fast ther were created.
12993         # Many of them were touched in almost the same moment and thus will
12994         # be killed in groups.
12995         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12996
12997         # Use $LRU_SIZE_B here to take into account real number of locks
12998         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12999         local LRU_SIZE_B=$LRU_SIZE
13000         log "LVF=$LVF"
13001         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13002         log "OLD_LVF=$OLD_LVF"
13003         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13004
13005         # Let's make sure that we really have some margin. Client checks
13006         # cached locks every 10 sec.
13007         SLEEP=$((SLEEP+20))
13008         log "Sleep ${SLEEP} sec"
13009         local SEC=0
13010         while ((SEC<$SLEEP)); do
13011                 echo -n "..."
13012                 sleep 5
13013                 SEC=$((SEC+5))
13014                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13015                 echo -n "$LRU_SIZE"
13016         done
13017         echo ""
13018         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13019         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13020
13021         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13022                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13023                 unlinkmany $DIR/$tdir/f $NR
13024                 return
13025         }
13026
13027         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13028         log "unlink $NR files at $DIR/$tdir"
13029         unlinkmany $DIR/$tdir/f $NR
13030 }
13031 run_test 124a "lru resize ======================================="
13032
13033 get_max_pool_limit()
13034 {
13035         local limit=$($LCTL get_param \
13036                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13037         local max=0
13038         for l in $limit; do
13039                 if [[ $l -gt $max ]]; then
13040                         max=$l
13041                 fi
13042         done
13043         echo $max
13044 }
13045
13046 test_124b() {
13047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13048         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13049                 skip_env "no lru resize on server"
13050
13051         LIMIT=$(get_max_pool_limit)
13052
13053         NR=$(($(default_lru_size)*20))
13054         if [[ $NR -gt $LIMIT ]]; then
13055                 log "Limit lock number by $LIMIT locks"
13056                 NR=$LIMIT
13057         fi
13058
13059         IFree=$(mdsrate_inodes_available)
13060         if [ $IFree -lt $NR ]; then
13061                 log "Limit lock number by $IFree inodes"
13062                 NR=$IFree
13063         fi
13064
13065         lru_resize_disable mdc
13066         test_mkdir -p $DIR/$tdir/disable_lru_resize
13067
13068         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13069         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13070         cancel_lru_locks mdc
13071         stime=`date +%s`
13072         PID=""
13073         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13074         PID="$PID $!"
13075         sleep 2
13076         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13077         PID="$PID $!"
13078         sleep 2
13079         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13080         PID="$PID $!"
13081         wait $PID
13082         etime=`date +%s`
13083         nolruresize_delta=$((etime-stime))
13084         log "ls -la time: $nolruresize_delta seconds"
13085         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13086         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13087
13088         lru_resize_enable mdc
13089         test_mkdir -p $DIR/$tdir/enable_lru_resize
13090
13091         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13092         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13093         cancel_lru_locks mdc
13094         stime=`date +%s`
13095         PID=""
13096         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13097         PID="$PID $!"
13098         sleep 2
13099         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13100         PID="$PID $!"
13101         sleep 2
13102         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13103         PID="$PID $!"
13104         wait $PID
13105         etime=`date +%s`
13106         lruresize_delta=$((etime-stime))
13107         log "ls -la time: $lruresize_delta seconds"
13108         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13109
13110         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13111                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13112         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13113                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13114         else
13115                 log "lru resize performs the same with no lru resize"
13116         fi
13117         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13118 }
13119 run_test 124b "lru resize (performance test) ======================="
13120
13121 test_124c() {
13122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13123         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13124                 skip_env "no lru resize on server"
13125
13126         # cache ununsed locks on client
13127         local nr=100
13128         cancel_lru_locks mdc
13129         test_mkdir $DIR/$tdir
13130         createmany -o $DIR/$tdir/f $nr ||
13131                 error "failed to create $nr files in $DIR/$tdir"
13132         ls -l $DIR/$tdir > /dev/null
13133
13134         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13135         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13136         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13137         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13138         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13139
13140         # set lru_max_age to 1 sec
13141         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13142         echo "sleep $((recalc_p * 2)) seconds..."
13143         sleep $((recalc_p * 2))
13144
13145         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13146         # restore lru_max_age
13147         $LCTL set_param -n $nsdir.lru_max_age $max_age
13148         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13149         unlinkmany $DIR/$tdir/f $nr
13150 }
13151 run_test 124c "LRUR cancel very aged locks"
13152
13153 test_124d() {
13154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13155         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13156                 skip_env "no lru resize on server"
13157
13158         # cache ununsed locks on client
13159         local nr=100
13160
13161         lru_resize_disable mdc
13162         stack_trap "lru_resize_enable mdc" EXIT
13163
13164         cancel_lru_locks mdc
13165
13166         # asynchronous object destroy at MDT could cause bl ast to client
13167         test_mkdir $DIR/$tdir
13168         createmany -o $DIR/$tdir/f $nr ||
13169                 error "failed to create $nr files in $DIR/$tdir"
13170         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13171
13172         ls -l $DIR/$tdir > /dev/null
13173
13174         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13175         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13176         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13177         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13178
13179         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13180
13181         # set lru_max_age to 1 sec
13182         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13183         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13184
13185         echo "sleep $((recalc_p * 2)) seconds..."
13186         sleep $((recalc_p * 2))
13187
13188         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13189
13190         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13191 }
13192 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13193
13194 test_125() { # 13358
13195         $LCTL get_param -n llite.*.client_type | grep -q local ||
13196                 skip "must run as local client"
13197         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13198                 skip_env "must have acl enabled"
13199         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13200
13201         test_mkdir $DIR/$tdir
13202         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13203         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13204         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13205 }
13206 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13207
13208 test_126() { # bug 12829/13455
13209         $GSS && skip_env "must run as gss disabled"
13210         $LCTL get_param -n llite.*.client_type | grep -q local ||
13211                 skip "must run as local client"
13212         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13213
13214         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13215         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13216         rm -f $DIR/$tfile
13217         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13218 }
13219 run_test 126 "check that the fsgid provided by the client is taken into account"
13220
13221 test_127a() { # bug 15521
13222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13223         local name count samp unit min max sum sumsq
13224
13225         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13226         echo "stats before reset"
13227         $LCTL get_param osc.*.stats
13228         $LCTL set_param osc.*.stats=0
13229         local fsize=$((2048 * 1024))
13230
13231         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13232         cancel_lru_locks osc
13233         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13234
13235         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13236         stack_trap "rm -f $TMP/$tfile.tmp"
13237         while read name count samp unit min max sum sumsq; do
13238                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13239                 [ ! $min ] && error "Missing min value for $name proc entry"
13240                 eval $name=$count || error "Wrong proc format"
13241
13242                 case $name in
13243                 read_bytes|write_bytes)
13244                         [[ "$unit" =~ "bytes" ]] ||
13245                                 error "unit is not 'bytes': $unit"
13246                         (( $min >= 4096 )) || error "min is too small: $min"
13247                         (( $min <= $fsize )) || error "min is too big: $min"
13248                         (( $max >= 4096 )) || error "max is too small: $max"
13249                         (( $max <= $fsize )) || error "max is too big: $max"
13250                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13251                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13252                                 error "sumsquare is too small: $sumsq"
13253                         (( $sumsq <= $fsize * $fsize )) ||
13254                                 error "sumsquare is too big: $sumsq"
13255                         ;;
13256                 ost_read|ost_write)
13257                         [[ "$unit" =~ "usec" ]] ||
13258                                 error "unit is not 'usec': $unit"
13259                         ;;
13260                 *)      ;;
13261                 esac
13262         done < $DIR/$tfile.tmp
13263
13264         #check that we actually got some stats
13265         [ "$read_bytes" ] || error "Missing read_bytes stats"
13266         [ "$write_bytes" ] || error "Missing write_bytes stats"
13267         [ "$read_bytes" != 0 ] || error "no read done"
13268         [ "$write_bytes" != 0 ] || error "no write done"
13269 }
13270 run_test 127a "verify the client stats are sane"
13271
13272 test_127b() { # bug LU-333
13273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13274         local name count samp unit min max sum sumsq
13275
13276         echo "stats before reset"
13277         $LCTL get_param llite.*.stats
13278         $LCTL set_param llite.*.stats=0
13279
13280         # perform 2 reads and writes so MAX is different from SUM.
13281         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13282         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13283         cancel_lru_locks osc
13284         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13285         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13286
13287         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13288         stack_trap "rm -f $TMP/$tfile.tmp"
13289         while read name count samp unit min max sum sumsq; do
13290                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13291                 eval $name=$count || error "Wrong proc format"
13292
13293                 case $name in
13294                 read_bytes|write_bytes)
13295                         [[ "$unit" =~ "bytes" ]] ||
13296                                 error "unit is not 'bytes': $unit"
13297                         (( $count == 2 )) || error "count is not 2: $count"
13298                         (( $min == $PAGE_SIZE )) ||
13299                                 error "min is not $PAGE_SIZE: $min"
13300                         (( $max == $PAGE_SIZE )) ||
13301                                 error "max is not $PAGE_SIZE: $max"
13302                         (( $sum == $PAGE_SIZE * 2 )) ||
13303                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13304                         ;;
13305                 read|write)
13306                         [[ "$unit" =~ "usec" ]] ||
13307                                 error "unit is not 'usec': $unit"
13308                         ;;
13309                 *)      ;;
13310                 esac
13311         done < $TMP/$tfile.tmp
13312
13313         #check that we actually got some stats
13314         [ "$read_bytes" ] || error "Missing read_bytes stats"
13315         [ "$write_bytes" ] || error "Missing write_bytes stats"
13316         [ "$read_bytes" != 0 ] || error "no read done"
13317         [ "$write_bytes" != 0 ] || error "no write done"
13318 }
13319 run_test 127b "verify the llite client stats are sane"
13320
13321 test_127c() { # LU-12394
13322         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13323         local size
13324         local bsize
13325         local reads
13326         local writes
13327         local count
13328
13329         $LCTL set_param llite.*.extents_stats=1
13330         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13331
13332         # Use two stripes so there is enough space in default config
13333         $LFS setstripe -c 2 $DIR/$tfile
13334
13335         # Extent stats start at 0-4K and go in power of two buckets
13336         # LL_HIST_START = 12 --> 2^12 = 4K
13337         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13338         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13339         # small configs
13340         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13341                 do
13342                 # Write and read, 2x each, second time at a non-zero offset
13343                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13344                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13345                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13346                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13347                 rm -f $DIR/$tfile
13348         done
13349
13350         $LCTL get_param llite.*.extents_stats
13351
13352         count=2
13353         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13354                 do
13355                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13356                                 grep -m 1 $bsize)
13357                 reads=$(echo $bucket | awk '{print $5}')
13358                 writes=$(echo $bucket | awk '{print $9}')
13359                 [ "$reads" -eq $count ] ||
13360                         error "$reads reads in < $bsize bucket, expect $count"
13361                 [ "$writes" -eq $count ] ||
13362                         error "$writes writes in < $bsize bucket, expect $count"
13363         done
13364
13365         # Test mmap write and read
13366         $LCTL set_param llite.*.extents_stats=c
13367         size=512
13368         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13369         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13370         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13371
13372         $LCTL get_param llite.*.extents_stats
13373
13374         count=$(((size*1024) / PAGE_SIZE))
13375
13376         bsize=$((2 * PAGE_SIZE / 1024))K
13377
13378         bucket=$($LCTL get_param -n llite.*.extents_stats |
13379                         grep -m 1 $bsize)
13380         reads=$(echo $bucket | awk '{print $5}')
13381         writes=$(echo $bucket | awk '{print $9}')
13382         # mmap writes fault in the page first, creating an additonal read
13383         [ "$reads" -eq $((2 * count)) ] ||
13384                 error "$reads reads in < $bsize bucket, expect $count"
13385         [ "$writes" -eq $count ] ||
13386                 error "$writes writes in < $bsize bucket, expect $count"
13387 }
13388 run_test 127c "test llite extent stats with regular & mmap i/o"
13389
13390 test_128() { # bug 15212
13391         touch $DIR/$tfile
13392         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13393                 find $DIR/$tfile
13394                 find $DIR/$tfile
13395         EOF
13396
13397         result=$(grep error $TMP/$tfile.log)
13398         rm -f $DIR/$tfile $TMP/$tfile.log
13399         [ -z "$result" ] ||
13400                 error "consecutive find's under interactive lfs failed"
13401 }
13402 run_test 128 "interactive lfs for 2 consecutive find's"
13403
13404 set_dir_limits () {
13405         local mntdev
13406         local canondev
13407         local node
13408
13409         local ldproc=/proc/fs/ldiskfs
13410         local facets=$(get_facets MDS)
13411
13412         for facet in ${facets//,/ }; do
13413                 canondev=$(ldiskfs_canon \
13414                            *.$(convert_facet2label $facet).mntdev $facet)
13415                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13416                         ldproc=/sys/fs/ldiskfs
13417                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13418                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13419         done
13420 }
13421
13422 check_mds_dmesg() {
13423         local facets=$(get_facets MDS)
13424         for facet in ${facets//,/ }; do
13425                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13426         done
13427         return 1
13428 }
13429
13430 test_129() {
13431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13432         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13433                 skip "Need MDS version with at least 2.5.56"
13434         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13435                 skip_env "ldiskfs only test"
13436         fi
13437         remote_mds_nodsh && skip "remote MDS with nodsh"
13438
13439         local ENOSPC=28
13440         local has_warning=false
13441
13442         rm -rf $DIR/$tdir
13443         mkdir -p $DIR/$tdir
13444
13445         # block size of mds1
13446         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13447         set_dir_limits $maxsize $((maxsize * 6 / 8))
13448         stack_trap "set_dir_limits 0 0"
13449         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13450         local dirsize=$(stat -c%s "$DIR/$tdir")
13451         local nfiles=0
13452         while (( $dirsize <= $maxsize )); do
13453                 $MCREATE $DIR/$tdir/file_base_$nfiles
13454                 rc=$?
13455                 # check two errors:
13456                 # ENOSPC for ext4 max_dir_size, which has been used since
13457                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13458                 if (( rc == ENOSPC )); then
13459                         set_dir_limits 0 0
13460                         echo "rc=$rc returned as expected after $nfiles files"
13461
13462                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13463                                 error "create failed w/o dir size limit"
13464
13465                         # messages may be rate limited if test is run repeatedly
13466                         check_mds_dmesg '"is approaching max"' ||
13467                                 echo "warning message should be output"
13468                         check_mds_dmesg '"has reached max"' ||
13469                                 echo "reached message should be output"
13470
13471                         dirsize=$(stat -c%s "$DIR/$tdir")
13472
13473                         [[ $dirsize -ge $maxsize ]] && return 0
13474                         error "dirsize $dirsize < $maxsize after $nfiles files"
13475                 elif (( rc != 0 )); then
13476                         break
13477                 fi
13478                 nfiles=$((nfiles + 1))
13479                 dirsize=$(stat -c%s "$DIR/$tdir")
13480         done
13481
13482         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13483 }
13484 run_test 129 "test directory size limit ========================"
13485
13486 OLDIFS="$IFS"
13487 cleanup_130() {
13488         trap 0
13489         IFS="$OLDIFS"
13490 }
13491
13492 test_130a() {
13493         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13494         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13495
13496         trap cleanup_130 EXIT RETURN
13497
13498         local fm_file=$DIR/$tfile
13499         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13500         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13501                 error "dd failed for $fm_file"
13502
13503         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13504         filefrag -ves $fm_file
13505         RC=$?
13506         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13507                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13508         [ $RC != 0 ] && error "filefrag $fm_file failed"
13509
13510         filefrag_op=$(filefrag -ve -k $fm_file |
13511                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13512         lun=$($LFS getstripe -i $fm_file)
13513
13514         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13515         IFS=$'\n'
13516         tot_len=0
13517         for line in $filefrag_op
13518         do
13519                 frag_lun=`echo $line | cut -d: -f5`
13520                 ext_len=`echo $line | cut -d: -f4`
13521                 if (( $frag_lun != $lun )); then
13522                         cleanup_130
13523                         error "FIEMAP on 1-stripe file($fm_file) failed"
13524                         return
13525                 fi
13526                 (( tot_len += ext_len ))
13527         done
13528
13529         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13530                 cleanup_130
13531                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13532                 return
13533         fi
13534
13535         cleanup_130
13536
13537         echo "FIEMAP on single striped file succeeded"
13538 }
13539 run_test 130a "FIEMAP (1-stripe file)"
13540
13541 test_130b() {
13542         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13543
13544         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13545         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13546
13547         trap cleanup_130 EXIT RETURN
13548
13549         local fm_file=$DIR/$tfile
13550         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13551                         error "setstripe on $fm_file"
13552         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13553                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13554
13555         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13556                 error "dd failed on $fm_file"
13557
13558         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13559         filefrag_op=$(filefrag -ve -k $fm_file |
13560                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13561
13562         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13563                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13564
13565         IFS=$'\n'
13566         tot_len=0
13567         num_luns=1
13568         for line in $filefrag_op
13569         do
13570                 frag_lun=$(echo $line | cut -d: -f5 |
13571                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13572                 ext_len=$(echo $line | cut -d: -f4)
13573                 if (( $frag_lun != $last_lun )); then
13574                         if (( tot_len != 1024 )); then
13575                                 cleanup_130
13576                                 error "FIEMAP on $fm_file failed; returned " \
13577                                 "len $tot_len for OST $last_lun instead of 1024"
13578                                 return
13579                         else
13580                                 (( num_luns += 1 ))
13581                                 tot_len=0
13582                         fi
13583                 fi
13584                 (( tot_len += ext_len ))
13585                 last_lun=$frag_lun
13586         done
13587         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13588                 cleanup_130
13589                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13590                         "luns or wrong len for OST $last_lun"
13591                 return
13592         fi
13593
13594         cleanup_130
13595
13596         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13597 }
13598 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13599
13600 test_130c() {
13601         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13602
13603         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13604         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13605
13606         trap cleanup_130 EXIT RETURN
13607
13608         local fm_file=$DIR/$tfile
13609         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13610         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13611                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13612
13613         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13614                         error "dd failed on $fm_file"
13615
13616         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13617         filefrag_op=$(filefrag -ve -k $fm_file |
13618                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13619
13620         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13621                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13622
13623         IFS=$'\n'
13624         tot_len=0
13625         num_luns=1
13626         for line in $filefrag_op
13627         do
13628                 frag_lun=$(echo $line | cut -d: -f5 |
13629                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13630                 ext_len=$(echo $line | cut -d: -f4)
13631                 if (( $frag_lun != $last_lun )); then
13632                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13633                         if (( logical != 512 )); then
13634                                 cleanup_130
13635                                 error "FIEMAP on $fm_file failed; returned " \
13636                                 "logical start for lun $logical instead of 512"
13637                                 return
13638                         fi
13639                         if (( tot_len != 512 )); then
13640                                 cleanup_130
13641                                 error "FIEMAP on $fm_file failed; returned " \
13642                                 "len $tot_len for OST $last_lun instead of 1024"
13643                                 return
13644                         else
13645                                 (( num_luns += 1 ))
13646                                 tot_len=0
13647                         fi
13648                 fi
13649                 (( tot_len += ext_len ))
13650                 last_lun=$frag_lun
13651         done
13652         if (( num_luns != 2 || tot_len != 512 )); then
13653                 cleanup_130
13654                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13655                         "luns or wrong len for OST $last_lun"
13656                 return
13657         fi
13658
13659         cleanup_130
13660
13661         echo "FIEMAP on 2-stripe file with hole succeeded"
13662 }
13663 run_test 130c "FIEMAP (2-stripe file with hole)"
13664
13665 test_130d() {
13666         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13667
13668         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13669         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13670
13671         trap cleanup_130 EXIT RETURN
13672
13673         local fm_file=$DIR/$tfile
13674         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13675                         error "setstripe on $fm_file"
13676         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13677                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13678
13679         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13680         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13681                 error "dd failed on $fm_file"
13682
13683         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13684         filefrag_op=$(filefrag -ve -k $fm_file |
13685                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13686
13687         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13688                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13689
13690         IFS=$'\n'
13691         tot_len=0
13692         num_luns=1
13693         for line in $filefrag_op
13694         do
13695                 frag_lun=$(echo $line | cut -d: -f5 |
13696                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13697                 ext_len=$(echo $line | cut -d: -f4)
13698                 if (( $frag_lun != $last_lun )); then
13699                         if (( tot_len != 1024 )); then
13700                                 cleanup_130
13701                                 error "FIEMAP on $fm_file failed; returned " \
13702                                 "len $tot_len for OST $last_lun instead of 1024"
13703                                 return
13704                         else
13705                                 (( num_luns += 1 ))
13706                                 tot_len=0
13707                         fi
13708                 fi
13709                 (( tot_len += ext_len ))
13710                 last_lun=$frag_lun
13711         done
13712         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13713                 cleanup_130
13714                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13715                         "luns or wrong len for OST $last_lun"
13716                 return
13717         fi
13718
13719         cleanup_130
13720
13721         echo "FIEMAP on N-stripe file succeeded"
13722 }
13723 run_test 130d "FIEMAP (N-stripe file)"
13724
13725 test_130e() {
13726         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13727
13728         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13729         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13730
13731         trap cleanup_130 EXIT RETURN
13732
13733         local fm_file=$DIR/$tfile
13734         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13735
13736         NUM_BLKS=512
13737         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13738         for ((i = 0; i < $NUM_BLKS; i++)); do
13739                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13740                         conv=notrunc > /dev/null 2>&1
13741         done
13742
13743         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13744         filefrag_op=$(filefrag -ve -k $fm_file |
13745                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13746
13747         last_lun=$(echo $filefrag_op | cut -d: -f5)
13748
13749         IFS=$'\n'
13750         tot_len=0
13751         num_luns=1
13752         for line in $filefrag_op; do
13753                 frag_lun=$(echo $line | cut -d: -f5)
13754                 ext_len=$(echo $line | cut -d: -f4)
13755                 if [[ "$frag_lun" != "$last_lun" ]]; then
13756                         if (( tot_len != $EXPECTED_LEN )); then
13757                                 cleanup_130
13758                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13759                         else
13760                                 (( num_luns += 1 ))
13761                                 tot_len=0
13762                         fi
13763                 fi
13764                 (( tot_len += ext_len ))
13765                 last_lun=$frag_lun
13766         done
13767         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13768                 cleanup_130
13769                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13770         fi
13771
13772         echo "FIEMAP with continuation calls succeeded"
13773 }
13774 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13775
13776 test_130f() {
13777         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13778         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13779
13780         local fm_file=$DIR/$tfile
13781         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13782                 error "multiop create with lov_delay_create on $fm_file"
13783
13784         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13785         filefrag_extents=$(filefrag -vek $fm_file |
13786                            awk '/extents? found/ { print $2 }')
13787         if [[ "$filefrag_extents" != "0" ]]; then
13788                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13789         fi
13790
13791         rm -f $fm_file
13792 }
13793 run_test 130f "FIEMAP (unstriped file)"
13794
13795 test_130g() {
13796         local file=$DIR/$tfile
13797         local nr=$((OSTCOUNT * 100))
13798
13799         $LFS setstripe -C $nr $file ||
13800                 error "failed to setstripe -C $nr $file"
13801
13802         dd if=/dev/zero of=$file count=$nr bs=1M
13803         sync
13804         nr=$($LFS getstripe -c $file)
13805
13806         local extents=$(filefrag -v $file |
13807                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13808
13809         echo "filefrag list $extents extents in file with stripecount $nr"
13810         if (( extents < nr )); then
13811                 $LFS getstripe $file
13812                 filefrag -v $file
13813                 error "filefrag printed $extents < $nr extents"
13814         fi
13815
13816         rm -f $file
13817 }
13818 run_test 130g "FIEMAP (overstripe file)"
13819
13820 # Test for writev/readv
13821 test_131a() {
13822         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13823                 error "writev test failed"
13824         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13825                 error "readv failed"
13826         rm -f $DIR/$tfile
13827 }
13828 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13829
13830 test_131b() {
13831         local fsize=$((524288 + 1048576 + 1572864))
13832         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13833                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13834                         error "append writev test failed"
13835
13836         ((fsize += 1572864 + 1048576))
13837         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13838                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13839                         error "append writev test failed"
13840         rm -f $DIR/$tfile
13841 }
13842 run_test 131b "test append writev"
13843
13844 test_131c() {
13845         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13846         error "NOT PASS"
13847 }
13848 run_test 131c "test read/write on file w/o objects"
13849
13850 test_131d() {
13851         rwv -f $DIR/$tfile -w -n 1 1572864
13852         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13853         if [ "$NOB" != 1572864 ]; then
13854                 error "Short read filed: read $NOB bytes instead of 1572864"
13855         fi
13856         rm -f $DIR/$tfile
13857 }
13858 run_test 131d "test short read"
13859
13860 test_131e() {
13861         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13862         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13863         error "read hitting hole failed"
13864         rm -f $DIR/$tfile
13865 }
13866 run_test 131e "test read hitting hole"
13867
13868 check_stats() {
13869         local facet=$1
13870         local op=$2
13871         local want=${3:-0}
13872         local res
13873
13874         case $facet in
13875         mds*) res=$(do_facet $facet \
13876                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13877                  ;;
13878         ost*) res=$(do_facet $facet \
13879                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13880                  ;;
13881         *) error "Wrong facet '$facet'" ;;
13882         esac
13883         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13884         # if the argument $3 is zero, it means any stat increment is ok.
13885         if [[ $want -gt 0 ]]; then
13886                 local count=$(echo $res | awk '{ print $2 }')
13887                 [[ $count -ne $want ]] &&
13888                         error "The $op counter on $facet is $count, not $want"
13889         fi
13890 }
13891
13892 test_133a() {
13893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13894         remote_ost_nodsh && skip "remote OST with nodsh"
13895         remote_mds_nodsh && skip "remote MDS with nodsh"
13896         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13897                 skip_env "MDS doesn't support rename stats"
13898
13899         local testdir=$DIR/${tdir}/stats_testdir
13900
13901         mkdir -p $DIR/${tdir}
13902
13903         # clear stats.
13904         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13905         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13906
13907         # verify mdt stats first.
13908         mkdir ${testdir} || error "mkdir failed"
13909         check_stats $SINGLEMDS "mkdir" 1
13910         touch ${testdir}/${tfile} || error "touch failed"
13911         check_stats $SINGLEMDS "open" 1
13912         check_stats $SINGLEMDS "close" 1
13913         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13914                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13915                 check_stats $SINGLEMDS "mknod" 2
13916         }
13917         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13918         check_stats $SINGLEMDS "unlink" 1
13919         rm -f ${testdir}/${tfile} || error "file remove failed"
13920         check_stats $SINGLEMDS "unlink" 2
13921
13922         # remove working dir and check mdt stats again.
13923         rmdir ${testdir} || error "rmdir failed"
13924         check_stats $SINGLEMDS "rmdir" 1
13925
13926         local testdir1=$DIR/${tdir}/stats_testdir1
13927         mkdir -p ${testdir}
13928         mkdir -p ${testdir1}
13929         touch ${testdir1}/test1
13930         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13931         check_stats $SINGLEMDS "crossdir_rename" 1
13932
13933         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13934         check_stats $SINGLEMDS "samedir_rename" 1
13935
13936         rm -rf $DIR/${tdir}
13937 }
13938 run_test 133a "Verifying MDT stats ========================================"
13939
13940 test_133b() {
13941         local res
13942
13943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13944         remote_ost_nodsh && skip "remote OST with nodsh"
13945         remote_mds_nodsh && skip "remote MDS with nodsh"
13946
13947         local testdir=$DIR/${tdir}/stats_testdir
13948
13949         mkdir -p ${testdir} || error "mkdir failed"
13950         touch ${testdir}/${tfile} || error "touch failed"
13951         cancel_lru_locks mdc
13952
13953         # clear stats.
13954         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13955         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13956
13957         # extra mdt stats verification.
13958         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13959         check_stats $SINGLEMDS "setattr" 1
13960         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13961         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13962         then            # LU-1740
13963                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13964                 check_stats $SINGLEMDS "getattr" 1
13965         fi
13966         rm -rf $DIR/${tdir}
13967
13968         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13969         # so the check below is not reliable
13970         [ $MDSCOUNT -eq 1 ] || return 0
13971
13972         # Sleep to avoid a cached response.
13973         #define OBD_STATFS_CACHE_SECONDS 1
13974         sleep 2
13975         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13976         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13977         $LFS df || error "lfs failed"
13978         check_stats $SINGLEMDS "statfs" 1
13979
13980         # check aggregated statfs (LU-10018)
13981         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13982                 return 0
13983         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13984                 return 0
13985         sleep 2
13986         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13987         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13988         df $DIR
13989         check_stats $SINGLEMDS "statfs" 1
13990
13991         # We want to check that the client didn't send OST_STATFS to
13992         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13993         # extra care is needed here.
13994         if remote_mds; then
13995                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13996                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13997
13998                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13999                 [ "$res" ] && error "OST got STATFS"
14000         fi
14001
14002         return 0
14003 }
14004 run_test 133b "Verifying extra MDT stats =================================="
14005
14006 test_133c() {
14007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14008         remote_ost_nodsh && skip "remote OST with nodsh"
14009         remote_mds_nodsh && skip "remote MDS with nodsh"
14010
14011         local testdir=$DIR/$tdir/stats_testdir
14012
14013         test_mkdir -p $testdir
14014
14015         # verify obdfilter stats.
14016         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14017         sync
14018         cancel_lru_locks osc
14019         wait_delete_completed
14020
14021         # clear stats.
14022         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14023         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14024
14025         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14026                 error "dd failed"
14027         sync
14028         cancel_lru_locks osc
14029         check_stats ost1 "write" 1
14030
14031         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14032         check_stats ost1 "read" 1
14033
14034         > $testdir/$tfile || error "truncate failed"
14035         check_stats ost1 "punch" 1
14036
14037         rm -f $testdir/$tfile || error "file remove failed"
14038         wait_delete_completed
14039         check_stats ost1 "destroy" 1
14040
14041         rm -rf $DIR/$tdir
14042 }
14043 run_test 133c "Verifying OST stats ========================================"
14044
14045 order_2() {
14046         local value=$1
14047         local orig=$value
14048         local order=1
14049
14050         while [ $value -ge 2 ]; do
14051                 order=$((order*2))
14052                 value=$((value/2))
14053         done
14054
14055         if [ $orig -gt $order ]; then
14056                 order=$((order*2))
14057         fi
14058         echo $order
14059 }
14060
14061 size_in_KMGT() {
14062     local value=$1
14063     local size=('K' 'M' 'G' 'T');
14064     local i=0
14065     local size_string=$value
14066
14067     while [ $value -ge 1024 ]; do
14068         if [ $i -gt 3 ]; then
14069             #T is the biggest unit we get here, if that is bigger,
14070             #just return XXXT
14071             size_string=${value}T
14072             break
14073         fi
14074         value=$((value >> 10))
14075         if [ $value -lt 1024 ]; then
14076             size_string=${value}${size[$i]}
14077             break
14078         fi
14079         i=$((i + 1))
14080     done
14081
14082     echo $size_string
14083 }
14084
14085 get_rename_size() {
14086         local size=$1
14087         local context=${2:-.}
14088         local sample=$(do_facet $SINGLEMDS $LCTL \
14089                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14090                 grep -A1 $context |
14091                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14092         echo $sample
14093 }
14094
14095 test_133d() {
14096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14097         remote_ost_nodsh && skip "remote OST with nodsh"
14098         remote_mds_nodsh && skip "remote MDS with nodsh"
14099         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14100                 skip_env "MDS doesn't support rename stats"
14101
14102         local testdir1=$DIR/${tdir}/stats_testdir1
14103         local testdir2=$DIR/${tdir}/stats_testdir2
14104         mkdir -p $DIR/${tdir}
14105
14106         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14107
14108         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14109         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14110
14111         createmany -o $testdir1/test 512 || error "createmany failed"
14112
14113         # check samedir rename size
14114         mv ${testdir1}/test0 ${testdir1}/test_0
14115
14116         local testdir1_size=$(ls -l $DIR/${tdir} |
14117                 awk '/stats_testdir1/ {print $5}')
14118         local testdir2_size=$(ls -l $DIR/${tdir} |
14119                 awk '/stats_testdir2/ {print $5}')
14120
14121         testdir1_size=$(order_2 $testdir1_size)
14122         testdir2_size=$(order_2 $testdir2_size)
14123
14124         testdir1_size=$(size_in_KMGT $testdir1_size)
14125         testdir2_size=$(size_in_KMGT $testdir2_size)
14126
14127         echo "source rename dir size: ${testdir1_size}"
14128         echo "target rename dir size: ${testdir2_size}"
14129
14130         local cmd="do_facet $SINGLEMDS $LCTL "
14131         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14132
14133         eval $cmd || error "$cmd failed"
14134         local samedir=$($cmd | grep 'same_dir')
14135         local same_sample=$(get_rename_size $testdir1_size)
14136         [ -z "$samedir" ] && error "samedir_rename_size count error"
14137         [[ $same_sample -eq 1 ]] ||
14138                 error "samedir_rename_size error $same_sample"
14139         echo "Check same dir rename stats success"
14140
14141         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14142
14143         # check crossdir rename size
14144         mv ${testdir1}/test_0 ${testdir2}/test_0
14145
14146         testdir1_size=$(ls -l $DIR/${tdir} |
14147                 awk '/stats_testdir1/ {print $5}')
14148         testdir2_size=$(ls -l $DIR/${tdir} |
14149                 awk '/stats_testdir2/ {print $5}')
14150
14151         testdir1_size=$(order_2 $testdir1_size)
14152         testdir2_size=$(order_2 $testdir2_size)
14153
14154         testdir1_size=$(size_in_KMGT $testdir1_size)
14155         testdir2_size=$(size_in_KMGT $testdir2_size)
14156
14157         echo "source rename dir size: ${testdir1_size}"
14158         echo "target rename dir size: ${testdir2_size}"
14159
14160         eval $cmd || error "$cmd failed"
14161         local crossdir=$($cmd | grep 'crossdir')
14162         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14163         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14164         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14165         [[ $src_sample -eq 1 ]] ||
14166                 error "crossdir_rename_size error $src_sample"
14167         [[ $tgt_sample -eq 1 ]] ||
14168                 error "crossdir_rename_size error $tgt_sample"
14169         echo "Check cross dir rename stats success"
14170         rm -rf $DIR/${tdir}
14171 }
14172 run_test 133d "Verifying rename_stats ========================================"
14173
14174 test_133e() {
14175         remote_mds_nodsh && skip "remote MDS with nodsh"
14176         remote_ost_nodsh && skip "remote OST with nodsh"
14177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14178
14179         local testdir=$DIR/${tdir}/stats_testdir
14180         local ctr f0 f1 bs=32768 count=42 sum
14181
14182         mkdir -p ${testdir} || error "mkdir failed"
14183
14184         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14185
14186         for ctr in {write,read}_bytes; do
14187                 sync
14188                 cancel_lru_locks osc
14189
14190                 do_facet ost1 $LCTL set_param -n \
14191                         "obdfilter.*.exports.clear=clear"
14192
14193                 if [ $ctr = write_bytes ]; then
14194                         f0=/dev/zero
14195                         f1=${testdir}/${tfile}
14196                 else
14197                         f0=${testdir}/${tfile}
14198                         f1=/dev/null
14199                 fi
14200
14201                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14202                         error "dd failed"
14203                 sync
14204                 cancel_lru_locks osc
14205
14206                 sum=$(do_facet ost1 $LCTL get_param \
14207                         "obdfilter.*.exports.*.stats" |
14208                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14209                                 $1 == ctr { sum += $7 }
14210                                 END { printf("%0.0f", sum) }')
14211
14212                 if ((sum != bs * count)); then
14213                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14214                 fi
14215         done
14216
14217         rm -rf $DIR/${tdir}
14218 }
14219 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14220
14221 test_133f() {
14222         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14223                 skip "too old lustre for get_param -R ($facet_ver)"
14224
14225         # verifying readability.
14226         $LCTL get_param -R '*' &> /dev/null
14227
14228         # Verifing writability with badarea_io.
14229         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14230         local skipped_params='force_lbug|changelog_mask|daemon_file'
14231         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14232                 egrep -v "$skipped_params" |
14233                 xargs -n 1 find $proc_dirs -name |
14234                 xargs -n 1 badarea_io ||
14235                 error "client badarea_io failed"
14236
14237         # remount the FS in case writes/reads /proc break the FS
14238         cleanup || error "failed to unmount"
14239         setup || error "failed to setup"
14240 }
14241 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14242
14243 test_133g() {
14244         remote_mds_nodsh && skip "remote MDS with nodsh"
14245         remote_ost_nodsh && skip "remote OST with nodsh"
14246
14247         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14248         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14249         local facet
14250         for facet in mds1 ost1; do
14251                 local facet_ver=$(lustre_version_code $facet)
14252                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14253                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14254                 else
14255                         log "$facet: too old lustre for get_param -R"
14256                 fi
14257                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14258                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14259                                 tr -d = | egrep -v $skipped_params |
14260                                 xargs -n 1 find $proc_dirs -name |
14261                                 xargs -n 1 badarea_io" ||
14262                                         error "$facet badarea_io failed"
14263                 else
14264                         skip_noexit "$facet: too old lustre for get_param -R"
14265                 fi
14266         done
14267
14268         # remount the FS in case writes/reads /proc break the FS
14269         cleanup || error "failed to unmount"
14270         setup || error "failed to setup"
14271 }
14272 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14273
14274 test_133h() {
14275         remote_mds_nodsh && skip "remote MDS with nodsh"
14276         remote_ost_nodsh && skip "remote OST with nodsh"
14277         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14278                 skip "Need MDS version at least 2.9.54"
14279
14280         local facet
14281         for facet in client mds1 ost1; do
14282                 # Get the list of files that are missing the terminating newline
14283                 local plist=$(do_facet $facet
14284                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14285                 local ent
14286                 for ent in $plist; do
14287                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14288                                 awk -v FS='\v' -v RS='\v\v' \
14289                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14290                                         print FILENAME}'" 2>/dev/null)
14291                         [ -z $missing ] || {
14292                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14293                                 error "file does not end with newline: $facet-$ent"
14294                         }
14295                 done
14296         done
14297 }
14298 run_test 133h "Proc files should end with newlines"
14299
14300 test_134a() {
14301         remote_mds_nodsh && skip "remote MDS with nodsh"
14302         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14303                 skip "Need MDS version at least 2.7.54"
14304
14305         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14306         cancel_lru_locks mdc
14307
14308         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14309         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14310         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14311
14312         local nr=1000
14313         createmany -o $DIR/$tdir/f $nr ||
14314                 error "failed to create $nr files in $DIR/$tdir"
14315         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14316
14317         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14318         do_facet mds1 $LCTL set_param fail_loc=0x327
14319         do_facet mds1 $LCTL set_param fail_val=500
14320         touch $DIR/$tdir/m
14321
14322         echo "sleep 10 seconds ..."
14323         sleep 10
14324         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14325
14326         do_facet mds1 $LCTL set_param fail_loc=0
14327         do_facet mds1 $LCTL set_param fail_val=0
14328         [ $lck_cnt -lt $unused ] ||
14329                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14330
14331         rm $DIR/$tdir/m
14332         unlinkmany $DIR/$tdir/f $nr
14333 }
14334 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14335
14336 test_134b() {
14337         remote_mds_nodsh && skip "remote MDS with nodsh"
14338         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14339                 skip "Need MDS version at least 2.7.54"
14340
14341         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14342         cancel_lru_locks mdc
14343
14344         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14345                         ldlm.lock_reclaim_threshold_mb)
14346         # disable reclaim temporarily
14347         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14348
14349         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14350         do_facet mds1 $LCTL set_param fail_loc=0x328
14351         do_facet mds1 $LCTL set_param fail_val=500
14352
14353         $LCTL set_param debug=+trace
14354
14355         local nr=600
14356         createmany -o $DIR/$tdir/f $nr &
14357         local create_pid=$!
14358
14359         echo "Sleep $TIMEOUT seconds ..."
14360         sleep $TIMEOUT
14361         if ! ps -p $create_pid  > /dev/null 2>&1; then
14362                 do_facet mds1 $LCTL set_param fail_loc=0
14363                 do_facet mds1 $LCTL set_param fail_val=0
14364                 do_facet mds1 $LCTL set_param \
14365                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14366                 error "createmany finished incorrectly!"
14367         fi
14368         do_facet mds1 $LCTL set_param fail_loc=0
14369         do_facet mds1 $LCTL set_param fail_val=0
14370         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14371         wait $create_pid || return 1
14372
14373         unlinkmany $DIR/$tdir/f $nr
14374 }
14375 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14376
14377 test_135() {
14378         remote_mds_nodsh && skip "remote MDS with nodsh"
14379         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14380                 skip "Need MDS version at least 2.13.50"
14381         local fname
14382
14383         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14384
14385 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14386         #set only one record at plain llog
14387         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14388
14389         #fill already existed plain llog each 64767
14390         #wrapping whole catalog
14391         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14392
14393         createmany -o $DIR/$tdir/$tfile_ 64700
14394         for (( i = 0; i < 64700; i = i + 2 ))
14395         do
14396                 rm $DIR/$tdir/$tfile_$i &
14397                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14398                 local pid=$!
14399                 wait $pid
14400         done
14401
14402         #waiting osp synchronization
14403         wait_delete_completed
14404 }
14405 run_test 135 "Race catalog processing"
14406
14407 test_136() {
14408         remote_mds_nodsh && skip "remote MDS with nodsh"
14409         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14410                 skip "Need MDS version at least 2.13.50"
14411         local fname
14412
14413         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14414         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14415         #set only one record at plain llog
14416 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14417         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14418
14419         #fill already existed 2 plain llogs each 64767
14420         #wrapping whole catalog
14421         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14422         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14423         wait_delete_completed
14424
14425         createmany -o $DIR/$tdir/$tfile_ 10
14426         sleep 25
14427
14428         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14429         for (( i = 0; i < 10; i = i + 3 ))
14430         do
14431                 rm $DIR/$tdir/$tfile_$i &
14432                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14433                 local pid=$!
14434                 wait $pid
14435                 sleep 7
14436                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14437         done
14438
14439         #waiting osp synchronization
14440         wait_delete_completed
14441 }
14442 run_test 136 "Race catalog processing 2"
14443
14444 test_140() { #bug-17379
14445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14446
14447         test_mkdir $DIR/$tdir
14448         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14449         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14450
14451         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14452         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14453         local i=0
14454         while i=$((i + 1)); do
14455                 test_mkdir $i
14456                 cd $i || error "Changing to $i"
14457                 ln -s ../stat stat || error "Creating stat symlink"
14458                 # Read the symlink until ELOOP present,
14459                 # not LBUGing the system is considered success,
14460                 # we didn't overrun the stack.
14461                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14462                 if [ $ret -ne 0 ]; then
14463                         if [ $ret -eq 40 ]; then
14464                                 break  # -ELOOP
14465                         else
14466                                 error "Open stat symlink"
14467                                         return
14468                         fi
14469                 fi
14470         done
14471         i=$((i - 1))
14472         echo "The symlink depth = $i"
14473         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14474                 error "Invalid symlink depth"
14475
14476         # Test recursive symlink
14477         ln -s symlink_self symlink_self
14478         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14479         echo "open symlink_self returns $ret"
14480         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14481 }
14482 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14483
14484 test_150a() {
14485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14486
14487         local TF="$TMP/$tfile"
14488
14489         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14490         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14491         cp $TF $DIR/$tfile
14492         cancel_lru_locks $OSC
14493         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14494         remount_client $MOUNT
14495         df -P $MOUNT
14496         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14497
14498         $TRUNCATE $TF 6000
14499         $TRUNCATE $DIR/$tfile 6000
14500         cancel_lru_locks $OSC
14501         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14502
14503         echo "12345" >>$TF
14504         echo "12345" >>$DIR/$tfile
14505         cancel_lru_locks $OSC
14506         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14507
14508         echo "12345" >>$TF
14509         echo "12345" >>$DIR/$tfile
14510         cancel_lru_locks $OSC
14511         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14512 }
14513 run_test 150a "truncate/append tests"
14514
14515 test_150b() {
14516         check_set_fallocate_or_skip
14517
14518         touch $DIR/$tfile
14519         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14520         check_fallocate $DIR/$tfile || error "fallocate failed"
14521 }
14522 run_test 150b "Verify fallocate (prealloc) functionality"
14523
14524 test_150bb() {
14525         check_set_fallocate_or_skip
14526
14527         touch $DIR/$tfile
14528         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14529         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14530         > $DIR/$tfile
14531         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14532         # precomputed md5sum for 20MB of zeroes
14533         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14534         local sum=($(md5sum $DIR/$tfile))
14535
14536         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14537
14538         check_set_fallocate 1
14539
14540         > $DIR/$tfile
14541         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14542         sum=($(md5sum $DIR/$tfile))
14543
14544         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14545 }
14546 run_test 150bb "Verify fallocate modes both zero space"
14547
14548 test_150c() {
14549         check_set_fallocate_or_skip
14550         local striping="-c2"
14551
14552         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14553         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14554         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14555         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14556         local want=$((OSTCOUNT * 1048576))
14557
14558         # Must allocate all requested space, not more than 5% extra
14559         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14560                 error "bytes $bytes is not $want"
14561
14562         rm -f $DIR/$tfile
14563
14564         echo "verify fallocate on PFL file"
14565
14566         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14567
14568         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14569                 error "Create $DIR/$tfile failed"
14570         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14571                         error "fallocate failed"
14572         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14573         want=$((512 * 1048576))
14574
14575         # Must allocate all requested space, not more than 5% extra
14576         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14577                 error "bytes $bytes is not $want"
14578 }
14579 run_test 150c "Verify fallocate Size and Blocks"
14580
14581 test_150d() {
14582         check_set_fallocate_or_skip
14583         local striping="-c2"
14584
14585         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14586
14587         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14588         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14589                 error "setstripe failed"
14590         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14591         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14592         local want=$((OSTCOUNT * 1048576))
14593
14594         # Must allocate all requested space, not more than 5% extra
14595         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14596                 error "bytes $bytes is not $want"
14597 }
14598 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14599
14600 test_150e() {
14601         check_set_fallocate_or_skip
14602
14603         echo "df before:"
14604         $LFS df
14605         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14606         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14607                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14608
14609         # Find OST with Minimum Size
14610         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14611                        sort -un | head -1)
14612
14613         # Get 100MB per OST of the available space to reduce run time
14614         # else 60% of the available space if we are running SLOW tests
14615         if [ $SLOW == "no" ]; then
14616                 local space=$((1024 * 100 * OSTCOUNT))
14617         else
14618                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14619         fi
14620
14621         fallocate -l${space}k $DIR/$tfile ||
14622                 error "fallocate ${space}k $DIR/$tfile failed"
14623         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14624
14625         # get size immediately after fallocate. This should be correctly
14626         # updated
14627         local size=$(stat -c '%s' $DIR/$tfile)
14628         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14629
14630         # Sleep for a while for statfs to get updated. And not pull from cache.
14631         sleep 2
14632
14633         echo "df after fallocate:"
14634         $LFS df
14635
14636         (( size / 1024 == space )) || error "size $size != requested $space"
14637         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14638                 error "used $used < space $space"
14639
14640         rm $DIR/$tfile || error "rm failed"
14641         sync
14642         wait_delete_completed
14643
14644         echo "df after unlink:"
14645         $LFS df
14646 }
14647 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14648
14649 test_150f() {
14650         local size
14651         local blocks
14652         local want_size_before=20480 # in bytes
14653         local want_blocks_before=40 # 512 sized blocks
14654         local want_blocks_after=24  # 512 sized blocks
14655         local length=$(((want_blocks_before - want_blocks_after) * 512))
14656
14657         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14658                 skip "need at least 2.14.0 for fallocate punch"
14659
14660         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14661                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14662         fi
14663
14664         check_set_fallocate_or_skip
14665         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14666
14667         [[ "x$DOM" == "xyes" ]] &&
14668                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14669
14670         echo "Verify fallocate punch: Range within the file range"
14671         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14672                 error "dd failed for bs 4096 and count 5"
14673
14674         # Call fallocate with punch range which is within the file range
14675         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14676                 error "fallocate failed: offset 4096 and length $length"
14677         # client must see changes immediately after fallocate
14678         size=$(stat -c '%s' $DIR/$tfile)
14679         blocks=$(stat -c '%b' $DIR/$tfile)
14680
14681         # Verify punch worked.
14682         (( blocks == want_blocks_after )) ||
14683                 error "punch failed: blocks $blocks != $want_blocks_after"
14684
14685         (( size == want_size_before )) ||
14686                 error "punch failed: size $size != $want_size_before"
14687
14688         # Verify there is hole in file
14689         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14690         # precomputed md5sum
14691         local expect="4a9a834a2db02452929c0a348273b4aa"
14692
14693         cksum=($(md5sum $DIR/$tfile))
14694         [[ "${cksum[0]}" == "$expect" ]] ||
14695                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14696
14697         # Start second sub-case for fallocate punch.
14698         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14699         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14700                 error "dd failed for bs 4096 and count 5"
14701
14702         # Punch range less than block size will have no change in block count
14703         want_blocks_after=40  # 512 sized blocks
14704
14705         # Punch overlaps two blocks and less than blocksize
14706         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14707                 error "fallocate failed: offset 4000 length 3000"
14708         size=$(stat -c '%s' $DIR/$tfile)
14709         blocks=$(stat -c '%b' $DIR/$tfile)
14710
14711         # Verify punch worked.
14712         (( blocks == want_blocks_after )) ||
14713                 error "punch failed: blocks $blocks != $want_blocks_after"
14714
14715         (( size == want_size_before )) ||
14716                 error "punch failed: size $size != $want_size_before"
14717
14718         # Verify if range is really zero'ed out. We expect Zeros.
14719         # precomputed md5sum
14720         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14721         cksum=($(md5sum $DIR/$tfile))
14722         [[ "${cksum[0]}" == "$expect" ]] ||
14723                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14724 }
14725 run_test 150f "Verify fallocate punch functionality"
14726
14727 test_150g() {
14728         local space
14729         local size
14730         local blocks
14731         local blocks_after
14732         local size_after
14733         local BS=4096 # Block size in bytes
14734
14735         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14736                 skip "need at least 2.14.0 for fallocate punch"
14737
14738         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14739                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14740         fi
14741
14742         check_set_fallocate_or_skip
14743         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14744
14745         if [[ "x$DOM" == "xyes" ]]; then
14746                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14747                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14748         else
14749                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14750                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14751         fi
14752
14753         # Get 100MB per OST of the available space to reduce run time
14754         # else 60% of the available space if we are running SLOW tests
14755         if [ $SLOW == "no" ]; then
14756                 space=$((1024 * 100 * OSTCOUNT))
14757         else
14758                 # Find OST with Minimum Size
14759                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14760                         sort -un | head -1)
14761                 echo "min size OST: $space"
14762                 space=$(((space * 60)/100 * OSTCOUNT))
14763         fi
14764         # space in 1k units, round to 4k blocks
14765         local blkcount=$((space * 1024 / $BS))
14766
14767         echo "Verify fallocate punch: Very large Range"
14768         fallocate -l${space}k $DIR/$tfile ||
14769                 error "fallocate ${space}k $DIR/$tfile failed"
14770         # write 1M at the end, start and in the middle
14771         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14772                 error "dd failed: bs $BS count 256"
14773         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14774                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14775         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14776                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14777
14778         # Gather stats.
14779         size=$(stat -c '%s' $DIR/$tfile)
14780
14781         # gather punch length.
14782         local punch_size=$((size - (BS * 2)))
14783
14784         echo "punch_size = $punch_size"
14785         echo "size - punch_size: $((size - punch_size))"
14786         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14787
14788         # Call fallocate to punch all except 2 blocks. We leave the
14789         # first and the last block
14790         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14791         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14792                 error "fallocate failed: offset $BS length $punch_size"
14793
14794         size_after=$(stat -c '%s' $DIR/$tfile)
14795         blocks_after=$(stat -c '%b' $DIR/$tfile)
14796
14797         # Verify punch worked.
14798         # Size should be kept
14799         (( size == size_after )) ||
14800                 error "punch failed: size $size != $size_after"
14801
14802         # two 4k data blocks to remain plus possible 1 extra extent block
14803         (( blocks_after <= ((BS / 512) * 3) )) ||
14804                 error "too many blocks remains: $blocks_after"
14805
14806         # Verify that file has hole between the first and the last blocks
14807         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14808         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14809
14810         echo "Hole at [$hole_start, $hole_end)"
14811         (( hole_start == BS )) ||
14812                 error "no hole at offset $BS after punch"
14813
14814         (( hole_end == BS + punch_size )) ||
14815                 error "data at offset $hole_end < $((BS + punch_size))"
14816 }
14817 run_test 150g "Verify fallocate punch on large range"
14818
14819 #LU-2902 roc_hit was not able to read all values from lproc
14820 function roc_hit_init() {
14821         local list=$(comma_list $(osts_nodes))
14822         local dir=$DIR/$tdir-check
14823         local file=$dir/$tfile
14824         local BEFORE
14825         local AFTER
14826         local idx
14827
14828         test_mkdir $dir
14829         #use setstripe to do a write to every ost
14830         for i in $(seq 0 $((OSTCOUNT-1))); do
14831                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14832                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14833                 idx=$(printf %04x $i)
14834                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14835                         awk '$1 == "cache_access" {sum += $7}
14836                                 END { printf("%0.0f", sum) }')
14837
14838                 cancel_lru_locks osc
14839                 cat $file >/dev/null
14840
14841                 AFTER=$(get_osd_param $list *OST*$idx stats |
14842                         awk '$1 == "cache_access" {sum += $7}
14843                                 END { printf("%0.0f", sum) }')
14844
14845                 echo BEFORE:$BEFORE AFTER:$AFTER
14846                 if ! let "AFTER - BEFORE == 4"; then
14847                         rm -rf $dir
14848                         error "roc_hit is not safe to use"
14849                 fi
14850                 rm $file
14851         done
14852
14853         rm -rf $dir
14854 }
14855
14856 function roc_hit() {
14857         local list=$(comma_list $(osts_nodes))
14858         echo $(get_osd_param $list '' stats |
14859                 awk '$1 == "cache_hit" {sum += $7}
14860                         END { printf("%0.0f", sum) }')
14861 }
14862
14863 function set_cache() {
14864         local on=1
14865
14866         if [ "$2" == "off" ]; then
14867                 on=0;
14868         fi
14869         local list=$(comma_list $(osts_nodes))
14870         set_osd_param $list '' $1_cache_enable $on
14871
14872         cancel_lru_locks osc
14873 }
14874
14875 test_151() {
14876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14877         remote_ost_nodsh && skip "remote OST with nodsh"
14878
14879         local CPAGES=3
14880         local list=$(comma_list $(osts_nodes))
14881
14882         # check whether obdfilter is cache capable at all
14883         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14884                 skip "not cache-capable obdfilter"
14885         fi
14886
14887         # check cache is enabled on all obdfilters
14888         if get_osd_param $list '' read_cache_enable | grep 0; then
14889                 skip "oss cache is disabled"
14890         fi
14891
14892         set_osd_param $list '' writethrough_cache_enable 1
14893
14894         # check write cache is enabled on all obdfilters
14895         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14896                 skip "oss write cache is NOT enabled"
14897         fi
14898
14899         roc_hit_init
14900
14901         #define OBD_FAIL_OBD_NO_LRU  0x609
14902         do_nodes $list $LCTL set_param fail_loc=0x609
14903
14904         # pages should be in the case right after write
14905         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14906                 error "dd failed"
14907
14908         local BEFORE=$(roc_hit)
14909         cancel_lru_locks osc
14910         cat $DIR/$tfile >/dev/null
14911         local AFTER=$(roc_hit)
14912
14913         do_nodes $list $LCTL set_param fail_loc=0
14914
14915         if ! let "AFTER - BEFORE == CPAGES"; then
14916                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14917         fi
14918
14919         cancel_lru_locks osc
14920         # invalidates OST cache
14921         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14922         set_osd_param $list '' read_cache_enable 0
14923         cat $DIR/$tfile >/dev/null
14924
14925         # now data shouldn't be found in the cache
14926         BEFORE=$(roc_hit)
14927         cancel_lru_locks osc
14928         cat $DIR/$tfile >/dev/null
14929         AFTER=$(roc_hit)
14930         if let "AFTER - BEFORE != 0"; then
14931                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14932         fi
14933
14934         set_osd_param $list '' read_cache_enable 1
14935         rm -f $DIR/$tfile
14936 }
14937 run_test 151 "test cache on oss and controls ==============================="
14938
14939 test_152() {
14940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14941
14942         local TF="$TMP/$tfile"
14943
14944         # simulate ENOMEM during write
14945 #define OBD_FAIL_OST_NOMEM      0x226
14946         lctl set_param fail_loc=0x80000226
14947         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14948         cp $TF $DIR/$tfile
14949         sync || error "sync failed"
14950         lctl set_param fail_loc=0
14951
14952         # discard client's cache
14953         cancel_lru_locks osc
14954
14955         # simulate ENOMEM during read
14956         lctl set_param fail_loc=0x80000226
14957         cmp $TF $DIR/$tfile || error "cmp failed"
14958         lctl set_param fail_loc=0
14959
14960         rm -f $TF
14961 }
14962 run_test 152 "test read/write with enomem ============================"
14963
14964 test_153() {
14965         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14966 }
14967 run_test 153 "test if fdatasync does not crash ======================="
14968
14969 dot_lustre_fid_permission_check() {
14970         local fid=$1
14971         local ffid=$MOUNT/.lustre/fid/$fid
14972         local test_dir=$2
14973
14974         echo "stat fid $fid"
14975         stat $ffid > /dev/null || error "stat $ffid failed."
14976         echo "touch fid $fid"
14977         touch $ffid || error "touch $ffid failed."
14978         echo "write to fid $fid"
14979         cat /etc/hosts > $ffid || error "write $ffid failed."
14980         echo "read fid $fid"
14981         diff /etc/hosts $ffid || error "read $ffid failed."
14982         echo "append write to fid $fid"
14983         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14984         echo "rename fid $fid"
14985         mv $ffid $test_dir/$tfile.1 &&
14986                 error "rename $ffid to $tfile.1 should fail."
14987         touch $test_dir/$tfile.1
14988         mv $test_dir/$tfile.1 $ffid &&
14989                 error "rename $tfile.1 to $ffid should fail."
14990         rm -f $test_dir/$tfile.1
14991         echo "truncate fid $fid"
14992         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14993         echo "link fid $fid"
14994         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14995         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14996                 echo "setfacl fid $fid"
14997                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14998                 echo "getfacl fid $fid"
14999                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15000         fi
15001         echo "unlink fid $fid"
15002         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15003         echo "mknod fid $fid"
15004         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15005
15006         fid=[0xf00000400:0x1:0x0]
15007         ffid=$MOUNT/.lustre/fid/$fid
15008
15009         echo "stat non-exist fid $fid"
15010         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15011         echo "write to non-exist fid $fid"
15012         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15013         echo "link new fid $fid"
15014         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15015
15016         mkdir -p $test_dir/$tdir
15017         touch $test_dir/$tdir/$tfile
15018         fid=$($LFS path2fid $test_dir/$tdir)
15019         rc=$?
15020         [ $rc -ne 0 ] &&
15021                 error "error: could not get fid for $test_dir/$dir/$tfile."
15022
15023         ffid=$MOUNT/.lustre/fid/$fid
15024
15025         echo "ls $fid"
15026         ls $ffid > /dev/null || error "ls $ffid failed."
15027         echo "touch $fid/$tfile.1"
15028         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15029
15030         echo "touch $MOUNT/.lustre/fid/$tfile"
15031         touch $MOUNT/.lustre/fid/$tfile && \
15032                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15033
15034         echo "setxattr to $MOUNT/.lustre/fid"
15035         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15036
15037         echo "listxattr for $MOUNT/.lustre/fid"
15038         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15039
15040         echo "delxattr from $MOUNT/.lustre/fid"
15041         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15042
15043         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15044         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15045                 error "touch invalid fid should fail."
15046
15047         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15048         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15049                 error "touch non-normal fid should fail."
15050
15051         echo "rename $tdir to $MOUNT/.lustre/fid"
15052         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15053                 error "rename to $MOUNT/.lustre/fid should fail."
15054
15055         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15056         then            # LU-3547
15057                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15058                 local new_obf_mode=777
15059
15060                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15061                 chmod $new_obf_mode $DIR/.lustre/fid ||
15062                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15063
15064                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15065                 [ $obf_mode -eq $new_obf_mode ] ||
15066                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15067
15068                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15069                 chmod $old_obf_mode $DIR/.lustre/fid ||
15070                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15071         fi
15072
15073         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15074         fid=$($LFS path2fid $test_dir/$tfile-2)
15075
15076         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15077         then # LU-5424
15078                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15079                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15080                         error "create lov data thru .lustre failed"
15081         fi
15082         echo "cp /etc/passwd $test_dir/$tfile-2"
15083         cp /etc/passwd $test_dir/$tfile-2 ||
15084                 error "copy to $test_dir/$tfile-2 failed."
15085         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15086         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15087                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15088
15089         rm -rf $test_dir/tfile.lnk
15090         rm -rf $test_dir/$tfile-2
15091 }
15092
15093 test_154A() {
15094         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15095                 skip "Need MDS version at least 2.4.1"
15096
15097         local tf=$DIR/$tfile
15098         touch $tf
15099
15100         local fid=$($LFS path2fid $tf)
15101         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15102
15103         # check that we get the same pathname back
15104         local rootpath
15105         local found
15106         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15107                 echo "$rootpath $fid"
15108                 found=$($LFS fid2path $rootpath "$fid")
15109                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15110                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15111         done
15112
15113         # check wrong root path format
15114         rootpath=$MOUNT"_wrong"
15115         found=$($LFS fid2path $rootpath "$fid")
15116         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15117 }
15118 run_test 154A "lfs path2fid and fid2path basic checks"
15119
15120 test_154B() {
15121         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15122                 skip "Need MDS version at least 2.4.1"
15123
15124         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15125         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15126         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15127         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15128
15129         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15130         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15131
15132         # check that we get the same pathname
15133         echo "PFID: $PFID, name: $name"
15134         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15135         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15136         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15137                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15138
15139         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15140 }
15141 run_test 154B "verify the ll_decode_linkea tool"
15142
15143 test_154a() {
15144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15145         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15146         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15147                 skip "Need MDS version at least 2.2.51"
15148         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15149
15150         cp /etc/hosts $DIR/$tfile
15151
15152         fid=$($LFS path2fid $DIR/$tfile)
15153         rc=$?
15154         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15155
15156         dot_lustre_fid_permission_check "$fid" $DIR ||
15157                 error "dot lustre permission check $fid failed"
15158
15159         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15160
15161         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15162
15163         touch $MOUNT/.lustre/file &&
15164                 error "creation is not allowed under .lustre"
15165
15166         mkdir $MOUNT/.lustre/dir &&
15167                 error "mkdir is not allowed under .lustre"
15168
15169         rm -rf $DIR/$tfile
15170 }
15171 run_test 154a "Open-by-FID"
15172
15173 test_154b() {
15174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15175         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15177         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15178                 skip "Need MDS version at least 2.2.51"
15179
15180         local remote_dir=$DIR/$tdir/remote_dir
15181         local MDTIDX=1
15182         local rc=0
15183
15184         mkdir -p $DIR/$tdir
15185         $LFS mkdir -i $MDTIDX $remote_dir ||
15186                 error "create remote directory failed"
15187
15188         cp /etc/hosts $remote_dir/$tfile
15189
15190         fid=$($LFS path2fid $remote_dir/$tfile)
15191         rc=$?
15192         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15193
15194         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15195                 error "dot lustre permission check $fid failed"
15196         rm -rf $DIR/$tdir
15197 }
15198 run_test 154b "Open-by-FID for remote directory"
15199
15200 test_154c() {
15201         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15202                 skip "Need MDS version at least 2.4.1"
15203
15204         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15205         local FID1=$($LFS path2fid $DIR/$tfile.1)
15206         local FID2=$($LFS path2fid $DIR/$tfile.2)
15207         local FID3=$($LFS path2fid $DIR/$tfile.3)
15208
15209         local N=1
15210         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15211                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15212                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15213                 local want=FID$N
15214                 [ "$FID" = "${!want}" ] ||
15215                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15216                 N=$((N + 1))
15217         done
15218
15219         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15220         do
15221                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15222                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15223                 N=$((N + 1))
15224         done
15225 }
15226 run_test 154c "lfs path2fid and fid2path multiple arguments"
15227
15228 test_154d() {
15229         remote_mds_nodsh && skip "remote MDS with nodsh"
15230         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15231                 skip "Need MDS version at least 2.5.53"
15232
15233         if remote_mds; then
15234                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15235         else
15236                 nid="0@lo"
15237         fi
15238         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15239         local fd
15240         local cmd
15241
15242         rm -f $DIR/$tfile
15243         touch $DIR/$tfile
15244
15245         local fid=$($LFS path2fid $DIR/$tfile)
15246         # Open the file
15247         fd=$(free_fd)
15248         cmd="exec $fd<$DIR/$tfile"
15249         eval $cmd
15250         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15251         echo "$fid_list" | grep "$fid"
15252         rc=$?
15253
15254         cmd="exec $fd>/dev/null"
15255         eval $cmd
15256         if [ $rc -ne 0 ]; then
15257                 error "FID $fid not found in open files list $fid_list"
15258         fi
15259 }
15260 run_test 154d "Verify open file fid"
15261
15262 test_154e()
15263 {
15264         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15265                 skip "Need MDS version at least 2.6.50"
15266
15267         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15268                 error ".lustre returned by readdir"
15269         fi
15270 }
15271 run_test 154e ".lustre is not returned by readdir"
15272
15273 test_154f() {
15274         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15275
15276         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15277         mkdir_on_mdt0 $DIR/$tdir
15278         # test dirs inherit from its stripe
15279         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15280         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15281         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15282         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15283         touch $DIR/f
15284
15285         # get fid of parents
15286         local FID0=$($LFS path2fid $DIR/$tdir)
15287         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15288         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15289         local FID3=$($LFS path2fid $DIR)
15290
15291         # check that path2fid --parents returns expected <parent_fid>/name
15292         # 1) test for a directory (single parent)
15293         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15294         [ "$parent" == "$FID0/foo1" ] ||
15295                 error "expected parent: $FID0/foo1, got: $parent"
15296
15297         # 2) test for a file with nlink > 1 (multiple parents)
15298         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15299         echo "$parent" | grep -F "$FID1/$tfile" ||
15300                 error "$FID1/$tfile not returned in parent list"
15301         echo "$parent" | grep -F "$FID2/link" ||
15302                 error "$FID2/link not returned in parent list"
15303
15304         # 3) get parent by fid
15305         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15306         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15307         echo "$parent" | grep -F "$FID1/$tfile" ||
15308                 error "$FID1/$tfile not returned in parent list (by fid)"
15309         echo "$parent" | grep -F "$FID2/link" ||
15310                 error "$FID2/link not returned in parent list (by fid)"
15311
15312         # 4) test for entry in root directory
15313         parent=$($LFS path2fid --parents $DIR/f)
15314         echo "$parent" | grep -F "$FID3/f" ||
15315                 error "$FID3/f not returned in parent list"
15316
15317         # 5) test it on root directory
15318         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15319                 error "$MOUNT should not have parents"
15320
15321         # enable xattr caching and check that linkea is correctly updated
15322         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15323         save_lustre_params client "llite.*.xattr_cache" > $save
15324         lctl set_param llite.*.xattr_cache 1
15325
15326         # 6.1) linkea update on rename
15327         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15328
15329         # get parents by fid
15330         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15331         # foo1 should no longer be returned in parent list
15332         echo "$parent" | grep -F "$FID1" &&
15333                 error "$FID1 should no longer be in parent list"
15334         # the new path should appear
15335         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15336                 error "$FID2/$tfile.moved is not in parent list"
15337
15338         # 6.2) linkea update on unlink
15339         rm -f $DIR/$tdir/foo2/link
15340         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15341         # foo2/link should no longer be returned in parent list
15342         echo "$parent" | grep -F "$FID2/link" &&
15343                 error "$FID2/link should no longer be in parent list"
15344         true
15345
15346         rm -f $DIR/f
15347         restore_lustre_params < $save
15348         rm -f $save
15349 }
15350 run_test 154f "get parent fids by reading link ea"
15351
15352 test_154g()
15353 {
15354         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15355         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15356            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15357                 skip "Need MDS version at least 2.6.92"
15358
15359         mkdir_on_mdt0 $DIR/$tdir
15360         llapi_fid_test -d $DIR/$tdir
15361 }
15362 run_test 154g "various llapi FID tests"
15363
15364 test_155_small_load() {
15365     local temp=$TMP/$tfile
15366     local file=$DIR/$tfile
15367
15368     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15369         error "dd of=$temp bs=6096 count=1 failed"
15370     cp $temp $file
15371     cancel_lru_locks $OSC
15372     cmp $temp $file || error "$temp $file differ"
15373
15374     $TRUNCATE $temp 6000
15375     $TRUNCATE $file 6000
15376     cmp $temp $file || error "$temp $file differ (truncate1)"
15377
15378     echo "12345" >>$temp
15379     echo "12345" >>$file
15380     cmp $temp $file || error "$temp $file differ (append1)"
15381
15382     echo "12345" >>$temp
15383     echo "12345" >>$file
15384     cmp $temp $file || error "$temp $file differ (append2)"
15385
15386     rm -f $temp $file
15387     true
15388 }
15389
15390 test_155_big_load() {
15391         remote_ost_nodsh && skip "remote OST with nodsh"
15392
15393         local temp=$TMP/$tfile
15394         local file=$DIR/$tfile
15395
15396         free_min_max
15397         local cache_size=$(do_facet ost$((MAXI+1)) \
15398                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15399         local large_file_size=$((cache_size * 2))
15400
15401         echo "OSS cache size: $cache_size KB"
15402         echo "Large file size: $large_file_size KB"
15403
15404         [ $MAXV -le $large_file_size ] &&
15405                 skip_env "max available OST size needs > $large_file_size KB"
15406
15407         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15408
15409         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15410                 error "dd of=$temp bs=$large_file_size count=1k failed"
15411         cp $temp $file
15412         ls -lh $temp $file
15413         cancel_lru_locks osc
15414         cmp $temp $file || error "$temp $file differ"
15415
15416         rm -f $temp $file
15417         true
15418 }
15419
15420 save_writethrough() {
15421         local facets=$(get_facets OST)
15422
15423         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15424 }
15425
15426 test_155a() {
15427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15428
15429         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15430
15431         save_writethrough $p
15432
15433         set_cache read on
15434         set_cache writethrough on
15435         test_155_small_load
15436         restore_lustre_params < $p
15437         rm -f $p
15438 }
15439 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15440
15441 test_155b() {
15442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15443
15444         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15445
15446         save_writethrough $p
15447
15448         set_cache read on
15449         set_cache writethrough off
15450         test_155_small_load
15451         restore_lustre_params < $p
15452         rm -f $p
15453 }
15454 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15455
15456 test_155c() {
15457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15458
15459         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15460
15461         save_writethrough $p
15462
15463         set_cache read off
15464         set_cache writethrough on
15465         test_155_small_load
15466         restore_lustre_params < $p
15467         rm -f $p
15468 }
15469 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15470
15471 test_155d() {
15472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15473
15474         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15475
15476         save_writethrough $p
15477
15478         set_cache read off
15479         set_cache writethrough off
15480         test_155_small_load
15481         restore_lustre_params < $p
15482         rm -f $p
15483 }
15484 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15485
15486 test_155e() {
15487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15488
15489         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15490
15491         save_writethrough $p
15492
15493         set_cache read on
15494         set_cache writethrough on
15495         test_155_big_load
15496         restore_lustre_params < $p
15497         rm -f $p
15498 }
15499 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15500
15501 test_155f() {
15502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15503
15504         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15505
15506         save_writethrough $p
15507
15508         set_cache read on
15509         set_cache writethrough off
15510         test_155_big_load
15511         restore_lustre_params < $p
15512         rm -f $p
15513 }
15514 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15515
15516 test_155g() {
15517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15518
15519         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15520
15521         save_writethrough $p
15522
15523         set_cache read off
15524         set_cache writethrough on
15525         test_155_big_load
15526         restore_lustre_params < $p
15527         rm -f $p
15528 }
15529 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15530
15531 test_155h() {
15532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15533
15534         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15535
15536         save_writethrough $p
15537
15538         set_cache read off
15539         set_cache writethrough off
15540         test_155_big_load
15541         restore_lustre_params < $p
15542         rm -f $p
15543 }
15544 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15545
15546 test_156() {
15547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15548         remote_ost_nodsh && skip "remote OST with nodsh"
15549         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15550                 skip "stats not implemented on old servers"
15551         [ "$ost1_FSTYPE" = "zfs" ] &&
15552                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15553
15554         local CPAGES=3
15555         local BEFORE
15556         local AFTER
15557         local file="$DIR/$tfile"
15558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15559
15560         save_writethrough $p
15561         roc_hit_init
15562
15563         log "Turn on read and write cache"
15564         set_cache read on
15565         set_cache writethrough on
15566
15567         log "Write data and read it back."
15568         log "Read should be satisfied from the cache."
15569         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15570         BEFORE=$(roc_hit)
15571         cancel_lru_locks osc
15572         cat $file >/dev/null
15573         AFTER=$(roc_hit)
15574         if ! let "AFTER - BEFORE == CPAGES"; then
15575                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15576         else
15577                 log "cache hits: before: $BEFORE, after: $AFTER"
15578         fi
15579
15580         log "Read again; it should be satisfied from the cache."
15581         BEFORE=$AFTER
15582         cancel_lru_locks osc
15583         cat $file >/dev/null
15584         AFTER=$(roc_hit)
15585         if ! let "AFTER - BEFORE == CPAGES"; then
15586                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15587         else
15588                 log "cache hits:: before: $BEFORE, after: $AFTER"
15589         fi
15590
15591         log "Turn off the read cache and turn on the write cache"
15592         set_cache read off
15593         set_cache writethrough on
15594
15595         log "Read again; it should be satisfied from the cache."
15596         BEFORE=$(roc_hit)
15597         cancel_lru_locks osc
15598         cat $file >/dev/null
15599         AFTER=$(roc_hit)
15600         if ! let "AFTER - BEFORE == CPAGES"; then
15601                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15602         else
15603                 log "cache hits:: before: $BEFORE, after: $AFTER"
15604         fi
15605
15606         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15607                 # > 2.12.56 uses pagecache if cached
15608                 log "Read again; it should not be satisfied from the cache."
15609                 BEFORE=$AFTER
15610                 cancel_lru_locks osc
15611                 cat $file >/dev/null
15612                 AFTER=$(roc_hit)
15613                 if ! let "AFTER - BEFORE == 0"; then
15614                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15615                 else
15616                         log "cache hits:: before: $BEFORE, after: $AFTER"
15617                 fi
15618         fi
15619
15620         log "Write data and read it back."
15621         log "Read should be satisfied from the cache."
15622         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15623         BEFORE=$(roc_hit)
15624         cancel_lru_locks osc
15625         cat $file >/dev/null
15626         AFTER=$(roc_hit)
15627         if ! let "AFTER - BEFORE == CPAGES"; then
15628                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15629         else
15630                 log "cache hits:: before: $BEFORE, after: $AFTER"
15631         fi
15632
15633         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15634                 # > 2.12.56 uses pagecache if cached
15635                 log "Read again; it should not be satisfied from the cache."
15636                 BEFORE=$AFTER
15637                 cancel_lru_locks osc
15638                 cat $file >/dev/null
15639                 AFTER=$(roc_hit)
15640                 if ! let "AFTER - BEFORE == 0"; then
15641                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15642                 else
15643                         log "cache hits:: before: $BEFORE, after: $AFTER"
15644                 fi
15645         fi
15646
15647         log "Turn off read and write cache"
15648         set_cache read off
15649         set_cache writethrough off
15650
15651         log "Write data and read it back"
15652         log "It should not be satisfied from the cache."
15653         rm -f $file
15654         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15655         cancel_lru_locks osc
15656         BEFORE=$(roc_hit)
15657         cat $file >/dev/null
15658         AFTER=$(roc_hit)
15659         if ! let "AFTER - BEFORE == 0"; then
15660                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15661         else
15662                 log "cache hits:: before: $BEFORE, after: $AFTER"
15663         fi
15664
15665         log "Turn on the read cache and turn off the write cache"
15666         set_cache read on
15667         set_cache writethrough off
15668
15669         log "Write data and read it back"
15670         log "It should not be satisfied from the cache."
15671         rm -f $file
15672         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15673         BEFORE=$(roc_hit)
15674         cancel_lru_locks osc
15675         cat $file >/dev/null
15676         AFTER=$(roc_hit)
15677         if ! let "AFTER - BEFORE == 0"; then
15678                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15679         else
15680                 log "cache hits:: before: $BEFORE, after: $AFTER"
15681         fi
15682
15683         log "Read again; it should be satisfied from the cache."
15684         BEFORE=$(roc_hit)
15685         cancel_lru_locks osc
15686         cat $file >/dev/null
15687         AFTER=$(roc_hit)
15688         if ! let "AFTER - BEFORE == CPAGES"; then
15689                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15690         else
15691                 log "cache hits:: before: $BEFORE, after: $AFTER"
15692         fi
15693
15694         restore_lustre_params < $p
15695         rm -f $p $file
15696 }
15697 run_test 156 "Verification of tunables"
15698
15699 test_160a() {
15700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15701         remote_mds_nodsh && skip "remote MDS with nodsh"
15702         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15703                 skip "Need MDS version at least 2.2.0"
15704
15705         changelog_register || error "changelog_register failed"
15706         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15707         changelog_users $SINGLEMDS | grep -q $cl_user ||
15708                 error "User $cl_user not found in changelog_users"
15709
15710         mkdir_on_mdt0 $DIR/$tdir
15711
15712         # change something
15713         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15714         changelog_clear 0 || error "changelog_clear failed"
15715         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15716         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15717         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15718         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15719         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15720         rm $DIR/$tdir/pics/desktop.jpg
15721
15722         echo "verifying changelog mask"
15723         changelog_chmask "-MKDIR"
15724         changelog_chmask "-CLOSE"
15725
15726         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15727         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15728
15729         changelog_chmask "+MKDIR"
15730         changelog_chmask "+CLOSE"
15731
15732         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15733         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15734
15735         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15736         CLOSES=$(changelog_dump | grep -c "CLOSE")
15737         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15738         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15739
15740         # verify contents
15741         echo "verifying target fid"
15742         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15743         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15744         [ "$fidc" == "$fidf" ] ||
15745                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15746         echo "verifying parent fid"
15747         # The FID returned from the Changelog may be the directory shard on
15748         # a different MDT, and not the FID returned by path2fid on the parent.
15749         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15750         # since this is what will matter when recreating this file in the tree.
15751         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15752         local pathp=$($LFS fid2path $MOUNT "$fidp")
15753         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15754                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15755
15756         echo "getting records for $cl_user"
15757         changelog_users $SINGLEMDS
15758         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15759         local nclr=3
15760         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15761                 error "changelog_clear failed"
15762         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15763         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15764         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15765                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15766
15767         local min0_rec=$(changelog_users $SINGLEMDS |
15768                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15769         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15770                           awk '{ print $1; exit; }')
15771
15772         changelog_dump | tail -n 5
15773         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15774         [ $first_rec == $((min0_rec + 1)) ] ||
15775                 error "first index should be $min0_rec + 1 not $first_rec"
15776
15777         # LU-3446 changelog index reset on MDT restart
15778         local cur_rec1=$(changelog_users $SINGLEMDS |
15779                          awk '/^current.index:/ { print $NF }')
15780         changelog_clear 0 ||
15781                 error "clear all changelog records for $cl_user failed"
15782         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15783         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15784                 error "Fail to start $SINGLEMDS"
15785         local cur_rec2=$(changelog_users $SINGLEMDS |
15786                          awk '/^current.index:/ { print $NF }')
15787         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15788         [ $cur_rec1 == $cur_rec2 ] ||
15789                 error "current index should be $cur_rec1 not $cur_rec2"
15790
15791         echo "verifying users from this test are deregistered"
15792         changelog_deregister || error "changelog_deregister failed"
15793         changelog_users $SINGLEMDS | grep -q $cl_user &&
15794                 error "User '$cl_user' still in changelog_users"
15795
15796         # lctl get_param -n mdd.*.changelog_users
15797         # current_index: 144
15798         # ID    index (idle seconds)
15799         # cl3   144   (2) mask=<list>
15800         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15801                 # this is the normal case where all users were deregistered
15802                 # make sure no new records are added when no users are present
15803                 local last_rec1=$(changelog_users $SINGLEMDS |
15804                                   awk '/^current.index:/ { print $NF }')
15805                 touch $DIR/$tdir/chloe
15806                 local last_rec2=$(changelog_users $SINGLEMDS |
15807                                   awk '/^current.index:/ { print $NF }')
15808                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15809                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15810         else
15811                 # any changelog users must be leftovers from a previous test
15812                 changelog_users $SINGLEMDS
15813                 echo "other changelog users; can't verify off"
15814         fi
15815 }
15816 run_test 160a "changelog sanity"
15817
15818 test_160b() { # LU-3587
15819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15820         remote_mds_nodsh && skip "remote MDS with nodsh"
15821         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15822                 skip "Need MDS version at least 2.2.0"
15823
15824         changelog_register || error "changelog_register failed"
15825         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15826         changelog_users $SINGLEMDS | grep -q $cl_user ||
15827                 error "User '$cl_user' not found in changelog_users"
15828
15829         local longname1=$(str_repeat a 255)
15830         local longname2=$(str_repeat b 255)
15831
15832         cd $DIR
15833         echo "creating very long named file"
15834         touch $longname1 || error "create of '$longname1' failed"
15835         echo "renaming very long named file"
15836         mv $longname1 $longname2
15837
15838         changelog_dump | grep RENME | tail -n 5
15839         rm -f $longname2
15840 }
15841 run_test 160b "Verify that very long rename doesn't crash in changelog"
15842
15843 test_160c() {
15844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15845         remote_mds_nodsh && skip "remote MDS with nodsh"
15846
15847         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15848                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15849                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15850                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15851
15852         local rc=0
15853
15854         # Registration step
15855         changelog_register || error "changelog_register failed"
15856
15857         rm -rf $DIR/$tdir
15858         mkdir -p $DIR/$tdir
15859         $MCREATE $DIR/$tdir/foo_160c
15860         changelog_chmask "-TRUNC"
15861         $TRUNCATE $DIR/$tdir/foo_160c 200
15862         changelog_chmask "+TRUNC"
15863         $TRUNCATE $DIR/$tdir/foo_160c 199
15864         changelog_dump | tail -n 5
15865         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15866         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15867 }
15868 run_test 160c "verify that changelog log catch the truncate event"
15869
15870 test_160d() {
15871         remote_mds_nodsh && skip "remote MDS with nodsh"
15872         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15874         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15875                 skip "Need MDS version at least 2.7.60"
15876
15877         # Registration step
15878         changelog_register || error "changelog_register failed"
15879
15880         mkdir -p $DIR/$tdir/migrate_dir
15881         changelog_clear 0 || error "changelog_clear failed"
15882
15883         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15884         changelog_dump | tail -n 5
15885         local migrates=$(changelog_dump | grep -c "MIGRT")
15886         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15887 }
15888 run_test 160d "verify that changelog log catch the migrate event"
15889
15890 test_160e() {
15891         remote_mds_nodsh && skip "remote MDS with nodsh"
15892
15893         # Create a user
15894         changelog_register || error "changelog_register failed"
15895
15896         local MDT0=$(facet_svc $SINGLEMDS)
15897         local rc
15898
15899         # No user (expect fail)
15900         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15901         rc=$?
15902         if [ $rc -eq 0 ]; then
15903                 error "Should fail without user"
15904         elif [ $rc -ne 4 ]; then
15905                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15906         fi
15907
15908         # Delete a future user (expect fail)
15909         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15910         rc=$?
15911         if [ $rc -eq 0 ]; then
15912                 error "Deleted non-existant user cl77"
15913         elif [ $rc -ne 2 ]; then
15914                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15915         fi
15916
15917         # Clear to a bad index (1 billion should be safe)
15918         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15919         rc=$?
15920
15921         if [ $rc -eq 0 ]; then
15922                 error "Successfully cleared to invalid CL index"
15923         elif [ $rc -ne 22 ]; then
15924                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15925         fi
15926 }
15927 run_test 160e "changelog negative testing (should return errors)"
15928
15929 test_160f() {
15930         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15931         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15932                 skip "Need MDS version at least 2.10.56"
15933
15934         local mdts=$(comma_list $(mdts_nodes))
15935
15936         # Create a user
15937         changelog_register || error "first changelog_register failed"
15938         changelog_register || error "second changelog_register failed"
15939         local cl_users
15940         declare -A cl_user1
15941         declare -A cl_user2
15942         local user_rec1
15943         local user_rec2
15944         local i
15945
15946         # generate some changelog records to accumulate on each MDT
15947         # use all_char because created files should be evenly distributed
15948         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15949                 error "test_mkdir $tdir failed"
15950         log "$(date +%s): creating first files"
15951         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15952                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15953                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15954         done
15955
15956         # check changelogs have been generated
15957         local start=$SECONDS
15958         local idle_time=$((MDSCOUNT * 5 + 5))
15959         local nbcl=$(changelog_dump | wc -l)
15960         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15961
15962         for param in "changelog_max_idle_time=$idle_time" \
15963                      "changelog_gc=1" \
15964                      "changelog_min_gc_interval=2" \
15965                      "changelog_min_free_cat_entries=3"; do
15966                 local MDT0=$(facet_svc $SINGLEMDS)
15967                 local var="${param%=*}"
15968                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15969
15970                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15971                 do_nodes $mdts $LCTL set_param mdd.*.$param
15972         done
15973
15974         # force cl_user2 to be idle (1st part), but also cancel the
15975         # cl_user1 records so that it is not evicted later in the test.
15976         local sleep1=$((idle_time / 2))
15977         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15978         sleep $sleep1
15979
15980         # simulate changelog catalog almost full
15981         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15982         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15983
15984         for i in $(seq $MDSCOUNT); do
15985                 cl_users=(${CL_USERS[mds$i]})
15986                 cl_user1[mds$i]="${cl_users[0]}"
15987                 cl_user2[mds$i]="${cl_users[1]}"
15988
15989                 [ -n "${cl_user1[mds$i]}" ] ||
15990                         error "mds$i: no user registered"
15991                 [ -n "${cl_user2[mds$i]}" ] ||
15992                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15993
15994                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15995                 [ -n "$user_rec1" ] ||
15996                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15997                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15998                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15999                 [ -n "$user_rec2" ] ||
16000                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16001                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16002                      "$user_rec1 + 2 == $user_rec2"
16003                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16004                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16005                               "$user_rec1 + 2, but is $user_rec2"
16006                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16007                 [ -n "$user_rec2" ] ||
16008                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16009                 [ $user_rec1 == $user_rec2 ] ||
16010                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16011                               "$user_rec1, but is $user_rec2"
16012         done
16013
16014         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16015         local sleep2=$((idle_time - (SECONDS - start) + 1))
16016         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16017         sleep $sleep2
16018
16019         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16020         # cl_user1 should be OK because it recently processed records.
16021         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16022         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16023                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16024                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16025         done
16026
16027         # ensure gc thread is done
16028         for i in $(mdts_nodes); do
16029                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16030                         error "$i: GC-thread not done"
16031         done
16032
16033         local first_rec
16034         for (( i = 1; i <= MDSCOUNT; i++ )); do
16035                 # check cl_user1 still registered
16036                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16037                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16038                 # check cl_user2 unregistered
16039                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16040                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16041
16042                 # check changelogs are present and starting at $user_rec1 + 1
16043                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16044                 [ -n "$user_rec1" ] ||
16045                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16046                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16047                             awk '{ print $1; exit; }')
16048
16049                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16050                 [ $((user_rec1 + 1)) == $first_rec ] ||
16051                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16052         done
16053 }
16054 run_test 160f "changelog garbage collect (timestamped users)"
16055
16056 test_160g() {
16057         remote_mds_nodsh && skip "remote MDS with nodsh"
16058         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16059                 skip "Need MDS version at least 2.14.55"
16060
16061         local mdts=$(comma_list $(mdts_nodes))
16062
16063         # Create a user
16064         changelog_register || error "first changelog_register failed"
16065         changelog_register || error "second changelog_register failed"
16066         local cl_users
16067         declare -A cl_user1
16068         declare -A cl_user2
16069         local user_rec1
16070         local user_rec2
16071         local i
16072
16073         # generate some changelog records to accumulate on each MDT
16074         # use all_char because created files should be evenly distributed
16075         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16076                 error "test_mkdir $tdir failed"
16077         for ((i = 0; i < MDSCOUNT; i++)); do
16078                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16079                         error "create $DIR/$tdir/d$i.1 failed"
16080         done
16081
16082         # check changelogs have been generated
16083         local nbcl=$(changelog_dump | wc -l)
16084         (( $nbcl > 0 )) || error "no changelogs found"
16085
16086         # reduce the max_idle_indexes value to make sure we exceed it
16087         for param in "changelog_max_idle_indexes=2" \
16088                      "changelog_gc=1" \
16089                      "changelog_min_gc_interval=2"; do
16090                 local MDT0=$(facet_svc $SINGLEMDS)
16091                 local var="${param%=*}"
16092                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16093
16094                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16095                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16096                         error "unable to set mdd.*.$param"
16097         done
16098
16099         local start=$SECONDS
16100         for i in $(seq $MDSCOUNT); do
16101                 cl_users=(${CL_USERS[mds$i]})
16102                 cl_user1[mds$i]="${cl_users[0]}"
16103                 cl_user2[mds$i]="${cl_users[1]}"
16104
16105                 [ -n "${cl_user1[mds$i]}" ] ||
16106                         error "mds$i: user1 is not registered"
16107                 [ -n "${cl_user2[mds$i]}" ] ||
16108                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16109
16110                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16111                 [ -n "$user_rec1" ] ||
16112                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16113                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16114                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16115                 [ -n "$user_rec2" ] ||
16116                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16117                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16118                      "$user_rec1 + 2 == $user_rec2"
16119                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16120                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16121                               "expected $user_rec1 + 2, but is $user_rec2"
16122                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16123                 [ -n "$user_rec2" ] ||
16124                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16125                 [ $user_rec1 == $user_rec2 ] ||
16126                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16127                               "expected $user_rec1, but is $user_rec2"
16128         done
16129
16130         # ensure we are past the previous changelog_min_gc_interval set above
16131         local sleep2=$((start + 2 - SECONDS))
16132         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16133         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16134         # cl_user1 should be OK because it recently processed records.
16135         for ((i = 0; i < MDSCOUNT; i++)); do
16136                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16137                         error "create $DIR/$tdir/d$i.3 failed"
16138         done
16139
16140         # ensure gc thread is done
16141         for i in $(mdts_nodes); do
16142                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16143                         error "$i: GC-thread not done"
16144         done
16145
16146         local first_rec
16147         for (( i = 1; i <= MDSCOUNT; i++ )); do
16148                 # check cl_user1 still registered
16149                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16150                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16151                 # check cl_user2 unregistered
16152                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16153                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16154
16155                 # check changelogs are present and starting at $user_rec1 + 1
16156                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16157                 [ -n "$user_rec1" ] ||
16158                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16159                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16160                             awk '{ print $1; exit; }')
16161
16162                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16163                 [ $((user_rec1 + 1)) == $first_rec ] ||
16164                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16165         done
16166 }
16167 run_test 160g "changelog garbage collect on idle records"
16168
16169 test_160h() {
16170         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16171         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16172                 skip "Need MDS version at least 2.10.56"
16173
16174         local mdts=$(comma_list $(mdts_nodes))
16175
16176         # Create a user
16177         changelog_register || error "first changelog_register failed"
16178         changelog_register || error "second changelog_register failed"
16179         local cl_users
16180         declare -A cl_user1
16181         declare -A cl_user2
16182         local user_rec1
16183         local user_rec2
16184         local i
16185
16186         # generate some changelog records to accumulate on each MDT
16187         # use all_char because created files should be evenly distributed
16188         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16189                 error "test_mkdir $tdir failed"
16190         for ((i = 0; i < MDSCOUNT; i++)); do
16191                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16192                         error "create $DIR/$tdir/d$i.1 failed"
16193         done
16194
16195         # check changelogs have been generated
16196         local nbcl=$(changelog_dump | wc -l)
16197         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16198
16199         for param in "changelog_max_idle_time=10" \
16200                      "changelog_gc=1" \
16201                      "changelog_min_gc_interval=2"; do
16202                 local MDT0=$(facet_svc $SINGLEMDS)
16203                 local var="${param%=*}"
16204                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16205
16206                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16207                 do_nodes $mdts $LCTL set_param mdd.*.$param
16208         done
16209
16210         # force cl_user2 to be idle (1st part)
16211         sleep 9
16212
16213         for i in $(seq $MDSCOUNT); do
16214                 cl_users=(${CL_USERS[mds$i]})
16215                 cl_user1[mds$i]="${cl_users[0]}"
16216                 cl_user2[mds$i]="${cl_users[1]}"
16217
16218                 [ -n "${cl_user1[mds$i]}" ] ||
16219                         error "mds$i: no user registered"
16220                 [ -n "${cl_user2[mds$i]}" ] ||
16221                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16222
16223                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16224                 [ -n "$user_rec1" ] ||
16225                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16226                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16227                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16228                 [ -n "$user_rec2" ] ||
16229                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16230                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16231                      "$user_rec1 + 2 == $user_rec2"
16232                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16233                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16234                               "$user_rec1 + 2, but is $user_rec2"
16235                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16236                 [ -n "$user_rec2" ] ||
16237                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16238                 [ $user_rec1 == $user_rec2 ] ||
16239                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16240                               "$user_rec1, but is $user_rec2"
16241         done
16242
16243         # force cl_user2 to be idle (2nd part) and to reach
16244         # changelog_max_idle_time
16245         sleep 2
16246
16247         # force each GC-thread start and block then
16248         # one per MDT/MDD, set fail_val accordingly
16249         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16250         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16251
16252         # generate more changelogs to trigger fail_loc
16253         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16254                 error "create $DIR/$tdir/${tfile}bis failed"
16255
16256         # stop MDT to stop GC-thread, should be done in back-ground as it will
16257         # block waiting for the thread to be released and exit
16258         declare -A stop_pids
16259         for i in $(seq $MDSCOUNT); do
16260                 stop mds$i &
16261                 stop_pids[mds$i]=$!
16262         done
16263
16264         for i in $(mdts_nodes); do
16265                 local facet
16266                 local nb=0
16267                 local facets=$(facets_up_on_host $i)
16268
16269                 for facet in ${facets//,/ }; do
16270                         if [[ $facet == mds* ]]; then
16271                                 nb=$((nb + 1))
16272                         fi
16273                 done
16274                 # ensure each MDS's gc threads are still present and all in "R"
16275                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16276                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16277                         error "$i: expected $nb GC-thread"
16278                 wait_update $i \
16279                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16280                         "R" 20 ||
16281                         error "$i: GC-thread not found in R-state"
16282                 # check umounts of each MDT on MDS have reached kthread_stop()
16283                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16284                         error "$i: expected $nb umount"
16285                 wait_update $i \
16286                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16287                         error "$i: umount not found in D-state"
16288         done
16289
16290         # release all GC-threads
16291         do_nodes $mdts $LCTL set_param fail_loc=0
16292
16293         # wait for MDT stop to complete
16294         for i in $(seq $MDSCOUNT); do
16295                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16296         done
16297
16298         # XXX
16299         # may try to check if any orphan changelog records are present
16300         # via ldiskfs/zfs and llog_reader...
16301
16302         # re-start/mount MDTs
16303         for i in $(seq $MDSCOUNT); do
16304                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16305                         error "Fail to start mds$i"
16306         done
16307
16308         local first_rec
16309         for i in $(seq $MDSCOUNT); do
16310                 # check cl_user1 still registered
16311                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16312                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16313                 # check cl_user2 unregistered
16314                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16315                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16316
16317                 # check changelogs are present and starting at $user_rec1 + 1
16318                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16319                 [ -n "$user_rec1" ] ||
16320                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16321                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16322                             awk '{ print $1; exit; }')
16323
16324                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16325                 [ $((user_rec1 + 1)) == $first_rec ] ||
16326                         error "mds$i: first index should be $user_rec1 + 1, " \
16327                               "but is $first_rec"
16328         done
16329 }
16330 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16331               "during mount"
16332
16333 test_160i() {
16334
16335         local mdts=$(comma_list $(mdts_nodes))
16336
16337         changelog_register || error "first changelog_register failed"
16338
16339         # generate some changelog records to accumulate on each MDT
16340         # use all_char because created files should be evenly distributed
16341         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16342                 error "test_mkdir $tdir failed"
16343         for ((i = 0; i < MDSCOUNT; i++)); do
16344                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16345                         error "create $DIR/$tdir/d$i.1 failed"
16346         done
16347
16348         # check changelogs have been generated
16349         local nbcl=$(changelog_dump | wc -l)
16350         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16351
16352         # simulate race between register and unregister
16353         # XXX as fail_loc is set per-MDS, with DNE configs the race
16354         # simulation will only occur for one MDT per MDS and for the
16355         # others the normal race scenario will take place
16356         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16357         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16358         do_nodes $mdts $LCTL set_param fail_val=1
16359
16360         # unregister 1st user
16361         changelog_deregister &
16362         local pid1=$!
16363         # wait some time for deregister work to reach race rdv
16364         sleep 2
16365         # register 2nd user
16366         changelog_register || error "2nd user register failed"
16367
16368         wait $pid1 || error "1st user deregister failed"
16369
16370         local i
16371         local last_rec
16372         declare -A LAST_REC
16373         for i in $(seq $MDSCOUNT); do
16374                 if changelog_users mds$i | grep "^cl"; then
16375                         # make sure new records are added with one user present
16376                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16377                                           awk '/^current.index:/ { print $NF }')
16378                 else
16379                         error "mds$i has no user registered"
16380                 fi
16381         done
16382
16383         # generate more changelog records to accumulate on each MDT
16384         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16385                 error "create $DIR/$tdir/${tfile}bis failed"
16386
16387         for i in $(seq $MDSCOUNT); do
16388                 last_rec=$(changelog_users $SINGLEMDS |
16389                            awk '/^current.index:/ { print $NF }')
16390                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16391                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16392                         error "changelogs are off on mds$i"
16393         done
16394 }
16395 run_test 160i "changelog user register/unregister race"
16396
16397 test_160j() {
16398         remote_mds_nodsh && skip "remote MDS with nodsh"
16399         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16400                 skip "Need MDS version at least 2.12.56"
16401
16402         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16403         stack_trap "umount $MOUNT2" EXIT
16404
16405         changelog_register || error "first changelog_register failed"
16406         stack_trap "changelog_deregister" EXIT
16407
16408         # generate some changelog
16409         # use all_char because created files should be evenly distributed
16410         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16411                 error "mkdir $tdir failed"
16412         for ((i = 0; i < MDSCOUNT; i++)); do
16413                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16414                         error "create $DIR/$tdir/d$i.1 failed"
16415         done
16416
16417         # open the changelog device
16418         exec 3>/dev/changelog-$FSNAME-MDT0000
16419         stack_trap "exec 3>&-" EXIT
16420         exec 4</dev/changelog-$FSNAME-MDT0000
16421         stack_trap "exec 4<&-" EXIT
16422
16423         # umount the first lustre mount
16424         umount $MOUNT
16425         stack_trap "mount_client $MOUNT" EXIT
16426
16427         # read changelog, which may or may not fail, but should not crash
16428         cat <&4 >/dev/null
16429
16430         # clear changelog
16431         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16432         changelog_users $SINGLEMDS | grep -q $cl_user ||
16433                 error "User $cl_user not found in changelog_users"
16434
16435         printf 'clear:'$cl_user':0' >&3
16436 }
16437 run_test 160j "client can be umounted while its chanangelog is being used"
16438
16439 test_160k() {
16440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16441         remote_mds_nodsh && skip "remote MDS with nodsh"
16442
16443         mkdir -p $DIR/$tdir/1/1
16444
16445         changelog_register || error "changelog_register failed"
16446         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16447
16448         changelog_users $SINGLEMDS | grep -q $cl_user ||
16449                 error "User '$cl_user' not found in changelog_users"
16450 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16451         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16452         rmdir $DIR/$tdir/1/1 & sleep 1
16453         mkdir $DIR/$tdir/2
16454         touch $DIR/$tdir/2/2
16455         rm -rf $DIR/$tdir/2
16456
16457         wait
16458         sleep 4
16459
16460         changelog_dump | grep rmdir || error "rmdir not recorded"
16461 }
16462 run_test 160k "Verify that changelog records are not lost"
16463
16464 # Verifies that a file passed as a parameter has recently had an operation
16465 # performed on it that has generated an MTIME changelog which contains the
16466 # correct parent FID. As files might reside on a different MDT from the
16467 # parent directory in DNE configurations, the FIDs are translated to paths
16468 # before being compared, which should be identical
16469 compare_mtime_changelog() {
16470         local file="${1}"
16471         local mdtidx
16472         local mtime
16473         local cl_fid
16474         local pdir
16475         local dir
16476
16477         mdtidx=$($LFS getstripe --mdt-index $file)
16478         mdtidx=$(printf "%04x" $mdtidx)
16479
16480         # Obtain the parent FID from the MTIME changelog
16481         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16482         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16483
16484         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16485         [ -z "$cl_fid" ] && error "parent FID not present"
16486
16487         # Verify that the path for the parent FID is the same as the path for
16488         # the test directory
16489         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16490
16491         dir=$(dirname $1)
16492
16493         [[ "${pdir%/}" == "$dir" ]] ||
16494                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16495 }
16496
16497 test_160l() {
16498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16499
16500         remote_mds_nodsh && skip "remote MDS with nodsh"
16501         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16502                 skip "Need MDS version at least 2.13.55"
16503
16504         local cl_user
16505
16506         changelog_register || error "changelog_register failed"
16507         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16508
16509         changelog_users $SINGLEMDS | grep -q $cl_user ||
16510                 error "User '$cl_user' not found in changelog_users"
16511
16512         # Clear some types so that MTIME changelogs are generated
16513         changelog_chmask "-CREAT"
16514         changelog_chmask "-CLOSE"
16515
16516         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16517
16518         # Test CL_MTIME during setattr
16519         touch $DIR/$tdir/$tfile
16520         compare_mtime_changelog $DIR/$tdir/$tfile
16521
16522         # Test CL_MTIME during close
16523         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16524         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16525 }
16526 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16527
16528 test_160m() {
16529         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16530         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16531                 skip "Need MDS version at least 2.14.51"
16532         local cl_users
16533         local cl_user1
16534         local cl_user2
16535         local pid1
16536
16537         # Create a user
16538         changelog_register || error "first changelog_register failed"
16539         changelog_register || error "second changelog_register failed"
16540
16541         cl_users=(${CL_USERS[mds1]})
16542         cl_user1="${cl_users[0]}"
16543         cl_user2="${cl_users[1]}"
16544         # generate some changelog records to accumulate on MDT0
16545         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16546         createmany -m $DIR/$tdir/$tfile 50 ||
16547                 error "create $DIR/$tdir/$tfile failed"
16548         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16549         rm -f $DIR/$tdir
16550
16551         # check changelogs have been generated
16552         local nbcl=$(changelog_dump | wc -l)
16553         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16554
16555 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16556         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16557
16558         __changelog_clear mds1 $cl_user1 +10
16559         __changelog_clear mds1 $cl_user2 0 &
16560         pid1=$!
16561         sleep 2
16562         __changelog_clear mds1 $cl_user1 0 ||
16563                 error "fail to cancel record for $cl_user1"
16564         wait $pid1
16565         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16566 }
16567 run_test 160m "Changelog clear race"
16568
16569 test_160n() {
16570         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16571         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16572                 skip "Need MDS version at least 2.14.51"
16573         local cl_users
16574         local cl_user1
16575         local cl_user2
16576         local pid1
16577         local first_rec
16578         local last_rec=0
16579
16580         # Create a user
16581         changelog_register || error "first changelog_register failed"
16582
16583         cl_users=(${CL_USERS[mds1]})
16584         cl_user1="${cl_users[0]}"
16585
16586         # generate some changelog records to accumulate on MDT0
16587         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16588         first_rec=$(changelog_users $SINGLEMDS |
16589                         awk '/^current.index:/ { print $NF }')
16590         while (( last_rec < (( first_rec + 65000)) )); do
16591                 createmany -m $DIR/$tdir/$tfile 10000 ||
16592                         error "create $DIR/$tdir/$tfile failed"
16593
16594                 for i in $(seq 0 10000); do
16595                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16596                                 > /dev/null
16597                 done
16598
16599                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16600                         error "unlinkmany failed unlink"
16601                 last_rec=$(changelog_users $SINGLEMDS |
16602                         awk '/^current.index:/ { print $NF }')
16603                 echo last record $last_rec
16604                 (( last_rec == 0 )) && error "no changelog found"
16605         done
16606
16607 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16608         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16609
16610         __changelog_clear mds1 $cl_user1 0 &
16611         pid1=$!
16612         sleep 2
16613         __changelog_clear mds1 $cl_user1 0 ||
16614                 error "fail to cancel record for $cl_user1"
16615         wait $pid1
16616         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16617 }
16618 run_test 160n "Changelog destroy race"
16619
16620 test_160o() {
16621         local mdt="$(facet_svc $SINGLEMDS)"
16622
16623         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16624         remote_mds_nodsh && skip "remote MDS with nodsh"
16625         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16626                 skip "Need MDS version at least 2.14.52"
16627
16628         changelog_register --user test_160o -m unlnk+close+open ||
16629                 error "changelog_register failed"
16630
16631         do_facet $SINGLEMDS $LCTL --device $mdt \
16632                                 changelog_register -u "Tt3_-#" &&
16633                 error "bad symbols in name should fail"
16634
16635         do_facet $SINGLEMDS $LCTL --device $mdt \
16636                                 changelog_register -u test_160o &&
16637                 error "the same name registration should fail"
16638
16639         do_facet $SINGLEMDS $LCTL --device $mdt \
16640                         changelog_register -u test_160toolongname &&
16641                 error "too long name registration should fail"
16642
16643         changelog_chmask "MARK+HSM"
16644         lctl get_param mdd.*.changelog*mask
16645         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16646         changelog_users $SINGLEMDS | grep -q $cl_user ||
16647                 error "User $cl_user not found in changelog_users"
16648         #verify username
16649         echo $cl_user | grep -q test_160o ||
16650                 error "User $cl_user has no specific name 'test160o'"
16651
16652         # change something
16653         changelog_clear 0 || error "changelog_clear failed"
16654         # generate some changelog records to accumulate on MDT0
16655         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16656         touch $DIR/$tdir/$tfile                 # open 1
16657
16658         OPENS=$(changelog_dump | grep -c "OPEN")
16659         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16660
16661         # must be no MKDIR it wasn't set as user mask
16662         MKDIR=$(changelog_dump | grep -c "MKDIR")
16663         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16664
16665         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16666                                 mdd.$mdt.changelog_current_mask -n)
16667         # register maskless user
16668         changelog_register || error "changelog_register failed"
16669         # effective mask should be not changed because it is not minimal
16670         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16671                                 mdd.$mdt.changelog_current_mask -n)
16672         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16673         # set server mask to minimal value
16674         changelog_chmask "MARK"
16675         # check effective mask again, should be treated as DEFMASK now
16676         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16677                                 mdd.$mdt.changelog_current_mask -n)
16678         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16679
16680         do_facet $SINGLEMDS $LCTL --device $mdt \
16681                                 changelog_deregister -u test_160o ||
16682                 error "cannot deregister by name"
16683 }
16684 run_test 160o "changelog user name and mask"
16685
16686 test_160p() {
16687         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16688         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16689                 skip "Need MDS version at least 2.14.51"
16690         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16691         local cl_users
16692         local cl_user1
16693         local entry_count
16694
16695         # Create a user
16696         changelog_register || error "first changelog_register failed"
16697
16698         cl_users=(${CL_USERS[mds1]})
16699         cl_user1="${cl_users[0]}"
16700
16701         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16702         createmany -m $DIR/$tdir/$tfile 50 ||
16703                 error "create $DIR/$tdir/$tfile failed"
16704         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16705         rm -rf $DIR/$tdir
16706
16707         # check changelogs have been generated
16708         entry_count=$(changelog_dump | wc -l)
16709         ((entry_count != 0)) || error "no changelog entries found"
16710
16711         # remove changelog_users and check that orphan entries are removed
16712         stop mds1
16713         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16714         start mds1 || error "cannot start mdt"
16715         entry_count=$(changelog_dump | wc -l)
16716         ((entry_count == 0)) ||
16717                 error "found $entry_count changelog entries, expected none"
16718 }
16719 run_test 160p "Changelog orphan cleanup with no users"
16720
16721 test_160q() {
16722         local mdt="$(facet_svc $SINGLEMDS)"
16723         local clu
16724
16725         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16726         remote_mds_nodsh && skip "remote MDS with nodsh"
16727         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16728                 skip "Need MDS version at least 2.14.54"
16729
16730         # set server mask to minimal value like server init does
16731         changelog_chmask "MARK"
16732         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16733                 error "changelog_register failed"
16734         # check effective mask again, should be treated as DEFMASK now
16735         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16736                                 mdd.$mdt.changelog_current_mask -n)
16737         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16738                 error "changelog_deregister failed"
16739         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16740 }
16741 run_test 160q "changelog effective mask is DEFMASK if not set"
16742
16743 test_160s() {
16744         remote_mds_nodsh && skip "remote MDS with nodsh"
16745         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16746                 skip "Need MDS version at least 2.14.55"
16747
16748         local mdts=$(comma_list $(mdts_nodes))
16749
16750         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16751         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16752                                        fail_val=$((24 * 3600 * 10))
16753
16754         # Create a user which is 10 days old
16755         changelog_register || error "first changelog_register failed"
16756         local cl_users
16757         declare -A cl_user1
16758         local i
16759
16760         # generate some changelog records to accumulate on each MDT
16761         # use all_char because created files should be evenly distributed
16762         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16763                 error "test_mkdir $tdir failed"
16764         for ((i = 0; i < MDSCOUNT; i++)); do
16765                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16766                         error "create $DIR/$tdir/d$i.1 failed"
16767         done
16768
16769         # check changelogs have been generated
16770         local nbcl=$(changelog_dump | wc -l)
16771         (( nbcl > 0 )) || error "no changelogs found"
16772
16773         # reduce the max_idle_indexes value to make sure we exceed it
16774         for param in "changelog_max_idle_indexes=2097446912" \
16775                      "changelog_max_idle_time=2592000" \
16776                      "changelog_gc=1" \
16777                      "changelog_min_gc_interval=2"; do
16778                 local MDT0=$(facet_svc $SINGLEMDS)
16779                 local var="${param%=*}"
16780                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16781
16782                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16783                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16784                         error "unable to set mdd.*.$param"
16785         done
16786
16787         local start=$SECONDS
16788         for i in $(seq $MDSCOUNT); do
16789                 cl_users=(${CL_USERS[mds$i]})
16790                 cl_user1[mds$i]="${cl_users[0]}"
16791
16792                 [[ -n "${cl_user1[mds$i]}" ]] ||
16793                         error "mds$i: no user registered"
16794         done
16795
16796         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16797         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16798
16799         # ensure we are past the previous changelog_min_gc_interval set above
16800         local sleep2=$((start + 2 - SECONDS))
16801         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16802
16803         # Generate one more changelog to trigger GC
16804         for ((i = 0; i < MDSCOUNT; i++)); do
16805                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16806                         error "create $DIR/$tdir/d$i.3 failed"
16807         done
16808
16809         # ensure gc thread is done
16810         for node in $(mdts_nodes); do
16811                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16812                         error "$node: GC-thread not done"
16813         done
16814
16815         do_nodes $mdts $LCTL set_param fail_loc=0
16816
16817         for (( i = 1; i <= MDSCOUNT; i++ )); do
16818                 # check cl_user1 is purged
16819                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16820                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16821         done
16822         return 0
16823 }
16824 run_test 160s "changelog garbage collect on idle records * time"
16825
16826 test_161a() {
16827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16828
16829         test_mkdir -c1 $DIR/$tdir
16830         cp /etc/hosts $DIR/$tdir/$tfile
16831         test_mkdir -c1 $DIR/$tdir/foo1
16832         test_mkdir -c1 $DIR/$tdir/foo2
16833         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16834         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16835         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16836         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16837         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16838         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16839                 $LFS fid2path $DIR $FID
16840                 error "bad link ea"
16841         fi
16842         # middle
16843         rm $DIR/$tdir/foo2/zachary
16844         # last
16845         rm $DIR/$tdir/foo2/thor
16846         # first
16847         rm $DIR/$tdir/$tfile
16848         # rename
16849         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16850         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16851                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16852         rm $DIR/$tdir/foo2/maggie
16853
16854         # overflow the EA
16855         local longname=$tfile.avg_len_is_thirty_two_
16856         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16857                 error_noexit 'failed to unlink many hardlinks'" EXIT
16858         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16859                 error "failed to hardlink many files"
16860         links=$($LFS fid2path $DIR $FID | wc -l)
16861         echo -n "${links}/1000 links in link EA"
16862         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16863 }
16864 run_test 161a "link ea sanity"
16865
16866 test_161b() {
16867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16868         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16869
16870         local MDTIDX=1
16871         local remote_dir=$DIR/$tdir/remote_dir
16872
16873         mkdir -p $DIR/$tdir
16874         $LFS mkdir -i $MDTIDX $remote_dir ||
16875                 error "create remote directory failed"
16876
16877         cp /etc/hosts $remote_dir/$tfile
16878         mkdir -p $remote_dir/foo1
16879         mkdir -p $remote_dir/foo2
16880         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16881         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16882         ln $remote_dir/$tfile $remote_dir/foo1/luna
16883         ln $remote_dir/$tfile $remote_dir/foo2/thor
16884
16885         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16886                      tr -d ']')
16887         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16888                 $LFS fid2path $DIR $FID
16889                 error "bad link ea"
16890         fi
16891         # middle
16892         rm $remote_dir/foo2/zachary
16893         # last
16894         rm $remote_dir/foo2/thor
16895         # first
16896         rm $remote_dir/$tfile
16897         # rename
16898         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16899         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16900         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16901                 $LFS fid2path $DIR $FID
16902                 error "bad link rename"
16903         fi
16904         rm $remote_dir/foo2/maggie
16905
16906         # overflow the EA
16907         local longname=filename_avg_len_is_thirty_two_
16908         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16909                 error "failed to hardlink many files"
16910         links=$($LFS fid2path $DIR $FID | wc -l)
16911         echo -n "${links}/1000 links in link EA"
16912         [[ ${links} -gt 60 ]] ||
16913                 error "expected at least 60 links in link EA"
16914         unlinkmany $remote_dir/foo2/$longname 1000 ||
16915         error "failed to unlink many hardlinks"
16916 }
16917 run_test 161b "link ea sanity under remote directory"
16918
16919 test_161c() {
16920         remote_mds_nodsh && skip "remote MDS with nodsh"
16921         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16922         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16923                 skip "Need MDS version at least 2.1.5"
16924
16925         # define CLF_RENAME_LAST 0x0001
16926         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16927         changelog_register || error "changelog_register failed"
16928
16929         rm -rf $DIR/$tdir
16930         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16931         touch $DIR/$tdir/foo_161c
16932         touch $DIR/$tdir/bar_161c
16933         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16934         changelog_dump | grep RENME | tail -n 5
16935         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16936         changelog_clear 0 || error "changelog_clear failed"
16937         if [ x$flags != "x0x1" ]; then
16938                 error "flag $flags is not 0x1"
16939         fi
16940
16941         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16942         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16943         touch $DIR/$tdir/foo_161c
16944         touch $DIR/$tdir/bar_161c
16945         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16946         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16947         changelog_dump | grep RENME | tail -n 5
16948         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16949         changelog_clear 0 || error "changelog_clear failed"
16950         if [ x$flags != "x0x0" ]; then
16951                 error "flag $flags is not 0x0"
16952         fi
16953         echo "rename overwrite a target having nlink > 1," \
16954                 "changelog record has flags of $flags"
16955
16956         # rename doesn't overwrite a target (changelog flag 0x0)
16957         touch $DIR/$tdir/foo_161c
16958         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16959         changelog_dump | grep RENME | tail -n 5
16960         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16961         changelog_clear 0 || error "changelog_clear failed"
16962         if [ x$flags != "x0x0" ]; then
16963                 error "flag $flags is not 0x0"
16964         fi
16965         echo "rename doesn't overwrite a target," \
16966                 "changelog record has flags of $flags"
16967
16968         # define CLF_UNLINK_LAST 0x0001
16969         # unlink a file having nlink = 1 (changelog flag 0x1)
16970         rm -f $DIR/$tdir/foo2_161c
16971         changelog_dump | grep UNLNK | tail -n 5
16972         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16973         changelog_clear 0 || error "changelog_clear failed"
16974         if [ x$flags != "x0x1" ]; then
16975                 error "flag $flags is not 0x1"
16976         fi
16977         echo "unlink a file having nlink = 1," \
16978                 "changelog record has flags of $flags"
16979
16980         # unlink a file having nlink > 1 (changelog flag 0x0)
16981         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16982         rm -f $DIR/$tdir/foobar_161c
16983         changelog_dump | grep UNLNK | tail -n 5
16984         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16985         changelog_clear 0 || error "changelog_clear failed"
16986         if [ x$flags != "x0x0" ]; then
16987                 error "flag $flags is not 0x0"
16988         fi
16989         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16990 }
16991 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16992
16993 test_161d() {
16994         remote_mds_nodsh && skip "remote MDS with nodsh"
16995         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16996
16997         local pid
16998         local fid
16999
17000         changelog_register || error "changelog_register failed"
17001
17002         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17003         # interfer with $MOUNT/.lustre/fid/ access
17004         mkdir $DIR/$tdir
17005         [[ $? -eq 0 ]] || error "mkdir failed"
17006
17007         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17008         $LCTL set_param fail_loc=0x8000140c
17009         # 5s pause
17010         $LCTL set_param fail_val=5
17011
17012         # create file
17013         echo foofoo > $DIR/$tdir/$tfile &
17014         pid=$!
17015
17016         # wait for create to be delayed
17017         sleep 2
17018
17019         ps -p $pid
17020         [[ $? -eq 0 ]] || error "create should be blocked"
17021
17022         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17023         stack_trap "rm -f $tempfile"
17024         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17025         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17026         # some delay may occur during ChangeLog publishing and file read just
17027         # above, that could allow file write to happen finally
17028         [[ -s $tempfile ]] && echo "file should be empty"
17029
17030         $LCTL set_param fail_loc=0
17031
17032         wait $pid
17033         [[ $? -eq 0 ]] || error "create failed"
17034 }
17035 run_test 161d "create with concurrent .lustre/fid access"
17036
17037 check_path() {
17038         local expected="$1"
17039         shift
17040         local fid="$2"
17041
17042         local path
17043         path=$($LFS fid2path "$@")
17044         local rc=$?
17045
17046         if [ $rc -ne 0 ]; then
17047                 error "path looked up of '$expected' failed: rc=$rc"
17048         elif [ "$path" != "$expected" ]; then
17049                 error "path looked up '$path' instead of '$expected'"
17050         else
17051                 echo "FID '$fid' resolves to path '$path' as expected"
17052         fi
17053 }
17054
17055 test_162a() { # was test_162
17056         test_mkdir -p -c1 $DIR/$tdir/d2
17057         touch $DIR/$tdir/d2/$tfile
17058         touch $DIR/$tdir/d2/x1
17059         touch $DIR/$tdir/d2/x2
17060         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17061         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17062         # regular file
17063         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17064         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17065
17066         # softlink
17067         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17068         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17069         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17070
17071         # softlink to wrong file
17072         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17073         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17074         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17075
17076         # hardlink
17077         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17078         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17079         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17080         # fid2path dir/fsname should both work
17081         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17082         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17083
17084         # hardlink count: check that there are 2 links
17085         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17086         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17087
17088         # hardlink indexing: remove the first link
17089         rm $DIR/$tdir/d2/p/q/r/hlink
17090         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17091 }
17092 run_test 162a "path lookup sanity"
17093
17094 test_162b() {
17095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17096         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17097
17098         mkdir $DIR/$tdir
17099         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17100                                 error "create striped dir failed"
17101
17102         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17103                                         tail -n 1 | awk '{print $2}')
17104         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17105
17106         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17107         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17108
17109         # regular file
17110         for ((i=0;i<5;i++)); do
17111                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17112                         error "get fid for f$i failed"
17113                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17114
17115                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17116                         error "get fid for d$i failed"
17117                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17118         done
17119
17120         return 0
17121 }
17122 run_test 162b "striped directory path lookup sanity"
17123
17124 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17125 test_162c() {
17126         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17127                 skip "Need MDS version at least 2.7.51"
17128
17129         local lpath=$tdir.local
17130         local rpath=$tdir.remote
17131
17132         test_mkdir $DIR/$lpath
17133         test_mkdir $DIR/$rpath
17134
17135         for ((i = 0; i <= 101; i++)); do
17136                 lpath="$lpath/$i"
17137                 mkdir $DIR/$lpath
17138                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17139                         error "get fid for local directory $DIR/$lpath failed"
17140                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17141
17142                 rpath="$rpath/$i"
17143                 test_mkdir $DIR/$rpath
17144                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17145                         error "get fid for remote directory $DIR/$rpath failed"
17146                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17147         done
17148
17149         return 0
17150 }
17151 run_test 162c "fid2path works with paths 100 or more directories deep"
17152
17153 oalr_event_count() {
17154         local event="${1}"
17155         local trace="${2}"
17156
17157         awk -v name="${FSNAME}-OST0000" \
17158             -v event="${event}" \
17159             '$1 == "TRACE" && $2 == event && $3 == name' \
17160             "${trace}" |
17161         wc -l
17162 }
17163
17164 oalr_expect_event_count() {
17165         local event="${1}"
17166         local trace="${2}"
17167         local expect="${3}"
17168         local count
17169
17170         count=$(oalr_event_count "${event}" "${trace}")
17171         if ((count == expect)); then
17172                 return 0
17173         fi
17174
17175         error_noexit "${event} event count was '${count}', expected ${expect}"
17176         cat "${trace}" >&2
17177         exit 1
17178 }
17179
17180 cleanup_165() {
17181         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17182         stop ost1
17183         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17184 }
17185
17186 setup_165() {
17187         sync # Flush previous IOs so we can count log entries.
17188         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17189         stack_trap cleanup_165 EXIT
17190 }
17191
17192 test_165a() {
17193         local trace="/tmp/${tfile}.trace"
17194         local rc
17195         local count
17196
17197         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17198                 skip "OFD access log unsupported"
17199
17200         setup_165
17201         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17202         sleep 5
17203
17204         do_facet ost1 ofd_access_log_reader --list
17205         stop ost1
17206
17207         do_facet ost1 killall -TERM ofd_access_log_reader
17208         wait
17209         rc=$?
17210
17211         if ((rc != 0)); then
17212                 error "ofd_access_log_reader exited with rc = '${rc}'"
17213         fi
17214
17215         # Parse trace file for discovery events:
17216         oalr_expect_event_count alr_log_add "${trace}" 1
17217         oalr_expect_event_count alr_log_eof "${trace}" 1
17218         oalr_expect_event_count alr_log_free "${trace}" 1
17219 }
17220 run_test 165a "ofd access log discovery"
17221
17222 test_165b() {
17223         local trace="/tmp/${tfile}.trace"
17224         local file="${DIR}/${tfile}"
17225         local pfid1
17226         local pfid2
17227         local -a entry
17228         local rc
17229         local count
17230         local size
17231         local flags
17232
17233         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17234                 skip "OFD access log unsupported"
17235
17236         setup_165
17237         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17238         sleep 5
17239
17240         do_facet ost1 ofd_access_log_reader --list
17241
17242         lfs setstripe -c 1 -i 0 "${file}"
17243         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17244                 error "cannot create '${file}'"
17245
17246         sleep 5
17247         do_facet ost1 killall -TERM ofd_access_log_reader
17248         wait
17249         rc=$?
17250
17251         if ((rc != 0)); then
17252                 error "ofd_access_log_reader exited with rc = '${rc}'"
17253         fi
17254
17255         oalr_expect_event_count alr_log_entry "${trace}" 1
17256
17257         pfid1=$($LFS path2fid "${file}")
17258
17259         # 1     2             3   4    5     6   7    8    9     10
17260         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17261         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17262
17263         echo "entry = '${entry[*]}'" >&2
17264
17265         pfid2=${entry[4]}
17266         if [[ "${pfid1}" != "${pfid2}" ]]; then
17267                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17268         fi
17269
17270         size=${entry[8]}
17271         if ((size != 1048576)); then
17272                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17273         fi
17274
17275         flags=${entry[10]}
17276         if [[ "${flags}" != "w" ]]; then
17277                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17278         fi
17279
17280         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17281         sleep 5
17282
17283         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17284                 error "cannot read '${file}'"
17285         sleep 5
17286
17287         do_facet ost1 killall -TERM ofd_access_log_reader
17288         wait
17289         rc=$?
17290
17291         if ((rc != 0)); then
17292                 error "ofd_access_log_reader exited with rc = '${rc}'"
17293         fi
17294
17295         oalr_expect_event_count alr_log_entry "${trace}" 1
17296
17297         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17298         echo "entry = '${entry[*]}'" >&2
17299
17300         pfid2=${entry[4]}
17301         if [[ "${pfid1}" != "${pfid2}" ]]; then
17302                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17303         fi
17304
17305         size=${entry[8]}
17306         if ((size != 524288)); then
17307                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17308         fi
17309
17310         flags=${entry[10]}
17311         if [[ "${flags}" != "r" ]]; then
17312                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17313         fi
17314 }
17315 run_test 165b "ofd access log entries are produced and consumed"
17316
17317 test_165c() {
17318         local trace="/tmp/${tfile}.trace"
17319         local file="${DIR}/${tdir}/${tfile}"
17320
17321         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17322                 skip "OFD access log unsupported"
17323
17324         test_mkdir "${DIR}/${tdir}"
17325
17326         setup_165
17327         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17328         sleep 5
17329
17330         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17331
17332         # 4096 / 64 = 64. Create twice as many entries.
17333         for ((i = 0; i < 128; i++)); do
17334                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17335                         error "cannot create file"
17336         done
17337
17338         sync
17339
17340         do_facet ost1 killall -TERM ofd_access_log_reader
17341         wait
17342         rc=$?
17343         if ((rc != 0)); then
17344                 error "ofd_access_log_reader exited with rc = '${rc}'"
17345         fi
17346
17347         unlinkmany  "${file}-%d" 128
17348 }
17349 run_test 165c "full ofd access logs do not block IOs"
17350
17351 oal_get_read_count() {
17352         local stats="$1"
17353
17354         # STATS lustre-OST0001 alr_read_count 1
17355
17356         do_facet ost1 cat "${stats}" |
17357         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17358              END { print count; }'
17359 }
17360
17361 oal_expect_read_count() {
17362         local stats="$1"
17363         local count
17364         local expect="$2"
17365
17366         # Ask ofd_access_log_reader to write stats.
17367         do_facet ost1 killall -USR1 ofd_access_log_reader
17368
17369         # Allow some time for things to happen.
17370         sleep 1
17371
17372         count=$(oal_get_read_count "${stats}")
17373         if ((count == expect)); then
17374                 return 0
17375         fi
17376
17377         error_noexit "bad read count, got ${count}, expected ${expect}"
17378         do_facet ost1 cat "${stats}" >&2
17379         exit 1
17380 }
17381
17382 test_165d() {
17383         local stats="/tmp/${tfile}.stats"
17384         local file="${DIR}/${tdir}/${tfile}"
17385         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17386
17387         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17388                 skip "OFD access log unsupported"
17389
17390         test_mkdir "${DIR}/${tdir}"
17391
17392         setup_165
17393         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17394         sleep 5
17395
17396         lfs setstripe -c 1 -i 0 "${file}"
17397
17398         do_facet ost1 lctl set_param "${param}=rw"
17399         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17400                 error "cannot create '${file}'"
17401         oal_expect_read_count "${stats}" 1
17402
17403         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17404                 error "cannot read '${file}'"
17405         oal_expect_read_count "${stats}" 2
17406
17407         do_facet ost1 lctl set_param "${param}=r"
17408         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17409                 error "cannot create '${file}'"
17410         oal_expect_read_count "${stats}" 2
17411
17412         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17413                 error "cannot read '${file}'"
17414         oal_expect_read_count "${stats}" 3
17415
17416         do_facet ost1 lctl set_param "${param}=w"
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 lctl set_param "${param}=0"
17426         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17427                 error "cannot create '${file}'"
17428         oal_expect_read_count "${stats}" 4
17429
17430         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17431                 error "cannot read '${file}'"
17432         oal_expect_read_count "${stats}" 4
17433
17434         do_facet ost1 killall -TERM ofd_access_log_reader
17435         wait
17436         rc=$?
17437         if ((rc != 0)); then
17438                 error "ofd_access_log_reader exited with rc = '${rc}'"
17439         fi
17440 }
17441 run_test 165d "ofd_access_log mask works"
17442
17443 test_165e() {
17444         local stats="/tmp/${tfile}.stats"
17445         local file0="${DIR}/${tdir}-0/${tfile}"
17446         local file1="${DIR}/${tdir}-1/${tfile}"
17447
17448         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17449                 skip "OFD access log unsupported"
17450
17451         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17452
17453         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17454         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17455
17456         lfs setstripe -c 1 -i 0 "${file0}"
17457         lfs setstripe -c 1 -i 0 "${file1}"
17458
17459         setup_165
17460         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17461         sleep 5
17462
17463         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17464                 error "cannot create '${file0}'"
17465         sync
17466         oal_expect_read_count "${stats}" 0
17467
17468         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17469                 error "cannot create '${file1}'"
17470         sync
17471         oal_expect_read_count "${stats}" 1
17472
17473         do_facet ost1 killall -TERM ofd_access_log_reader
17474         wait
17475         rc=$?
17476         if ((rc != 0)); then
17477                 error "ofd_access_log_reader exited with rc = '${rc}'"
17478         fi
17479 }
17480 run_test 165e "ofd_access_log MDT index filter works"
17481
17482 test_165f() {
17483         local trace="/tmp/${tfile}.trace"
17484         local rc
17485         local count
17486
17487         setup_165
17488         do_facet ost1 timeout 60 ofd_access_log_reader \
17489                 --exit-on-close --debug=- --trace=- > "${trace}" &
17490         sleep 5
17491         stop ost1
17492
17493         wait
17494         rc=$?
17495
17496         if ((rc != 0)); then
17497                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17498                 cat "${trace}"
17499                 exit 1
17500         fi
17501 }
17502 run_test 165f "ofd_access_log_reader --exit-on-close works"
17503
17504 test_169() {
17505         # do directio so as not to populate the page cache
17506         log "creating a 10 Mb file"
17507         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17508                 error "multiop failed while creating a file"
17509         log "starting reads"
17510         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17511         log "truncating the file"
17512         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17513                 error "multiop failed while truncating the file"
17514         log "killing dd"
17515         kill %+ || true # reads might have finished
17516         echo "wait until dd is finished"
17517         wait
17518         log "removing the temporary file"
17519         rm -rf $DIR/$tfile || error "tmp file removal failed"
17520 }
17521 run_test 169 "parallel read and truncate should not deadlock"
17522
17523 test_170() {
17524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17525
17526         $LCTL clear     # bug 18514
17527         $LCTL debug_daemon start $TMP/${tfile}_log_good
17528         touch $DIR/$tfile
17529         $LCTL debug_daemon stop
17530         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17531                 error "sed failed to read log_good"
17532
17533         $LCTL debug_daemon start $TMP/${tfile}_log_good
17534         rm -rf $DIR/$tfile
17535         $LCTL debug_daemon stop
17536
17537         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17538                error "lctl df log_bad failed"
17539
17540         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17541         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17542
17543         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17544         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17545
17546         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17547                 error "bad_line good_line1 good_line2 are empty"
17548
17549         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17550         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17551         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17552
17553         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17554         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17555         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17556
17557         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17558                 error "bad_line_new good_line_new are empty"
17559
17560         local expected_good=$((good_line1 + good_line2*2))
17561
17562         rm -f $TMP/${tfile}*
17563         # LU-231, short malformed line may not be counted into bad lines
17564         if [ $bad_line -ne $bad_line_new ] &&
17565                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17566                 error "expected $bad_line bad lines, but got $bad_line_new"
17567                 return 1
17568         fi
17569
17570         if [ $expected_good -ne $good_line_new ]; then
17571                 error "expected $expected_good good lines, but got $good_line_new"
17572                 return 2
17573         fi
17574         true
17575 }
17576 run_test 170 "test lctl df to handle corrupted log ====================="
17577
17578 test_171() { # bug20592
17579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17580
17581         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17582         $LCTL set_param fail_loc=0x50e
17583         $LCTL set_param fail_val=3000
17584         multiop_bg_pause $DIR/$tfile O_s || true
17585         local MULTIPID=$!
17586         kill -USR1 $MULTIPID
17587         # cause log dump
17588         sleep 3
17589         wait $MULTIPID
17590         if dmesg | grep "recursive fault"; then
17591                 error "caught a recursive fault"
17592         fi
17593         $LCTL set_param fail_loc=0
17594         true
17595 }
17596 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17597
17598 # it would be good to share it with obdfilter-survey/iokit-libecho code
17599 setup_obdecho_osc () {
17600         local rc=0
17601         local ost_nid=$1
17602         local obdfilter_name=$2
17603         echo "Creating new osc for $obdfilter_name on $ost_nid"
17604         # make sure we can find loopback nid
17605         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17606
17607         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17608                            ${obdfilter_name}_osc_UUID || rc=2; }
17609         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17610                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17611         return $rc
17612 }
17613
17614 cleanup_obdecho_osc () {
17615         local obdfilter_name=$1
17616         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17617         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17618         return 0
17619 }
17620
17621 obdecho_test() {
17622         local OBD=$1
17623         local node=$2
17624         local pages=${3:-64}
17625         local rc=0
17626         local id
17627
17628         local count=10
17629         local obd_size=$(get_obd_size $node $OBD)
17630         local page_size=$(get_page_size $node)
17631         if [[ -n "$obd_size" ]]; then
17632                 local new_count=$((obd_size / (pages * page_size / 1024)))
17633                 [[ $new_count -ge $count ]] || count=$new_count
17634         fi
17635
17636         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17637         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17638                            rc=2; }
17639         if [ $rc -eq 0 ]; then
17640             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17641             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17642         fi
17643         echo "New object id is $id"
17644         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17645                            rc=4; }
17646         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17647                            "test_brw $count w v $pages $id" || rc=4; }
17648         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17649                            rc=4; }
17650         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17651                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17652         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17653                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17654         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17655         return $rc
17656 }
17657
17658 test_180a() {
17659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17660
17661         if ! [ -d /sys/fs/lustre/echo_client ] &&
17662            ! module_loaded obdecho; then
17663                 load_module obdecho/obdecho &&
17664                         stack_trap "rmmod obdecho" EXIT ||
17665                         error "unable to load obdecho on client"
17666         fi
17667
17668         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17669         local host=$($LCTL get_param -n osc.$osc.import |
17670                      awk '/current_connection:/ { print $2 }' )
17671         local target=$($LCTL get_param -n osc.$osc.import |
17672                        awk '/target:/ { print $2 }' )
17673         target=${target%_UUID}
17674
17675         if [ -n "$target" ]; then
17676                 setup_obdecho_osc $host $target &&
17677                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17678                         { error "obdecho setup failed with $?"; return; }
17679
17680                 obdecho_test ${target}_osc client ||
17681                         error "obdecho_test failed on ${target}_osc"
17682         else
17683                 $LCTL get_param osc.$osc.import
17684                 error "there is no osc.$osc.import target"
17685         fi
17686 }
17687 run_test 180a "test obdecho on osc"
17688
17689 test_180b() {
17690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17691         remote_ost_nodsh && skip "remote OST with nodsh"
17692
17693         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17694                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17695                 error "failed to load module obdecho"
17696
17697         local target=$(do_facet ost1 $LCTL dl |
17698                        awk '/obdfilter/ { print $4; exit; }')
17699
17700         if [ -n "$target" ]; then
17701                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17702         else
17703                 do_facet ost1 $LCTL dl
17704                 error "there is no obdfilter target on ost1"
17705         fi
17706 }
17707 run_test 180b "test obdecho directly on obdfilter"
17708
17709 test_180c() { # LU-2598
17710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17711         remote_ost_nodsh && skip "remote OST with nodsh"
17712         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17713                 skip "Need MDS version at least 2.4.0"
17714
17715         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17716                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17717                 error "failed to load module obdecho"
17718
17719         local target=$(do_facet ost1 $LCTL dl |
17720                        awk '/obdfilter/ { print $4; exit; }')
17721
17722         if [ -n "$target" ]; then
17723                 local pages=16384 # 64MB bulk I/O RPC size
17724
17725                 obdecho_test "$target" ost1 "$pages" ||
17726                         error "obdecho_test with pages=$pages failed with $?"
17727         else
17728                 do_facet ost1 $LCTL dl
17729                 error "there is no obdfilter target on ost1"
17730         fi
17731 }
17732 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17733
17734 test_181() { # bug 22177
17735         test_mkdir $DIR/$tdir
17736         # create enough files to index the directory
17737         createmany -o $DIR/$tdir/foobar 4000
17738         # print attributes for debug purpose
17739         lsattr -d .
17740         # open dir
17741         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17742         MULTIPID=$!
17743         # remove the files & current working dir
17744         unlinkmany $DIR/$tdir/foobar 4000
17745         rmdir $DIR/$tdir
17746         kill -USR1 $MULTIPID
17747         wait $MULTIPID
17748         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17749         return 0
17750 }
17751 run_test 181 "Test open-unlinked dir ========================"
17752
17753 test_182() {
17754         local fcount=1000
17755         local tcount=10
17756
17757         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17758
17759         $LCTL set_param mdc.*.rpc_stats=clear
17760
17761         for (( i = 0; i < $tcount; i++ )) ; do
17762                 mkdir $DIR/$tdir/$i
17763         done
17764
17765         for (( i = 0; i < $tcount; i++ )) ; do
17766                 createmany -o $DIR/$tdir/$i/f- $fcount &
17767         done
17768         wait
17769
17770         for (( i = 0; i < $tcount; i++ )) ; do
17771                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17772         done
17773         wait
17774
17775         $LCTL get_param mdc.*.rpc_stats
17776
17777         rm -rf $DIR/$tdir
17778 }
17779 run_test 182 "Test parallel modify metadata operations ================"
17780
17781 test_183() { # LU-2275
17782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17783         remote_mds_nodsh && skip "remote MDS with nodsh"
17784         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17785                 skip "Need MDS version at least 2.3.56"
17786
17787         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17788         echo aaa > $DIR/$tdir/$tfile
17789
17790 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17791         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17792
17793         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17794         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17795
17796         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17797
17798         # Flush negative dentry cache
17799         touch $DIR/$tdir/$tfile
17800
17801         # We are not checking for any leaked references here, they'll
17802         # become evident next time we do cleanup with module unload.
17803         rm -rf $DIR/$tdir
17804 }
17805 run_test 183 "No crash or request leak in case of strange dispositions ========"
17806
17807 # test suite 184 is for LU-2016, LU-2017
17808 test_184a() {
17809         check_swap_layouts_support
17810
17811         dir0=$DIR/$tdir/$testnum
17812         test_mkdir -p -c1 $dir0
17813         ref1=/etc/passwd
17814         ref2=/etc/group
17815         file1=$dir0/f1
17816         file2=$dir0/f2
17817         $LFS setstripe -c1 $file1
17818         cp $ref1 $file1
17819         $LFS setstripe -c2 $file2
17820         cp $ref2 $file2
17821         gen1=$($LFS getstripe -g $file1)
17822         gen2=$($LFS getstripe -g $file2)
17823
17824         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17825         gen=$($LFS getstripe -g $file1)
17826         [[ $gen1 != $gen ]] ||
17827                 "Layout generation on $file1 does not change"
17828         gen=$($LFS getstripe -g $file2)
17829         [[ $gen2 != $gen ]] ||
17830                 "Layout generation on $file2 does not change"
17831
17832         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17833         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17834
17835         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17836 }
17837 run_test 184a "Basic layout swap"
17838
17839 test_184b() {
17840         check_swap_layouts_support
17841
17842         dir0=$DIR/$tdir/$testnum
17843         mkdir -p $dir0 || error "creating dir $dir0"
17844         file1=$dir0/f1
17845         file2=$dir0/f2
17846         file3=$dir0/f3
17847         dir1=$dir0/d1
17848         dir2=$dir0/d2
17849         mkdir $dir1 $dir2
17850         $LFS setstripe -c1 $file1
17851         $LFS setstripe -c2 $file2
17852         $LFS setstripe -c1 $file3
17853         chown $RUNAS_ID $file3
17854         gen1=$($LFS getstripe -g $file1)
17855         gen2=$($LFS getstripe -g $file2)
17856
17857         $LFS swap_layouts $dir1 $dir2 &&
17858                 error "swap of directories layouts should fail"
17859         $LFS swap_layouts $dir1 $file1 &&
17860                 error "swap of directory and file layouts should fail"
17861         $RUNAS $LFS swap_layouts $file1 $file2 &&
17862                 error "swap of file we cannot write should fail"
17863         $LFS swap_layouts $file1 $file3 &&
17864                 error "swap of file with different owner should fail"
17865         /bin/true # to clear error code
17866 }
17867 run_test 184b "Forbidden layout swap (will generate errors)"
17868
17869 test_184c() {
17870         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17871         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17872         check_swap_layouts_support
17873         check_swap_layout_no_dom $DIR
17874
17875         local dir0=$DIR/$tdir/$testnum
17876         mkdir -p $dir0 || error "creating dir $dir0"
17877
17878         local ref1=$dir0/ref1
17879         local ref2=$dir0/ref2
17880         local file1=$dir0/file1
17881         local file2=$dir0/file2
17882         # create a file large enough for the concurrent test
17883         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17884         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17885         echo "ref file size: ref1($(stat -c %s $ref1))," \
17886              "ref2($(stat -c %s $ref2))"
17887
17888         cp $ref2 $file2
17889         dd if=$ref1 of=$file1 bs=16k &
17890         local DD_PID=$!
17891
17892         # Make sure dd starts to copy file, but wait at most 5 seconds
17893         local loops=0
17894         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17895
17896         $LFS swap_layouts $file1 $file2
17897         local rc=$?
17898         wait $DD_PID
17899         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17900         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17901
17902         # how many bytes copied before swapping layout
17903         local copied=$(stat -c %s $file2)
17904         local remaining=$(stat -c %s $ref1)
17905         remaining=$((remaining - copied))
17906         echo "Copied $copied bytes before swapping layout..."
17907
17908         cmp -n $copied $file1 $ref2 | grep differ &&
17909                 error "Content mismatch [0, $copied) of ref2 and file1"
17910         cmp -n $copied $file2 $ref1 ||
17911                 error "Content mismatch [0, $copied) of ref1 and file2"
17912         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17913                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17914
17915         # clean up
17916         rm -f $ref1 $ref2 $file1 $file2
17917 }
17918 run_test 184c "Concurrent write and layout swap"
17919
17920 test_184d() {
17921         check_swap_layouts_support
17922         check_swap_layout_no_dom $DIR
17923         [ -z "$(which getfattr 2>/dev/null)" ] &&
17924                 skip_env "no getfattr command"
17925
17926         local file1=$DIR/$tdir/$tfile-1
17927         local file2=$DIR/$tdir/$tfile-2
17928         local file3=$DIR/$tdir/$tfile-3
17929         local lovea1
17930         local lovea2
17931
17932         mkdir -p $DIR/$tdir
17933         touch $file1 || error "create $file1 failed"
17934         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17935                 error "create $file2 failed"
17936         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17937                 error "create $file3 failed"
17938         lovea1=$(get_layout_param $file1)
17939
17940         $LFS swap_layouts $file2 $file3 ||
17941                 error "swap $file2 $file3 layouts failed"
17942         $LFS swap_layouts $file1 $file2 ||
17943                 error "swap $file1 $file2 layouts failed"
17944
17945         lovea2=$(get_layout_param $file2)
17946         echo "$lovea1"
17947         echo "$lovea2"
17948         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17949
17950         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17951         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17952 }
17953 run_test 184d "allow stripeless layouts swap"
17954
17955 test_184e() {
17956         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17957                 skip "Need MDS version at least 2.6.94"
17958         check_swap_layouts_support
17959         check_swap_layout_no_dom $DIR
17960         [ -z "$(which getfattr 2>/dev/null)" ] &&
17961                 skip_env "no getfattr command"
17962
17963         local file1=$DIR/$tdir/$tfile-1
17964         local file2=$DIR/$tdir/$tfile-2
17965         local file3=$DIR/$tdir/$tfile-3
17966         local lovea
17967
17968         mkdir -p $DIR/$tdir
17969         touch $file1 || error "create $file1 failed"
17970         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17971                 error "create $file2 failed"
17972         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17973                 error "create $file3 failed"
17974
17975         $LFS swap_layouts $file1 $file2 ||
17976                 error "swap $file1 $file2 layouts failed"
17977
17978         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17979         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17980
17981         echo 123 > $file1 || error "Should be able to write into $file1"
17982
17983         $LFS swap_layouts $file1 $file3 ||
17984                 error "swap $file1 $file3 layouts failed"
17985
17986         echo 123 > $file1 || error "Should be able to write into $file1"
17987
17988         rm -rf $file1 $file2 $file3
17989 }
17990 run_test 184e "Recreate layout after stripeless layout swaps"
17991
17992 test_184f() {
17993         # Create a file with name longer than sizeof(struct stat) ==
17994         # 144 to see if we can get chars from the file name to appear
17995         # in the returned striping. Note that 'f' == 0x66.
17996         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17997
17998         mkdir -p $DIR/$tdir
17999         mcreate $DIR/$tdir/$file
18000         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18001                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18002         fi
18003 }
18004 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18005
18006 test_185() { # LU-2441
18007         # LU-3553 - no volatile file support in old servers
18008         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18009                 skip "Need MDS version at least 2.3.60"
18010
18011         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18012         touch $DIR/$tdir/spoo
18013         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18014         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18015                 error "cannot create/write a volatile file"
18016         [ "$FILESET" == "" ] &&
18017         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18018                 error "FID is still valid after close"
18019
18020         multiop_bg_pause $DIR/$tdir vVw4096_c
18021         local multi_pid=$!
18022
18023         local OLD_IFS=$IFS
18024         IFS=":"
18025         local fidv=($fid)
18026         IFS=$OLD_IFS
18027         # assume that the next FID for this client is sequential, since stdout
18028         # is unfortunately eaten by multiop_bg_pause
18029         local n=$((${fidv[1]} + 1))
18030         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18031         if [ "$FILESET" == "" ]; then
18032                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18033                         error "FID is missing before close"
18034         fi
18035         kill -USR1 $multi_pid
18036         # 1 second delay, so if mtime change we will see it
18037         sleep 1
18038         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18039         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18040 }
18041 run_test 185 "Volatile file support"
18042
18043 function create_check_volatile() {
18044         local idx=$1
18045         local tgt
18046
18047         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18048         local PID=$!
18049         sleep 1
18050         local FID=$(cat /tmp/${tfile}.fid)
18051         [ "$FID" == "" ] && error "can't get FID for volatile"
18052         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18053         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18054         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18055         kill -USR1 $PID
18056         wait
18057         sleep 1
18058         cancel_lru_locks mdc # flush opencache
18059         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18060         return 0
18061 }
18062
18063 test_185a(){
18064         # LU-12516 - volatile creation via .lustre
18065         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18066                 skip "Need MDS version at least 2.3.55"
18067
18068         create_check_volatile 0
18069         [ $MDSCOUNT -lt 2 ] && return 0
18070
18071         # DNE case
18072         create_check_volatile 1
18073
18074         return 0
18075 }
18076 run_test 185a "Volatile file creation in .lustre/fid/"
18077
18078 test_187a() {
18079         remote_mds_nodsh && skip "remote MDS with nodsh"
18080         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18081                 skip "Need MDS version at least 2.3.0"
18082
18083         local dir0=$DIR/$tdir/$testnum
18084         mkdir -p $dir0 || error "creating dir $dir0"
18085
18086         local file=$dir0/file1
18087         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18088         local dv1=$($LFS data_version $file)
18089         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18090         local dv2=$($LFS data_version $file)
18091         [[ $dv1 != $dv2 ]] ||
18092                 error "data version did not change on write $dv1 == $dv2"
18093
18094         # clean up
18095         rm -f $file1
18096 }
18097 run_test 187a "Test data version change"
18098
18099 test_187b() {
18100         remote_mds_nodsh && skip "remote MDS with nodsh"
18101         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18102                 skip "Need MDS version at least 2.3.0"
18103
18104         local dir0=$DIR/$tdir/$testnum
18105         mkdir -p $dir0 || error "creating dir $dir0"
18106
18107         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18108         [[ ${DV[0]} != ${DV[1]} ]] ||
18109                 error "data version did not change on write"\
18110                       " ${DV[0]} == ${DV[1]}"
18111
18112         # clean up
18113         rm -f $file1
18114 }
18115 run_test 187b "Test data version change on volatile file"
18116
18117 test_200() {
18118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18119         remote_mgs_nodsh && skip "remote MGS with nodsh"
18120         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18121
18122         local POOL=${POOL:-cea1}
18123         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18124         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18125         # Pool OST targets
18126         local first_ost=0
18127         local last_ost=$(($OSTCOUNT - 1))
18128         local ost_step=2
18129         local ost_list=$(seq $first_ost $ost_step $last_ost)
18130         local ost_range="$first_ost $last_ost $ost_step"
18131         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18132         local file_dir=$POOL_ROOT/file_tst
18133         local subdir=$test_path/subdir
18134         local rc=0
18135
18136         while : ; do
18137                 # former test_200a test_200b
18138                 pool_add $POOL                          || { rc=$? ; break; }
18139                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18140                 # former test_200c test_200d
18141                 mkdir -p $test_path
18142                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18143                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18144                 mkdir -p $subdir
18145                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18146                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18147                                                         || { rc=$? ; break; }
18148                 # former test_200e test_200f
18149                 local files=$((OSTCOUNT*3))
18150                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18151                                                         || { rc=$? ; break; }
18152                 pool_create_files $POOL $file_dir $files "$ost_list" \
18153                                                         || { rc=$? ; break; }
18154                 # former test_200g test_200h
18155                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18156                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18157
18158                 # former test_201a test_201b test_201c
18159                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18160
18161                 local f=$test_path/$tfile
18162                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18163                 pool_remove $POOL $f                    || { rc=$? ; break; }
18164                 break
18165         done
18166
18167         destroy_test_pools
18168
18169         return $rc
18170 }
18171 run_test 200 "OST pools"
18172
18173 # usage: default_attr <count | size | offset>
18174 default_attr() {
18175         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18176 }
18177
18178 # usage: check_default_stripe_attr
18179 check_default_stripe_attr() {
18180         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18181         case $1 in
18182         --stripe-count|-c)
18183                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18184         --stripe-size|-S)
18185                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18186         --stripe-index|-i)
18187                 EXPECTED=-1;;
18188         *)
18189                 error "unknown getstripe attr '$1'"
18190         esac
18191
18192         [ $ACTUAL == $EXPECTED ] ||
18193                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18194 }
18195
18196 test_204a() {
18197         test_mkdir $DIR/$tdir
18198         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18199
18200         check_default_stripe_attr --stripe-count
18201         check_default_stripe_attr --stripe-size
18202         check_default_stripe_attr --stripe-index
18203 }
18204 run_test 204a "Print default stripe attributes"
18205
18206 test_204b() {
18207         test_mkdir $DIR/$tdir
18208         $LFS setstripe --stripe-count 1 $DIR/$tdir
18209
18210         check_default_stripe_attr --stripe-size
18211         check_default_stripe_attr --stripe-index
18212 }
18213 run_test 204b "Print default stripe size and offset"
18214
18215 test_204c() {
18216         test_mkdir $DIR/$tdir
18217         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18218
18219         check_default_stripe_attr --stripe-count
18220         check_default_stripe_attr --stripe-index
18221 }
18222 run_test 204c "Print default stripe count and offset"
18223
18224 test_204d() {
18225         test_mkdir $DIR/$tdir
18226         $LFS setstripe --stripe-index 0 $DIR/$tdir
18227
18228         check_default_stripe_attr --stripe-count
18229         check_default_stripe_attr --stripe-size
18230 }
18231 run_test 204d "Print default stripe count and size"
18232
18233 test_204e() {
18234         test_mkdir $DIR/$tdir
18235         $LFS setstripe -d $DIR/$tdir
18236
18237         check_default_stripe_attr --stripe-count --raw
18238         check_default_stripe_attr --stripe-size --raw
18239         check_default_stripe_attr --stripe-index --raw
18240 }
18241 run_test 204e "Print raw stripe attributes"
18242
18243 test_204f() {
18244         test_mkdir $DIR/$tdir
18245         $LFS setstripe --stripe-count 1 $DIR/$tdir
18246
18247         check_default_stripe_attr --stripe-size --raw
18248         check_default_stripe_attr --stripe-index --raw
18249 }
18250 run_test 204f "Print raw stripe size and offset"
18251
18252 test_204g() {
18253         test_mkdir $DIR/$tdir
18254         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18255
18256         check_default_stripe_attr --stripe-count --raw
18257         check_default_stripe_attr --stripe-index --raw
18258 }
18259 run_test 204g "Print raw stripe count and offset"
18260
18261 test_204h() {
18262         test_mkdir $DIR/$tdir
18263         $LFS setstripe --stripe-index 0 $DIR/$tdir
18264
18265         check_default_stripe_attr --stripe-count --raw
18266         check_default_stripe_attr --stripe-size --raw
18267 }
18268 run_test 204h "Print raw stripe count and size"
18269
18270 # Figure out which job scheduler is being used, if any,
18271 # or use a fake one
18272 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18273         JOBENV=SLURM_JOB_ID
18274 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18275         JOBENV=LSB_JOBID
18276 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18277         JOBENV=PBS_JOBID
18278 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18279         JOBENV=LOADL_STEP_ID
18280 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18281         JOBENV=JOB_ID
18282 else
18283         $LCTL list_param jobid_name > /dev/null 2>&1
18284         if [ $? -eq 0 ]; then
18285                 JOBENV=nodelocal
18286         else
18287                 JOBENV=FAKE_JOBID
18288         fi
18289 fi
18290 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18291
18292 verify_jobstats() {
18293         local cmd=($1)
18294         shift
18295         local facets="$@"
18296
18297 # we don't really need to clear the stats for this test to work, since each
18298 # command has a unique jobid, but it makes debugging easier if needed.
18299 #       for facet in $facets; do
18300 #               local dev=$(convert_facet2label $facet)
18301 #               # clear old jobstats
18302 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18303 #       done
18304
18305         # use a new JobID for each test, or we might see an old one
18306         [ "$JOBENV" = "FAKE_JOBID" ] &&
18307                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18308
18309         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18310
18311         [ "$JOBENV" = "nodelocal" ] && {
18312                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18313                 $LCTL set_param jobid_name=$FAKE_JOBID
18314                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18315         }
18316
18317         log "Test: ${cmd[*]}"
18318         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18319
18320         if [ $JOBENV = "FAKE_JOBID" ]; then
18321                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18322         else
18323                 ${cmd[*]}
18324         fi
18325
18326         # all files are created on OST0000
18327         for facet in $facets; do
18328                 local stats="*.$(convert_facet2label $facet).job_stats"
18329
18330                 # strip out libtool wrappers for in-tree executables
18331                 if [ $(do_facet $facet lctl get_param $stats |
18332                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18333                         do_facet $facet lctl get_param $stats
18334                         error "No jobstats for $JOBVAL found on $facet::$stats"
18335                 fi
18336         done
18337 }
18338
18339 jobstats_set() {
18340         local new_jobenv=$1
18341
18342         set_persistent_param_and_check client "jobid_var" \
18343                 "$FSNAME.sys.jobid_var" $new_jobenv
18344 }
18345
18346 test_205a() { # Job stats
18347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18348         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18349                 skip "Need MDS version with at least 2.7.1"
18350         remote_mgs_nodsh && skip "remote MGS with nodsh"
18351         remote_mds_nodsh && skip "remote MDS with nodsh"
18352         remote_ost_nodsh && skip "remote OST with nodsh"
18353         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18354                 skip "Server doesn't support jobstats"
18355         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18356
18357         local old_jobenv=$($LCTL get_param -n jobid_var)
18358         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18359
18360         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18361                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18362         else
18363                 stack_trap "do_facet mgs $PERM_CMD \
18364                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18365         fi
18366         changelog_register
18367
18368         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18369                                 mdt.*.job_cleanup_interval | head -n 1)
18370         local new_interval=5
18371         do_facet $SINGLEMDS \
18372                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18373         stack_trap "do_facet $SINGLEMDS \
18374                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18375         local start=$SECONDS
18376
18377         local cmd
18378         # mkdir
18379         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18380         verify_jobstats "$cmd" "$SINGLEMDS"
18381         # rmdir
18382         cmd="rmdir $DIR/$tdir"
18383         verify_jobstats "$cmd" "$SINGLEMDS"
18384         # mkdir on secondary MDT
18385         if [ $MDSCOUNT -gt 1 ]; then
18386                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18387                 verify_jobstats "$cmd" "mds2"
18388         fi
18389         # mknod
18390         cmd="mknod $DIR/$tfile c 1 3"
18391         verify_jobstats "$cmd" "$SINGLEMDS"
18392         # unlink
18393         cmd="rm -f $DIR/$tfile"
18394         verify_jobstats "$cmd" "$SINGLEMDS"
18395         # create all files on OST0000 so verify_jobstats can find OST stats
18396         # open & close
18397         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18398         verify_jobstats "$cmd" "$SINGLEMDS"
18399         # setattr
18400         cmd="touch $DIR/$tfile"
18401         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18402         # write
18403         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18404         verify_jobstats "$cmd" "ost1"
18405         # read
18406         cancel_lru_locks osc
18407         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18408         verify_jobstats "$cmd" "ost1"
18409         # truncate
18410         cmd="$TRUNCATE $DIR/$tfile 0"
18411         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18412         # rename
18413         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18414         verify_jobstats "$cmd" "$SINGLEMDS"
18415         # jobstats expiry - sleep until old stats should be expired
18416         local left=$((new_interval + 5 - (SECONDS - start)))
18417         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18418                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18419                         "0" $left
18420         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18421         verify_jobstats "$cmd" "$SINGLEMDS"
18422         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18423             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18424
18425         # Ensure that jobid are present in changelog (if supported by MDS)
18426         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18427                 changelog_dump | tail -10
18428                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18429                 [ $jobids -eq 9 ] ||
18430                         error "Wrong changelog jobid count $jobids != 9"
18431
18432                 # LU-5862
18433                 JOBENV="disable"
18434                 jobstats_set $JOBENV
18435                 touch $DIR/$tfile
18436                 changelog_dump | grep $tfile
18437                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18438                 [ $jobids -eq 0 ] ||
18439                         error "Unexpected jobids when jobid_var=$JOBENV"
18440         fi
18441
18442         # test '%j' access to environment variable - if supported
18443         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18444                 JOBENV="JOBCOMPLEX"
18445                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18446
18447                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18448         fi
18449
18450         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18451                 JOBENV="JOBCOMPLEX"
18452                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18453
18454                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18455         fi
18456
18457         # test '%j' access to per-session jobid - if supported
18458         if lctl list_param jobid_this_session > /dev/null 2>&1
18459         then
18460                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18461                 lctl set_param jobid_this_session=$USER
18462
18463                 JOBENV="JOBCOMPLEX"
18464                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18465
18466                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18467         fi
18468 }
18469 run_test 205a "Verify job stats"
18470
18471 # LU-13117, LU-13597
18472 test_205b() {
18473         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18474                 skip "Need MDS version at least 2.13.54.91"
18475
18476         job_stats="mdt.*.job_stats"
18477         $LCTL set_param $job_stats=clear
18478         # Setting jobid_var to USER might not be supported
18479         $LCTL set_param jobid_var=USER || true
18480         $LCTL set_param jobid_name="%e.%u"
18481         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18482         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18483                 grep "job_id:.*foolish" &&
18484                         error "Unexpected jobid found"
18485         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18486                 grep "open:.*min.*max.*sum" ||
18487                         error "wrong job_stats format found"
18488 }
18489 run_test 205b "Verify job stats jobid and output format"
18490
18491 # LU-13733
18492 test_205c() {
18493         $LCTL set_param llite.*.stats=0
18494         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18495         $LCTL get_param llite.*.stats
18496         $LCTL get_param llite.*.stats | grep \
18497                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18498                         error "wrong client stats format found"
18499 }
18500 run_test 205c "Verify client stats format"
18501
18502 # LU-1480, LU-1773 and LU-1657
18503 test_206() {
18504         mkdir -p $DIR/$tdir
18505         $LFS setstripe -c -1 $DIR/$tdir
18506 #define OBD_FAIL_LOV_INIT 0x1403
18507         $LCTL set_param fail_loc=0xa0001403
18508         $LCTL set_param fail_val=1
18509         touch $DIR/$tdir/$tfile || true
18510 }
18511 run_test 206 "fail lov_init_raid0() doesn't lbug"
18512
18513 test_207a() {
18514         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18515         local fsz=`stat -c %s $DIR/$tfile`
18516         cancel_lru_locks mdc
18517
18518         # do not return layout in getattr intent
18519 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18520         $LCTL set_param fail_loc=0x170
18521         local sz=`stat -c %s $DIR/$tfile`
18522
18523         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18524
18525         rm -rf $DIR/$tfile
18526 }
18527 run_test 207a "can refresh layout at glimpse"
18528
18529 test_207b() {
18530         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18531         local cksum=`md5sum $DIR/$tfile`
18532         local fsz=`stat -c %s $DIR/$tfile`
18533         cancel_lru_locks mdc
18534         cancel_lru_locks osc
18535
18536         # do not return layout in getattr intent
18537 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18538         $LCTL set_param fail_loc=0x171
18539
18540         # it will refresh layout after the file is opened but before read issues
18541         echo checksum is "$cksum"
18542         echo "$cksum" |md5sum -c --quiet || error "file differs"
18543
18544         rm -rf $DIR/$tfile
18545 }
18546 run_test 207b "can refresh layout at open"
18547
18548 test_208() {
18549         # FIXME: in this test suite, only RD lease is used. This is okay
18550         # for now as only exclusive open is supported. After generic lease
18551         # is done, this test suite should be revised. - Jinshan
18552
18553         remote_mds_nodsh && skip "remote MDS with nodsh"
18554         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18555                 skip "Need MDS version at least 2.4.52"
18556
18557         echo "==== test 1: verify get lease work"
18558         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18559
18560         echo "==== test 2: verify lease can be broken by upcoming open"
18561         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18562         local PID=$!
18563         sleep 1
18564
18565         $MULTIOP $DIR/$tfile oO_RDWR:c
18566         kill -USR1 $PID && wait $PID || error "break lease error"
18567
18568         echo "==== test 3: verify lease can't be granted if an open already exists"
18569         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18570         local PID=$!
18571         sleep 1
18572
18573         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18574         kill -USR1 $PID && wait $PID || error "open file error"
18575
18576         echo "==== test 4: lease can sustain over recovery"
18577         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18578         PID=$!
18579         sleep 1
18580
18581         fail mds1
18582
18583         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18584
18585         echo "==== test 5: lease broken can't be regained by replay"
18586         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18587         PID=$!
18588         sleep 1
18589
18590         # open file to break lease and then recovery
18591         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18592         fail mds1
18593
18594         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18595
18596         rm -f $DIR/$tfile
18597 }
18598 run_test 208 "Exclusive open"
18599
18600 test_209() {
18601         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18602                 skip_env "must have disp_stripe"
18603
18604         touch $DIR/$tfile
18605         sync; sleep 5; sync;
18606
18607         echo 3 > /proc/sys/vm/drop_caches
18608         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18609                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18610         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18611
18612         # open/close 500 times
18613         for i in $(seq 500); do
18614                 cat $DIR/$tfile
18615         done
18616
18617         echo 3 > /proc/sys/vm/drop_caches
18618         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18619                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18620         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18621
18622         echo "before: $req_before, after: $req_after"
18623         [ $((req_after - req_before)) -ge 300 ] &&
18624                 error "open/close requests are not freed"
18625         return 0
18626 }
18627 run_test 209 "read-only open/close requests should be freed promptly"
18628
18629 test_210() {
18630         local pid
18631
18632         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18633         pid=$!
18634         sleep 1
18635
18636         $LFS getstripe $DIR/$tfile
18637         kill -USR1 $pid
18638         wait $pid || error "multiop failed"
18639
18640         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18641         pid=$!
18642         sleep 1
18643
18644         $LFS getstripe $DIR/$tfile
18645         kill -USR1 $pid
18646         wait $pid || error "multiop failed"
18647 }
18648 run_test 210 "lfs getstripe does not break leases"
18649
18650 test_212() {
18651         size=`date +%s`
18652         size=$((size % 8192 + 1))
18653         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18654         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18655         rm -f $DIR/f212 $DIR/f212.xyz
18656 }
18657 run_test 212 "Sendfile test ============================================"
18658
18659 test_213() {
18660         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18661         cancel_lru_locks osc
18662         lctl set_param fail_loc=0x8000040f
18663         # generate a read lock
18664         cat $DIR/$tfile > /dev/null
18665         # write to the file, it will try to cancel the above read lock.
18666         cat /etc/hosts >> $DIR/$tfile
18667 }
18668 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18669
18670 test_214() { # for bug 20133
18671         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18672         for (( i=0; i < 340; i++ )) ; do
18673                 touch $DIR/$tdir/d214c/a$i
18674         done
18675
18676         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18677         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18678         ls $DIR/d214c || error "ls $DIR/d214c failed"
18679         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18680         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18681 }
18682 run_test 214 "hash-indexed directory test - bug 20133"
18683
18684 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18685 create_lnet_proc_files() {
18686         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18687 }
18688
18689 # counterpart of create_lnet_proc_files
18690 remove_lnet_proc_files() {
18691         rm -f $TMP/lnet_$1.sys
18692 }
18693
18694 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18695 # 3rd arg as regexp for body
18696 check_lnet_proc_stats() {
18697         local l=$(cat "$TMP/lnet_$1" |wc -l)
18698         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18699
18700         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18701 }
18702
18703 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18704 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18705 # optional and can be regexp for 2nd line (lnet.routes case)
18706 check_lnet_proc_entry() {
18707         local blp=2          # blp stands for 'position of 1st line of body'
18708         [ -z "$5" ] || blp=3 # lnet.routes case
18709
18710         local l=$(cat "$TMP/lnet_$1" |wc -l)
18711         # subtracting one from $blp because the body can be empty
18712         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18713
18714         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18715                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18716
18717         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18718                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18719
18720         # bail out if any unexpected line happened
18721         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18722         [ "$?" != 0 ] || error "$2 misformatted"
18723 }
18724
18725 test_215() { # for bugs 18102, 21079, 21517
18726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18727
18728         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18729         local P='[1-9][0-9]*'           # positive numeric
18730         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18731         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18732         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18733         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18734
18735         local L1 # regexp for 1st line
18736         local L2 # regexp for 2nd line (optional)
18737         local BR # regexp for the rest (body)
18738
18739         # lnet.stats should look as 11 space-separated non-negative numerics
18740         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18741         create_lnet_proc_files "stats"
18742         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18743         remove_lnet_proc_files "stats"
18744
18745         # lnet.routes should look like this:
18746         # Routing disabled/enabled
18747         # net hops priority state router
18748         # where net is a string like tcp0, hops > 0, priority >= 0,
18749         # state is up/down,
18750         # router is a string like 192.168.1.1@tcp2
18751         L1="^Routing (disabled|enabled)$"
18752         L2="^net +hops +priority +state +router$"
18753         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18754         create_lnet_proc_files "routes"
18755         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18756         remove_lnet_proc_files "routes"
18757
18758         # lnet.routers should look like this:
18759         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18760         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18761         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18762         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18763         L1="^ref +rtr_ref +alive +router$"
18764         BR="^$P +$P +(up|down) +$NID$"
18765         create_lnet_proc_files "routers"
18766         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18767         remove_lnet_proc_files "routers"
18768
18769         # lnet.peers should look like this:
18770         # nid refs state last max rtr min tx min queue
18771         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18772         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18773         # numeric (0 or >0 or <0), queue >= 0.
18774         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18775         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18776         create_lnet_proc_files "peers"
18777         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18778         remove_lnet_proc_files "peers"
18779
18780         # lnet.buffers  should look like this:
18781         # pages count credits min
18782         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18783         L1="^pages +count +credits +min$"
18784         BR="^ +$N +$N +$I +$I$"
18785         create_lnet_proc_files "buffers"
18786         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18787         remove_lnet_proc_files "buffers"
18788
18789         # lnet.nis should look like this:
18790         # nid status alive refs peer rtr max tx min
18791         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18792         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18793         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18794         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18795         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18796         create_lnet_proc_files "nis"
18797         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18798         remove_lnet_proc_files "nis"
18799
18800         # can we successfully write to lnet.stats?
18801         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18802 }
18803 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18804
18805 test_216() { # bug 20317
18806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18807         remote_ost_nodsh && skip "remote OST with nodsh"
18808
18809         local node
18810         local facets=$(get_facets OST)
18811         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18812
18813         save_lustre_params client "osc.*.contention_seconds" > $p
18814         save_lustre_params $facets \
18815                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18816         save_lustre_params $facets \
18817                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18818         save_lustre_params $facets \
18819                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18820         clear_stats osc.*.osc_stats
18821
18822         # agressive lockless i/o settings
18823         do_nodes $(comma_list $(osts_nodes)) \
18824                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18825                         ldlm.namespaces.filter-*.contended_locks=0 \
18826                         ldlm.namespaces.filter-*.contention_seconds=60"
18827         lctl set_param -n osc.*.contention_seconds=60
18828
18829         $DIRECTIO write $DIR/$tfile 0 10 4096
18830         $CHECKSTAT -s 40960 $DIR/$tfile
18831
18832         # disable lockless i/o
18833         do_nodes $(comma_list $(osts_nodes)) \
18834                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18835                         ldlm.namespaces.filter-*.contended_locks=32 \
18836                         ldlm.namespaces.filter-*.contention_seconds=0"
18837         lctl set_param -n osc.*.contention_seconds=0
18838         clear_stats osc.*.osc_stats
18839
18840         dd if=/dev/zero of=$DIR/$tfile count=0
18841         $CHECKSTAT -s 0 $DIR/$tfile
18842
18843         restore_lustre_params <$p
18844         rm -f $p
18845         rm $DIR/$tfile
18846 }
18847 run_test 216 "check lockless direct write updates file size and kms correctly"
18848
18849 test_217() { # bug 22430
18850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18851
18852         local node
18853         local nid
18854
18855         for node in $(nodes_list); do
18856                 nid=$(host_nids_address $node $NETTYPE)
18857                 if [[ $nid = *-* ]] ; then
18858                         echo "lctl ping $(h2nettype $nid)"
18859                         lctl ping $(h2nettype $nid)
18860                 else
18861                         echo "skipping $node (no hyphen detected)"
18862                 fi
18863         done
18864 }
18865 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18866
18867 test_218() {
18868        # do directio so as not to populate the page cache
18869        log "creating a 10 Mb file"
18870        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18871        log "starting reads"
18872        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18873        log "truncating the file"
18874        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18875        log "killing dd"
18876        kill %+ || true # reads might have finished
18877        echo "wait until dd is finished"
18878        wait
18879        log "removing the temporary file"
18880        rm -rf $DIR/$tfile || error "tmp file removal failed"
18881 }
18882 run_test 218 "parallel read and truncate should not deadlock"
18883
18884 test_219() {
18885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18886
18887         # write one partial page
18888         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18889         # set no grant so vvp_io_commit_write will do sync write
18890         $LCTL set_param fail_loc=0x411
18891         # write a full page at the end of file
18892         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18893
18894         $LCTL set_param fail_loc=0
18895         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18896         $LCTL set_param fail_loc=0x411
18897         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18898
18899         # LU-4201
18900         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18901         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18902 }
18903 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18904
18905 test_220() { #LU-325
18906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18907         remote_ost_nodsh && skip "remote OST with nodsh"
18908         remote_mds_nodsh && skip "remote MDS with nodsh"
18909         remote_mgs_nodsh && skip "remote MGS with nodsh"
18910
18911         local OSTIDX=0
18912
18913         # create on MDT0000 so the last_id and next_id are correct
18914         mkdir_on_mdt0 $DIR/$tdir
18915         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18916         OST=${OST%_UUID}
18917
18918         # on the mdt's osc
18919         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18920         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18921                         osp.$mdtosc_proc1.prealloc_last_id)
18922         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18923                         osp.$mdtosc_proc1.prealloc_next_id)
18924
18925         $LFS df -i
18926
18927         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18928         #define OBD_FAIL_OST_ENOINO              0x229
18929         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18930         create_pool $FSNAME.$TESTNAME || return 1
18931         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18932
18933         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18934
18935         MDSOBJS=$((last_id - next_id))
18936         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18937
18938         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18939         echo "OST still has $count kbytes free"
18940
18941         echo "create $MDSOBJS files @next_id..."
18942         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18943
18944         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18945                         osp.$mdtosc_proc1.prealloc_last_id)
18946         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18947                         osp.$mdtosc_proc1.prealloc_next_id)
18948
18949         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18950         $LFS df -i
18951
18952         echo "cleanup..."
18953
18954         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18955         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18956
18957         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18958                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18959         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18960                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18961         echo "unlink $MDSOBJS files @$next_id..."
18962         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18963 }
18964 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18965
18966 test_221() {
18967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18968
18969         dd if=`which date` of=$MOUNT/date oflag=sync
18970         chmod +x $MOUNT/date
18971
18972         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18973         $LCTL set_param fail_loc=0x80001401
18974
18975         $MOUNT/date > /dev/null
18976         rm -f $MOUNT/date
18977 }
18978 run_test 221 "make sure fault and truncate race to not cause OOM"
18979
18980 test_222a () {
18981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18982
18983         rm -rf $DIR/$tdir
18984         test_mkdir $DIR/$tdir
18985         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18986         createmany -o $DIR/$tdir/$tfile 10
18987         cancel_lru_locks mdc
18988         cancel_lru_locks osc
18989         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18990         $LCTL set_param fail_loc=0x31a
18991         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18992         $LCTL set_param fail_loc=0
18993         rm -r $DIR/$tdir
18994 }
18995 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18996
18997 test_222b () {
18998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18999
19000         rm -rf $DIR/$tdir
19001         test_mkdir $DIR/$tdir
19002         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19003         createmany -o $DIR/$tdir/$tfile 10
19004         cancel_lru_locks mdc
19005         cancel_lru_locks osc
19006         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19007         $LCTL set_param fail_loc=0x31a
19008         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19009         $LCTL set_param fail_loc=0
19010 }
19011 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19012
19013 test_223 () {
19014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19015
19016         rm -rf $DIR/$tdir
19017         test_mkdir $DIR/$tdir
19018         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19019         createmany -o $DIR/$tdir/$tfile 10
19020         cancel_lru_locks mdc
19021         cancel_lru_locks osc
19022         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19023         $LCTL set_param fail_loc=0x31b
19024         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19025         $LCTL set_param fail_loc=0
19026         rm -r $DIR/$tdir
19027 }
19028 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19029
19030 test_224a() { # LU-1039, MRP-303
19031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19032         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19033         $LCTL set_param fail_loc=0x508
19034         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19035         $LCTL set_param fail_loc=0
19036         df $DIR
19037 }
19038 run_test 224a "Don't panic on bulk IO failure"
19039
19040 test_224bd_sub() { # LU-1039, MRP-303
19041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19042         local timeout=$1
19043
19044         shift
19045         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19046
19047         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19048
19049         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19050         cancel_lru_locks osc
19051         set_checksums 0
19052         stack_trap "set_checksums $ORIG_CSUM" EXIT
19053         local at_max_saved=0
19054
19055         # adaptive timeouts may prevent seeing the issue
19056         if at_is_enabled; then
19057                 at_max_saved=$(at_max_get mds)
19058                 at_max_set 0 mds client
19059                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19060         fi
19061
19062         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19063         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19064         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19065
19066         do_facet ost1 $LCTL set_param fail_loc=0
19067         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19068         df $DIR
19069 }
19070
19071 test_224b() {
19072         test_224bd_sub 3 error "dd failed"
19073 }
19074 run_test 224b "Don't panic on bulk IO failure"
19075
19076 test_224c() { # LU-6441
19077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19078         remote_mds_nodsh && skip "remote MDS with nodsh"
19079
19080         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19081         save_writethrough $p
19082         set_cache writethrough on
19083
19084         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19085         local at_max=$($LCTL get_param -n at_max)
19086         local timeout=$($LCTL get_param -n timeout)
19087         local test_at="at_max"
19088         local param_at="$FSNAME.sys.at_max"
19089         local test_timeout="timeout"
19090         local param_timeout="$FSNAME.sys.timeout"
19091
19092         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19093
19094         set_persistent_param_and_check client "$test_at" "$param_at" 0
19095         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19096
19097         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19098         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19099         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19100         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19101         sync
19102         do_facet ost1 "$LCTL set_param fail_loc=0"
19103
19104         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19105         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19106                 $timeout
19107
19108         $LCTL set_param -n $pages_per_rpc
19109         restore_lustre_params < $p
19110         rm -f $p
19111 }
19112 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19113
19114 test_224d() { # LU-11169
19115         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19116 }
19117 run_test 224d "Don't corrupt data on bulk IO timeout"
19118
19119 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19120 test_225a () {
19121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19122         if [ -z ${MDSSURVEY} ]; then
19123                 skip_env "mds-survey not found"
19124         fi
19125         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19126                 skip "Need MDS version at least 2.2.51"
19127
19128         local mds=$(facet_host $SINGLEMDS)
19129         local target=$(do_nodes $mds 'lctl dl' |
19130                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19131
19132         local cmd1="file_count=1000 thrhi=4"
19133         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19134         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19135         local cmd="$cmd1 $cmd2 $cmd3"
19136
19137         rm -f ${TMP}/mds_survey*
19138         echo + $cmd
19139         eval $cmd || error "mds-survey with zero-stripe failed"
19140         cat ${TMP}/mds_survey*
19141         rm -f ${TMP}/mds_survey*
19142 }
19143 run_test 225a "Metadata survey sanity with zero-stripe"
19144
19145 test_225b () {
19146         if [ -z ${MDSSURVEY} ]; then
19147                 skip_env "mds-survey not found"
19148         fi
19149         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19150                 skip "Need MDS version at least 2.2.51"
19151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19152         remote_mds_nodsh && skip "remote MDS with nodsh"
19153         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19154                 skip_env "Need to mount OST to test"
19155         fi
19156
19157         local mds=$(facet_host $SINGLEMDS)
19158         local target=$(do_nodes $mds 'lctl dl' |
19159                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19160
19161         local cmd1="file_count=1000 thrhi=4"
19162         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19163         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19164         local cmd="$cmd1 $cmd2 $cmd3"
19165
19166         rm -f ${TMP}/mds_survey*
19167         echo + $cmd
19168         eval $cmd || error "mds-survey with stripe_count failed"
19169         cat ${TMP}/mds_survey*
19170         rm -f ${TMP}/mds_survey*
19171 }
19172 run_test 225b "Metadata survey sanity with stripe_count = 1"
19173
19174 mcreate_path2fid () {
19175         local mode=$1
19176         local major=$2
19177         local minor=$3
19178         local name=$4
19179         local desc=$5
19180         local path=$DIR/$tdir/$name
19181         local fid
19182         local rc
19183         local fid_path
19184
19185         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19186                 error "cannot create $desc"
19187
19188         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19189         rc=$?
19190         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19191
19192         fid_path=$($LFS fid2path $MOUNT $fid)
19193         rc=$?
19194         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19195
19196         [ "$path" == "$fid_path" ] ||
19197                 error "fid2path returned $fid_path, expected $path"
19198
19199         echo "pass with $path and $fid"
19200 }
19201
19202 test_226a () {
19203         rm -rf $DIR/$tdir
19204         mkdir -p $DIR/$tdir
19205
19206         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19207         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19208         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19209         mcreate_path2fid 0040666 0 0 dir "directory"
19210         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19211         mcreate_path2fid 0100666 0 0 file "regular file"
19212         mcreate_path2fid 0120666 0 0 link "symbolic link"
19213         mcreate_path2fid 0140666 0 0 sock "socket"
19214 }
19215 run_test 226a "call path2fid and fid2path on files of all type"
19216
19217 test_226b () {
19218         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19219
19220         local MDTIDX=1
19221
19222         rm -rf $DIR/$tdir
19223         mkdir -p $DIR/$tdir
19224         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19225                 error "create remote directory failed"
19226         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19227         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19228                                 "character special file (null)"
19229         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19230                                 "character special file (no device)"
19231         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19232         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19233                                 "block special file (loop)"
19234         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19235         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19236         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19237 }
19238 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19239
19240 test_226c () {
19241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19242         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19243                 skip "Need MDS version at least 2.13.55"
19244
19245         local submnt=/mnt/submnt
19246         local srcfile=/etc/passwd
19247         local dstfile=$submnt/passwd
19248         local path
19249         local fid
19250
19251         rm -rf $DIR/$tdir
19252         rm -rf $submnt
19253         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19254                 error "create remote directory failed"
19255         mkdir -p $submnt || error "create $submnt failed"
19256         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19257                 error "mount $submnt failed"
19258         stack_trap "umount $submnt" EXIT
19259
19260         cp $srcfile $dstfile
19261         fid=$($LFS path2fid $dstfile)
19262         path=$($LFS fid2path $submnt "$fid")
19263         [ "$path" = "$dstfile" ] ||
19264                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19265 }
19266 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19267
19268 # LU-1299 Executing or running ldd on a truncated executable does not
19269 # cause an out-of-memory condition.
19270 test_227() {
19271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19272         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19273
19274         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19275         chmod +x $MOUNT/date
19276
19277         $MOUNT/date > /dev/null
19278         ldd $MOUNT/date > /dev/null
19279         rm -f $MOUNT/date
19280 }
19281 run_test 227 "running truncated executable does not cause OOM"
19282
19283 # LU-1512 try to reuse idle OI blocks
19284 test_228a() {
19285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19286         remote_mds_nodsh && skip "remote MDS with nodsh"
19287         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19288
19289         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19290         local myDIR=$DIR/$tdir
19291
19292         mkdir -p $myDIR
19293         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19294         $LCTL set_param fail_loc=0x80001002
19295         createmany -o $myDIR/t- 10000
19296         $LCTL set_param fail_loc=0
19297         # The guard is current the largest FID holder
19298         touch $myDIR/guard
19299         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19300                     tr -d '[')
19301         local IDX=$(($SEQ % 64))
19302
19303         do_facet $SINGLEMDS sync
19304         # Make sure journal flushed.
19305         sleep 6
19306         local blk1=$(do_facet $SINGLEMDS \
19307                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19308                      grep Blockcount | awk '{print $4}')
19309
19310         # Remove old files, some OI blocks will become idle.
19311         unlinkmany $myDIR/t- 10000
19312         # Create new files, idle OI blocks should be reused.
19313         createmany -o $myDIR/t- 2000
19314         do_facet $SINGLEMDS sync
19315         # Make sure journal flushed.
19316         sleep 6
19317         local blk2=$(do_facet $SINGLEMDS \
19318                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19319                      grep Blockcount | awk '{print $4}')
19320
19321         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19322 }
19323 run_test 228a "try to reuse idle OI blocks"
19324
19325 test_228b() {
19326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19327         remote_mds_nodsh && skip "remote MDS with nodsh"
19328         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19329
19330         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19331         local myDIR=$DIR/$tdir
19332
19333         mkdir -p $myDIR
19334         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19335         $LCTL set_param fail_loc=0x80001002
19336         createmany -o $myDIR/t- 10000
19337         $LCTL set_param fail_loc=0
19338         # The guard is current the largest FID holder
19339         touch $myDIR/guard
19340         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19341                     tr -d '[')
19342         local IDX=$(($SEQ % 64))
19343
19344         do_facet $SINGLEMDS sync
19345         # Make sure journal flushed.
19346         sleep 6
19347         local blk1=$(do_facet $SINGLEMDS \
19348                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19349                      grep Blockcount | awk '{print $4}')
19350
19351         # Remove old files, some OI blocks will become idle.
19352         unlinkmany $myDIR/t- 10000
19353
19354         # stop the MDT
19355         stop $SINGLEMDS || error "Fail to stop MDT."
19356         # remount the MDT
19357         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19358
19359         df $MOUNT || error "Fail to df."
19360         # Create new files, idle OI blocks should be reused.
19361         createmany -o $myDIR/t- 2000
19362         do_facet $SINGLEMDS sync
19363         # Make sure journal flushed.
19364         sleep 6
19365         local blk2=$(do_facet $SINGLEMDS \
19366                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19367                      grep Blockcount | awk '{print $4}')
19368
19369         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19370 }
19371 run_test 228b "idle OI blocks can be reused after MDT restart"
19372
19373 #LU-1881
19374 test_228c() {
19375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19376         remote_mds_nodsh && skip "remote MDS with nodsh"
19377         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19378
19379         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19380         local myDIR=$DIR/$tdir
19381
19382         mkdir -p $myDIR
19383         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19384         $LCTL set_param fail_loc=0x80001002
19385         # 20000 files can guarantee there are index nodes in the OI file
19386         createmany -o $myDIR/t- 20000
19387         $LCTL set_param fail_loc=0
19388         # The guard is current the largest FID holder
19389         touch $myDIR/guard
19390         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19391                     tr -d '[')
19392         local IDX=$(($SEQ % 64))
19393
19394         do_facet $SINGLEMDS sync
19395         # Make sure journal flushed.
19396         sleep 6
19397         local blk1=$(do_facet $SINGLEMDS \
19398                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19399                      grep Blockcount | awk '{print $4}')
19400
19401         # Remove old files, some OI blocks will become idle.
19402         unlinkmany $myDIR/t- 20000
19403         rm -f $myDIR/guard
19404         # The OI file should become empty now
19405
19406         # Create new files, idle OI blocks should be reused.
19407         createmany -o $myDIR/t- 2000
19408         do_facet $SINGLEMDS sync
19409         # Make sure journal flushed.
19410         sleep 6
19411         local blk2=$(do_facet $SINGLEMDS \
19412                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19413                      grep Blockcount | awk '{print $4}')
19414
19415         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19416 }
19417 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19418
19419 test_229() { # LU-2482, LU-3448
19420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19421         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19422         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19423                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19424
19425         rm -f $DIR/$tfile
19426
19427         # Create a file with a released layout and stripe count 2.
19428         $MULTIOP $DIR/$tfile H2c ||
19429                 error "failed to create file with released layout"
19430
19431         $LFS getstripe -v $DIR/$tfile
19432
19433         local pattern=$($LFS getstripe -L $DIR/$tfile)
19434         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19435
19436         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19437                 error "getstripe"
19438         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19439         stat $DIR/$tfile || error "failed to stat released file"
19440
19441         chown $RUNAS_ID $DIR/$tfile ||
19442                 error "chown $RUNAS_ID $DIR/$tfile failed"
19443
19444         chgrp $RUNAS_ID $DIR/$tfile ||
19445                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19446
19447         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19448         rm $DIR/$tfile || error "failed to remove released file"
19449 }
19450 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19451
19452 test_230a() {
19453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19454         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19455         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19456                 skip "Need MDS version at least 2.11.52"
19457
19458         local MDTIDX=1
19459
19460         test_mkdir $DIR/$tdir
19461         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19462         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19463         [ $mdt_idx -ne 0 ] &&
19464                 error "create local directory on wrong MDT $mdt_idx"
19465
19466         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19467                         error "create remote directory failed"
19468         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19469         [ $mdt_idx -ne $MDTIDX ] &&
19470                 error "create remote directory on wrong MDT $mdt_idx"
19471
19472         createmany -o $DIR/$tdir/test_230/t- 10 ||
19473                 error "create files on remote directory failed"
19474         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19475         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19476         rm -r $DIR/$tdir || error "unlink remote directory failed"
19477 }
19478 run_test 230a "Create remote directory and files under the remote directory"
19479
19480 test_230b() {
19481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19483         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19484                 skip "Need MDS version at least 2.11.52"
19485
19486         local MDTIDX=1
19487         local mdt_index
19488         local i
19489         local file
19490         local pid
19491         local stripe_count
19492         local migrate_dir=$DIR/$tdir/migrate_dir
19493         local other_dir=$DIR/$tdir/other_dir
19494
19495         test_mkdir $DIR/$tdir
19496         test_mkdir -i0 -c1 $migrate_dir
19497         test_mkdir -i0 -c1 $other_dir
19498         for ((i=0; i<10; i++)); do
19499                 mkdir -p $migrate_dir/dir_${i}
19500                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19501                         error "create files under remote dir failed $i"
19502         done
19503
19504         cp /etc/passwd $migrate_dir/$tfile
19505         cp /etc/passwd $other_dir/$tfile
19506         chattr +SAD $migrate_dir
19507         chattr +SAD $migrate_dir/$tfile
19508
19509         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19510         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19511         local old_dir_mode=$(stat -c%f $migrate_dir)
19512         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19513
19514         mkdir -p $migrate_dir/dir_default_stripe2
19515         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19516         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19517
19518         mkdir -p $other_dir
19519         ln $migrate_dir/$tfile $other_dir/luna
19520         ln $migrate_dir/$tfile $migrate_dir/sofia
19521         ln $other_dir/$tfile $migrate_dir/david
19522         ln -s $migrate_dir/$tfile $other_dir/zachary
19523         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19524         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19525
19526         local len
19527         local lnktgt
19528
19529         # inline symlink
19530         for len in 58 59 60; do
19531                 lnktgt=$(str_repeat 'l' $len)
19532                 touch $migrate_dir/$lnktgt
19533                 ln -s $lnktgt $migrate_dir/${len}char_ln
19534         done
19535
19536         # PATH_MAX
19537         for len in 4094 4095; do
19538                 lnktgt=$(str_repeat 'l' $len)
19539                 ln -s $lnktgt $migrate_dir/${len}char_ln
19540         done
19541
19542         # NAME_MAX
19543         for len in 254 255; do
19544                 touch $migrate_dir/$(str_repeat 'l' $len)
19545         done
19546
19547         $LFS migrate -m $MDTIDX $migrate_dir ||
19548                 error "fails on migrating remote dir to MDT1"
19549
19550         echo "migratate to MDT1, then checking.."
19551         for ((i = 0; i < 10; i++)); do
19552                 for file in $(find $migrate_dir/dir_${i}); do
19553                         mdt_index=$($LFS getstripe -m $file)
19554                         # broken symlink getstripe will fail
19555                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19556                                 error "$file is not on MDT${MDTIDX}"
19557                 done
19558         done
19559
19560         # the multiple link file should still in MDT0
19561         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19562         [ $mdt_index == 0 ] ||
19563                 error "$file is not on MDT${MDTIDX}"
19564
19565         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19566         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19567                 error " expect $old_dir_flag get $new_dir_flag"
19568
19569         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19570         [ "$old_file_flag" = "$new_file_flag" ] ||
19571                 error " expect $old_file_flag get $new_file_flag"
19572
19573         local new_dir_mode=$(stat -c%f $migrate_dir)
19574         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19575                 error "expect mode $old_dir_mode get $new_dir_mode"
19576
19577         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19578         [ "$old_file_mode" = "$new_file_mode" ] ||
19579                 error "expect mode $old_file_mode get $new_file_mode"
19580
19581         diff /etc/passwd $migrate_dir/$tfile ||
19582                 error "$tfile different after migration"
19583
19584         diff /etc/passwd $other_dir/luna ||
19585                 error "luna different after migration"
19586
19587         diff /etc/passwd $migrate_dir/sofia ||
19588                 error "sofia different after migration"
19589
19590         diff /etc/passwd $migrate_dir/david ||
19591                 error "david different after migration"
19592
19593         diff /etc/passwd $other_dir/zachary ||
19594                 error "zachary different after migration"
19595
19596         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19597                 error "${tfile}_ln different after migration"
19598
19599         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19600                 error "${tfile}_ln_other different after migration"
19601
19602         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19603         [ $stripe_count = 2 ] ||
19604                 error "dir strpe_count $d != 2 after migration."
19605
19606         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19607         [ $stripe_count = 2 ] ||
19608                 error "file strpe_count $d != 2 after migration."
19609
19610         #migrate back to MDT0
19611         MDTIDX=0
19612
19613         $LFS migrate -m $MDTIDX $migrate_dir ||
19614                 error "fails on migrating remote dir to MDT0"
19615
19616         echo "migrate back to MDT0, checking.."
19617         for file in $(find $migrate_dir); do
19618                 mdt_index=$($LFS getstripe -m $file)
19619                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19620                         error "$file is not on MDT${MDTIDX}"
19621         done
19622
19623         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19624         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19625                 error " expect $old_dir_flag get $new_dir_flag"
19626
19627         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19628         [ "$old_file_flag" = "$new_file_flag" ] ||
19629                 error " expect $old_file_flag get $new_file_flag"
19630
19631         local new_dir_mode=$(stat -c%f $migrate_dir)
19632         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19633                 error "expect mode $old_dir_mode get $new_dir_mode"
19634
19635         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19636         [ "$old_file_mode" = "$new_file_mode" ] ||
19637                 error "expect mode $old_file_mode get $new_file_mode"
19638
19639         diff /etc/passwd ${migrate_dir}/$tfile ||
19640                 error "$tfile different after migration"
19641
19642         diff /etc/passwd ${other_dir}/luna ||
19643                 error "luna different after migration"
19644
19645         diff /etc/passwd ${migrate_dir}/sofia ||
19646                 error "sofia different after migration"
19647
19648         diff /etc/passwd ${other_dir}/zachary ||
19649                 error "zachary different after migration"
19650
19651         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19652                 error "${tfile}_ln different after migration"
19653
19654         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19655                 error "${tfile}_ln_other different after migration"
19656
19657         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19658         [ $stripe_count = 2 ] ||
19659                 error "dir strpe_count $d != 2 after migration."
19660
19661         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19662         [ $stripe_count = 2 ] ||
19663                 error "file strpe_count $d != 2 after migration."
19664
19665         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19666 }
19667 run_test 230b "migrate directory"
19668
19669 test_230c() {
19670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19671         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19672         remote_mds_nodsh && skip "remote MDS with nodsh"
19673         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19674                 skip "Need MDS version at least 2.11.52"
19675
19676         local MDTIDX=1
19677         local total=3
19678         local mdt_index
19679         local file
19680         local migrate_dir=$DIR/$tdir/migrate_dir
19681
19682         #If migrating directory fails in the middle, all entries of
19683         #the directory is still accessiable.
19684         test_mkdir $DIR/$tdir
19685         test_mkdir -i0 -c1 $migrate_dir
19686         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19687         stat $migrate_dir
19688         createmany -o $migrate_dir/f $total ||
19689                 error "create files under ${migrate_dir} failed"
19690
19691         # fail after migrating top dir, and this will fail only once, so the
19692         # first sub file migration will fail (currently f3), others succeed.
19693         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19694         do_facet mds1 lctl set_param fail_loc=0x1801
19695         local t=$(ls $migrate_dir | wc -l)
19696         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19697                 error "migrate should fail"
19698         local u=$(ls $migrate_dir | wc -l)
19699         [ "$u" == "$t" ] || error "$u != $t during migration"
19700
19701         # add new dir/file should succeed
19702         mkdir $migrate_dir/dir ||
19703                 error "mkdir failed under migrating directory"
19704         touch $migrate_dir/file ||
19705                 error "create file failed under migrating directory"
19706
19707         # add file with existing name should fail
19708         for file in $migrate_dir/f*; do
19709                 stat $file > /dev/null || error "stat $file failed"
19710                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19711                         error "open(O_CREAT|O_EXCL) $file should fail"
19712                 $MULTIOP $file m && error "create $file should fail"
19713                 touch $DIR/$tdir/remote_dir/$tfile ||
19714                         error "touch $tfile failed"
19715                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19716                         error "link $file should fail"
19717                 mdt_index=$($LFS getstripe -m $file)
19718                 if [ $mdt_index == 0 ]; then
19719                         # file failed to migrate is not allowed to rename to
19720                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19721                                 error "rename to $file should fail"
19722                 else
19723                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19724                                 error "rename to $file failed"
19725                 fi
19726                 echo hello >> $file || error "write $file failed"
19727         done
19728
19729         # resume migration with different options should fail
19730         $LFS migrate -m 0 $migrate_dir &&
19731                 error "migrate -m 0 $migrate_dir should fail"
19732
19733         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19734                 error "migrate -c 2 $migrate_dir should fail"
19735
19736         # resume migration should succeed
19737         $LFS migrate -m $MDTIDX $migrate_dir ||
19738                 error "migrate $migrate_dir failed"
19739
19740         echo "Finish migration, then checking.."
19741         for file in $(find $migrate_dir); do
19742                 mdt_index=$($LFS getstripe -m $file)
19743                 [ $mdt_index == $MDTIDX ] ||
19744                         error "$file is not on MDT${MDTIDX}"
19745         done
19746
19747         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19748 }
19749 run_test 230c "check directory accessiblity if migration failed"
19750
19751 test_230d() {
19752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19754         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19755                 skip "Need MDS version at least 2.11.52"
19756         # LU-11235
19757         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19758
19759         local migrate_dir=$DIR/$tdir/migrate_dir
19760         local old_index
19761         local new_index
19762         local old_count
19763         local new_count
19764         local new_hash
19765         local mdt_index
19766         local i
19767         local j
19768
19769         old_index=$((RANDOM % MDSCOUNT))
19770         old_count=$((MDSCOUNT - old_index))
19771         new_index=$((RANDOM % MDSCOUNT))
19772         new_count=$((MDSCOUNT - new_index))
19773         new_hash=1 # for all_char
19774
19775         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19776         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19777
19778         test_mkdir $DIR/$tdir
19779         test_mkdir -i $old_index -c $old_count $migrate_dir
19780
19781         for ((i=0; i<100; i++)); do
19782                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19783                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19784                         error "create files under remote dir failed $i"
19785         done
19786
19787         echo -n "Migrate from MDT$old_index "
19788         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19789         echo -n "to MDT$new_index"
19790         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19791         echo
19792
19793         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19794         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19795                 error "migrate remote dir error"
19796
19797         echo "Finish migration, then checking.."
19798         for file in $(find $migrate_dir -maxdepth 1); do
19799                 mdt_index=$($LFS getstripe -m $file)
19800                 if [ $mdt_index -lt $new_index ] ||
19801                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19802                         error "$file is on MDT$mdt_index"
19803                 fi
19804         done
19805
19806         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19807 }
19808 run_test 230d "check migrate big directory"
19809
19810 test_230e() {
19811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19813         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19814                 skip "Need MDS version at least 2.11.52"
19815
19816         local i
19817         local j
19818         local a_fid
19819         local b_fid
19820
19821         mkdir_on_mdt0 $DIR/$tdir
19822         mkdir $DIR/$tdir/migrate_dir
19823         mkdir $DIR/$tdir/other_dir
19824         touch $DIR/$tdir/migrate_dir/a
19825         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19826         ls $DIR/$tdir/other_dir
19827
19828         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19829                 error "migrate dir fails"
19830
19831         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19832         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19833
19834         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19835         [ $mdt_index == 0 ] || error "a is not on MDT0"
19836
19837         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19838                 error "migrate dir fails"
19839
19840         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19841         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19842
19843         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19844         [ $mdt_index == 1 ] || error "a is not on MDT1"
19845
19846         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19847         [ $mdt_index == 1 ] || error "b is not on MDT1"
19848
19849         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19850         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19851
19852         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19853
19854         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19855 }
19856 run_test 230e "migrate mulitple local link files"
19857
19858 test_230f() {
19859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19862                 skip "Need MDS version at least 2.11.52"
19863
19864         local a_fid
19865         local ln_fid
19866
19867         mkdir -p $DIR/$tdir
19868         mkdir $DIR/$tdir/migrate_dir
19869         $LFS mkdir -i1 $DIR/$tdir/other_dir
19870         touch $DIR/$tdir/migrate_dir/a
19871         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19872         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19873         ls $DIR/$tdir/other_dir
19874
19875         # a should be migrated to MDT1, since no other links on MDT0
19876         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19877                 error "#1 migrate dir fails"
19878         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19879         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19880         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19881         [ $mdt_index == 1 ] || error "a is not on MDT1"
19882
19883         # a should stay on MDT1, because it is a mulitple link file
19884         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19885                 error "#2 migrate dir fails"
19886         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19887         [ $mdt_index == 1 ] || error "a is not on MDT1"
19888
19889         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19890                 error "#3 migrate dir fails"
19891
19892         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19893         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19894         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19895
19896         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19897         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19898
19899         # a should be migrated to MDT0, since no other links on MDT1
19900         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19901                 error "#4 migrate dir fails"
19902         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19903         [ $mdt_index == 0 ] || error "a is not on MDT0"
19904
19905         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19906 }
19907 run_test 230f "migrate mulitple remote link files"
19908
19909 test_230g() {
19910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19912         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19913                 skip "Need MDS version at least 2.11.52"
19914
19915         mkdir -p $DIR/$tdir/migrate_dir
19916
19917         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19918                 error "migrating dir to non-exist MDT succeeds"
19919         true
19920 }
19921 run_test 230g "migrate dir to non-exist MDT"
19922
19923 test_230h() {
19924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19925         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19926         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19927                 skip "Need MDS version at least 2.11.52"
19928
19929         local mdt_index
19930
19931         mkdir -p $DIR/$tdir/migrate_dir
19932
19933         $LFS migrate -m1 $DIR &&
19934                 error "migrating mountpoint1 should fail"
19935
19936         $LFS migrate -m1 $DIR/$tdir/.. &&
19937                 error "migrating mountpoint2 should fail"
19938
19939         # same as mv
19940         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19941                 error "migrating $tdir/migrate_dir/.. should fail"
19942
19943         true
19944 }
19945 run_test 230h "migrate .. and root"
19946
19947 test_230i() {
19948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19949         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19950         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19951                 skip "Need MDS version at least 2.11.52"
19952
19953         mkdir -p $DIR/$tdir/migrate_dir
19954
19955         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19956                 error "migration fails with a tailing slash"
19957
19958         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19959                 error "migration fails with two tailing slashes"
19960 }
19961 run_test 230i "lfs migrate -m tolerates trailing slashes"
19962
19963 test_230j() {
19964         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19965         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19966                 skip "Need MDS version at least 2.11.52"
19967
19968         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19969         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19970                 error "create $tfile failed"
19971         cat /etc/passwd > $DIR/$tdir/$tfile
19972
19973         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19974
19975         cmp /etc/passwd $DIR/$tdir/$tfile ||
19976                 error "DoM file mismatch after migration"
19977 }
19978 run_test 230j "DoM file data not changed after dir migration"
19979
19980 test_230k() {
19981         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19982         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19983                 skip "Need MDS version at least 2.11.56"
19984
19985         local total=20
19986         local files_on_starting_mdt=0
19987
19988         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19989         $LFS getdirstripe $DIR/$tdir
19990         for i in $(seq $total); do
19991                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19992                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19993                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19994         done
19995
19996         echo "$files_on_starting_mdt files on MDT0"
19997
19998         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19999         $LFS getdirstripe $DIR/$tdir
20000
20001         files_on_starting_mdt=0
20002         for i in $(seq $total); do
20003                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20004                         error "file $tfile.$i mismatch after migration"
20005                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20006                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20007         done
20008
20009         echo "$files_on_starting_mdt files on MDT1 after migration"
20010         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20011
20012         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20013         $LFS getdirstripe $DIR/$tdir
20014
20015         files_on_starting_mdt=0
20016         for i in $(seq $total); do
20017                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20018                         error "file $tfile.$i mismatch after 2nd migration"
20019                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20020                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20021         done
20022
20023         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20024         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20025
20026         true
20027 }
20028 run_test 230k "file data not changed after dir migration"
20029
20030 test_230l() {
20031         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20032         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20033                 skip "Need MDS version at least 2.11.56"
20034
20035         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20036         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20037                 error "create files under remote dir failed $i"
20038         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20039 }
20040 run_test 230l "readdir between MDTs won't crash"
20041
20042 test_230m() {
20043         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20044         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20045                 skip "Need MDS version at least 2.11.56"
20046
20047         local MDTIDX=1
20048         local mig_dir=$DIR/$tdir/migrate_dir
20049         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20050         local shortstr="b"
20051         local val
20052
20053         echo "Creating files and dirs with xattrs"
20054         test_mkdir $DIR/$tdir
20055         test_mkdir -i0 -c1 $mig_dir
20056         mkdir $mig_dir/dir
20057         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20058                 error "cannot set xattr attr1 on dir"
20059         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20060                 error "cannot set xattr attr2 on dir"
20061         touch $mig_dir/dir/f0
20062         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20063                 error "cannot set xattr attr1 on file"
20064         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20065                 error "cannot set xattr attr2 on file"
20066         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20067         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20068         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20069         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20070         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20071         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20072         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20073         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20074         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20075
20076         echo "Migrating to MDT1"
20077         $LFS migrate -m $MDTIDX $mig_dir ||
20078                 error "fails on migrating dir to MDT1"
20079
20080         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20081         echo "Checking xattrs"
20082         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20083         [ "$val" = $longstr ] ||
20084                 error "expecting xattr1 $longstr on dir, found $val"
20085         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20086         [ "$val" = $shortstr ] ||
20087                 error "expecting xattr2 $shortstr on dir, found $val"
20088         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20089         [ "$val" = $longstr ] ||
20090                 error "expecting xattr1 $longstr on file, found $val"
20091         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20092         [ "$val" = $shortstr ] ||
20093                 error "expecting xattr2 $shortstr on file, found $val"
20094 }
20095 run_test 230m "xattrs not changed after dir migration"
20096
20097 test_230n() {
20098         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20099         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20100                 skip "Need MDS version at least 2.13.53"
20101
20102         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20103         cat /etc/hosts > $DIR/$tdir/$tfile
20104         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20105         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20106
20107         cmp /etc/hosts $DIR/$tdir/$tfile ||
20108                 error "File data mismatch after migration"
20109 }
20110 run_test 230n "Dir migration with mirrored file"
20111
20112 test_230o() {
20113         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20114         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20115                 skip "Need MDS version at least 2.13.52"
20116
20117         local mdts=$(comma_list $(mdts_nodes))
20118         local timeout=100
20119         local restripe_status
20120         local delta
20121         local i
20122
20123         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20124
20125         # in case "crush" hash type is not set
20126         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20127
20128         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20129                            mdt.*MDT0000.enable_dir_restripe)
20130         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20131         stack_trap "do_nodes $mdts $LCTL set_param \
20132                     mdt.*.enable_dir_restripe=$restripe_status"
20133
20134         mkdir $DIR/$tdir
20135         createmany -m $DIR/$tdir/f 100 ||
20136                 error "create files under remote dir failed $i"
20137         createmany -d $DIR/$tdir/d 100 ||
20138                 error "create dirs under remote dir failed $i"
20139
20140         for i in $(seq 2 $MDSCOUNT); do
20141                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20142                 $LFS setdirstripe -c $i $DIR/$tdir ||
20143                         error "split -c $i $tdir failed"
20144                 wait_update $HOSTNAME \
20145                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20146                         error "dir split not finished"
20147                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20148                         awk '/migrate/ {sum += $2} END { print sum }')
20149                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20150                 # delta is around total_files/stripe_count
20151                 (( $delta < 200 / (i - 1) + 4 )) ||
20152                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20153         done
20154 }
20155 run_test 230o "dir split"
20156
20157 test_230p() {
20158         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20159         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20160                 skip "Need MDS version at least 2.13.52"
20161
20162         local mdts=$(comma_list $(mdts_nodes))
20163         local timeout=100
20164         local restripe_status
20165         local delta
20166         local c
20167
20168         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20169
20170         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20171
20172         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20173                            mdt.*MDT0000.enable_dir_restripe)
20174         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20175         stack_trap "do_nodes $mdts $LCTL set_param \
20176                     mdt.*.enable_dir_restripe=$restripe_status"
20177
20178         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20179         createmany -m $DIR/$tdir/f 100 ||
20180                 error "create files under remote dir failed"
20181         createmany -d $DIR/$tdir/d 100 ||
20182                 error "create dirs under remote dir failed"
20183
20184         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20185                 local mdt_hash="crush"
20186
20187                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20188                 $LFS setdirstripe -c $c $DIR/$tdir ||
20189                         error "split -c $c $tdir failed"
20190                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20191                         mdt_hash="$mdt_hash,fixed"
20192                 elif [ $c -eq 1 ]; then
20193                         mdt_hash="none"
20194                 fi
20195                 wait_update $HOSTNAME \
20196                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20197                         error "dir merge not finished"
20198                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20199                         awk '/migrate/ {sum += $2} END { print sum }')
20200                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20201                 # delta is around total_files/stripe_count
20202                 (( delta < 200 / c + 4 )) ||
20203                         error "$delta files migrated >= $((200 / c + 4))"
20204         done
20205 }
20206 run_test 230p "dir merge"
20207
20208 test_230q() {
20209         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20210         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20211                 skip "Need MDS version at least 2.13.52"
20212
20213         local mdts=$(comma_list $(mdts_nodes))
20214         local saved_threshold=$(do_facet mds1 \
20215                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20216         local saved_delta=$(do_facet mds1 \
20217                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20218         local threshold=100
20219         local delta=2
20220         local total=0
20221         local stripe_count=0
20222         local stripe_index
20223         local nr_files
20224         local create
20225
20226         # test with fewer files on ZFS
20227         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20228
20229         stack_trap "do_nodes $mdts $LCTL set_param \
20230                     mdt.*.dir_split_count=$saved_threshold"
20231         stack_trap "do_nodes $mdts $LCTL set_param \
20232                     mdt.*.dir_split_delta=$saved_delta"
20233         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20234         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20235         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20236         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20237         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20238         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20239
20240         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20241         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20242
20243         create=$((threshold * 3 / 2))
20244         while [ $stripe_count -lt $MDSCOUNT ]; do
20245                 createmany -m $DIR/$tdir/f $total $create ||
20246                         error "create sub files failed"
20247                 stat $DIR/$tdir > /dev/null
20248                 total=$((total + create))
20249                 stripe_count=$((stripe_count + delta))
20250                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20251
20252                 wait_update $HOSTNAME \
20253                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20254                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20255
20256                 wait_update $HOSTNAME \
20257                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20258                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20259
20260                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20261                 echo "$nr_files/$total files on MDT$stripe_index after split"
20262                 # allow 10% margin of imbalance with crush hash
20263                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20264                         error "$nr_files files on MDT$stripe_index after split"
20265
20266                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20267                 [ $nr_files -eq $total ] ||
20268                         error "total sub files $nr_files != $total"
20269         done
20270
20271         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20272
20273         echo "fixed layout directory won't auto split"
20274         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20275         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20276                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20277         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20278                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20279 }
20280 run_test 230q "dir auto split"
20281
20282 test_230r() {
20283         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20284         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20285         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20286                 skip "Need MDS version at least 2.13.54"
20287
20288         # maximum amount of local locks:
20289         # parent striped dir - 2 locks
20290         # new stripe in parent to migrate to - 1 lock
20291         # source and target - 2 locks
20292         # Total 5 locks for regular file
20293         mkdir -p $DIR/$tdir
20294         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20295         touch $DIR/$tdir/dir1/eee
20296
20297         # create 4 hardlink for 4 more locks
20298         # Total: 9 locks > RS_MAX_LOCKS (8)
20299         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20300         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20301         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20302         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20303         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20304         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20305         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20306         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20307
20308         cancel_lru_locks mdc
20309
20310         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20311                 error "migrate dir fails"
20312
20313         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20314 }
20315 run_test 230r "migrate with too many local locks"
20316
20317 test_230s() {
20318         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20319                 skip "Need MDS version at least 2.13.57"
20320
20321         local mdts=$(comma_list $(mdts_nodes))
20322         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20323                                 mdt.*MDT0000.enable_dir_restripe)
20324
20325         stack_trap "do_nodes $mdts $LCTL set_param \
20326                     mdt.*.enable_dir_restripe=$restripe_status"
20327
20328         local st
20329         for st in 0 1; do
20330                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20331                 test_mkdir $DIR/$tdir
20332                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20333                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20334                 rmdir $DIR/$tdir
20335         done
20336 }
20337 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20338
20339 test_230t()
20340 {
20341         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20342         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20343                 skip "Need MDS version at least 2.14.50"
20344
20345         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20346         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20347         $LFS project -p 1 -s $DIR/$tdir ||
20348                 error "set $tdir project id failed"
20349         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20350                 error "set subdir project id failed"
20351         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20352 }
20353 run_test 230t "migrate directory with project ID set"
20354
20355 test_230u()
20356 {
20357         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20358         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20359                 skip "Need MDS version at least 2.14.53"
20360
20361         local count
20362
20363         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20364         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20365         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20366         for i in $(seq 0 $((MDSCOUNT - 1))); do
20367                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20368                 echo "$count dirs migrated to MDT$i"
20369         done
20370         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20371         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20372 }
20373 run_test 230u "migrate directory by QOS"
20374
20375 test_230v()
20376 {
20377         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20378         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20379                 skip "Need MDS version at least 2.14.53"
20380
20381         local count
20382
20383         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20384         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20385         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20386         for i in $(seq 0 $((MDSCOUNT - 1))); do
20387                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20388                 echo "$count subdirs migrated to MDT$i"
20389                 (( i == 3 )) && (( count > 0 )) &&
20390                         error "subdir shouldn't be migrated to MDT3"
20391         done
20392         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20393         (( count == 3 )) || error "dirs migrated to $count MDTs"
20394 }
20395 run_test 230v "subdir migrated to the MDT where its parent is located"
20396
20397 test_230w() {
20398         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20399         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20400                 skip "Need MDS version at least 2.14.53"
20401
20402         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20403
20404         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20405                 error "migrate failed"
20406
20407         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20408                 error "$tdir stripe count mismatch"
20409
20410         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20411                 error "$tdir/sub is striped"
20412 }
20413 run_test 230w "non-recursive mode dir migration"
20414
20415 test_231a()
20416 {
20417         # For simplicity this test assumes that max_pages_per_rpc
20418         # is the same across all OSCs
20419         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20420         local bulk_size=$((max_pages * PAGE_SIZE))
20421         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20422                                        head -n 1)
20423
20424         mkdir -p $DIR/$tdir
20425         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20426                 error "failed to set stripe with -S ${brw_size}M option"
20427
20428         # clear the OSC stats
20429         $LCTL set_param osc.*.stats=0 &>/dev/null
20430         stop_writeback
20431
20432         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20433         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20434                 oflag=direct &>/dev/null || error "dd failed"
20435
20436         sync; sleep 1; sync # just to be safe
20437         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20438         if [ x$nrpcs != "x1" ]; then
20439                 $LCTL get_param osc.*.stats
20440                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20441         fi
20442
20443         start_writeback
20444         # Drop the OSC cache, otherwise we will read from it
20445         cancel_lru_locks osc
20446
20447         # clear the OSC stats
20448         $LCTL set_param osc.*.stats=0 &>/dev/null
20449
20450         # Client reads $bulk_size.
20451         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20452                 iflag=direct &>/dev/null || error "dd failed"
20453
20454         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20455         if [ x$nrpcs != "x1" ]; then
20456                 $LCTL get_param osc.*.stats
20457                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20458         fi
20459 }
20460 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20461
20462 test_231b() {
20463         mkdir -p $DIR/$tdir
20464         local i
20465         for i in {0..1023}; do
20466                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20467                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20468                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20469         done
20470         sync
20471 }
20472 run_test 231b "must not assert on fully utilized OST request buffer"
20473
20474 test_232a() {
20475         mkdir -p $DIR/$tdir
20476         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20477
20478         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20479         do_facet ost1 $LCTL set_param fail_loc=0x31c
20480
20481         # ignore dd failure
20482         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20483
20484         do_facet ost1 $LCTL set_param fail_loc=0
20485         umount_client $MOUNT || error "umount failed"
20486         mount_client $MOUNT || error "mount failed"
20487         stop ost1 || error "cannot stop ost1"
20488         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20489 }
20490 run_test 232a "failed lock should not block umount"
20491
20492 test_232b() {
20493         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20494                 skip "Need MDS version at least 2.10.58"
20495
20496         mkdir -p $DIR/$tdir
20497         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20498         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20499         sync
20500         cancel_lru_locks osc
20501
20502         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20503         do_facet ost1 $LCTL set_param fail_loc=0x31c
20504
20505         # ignore failure
20506         $LFS data_version $DIR/$tdir/$tfile || true
20507
20508         do_facet ost1 $LCTL set_param fail_loc=0
20509         umount_client $MOUNT || error "umount failed"
20510         mount_client $MOUNT || error "mount failed"
20511         stop ost1 || error "cannot stop ost1"
20512         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20513 }
20514 run_test 232b "failed data version lock should not block umount"
20515
20516 test_233a() {
20517         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20518                 skip "Need MDS version at least 2.3.64"
20519         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20520
20521         local fid=$($LFS path2fid $MOUNT)
20522
20523         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20524                 error "cannot access $MOUNT using its FID '$fid'"
20525 }
20526 run_test 233a "checking that OBF of the FS root succeeds"
20527
20528 test_233b() {
20529         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20530                 skip "Need MDS version at least 2.5.90"
20531         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20532
20533         local fid=$($LFS path2fid $MOUNT/.lustre)
20534
20535         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20536                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20537
20538         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20539         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20540                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20541 }
20542 run_test 233b "checking that OBF of the FS .lustre succeeds"
20543
20544 test_234() {
20545         local p="$TMP/sanityN-$TESTNAME.parameters"
20546         save_lustre_params client "llite.*.xattr_cache" > $p
20547         lctl set_param llite.*.xattr_cache 1 ||
20548                 skip_env "xattr cache is not supported"
20549
20550         mkdir -p $DIR/$tdir || error "mkdir failed"
20551         touch $DIR/$tdir/$tfile || error "touch failed"
20552         # OBD_FAIL_LLITE_XATTR_ENOMEM
20553         $LCTL set_param fail_loc=0x1405
20554         getfattr -n user.attr $DIR/$tdir/$tfile &&
20555                 error "getfattr should have failed with ENOMEM"
20556         $LCTL set_param fail_loc=0x0
20557         rm -rf $DIR/$tdir
20558
20559         restore_lustre_params < $p
20560         rm -f $p
20561 }
20562 run_test 234 "xattr cache should not crash on ENOMEM"
20563
20564 test_235() {
20565         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20566                 skip "Need MDS version at least 2.4.52"
20567
20568         flock_deadlock $DIR/$tfile
20569         local RC=$?
20570         case $RC in
20571                 0)
20572                 ;;
20573                 124) error "process hangs on a deadlock"
20574                 ;;
20575                 *) error "error executing flock_deadlock $DIR/$tfile"
20576                 ;;
20577         esac
20578 }
20579 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20580
20581 #LU-2935
20582 test_236() {
20583         check_swap_layouts_support
20584
20585         local ref1=/etc/passwd
20586         local ref2=/etc/group
20587         local file1=$DIR/$tdir/f1
20588         local file2=$DIR/$tdir/f2
20589
20590         test_mkdir -c1 $DIR/$tdir
20591         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20592         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20593         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20594         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20595         local fd=$(free_fd)
20596         local cmd="exec $fd<>$file2"
20597         eval $cmd
20598         rm $file2
20599         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20600                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20601         cmd="exec $fd>&-"
20602         eval $cmd
20603         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20604
20605         #cleanup
20606         rm -rf $DIR/$tdir
20607 }
20608 run_test 236 "Layout swap on open unlinked file"
20609
20610 # LU-4659 linkea consistency
20611 test_238() {
20612         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20613                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20614                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20615                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20616
20617         touch $DIR/$tfile
20618         ln $DIR/$tfile $DIR/$tfile.lnk
20619         touch $DIR/$tfile.new
20620         mv $DIR/$tfile.new $DIR/$tfile
20621         local fid1=$($LFS path2fid $DIR/$tfile)
20622         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20623         local path1=$($LFS fid2path $FSNAME "$fid1")
20624         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20625         local path2=$($LFS fid2path $FSNAME "$fid2")
20626         [ $tfile.lnk == $path2 ] ||
20627                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20628         rm -f $DIR/$tfile*
20629 }
20630 run_test 238 "Verify linkea consistency"
20631
20632 test_239A() { # was test_239
20633         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20634                 skip "Need MDS version at least 2.5.60"
20635
20636         local list=$(comma_list $(mdts_nodes))
20637
20638         mkdir -p $DIR/$tdir
20639         createmany -o $DIR/$tdir/f- 5000
20640         unlinkmany $DIR/$tdir/f- 5000
20641         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20642                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20643         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20644                         osp.*MDT*.sync_in_flight" | calc_sum)
20645         [ "$changes" -eq 0 ] || error "$changes not synced"
20646 }
20647 run_test 239A "osp_sync test"
20648
20649 test_239a() { #LU-5297
20650         remote_mds_nodsh && skip "remote MDS with nodsh"
20651
20652         touch $DIR/$tfile
20653         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20654         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20655         chgrp $RUNAS_GID $DIR/$tfile
20656         wait_delete_completed
20657 }
20658 run_test 239a "process invalid osp sync record correctly"
20659
20660 test_239b() { #LU-5297
20661         remote_mds_nodsh && skip "remote MDS with nodsh"
20662
20663         touch $DIR/$tfile1
20664         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20665         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20666         chgrp $RUNAS_GID $DIR/$tfile1
20667         wait_delete_completed
20668         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20669         touch $DIR/$tfile2
20670         chgrp $RUNAS_GID $DIR/$tfile2
20671         wait_delete_completed
20672 }
20673 run_test 239b "process osp sync record with ENOMEM error correctly"
20674
20675 test_240() {
20676         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20677         remote_mds_nodsh && skip "remote MDS with nodsh"
20678
20679         mkdir -p $DIR/$tdir
20680
20681         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20682                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20683         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20684                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20685
20686         umount_client $MOUNT || error "umount failed"
20687         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20688         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20689         mount_client $MOUNT || error "failed to mount client"
20690
20691         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20692         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20693 }
20694 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20695
20696 test_241_bio() {
20697         local count=$1
20698         local bsize=$2
20699
20700         for LOOP in $(seq $count); do
20701                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20702                 cancel_lru_locks $OSC || true
20703         done
20704 }
20705
20706 test_241_dio() {
20707         local count=$1
20708         local bsize=$2
20709
20710         for LOOP in $(seq $1); do
20711                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20712                         2>/dev/null
20713         done
20714 }
20715
20716 test_241a() { # was test_241
20717         local bsize=$PAGE_SIZE
20718
20719         (( bsize < 40960 )) && bsize=40960
20720         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20721         ls -la $DIR/$tfile
20722         cancel_lru_locks $OSC
20723         test_241_bio 1000 $bsize &
20724         PID=$!
20725         test_241_dio 1000 $bsize
20726         wait $PID
20727 }
20728 run_test 241a "bio vs dio"
20729
20730 test_241b() {
20731         local bsize=$PAGE_SIZE
20732
20733         (( bsize < 40960 )) && bsize=40960
20734         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20735         ls -la $DIR/$tfile
20736         test_241_dio 1000 $bsize &
20737         PID=$!
20738         test_241_dio 1000 $bsize
20739         wait $PID
20740 }
20741 run_test 241b "dio vs dio"
20742
20743 test_242() {
20744         remote_mds_nodsh && skip "remote MDS with nodsh"
20745
20746         mkdir_on_mdt0 $DIR/$tdir
20747         touch $DIR/$tdir/$tfile
20748
20749         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20750         do_facet mds1 lctl set_param fail_loc=0x105
20751         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20752
20753         do_facet mds1 lctl set_param fail_loc=0
20754         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20755 }
20756 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20757
20758 test_243()
20759 {
20760         test_mkdir $DIR/$tdir
20761         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20762 }
20763 run_test 243 "various group lock tests"
20764
20765 test_244a()
20766 {
20767         test_mkdir $DIR/$tdir
20768         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20769         sendfile_grouplock $DIR/$tdir/$tfile || \
20770                 error "sendfile+grouplock failed"
20771         rm -rf $DIR/$tdir
20772 }
20773 run_test 244a "sendfile with group lock tests"
20774
20775 test_244b()
20776 {
20777         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20778
20779         local threads=50
20780         local size=$((1024*1024))
20781
20782         test_mkdir $DIR/$tdir
20783         for i in $(seq 1 $threads); do
20784                 local file=$DIR/$tdir/file_$((i / 10))
20785                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20786                 local pids[$i]=$!
20787         done
20788         for i in $(seq 1 $threads); do
20789                 wait ${pids[$i]}
20790         done
20791 }
20792 run_test 244b "multi-threaded write with group lock"
20793
20794 test_245() {
20795         local flagname="multi_mod_rpcs"
20796         local connect_data_name="max_mod_rpcs"
20797         local out
20798
20799         # check if multiple modify RPCs flag is set
20800         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20801                 grep "connect_flags:")
20802         echo "$out"
20803
20804         echo "$out" | grep -qw $flagname
20805         if [ $? -ne 0 ]; then
20806                 echo "connect flag $flagname is not set"
20807                 return
20808         fi
20809
20810         # check if multiple modify RPCs data is set
20811         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20812         echo "$out"
20813
20814         echo "$out" | grep -qw $connect_data_name ||
20815                 error "import should have connect data $connect_data_name"
20816 }
20817 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20818
20819 cleanup_247() {
20820         local submount=$1
20821
20822         trap 0
20823         umount_client $submount
20824         rmdir $submount
20825 }
20826
20827 test_247a() {
20828         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20829                 grep -q subtree ||
20830                 skip_env "Fileset feature is not supported"
20831
20832         local submount=${MOUNT}_$tdir
20833
20834         mkdir $MOUNT/$tdir
20835         mkdir -p $submount || error "mkdir $submount failed"
20836         FILESET="$FILESET/$tdir" mount_client $submount ||
20837                 error "mount $submount failed"
20838         trap "cleanup_247 $submount" EXIT
20839         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20840         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20841                 error "read $MOUNT/$tdir/$tfile failed"
20842         cleanup_247 $submount
20843 }
20844 run_test 247a "mount subdir as fileset"
20845
20846 test_247b() {
20847         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20848                 skip_env "Fileset feature is not supported"
20849
20850         local submount=${MOUNT}_$tdir
20851
20852         rm -rf $MOUNT/$tdir
20853         mkdir -p $submount || error "mkdir $submount failed"
20854         SKIP_FILESET=1
20855         FILESET="$FILESET/$tdir" mount_client $submount &&
20856                 error "mount $submount should fail"
20857         rmdir $submount
20858 }
20859 run_test 247b "mount subdir that dose not exist"
20860
20861 test_247c() {
20862         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20863                 skip_env "Fileset feature is not supported"
20864
20865         local submount=${MOUNT}_$tdir
20866
20867         mkdir -p $MOUNT/$tdir/dir1
20868         mkdir -p $submount || error "mkdir $submount failed"
20869         trap "cleanup_247 $submount" EXIT
20870         FILESET="$FILESET/$tdir" mount_client $submount ||
20871                 error "mount $submount failed"
20872         local fid=$($LFS path2fid $MOUNT/)
20873         $LFS fid2path $submount $fid && error "fid2path should fail"
20874         cleanup_247 $submount
20875 }
20876 run_test 247c "running fid2path outside subdirectory root"
20877
20878 test_247d() {
20879         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20880                 skip "Fileset feature is not supported"
20881
20882         local submount=${MOUNT}_$tdir
20883
20884         mkdir -p $MOUNT/$tdir/dir1
20885         mkdir -p $submount || error "mkdir $submount failed"
20886         FILESET="$FILESET/$tdir" mount_client $submount ||
20887                 error "mount $submount failed"
20888         trap "cleanup_247 $submount" EXIT
20889
20890         local td=$submount/dir1
20891         local fid=$($LFS path2fid $td)
20892         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20893
20894         # check that we get the same pathname back
20895         local rootpath
20896         local found
20897         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20898                 echo "$rootpath $fid"
20899                 found=$($LFS fid2path $rootpath "$fid")
20900                 [ -n "found" ] || error "fid2path should succeed"
20901                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20902         done
20903         # check wrong root path format
20904         rootpath=$submount"_wrong"
20905         found=$($LFS fid2path $rootpath "$fid")
20906         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20907
20908         cleanup_247 $submount
20909 }
20910 run_test 247d "running fid2path inside subdirectory root"
20911
20912 # LU-8037
20913 test_247e() {
20914         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20915                 grep -q subtree ||
20916                 skip "Fileset feature is not supported"
20917
20918         local submount=${MOUNT}_$tdir
20919
20920         mkdir $MOUNT/$tdir
20921         mkdir -p $submount || error "mkdir $submount failed"
20922         FILESET="$FILESET/.." mount_client $submount &&
20923                 error "mount $submount should fail"
20924         rmdir $submount
20925 }
20926 run_test 247e "mount .. as fileset"
20927
20928 test_247f() {
20929         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20930         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20931                 skip "Need at least version 2.13.52"
20932         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20933                 skip "Need at least version 2.14.50"
20934         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20935                 grep -q subtree ||
20936                 skip "Fileset feature is not supported"
20937
20938         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20939         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20940                 error "mkdir remote failed"
20941         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20942                 error "mkdir remote/subdir failed"
20943         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20944                 error "mkdir striped failed"
20945         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20946
20947         local submount=${MOUNT}_$tdir
20948
20949         mkdir -p $submount || error "mkdir $submount failed"
20950         stack_trap "rmdir $submount"
20951
20952         local dir
20953         local stat
20954         local fileset=$FILESET
20955         local mdts=$(comma_list $(mdts_nodes))
20956
20957         stat=$(do_facet mds1 $LCTL get_param -n \
20958                 mdt.*MDT0000.enable_remote_subdir_mount)
20959         stack_trap "do_nodes $mdts $LCTL set_param \
20960                 mdt.*.enable_remote_subdir_mount=$stat"
20961
20962         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20963         stack_trap "umount_client $submount"
20964         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20965                 error "mount remote dir $dir should fail"
20966
20967         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20968                 $tdir/striped/. ; do
20969                 FILESET="$fileset/$dir" mount_client $submount ||
20970                         error "mount $dir failed"
20971                 umount_client $submount
20972         done
20973
20974         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20975         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20976                 error "mount $tdir/remote failed"
20977 }
20978 run_test 247f "mount striped or remote directory as fileset"
20979
20980 test_247g() {
20981         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20982         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20983                 skip "Need at least version 2.14.50"
20984
20985         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20986                 error "mkdir $tdir failed"
20987         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20988
20989         local submount=${MOUNT}_$tdir
20990
20991         mkdir -p $submount || error "mkdir $submount failed"
20992         stack_trap "rmdir $submount"
20993
20994         FILESET="$fileset/$tdir" mount_client $submount ||
20995                 error "mount $dir failed"
20996         stack_trap "umount $submount"
20997
20998         local mdts=$(comma_list $(mdts_nodes))
20999
21000         local nrpcs
21001
21002         stat $submount > /dev/null
21003         cancel_lru_locks $MDC
21004         stat $submount > /dev/null
21005         stat $submount/$tfile > /dev/null
21006         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21007         stat $submount/$tfile > /dev/null
21008         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21009                 awk '/getattr/ {sum += $2} END {print sum}')
21010
21011         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21012 }
21013 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21014
21015 test_248a() {
21016         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21017         [ -z "$fast_read_sav" ] && skip "no fast read support"
21018
21019         # create a large file for fast read verification
21020         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21021
21022         # make sure the file is created correctly
21023         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21024                 { rm -f $DIR/$tfile; skip "file creation error"; }
21025
21026         echo "Test 1: verify that fast read is 4 times faster on cache read"
21027
21028         # small read with fast read enabled
21029         $LCTL set_param -n llite.*.fast_read=1
21030         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21031                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21032                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21033         # small read with fast read disabled
21034         $LCTL set_param -n llite.*.fast_read=0
21035         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21036                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21037                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21038
21039         # verify that fast read is 4 times faster for cache read
21040         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21041                 error_not_in_vm "fast read was not 4 times faster: " \
21042                            "$t_fast vs $t_slow"
21043
21044         echo "Test 2: verify the performance between big and small read"
21045         $LCTL set_param -n llite.*.fast_read=1
21046
21047         # 1k non-cache read
21048         cancel_lru_locks osc
21049         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21050                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21051                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21052
21053         # 1M non-cache read
21054         cancel_lru_locks osc
21055         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21056                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21057                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21058
21059         # verify that big IO is not 4 times faster than small IO
21060         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21061                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21062
21063         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21064         rm -f $DIR/$tfile
21065 }
21066 run_test 248a "fast read verification"
21067
21068 test_248b() {
21069         # Default short_io_bytes=16384, try both smaller and larger sizes.
21070         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21071         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21072         echo "bs=53248 count=113 normal buffered write"
21073         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21074                 error "dd of initial data file failed"
21075         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21076
21077         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21078         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21079                 error "dd with sync normal writes failed"
21080         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21081
21082         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21083         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21084                 error "dd with sync small writes failed"
21085         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21086
21087         cancel_lru_locks osc
21088
21089         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21090         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21091         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21092         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21093                 iflag=direct || error "dd with O_DIRECT small read failed"
21094         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21095         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21096                 error "compare $TMP/$tfile.1 failed"
21097
21098         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21099         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21100
21101         # just to see what the maximum tunable value is, and test parsing
21102         echo "test invalid parameter 2MB"
21103         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21104                 error "too-large short_io_bytes allowed"
21105         echo "test maximum parameter 512KB"
21106         # if we can set a larger short_io_bytes, run test regardless of version
21107         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21108                 # older clients may not allow setting it this large, that's OK
21109                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21110                         skip "Need at least client version 2.13.50"
21111                 error "medium short_io_bytes failed"
21112         fi
21113         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21114         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21115
21116         echo "test large parameter 64KB"
21117         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21118         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21119
21120         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21121         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21122                 error "dd with sync large writes failed"
21123         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21124
21125         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21126         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21127         num=$((113 * 4096 / PAGE_SIZE))
21128         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21129         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21130                 error "dd with O_DIRECT large writes failed"
21131         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21132                 error "compare $DIR/$tfile.3 failed"
21133
21134         cancel_lru_locks osc
21135
21136         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21137         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21138                 error "dd with O_DIRECT large read failed"
21139         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21140                 error "compare $TMP/$tfile.2 failed"
21141
21142         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21143         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21144                 error "dd with O_DIRECT large read failed"
21145         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21146                 error "compare $TMP/$tfile.3 failed"
21147 }
21148 run_test 248b "test short_io read and write for both small and large sizes"
21149
21150 test_249() { # LU-7890
21151         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21152                 skip "Need at least version 2.8.54"
21153
21154         rm -f $DIR/$tfile
21155         $LFS setstripe -c 1 $DIR/$tfile
21156         # Offset 2T == 4k * 512M
21157         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21158                 error "dd to 2T offset failed"
21159 }
21160 run_test 249 "Write above 2T file size"
21161
21162 test_250() {
21163         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21164          && skip "no 16TB file size limit on ZFS"
21165
21166         $LFS setstripe -c 1 $DIR/$tfile
21167         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21168         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21169         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21170         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21171                 conv=notrunc,fsync && error "append succeeded"
21172         return 0
21173 }
21174 run_test 250 "Write above 16T limit"
21175
21176 test_251() {
21177         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21178
21179         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21180         #Skip once - writing the first stripe will succeed
21181         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21182         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21183                 error "short write happened"
21184
21185         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21186         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21187                 error "short read happened"
21188
21189         rm -f $DIR/$tfile
21190 }
21191 run_test 251 "Handling short read and write correctly"
21192
21193 test_252() {
21194         remote_mds_nodsh && skip "remote MDS with nodsh"
21195         remote_ost_nodsh && skip "remote OST with nodsh"
21196         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21197                 skip_env "ldiskfs only test"
21198         fi
21199
21200         local tgt
21201         local dev
21202         local out
21203         local uuid
21204         local num
21205         local gen
21206
21207         # check lr_reader on OST0000
21208         tgt=ost1
21209         dev=$(facet_device $tgt)
21210         out=$(do_facet $tgt $LR_READER $dev)
21211         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21212         echo "$out"
21213         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21214         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21215                 error "Invalid uuid returned by $LR_READER on target $tgt"
21216         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21217
21218         # check lr_reader -c on MDT0000
21219         tgt=mds1
21220         dev=$(facet_device $tgt)
21221         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21222                 skip "$LR_READER does not support additional options"
21223         fi
21224         out=$(do_facet $tgt $LR_READER -c $dev)
21225         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21226         echo "$out"
21227         num=$(echo "$out" | grep -c "mdtlov")
21228         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21229                 error "Invalid number of mdtlov clients returned by $LR_READER"
21230         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21231
21232         # check lr_reader -cr on MDT0000
21233         out=$(do_facet $tgt $LR_READER -cr $dev)
21234         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21235         echo "$out"
21236         echo "$out" | grep -q "^reply_data:$" ||
21237                 error "$LR_READER should have returned 'reply_data' section"
21238         num=$(echo "$out" | grep -c "client_generation")
21239         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21240 }
21241 run_test 252 "check lr_reader tool"
21242
21243 test_253() {
21244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21245         remote_mds_nodsh && skip "remote MDS with nodsh"
21246         remote_mgs_nodsh && skip "remote MGS with nodsh"
21247
21248         local ostidx=0
21249         local rc=0
21250         local ost_name=$(ostname_from_index $ostidx)
21251
21252         # on the mdt's osc
21253         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21254         do_facet $SINGLEMDS $LCTL get_param -n \
21255                 osp.$mdtosc_proc1.reserved_mb_high ||
21256                 skip  "remote MDS does not support reserved_mb_high"
21257
21258         rm -rf $DIR/$tdir
21259         wait_mds_ost_sync
21260         wait_delete_completed
21261         mkdir $DIR/$tdir
21262
21263         pool_add $TESTNAME || error "Pool creation failed"
21264         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21265
21266         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21267                 error "Setstripe failed"
21268
21269         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21270
21271         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21272                     grep "watermarks")
21273         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21274
21275         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21276                         osp.$mdtosc_proc1.prealloc_status)
21277         echo "prealloc_status $oa_status"
21278
21279         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21280                 error "File creation should fail"
21281
21282         #object allocation was stopped, but we still able to append files
21283         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21284                 oflag=append || error "Append failed"
21285
21286         rm -f $DIR/$tdir/$tfile.0
21287
21288         # For this test, we want to delete the files we created to go out of
21289         # space but leave the watermark, so we remain nearly out of space
21290         ost_watermarks_enospc_delete_files $tfile $ostidx
21291
21292         wait_delete_completed
21293
21294         sleep_maxage
21295
21296         for i in $(seq 10 12); do
21297                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21298                         2>/dev/null || error "File creation failed after rm"
21299         done
21300
21301         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21302                         osp.$mdtosc_proc1.prealloc_status)
21303         echo "prealloc_status $oa_status"
21304
21305         if (( oa_status != 0 )); then
21306                 error "Object allocation still disable after rm"
21307         fi
21308 }
21309 run_test 253 "Check object allocation limit"
21310
21311 test_254() {
21312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21313         remote_mds_nodsh && skip "remote MDS with nodsh"
21314
21315         local mdt=$(facet_svc $SINGLEMDS)
21316
21317         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21318                 skip "MDS does not support changelog_size"
21319
21320         local cl_user
21321
21322         changelog_register || error "changelog_register failed"
21323
21324         changelog_clear 0 || error "changelog_clear failed"
21325
21326         local size1=$(do_facet $SINGLEMDS \
21327                       $LCTL get_param -n mdd.$mdt.changelog_size)
21328         echo "Changelog size $size1"
21329
21330         rm -rf $DIR/$tdir
21331         $LFS mkdir -i 0 $DIR/$tdir
21332         # change something
21333         mkdir -p $DIR/$tdir/pics/2008/zachy
21334         touch $DIR/$tdir/pics/2008/zachy/timestamp
21335         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21336         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21337         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21338         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21339         rm $DIR/$tdir/pics/desktop.jpg
21340
21341         local size2=$(do_facet $SINGLEMDS \
21342                       $LCTL get_param -n mdd.$mdt.changelog_size)
21343         echo "Changelog size after work $size2"
21344
21345         (( $size2 > $size1 )) ||
21346                 error "new Changelog size=$size2 less than old size=$size1"
21347 }
21348 run_test 254 "Check changelog size"
21349
21350 ladvise_no_type()
21351 {
21352         local type=$1
21353         local file=$2
21354
21355         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21356                 awk -F: '{print $2}' | grep $type > /dev/null
21357         if [ $? -ne 0 ]; then
21358                 return 0
21359         fi
21360         return 1
21361 }
21362
21363 ladvise_no_ioctl()
21364 {
21365         local file=$1
21366
21367         lfs ladvise -a willread $file > /dev/null 2>&1
21368         if [ $? -eq 0 ]; then
21369                 return 1
21370         fi
21371
21372         lfs ladvise -a willread $file 2>&1 |
21373                 grep "Inappropriate ioctl for device" > /dev/null
21374         if [ $? -eq 0 ]; then
21375                 return 0
21376         fi
21377         return 1
21378 }
21379
21380 percent() {
21381         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21382 }
21383
21384 # run a random read IO workload
21385 # usage: random_read_iops <filename> <filesize> <iosize>
21386 random_read_iops() {
21387         local file=$1
21388         local fsize=$2
21389         local iosize=${3:-4096}
21390
21391         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21392                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21393 }
21394
21395 drop_file_oss_cache() {
21396         local file="$1"
21397         local nodes="$2"
21398
21399         $LFS ladvise -a dontneed $file 2>/dev/null ||
21400                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21401 }
21402
21403 ladvise_willread_performance()
21404 {
21405         local repeat=10
21406         local average_origin=0
21407         local average_cache=0
21408         local average_ladvise=0
21409
21410         for ((i = 1; i <= $repeat; i++)); do
21411                 echo "Iter $i/$repeat: reading without willread hint"
21412                 cancel_lru_locks osc
21413                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21414                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21415                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21416                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21417
21418                 cancel_lru_locks osc
21419                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21420                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21421                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21422
21423                 cancel_lru_locks osc
21424                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21425                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21426                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21427                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21428                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21429         done
21430         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21431         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21432         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21433
21434         speedup_cache=$(percent $average_cache $average_origin)
21435         speedup_ladvise=$(percent $average_ladvise $average_origin)
21436
21437         echo "Average uncached read: $average_origin"
21438         echo "Average speedup with OSS cached read: " \
21439                 "$average_cache = +$speedup_cache%"
21440         echo "Average speedup with ladvise willread: " \
21441                 "$average_ladvise = +$speedup_ladvise%"
21442
21443         local lowest_speedup=20
21444         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21445                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21446                         "got $average_cache%. Skipping ladvise willread check."
21447                 return 0
21448         fi
21449
21450         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21451         # it is still good to run until then to exercise 'ladvise willread'
21452         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21453                 [ "$ost1_FSTYPE" = "zfs" ] &&
21454                 echo "osd-zfs does not support dontneed or drop_caches" &&
21455                 return 0
21456
21457         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21458         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21459                 error_not_in_vm "Speedup with willread is less than " \
21460                         "$lowest_speedup%, got $average_ladvise%"
21461 }
21462
21463 test_255a() {
21464         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21465                 skip "lustre < 2.8.54 does not support ladvise "
21466         remote_ost_nodsh && skip "remote OST with nodsh"
21467
21468         stack_trap "rm -f $DIR/$tfile"
21469         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21470
21471         ladvise_no_type willread $DIR/$tfile &&
21472                 skip "willread ladvise is not supported"
21473
21474         ladvise_no_ioctl $DIR/$tfile &&
21475                 skip "ladvise ioctl is not supported"
21476
21477         local size_mb=100
21478         local size=$((size_mb * 1048576))
21479         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21480                 error "dd to $DIR/$tfile failed"
21481
21482         lfs ladvise -a willread $DIR/$tfile ||
21483                 error "Ladvise failed with no range argument"
21484
21485         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21486                 error "Ladvise failed with no -l or -e argument"
21487
21488         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21489                 error "Ladvise failed with only -e argument"
21490
21491         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21492                 error "Ladvise failed with only -l argument"
21493
21494         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21495                 error "End offset should not be smaller than start offset"
21496
21497         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21498                 error "End offset should not be equal to start offset"
21499
21500         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21501                 error "Ladvise failed with overflowing -s argument"
21502
21503         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21504                 error "Ladvise failed with overflowing -e argument"
21505
21506         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21507                 error "Ladvise failed with overflowing -l argument"
21508
21509         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21510                 error "Ladvise succeeded with conflicting -l and -e arguments"
21511
21512         echo "Synchronous ladvise should wait"
21513         local delay=4
21514 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21515         do_nodes $(comma_list $(osts_nodes)) \
21516                 $LCTL set_param fail_val=$delay fail_loc=0x237
21517
21518         local start_ts=$SECONDS
21519         lfs ladvise -a willread $DIR/$tfile ||
21520                 error "Ladvise failed with no range argument"
21521         local end_ts=$SECONDS
21522         local inteval_ts=$((end_ts - start_ts))
21523
21524         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21525                 error "Synchronous advice didn't wait reply"
21526         fi
21527
21528         echo "Asynchronous ladvise shouldn't wait"
21529         local start_ts=$SECONDS
21530         lfs ladvise -a willread -b $DIR/$tfile ||
21531                 error "Ladvise failed with no range argument"
21532         local end_ts=$SECONDS
21533         local inteval_ts=$((end_ts - start_ts))
21534
21535         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21536                 error "Asynchronous advice blocked"
21537         fi
21538
21539         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21540         ladvise_willread_performance
21541 }
21542 run_test 255a "check 'lfs ladvise -a willread'"
21543
21544 facet_meminfo() {
21545         local facet=$1
21546         local info=$2
21547
21548         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21549 }
21550
21551 test_255b() {
21552         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21553                 skip "lustre < 2.8.54 does not support ladvise "
21554         remote_ost_nodsh && skip "remote OST with nodsh"
21555
21556         stack_trap "rm -f $DIR/$tfile"
21557         lfs setstripe -c 1 -i 0 $DIR/$tfile
21558
21559         ladvise_no_type dontneed $DIR/$tfile &&
21560                 skip "dontneed ladvise is not supported"
21561
21562         ladvise_no_ioctl $DIR/$tfile &&
21563                 skip "ladvise ioctl is not supported"
21564
21565         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21566                 [ "$ost1_FSTYPE" = "zfs" ] &&
21567                 skip "zfs-osd does not support 'ladvise dontneed'"
21568
21569         local size_mb=100
21570         local size=$((size_mb * 1048576))
21571         # In order to prevent disturbance of other processes, only check 3/4
21572         # of the memory usage
21573         local kibibytes=$((size_mb * 1024 * 3 / 4))
21574
21575         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21576                 error "dd to $DIR/$tfile failed"
21577
21578         #force write to complete before dropping OST cache & checking memory
21579         sync
21580
21581         local total=$(facet_meminfo ost1 MemTotal)
21582         echo "Total memory: $total KiB"
21583
21584         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21585         local before_read=$(facet_meminfo ost1 Cached)
21586         echo "Cache used before read: $before_read KiB"
21587
21588         lfs ladvise -a willread $DIR/$tfile ||
21589                 error "Ladvise willread failed"
21590         local after_read=$(facet_meminfo ost1 Cached)
21591         echo "Cache used after read: $after_read KiB"
21592
21593         lfs ladvise -a dontneed $DIR/$tfile ||
21594                 error "Ladvise dontneed again failed"
21595         local no_read=$(facet_meminfo ost1 Cached)
21596         echo "Cache used after dontneed ladvise: $no_read KiB"
21597
21598         if [ $total -lt $((before_read + kibibytes)) ]; then
21599                 echo "Memory is too small, abort checking"
21600                 return 0
21601         fi
21602
21603         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21604                 error "Ladvise willread should use more memory" \
21605                         "than $kibibytes KiB"
21606         fi
21607
21608         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21609                 error "Ladvise dontneed should release more memory" \
21610                         "than $kibibytes KiB"
21611         fi
21612 }
21613 run_test 255b "check 'lfs ladvise -a dontneed'"
21614
21615 test_255c() {
21616         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21617                 skip "lustre < 2.10.50 does not support lockahead"
21618
21619         local ost1_imp=$(get_osc_import_name client ost1)
21620         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21621                          cut -d'.' -f2)
21622         local count
21623         local new_count
21624         local difference
21625         local i
21626         local rc
21627
21628         test_mkdir -p $DIR/$tdir
21629         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21630
21631         #test 10 returns only success/failure
21632         i=10
21633         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21634         rc=$?
21635         if [ $rc -eq 255 ]; then
21636                 error "Ladvise test${i} failed, ${rc}"
21637         fi
21638
21639         #test 11 counts lock enqueue requests, all others count new locks
21640         i=11
21641         count=$(do_facet ost1 \
21642                 $LCTL get_param -n ost.OSS.ost.stats)
21643         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21644
21645         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21646         rc=$?
21647         if [ $rc -eq 255 ]; then
21648                 error "Ladvise test${i} failed, ${rc}"
21649         fi
21650
21651         new_count=$(do_facet ost1 \
21652                 $LCTL get_param -n ost.OSS.ost.stats)
21653         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21654                    awk '{ print $2 }')
21655
21656         difference="$((new_count - count))"
21657         if [ $difference -ne $rc ]; then
21658                 error "Ladvise test${i}, bad enqueue count, returned " \
21659                       "${rc}, actual ${difference}"
21660         fi
21661
21662         for i in $(seq 12 21); do
21663                 # If we do not do this, we run the risk of having too many
21664                 # locks and starting lock cancellation while we are checking
21665                 # lock counts.
21666                 cancel_lru_locks osc
21667
21668                 count=$($LCTL get_param -n \
21669                        ldlm.namespaces.$imp_name.lock_unused_count)
21670
21671                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21672                 rc=$?
21673                 if [ $rc -eq 255 ]; then
21674                         error "Ladvise test ${i} failed, ${rc}"
21675                 fi
21676
21677                 new_count=$($LCTL get_param -n \
21678                        ldlm.namespaces.$imp_name.lock_unused_count)
21679                 difference="$((new_count - count))"
21680
21681                 # Test 15 output is divided by 100 to map down to valid return
21682                 if [ $i -eq 15 ]; then
21683                         rc="$((rc * 100))"
21684                 fi
21685
21686                 if [ $difference -ne $rc ]; then
21687                         error "Ladvise test ${i}, bad lock count, returned " \
21688                               "${rc}, actual ${difference}"
21689                 fi
21690         done
21691
21692         #test 22 returns only success/failure
21693         i=22
21694         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21695         rc=$?
21696         if [ $rc -eq 255 ]; then
21697                 error "Ladvise test${i} failed, ${rc}"
21698         fi
21699 }
21700 run_test 255c "suite of ladvise lockahead tests"
21701
21702 test_256() {
21703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21704         remote_mds_nodsh && skip "remote MDS with nodsh"
21705         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21706         changelog_users $SINGLEMDS | grep "^cl" &&
21707                 skip "active changelog user"
21708
21709         local cl_user
21710         local cat_sl
21711         local mdt_dev
21712
21713         mdt_dev=$(mdsdevname 1)
21714         echo $mdt_dev
21715
21716         changelog_register || error "changelog_register failed"
21717
21718         rm -rf $DIR/$tdir
21719         mkdir_on_mdt0 $DIR/$tdir
21720
21721         changelog_clear 0 || error "changelog_clear failed"
21722
21723         # change something
21724         touch $DIR/$tdir/{1..10}
21725
21726         # stop the MDT
21727         stop $SINGLEMDS || error "Fail to stop MDT"
21728
21729         # remount the MDT
21730
21731         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21732
21733         #after mount new plainllog is used
21734         touch $DIR/$tdir/{11..19}
21735         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21736         stack_trap "rm -f $tmpfile"
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         do_facet $SINGLEMDS llog_reader $tmpfile
21741
21742         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21743
21744         changelog_clear 0 || error "changelog_clear failed"
21745
21746         cat_sl=$(do_facet $SINGLEMDS "sync; \
21747                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21748                  llog_reader $tmpfile | grep -c type=1064553b")
21749
21750         if (( cat_sl == 2 )); then
21751                 error "Empty plain llog was not deleted from changelog catalog"
21752         elif (( cat_sl != 1 )); then
21753                 error "Active plain llog shouldn't be deleted from catalog"
21754         fi
21755 }
21756 run_test 256 "Check llog delete for empty and not full state"
21757
21758 test_257() {
21759         remote_mds_nodsh && skip "remote MDS with nodsh"
21760         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21761                 skip "Need MDS version at least 2.8.55"
21762
21763         test_mkdir $DIR/$tdir
21764
21765         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21766                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21767         stat $DIR/$tdir
21768
21769 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21770         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21771         local facet=mds$((mdtidx + 1))
21772         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21773         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21774
21775         stop $facet || error "stop MDS failed"
21776         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21777                 error "start MDS fail"
21778         wait_recovery_complete $facet
21779 }
21780 run_test 257 "xattr locks are not lost"
21781
21782 # Verify we take the i_mutex when security requires it
21783 test_258a() {
21784 #define OBD_FAIL_IMUTEX_SEC 0x141c
21785         $LCTL set_param fail_loc=0x141c
21786         touch $DIR/$tfile
21787         chmod u+s $DIR/$tfile
21788         chmod a+rwx $DIR/$tfile
21789         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21790         RC=$?
21791         if [ $RC -ne 0 ]; then
21792                 error "error, failed to take i_mutex, rc=$?"
21793         fi
21794         rm -f $DIR/$tfile
21795 }
21796 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21797
21798 # Verify we do NOT take the i_mutex in the normal case
21799 test_258b() {
21800 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21801         $LCTL set_param fail_loc=0x141d
21802         touch $DIR/$tfile
21803         chmod a+rwx $DIR
21804         chmod a+rw $DIR/$tfile
21805         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21806         RC=$?
21807         if [ $RC -ne 0 ]; then
21808                 error "error, took i_mutex unnecessarily, rc=$?"
21809         fi
21810         rm -f $DIR/$tfile
21811
21812 }
21813 run_test 258b "verify i_mutex security behavior"
21814
21815 test_259() {
21816         local file=$DIR/$tfile
21817         local before
21818         local after
21819
21820         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21821
21822         stack_trap "rm -f $file" EXIT
21823
21824         wait_delete_completed
21825         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21826         echo "before: $before"
21827
21828         $LFS setstripe -i 0 -c 1 $file
21829         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21830         sync_all_data
21831         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21832         echo "after write: $after"
21833
21834 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21835         do_facet ost1 $LCTL set_param fail_loc=0x2301
21836         $TRUNCATE $file 0
21837         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21838         echo "after truncate: $after"
21839
21840         stop ost1
21841         do_facet ost1 $LCTL set_param fail_loc=0
21842         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21843         sleep 2
21844         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21845         echo "after restart: $after"
21846         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21847                 error "missing truncate?"
21848
21849         return 0
21850 }
21851 run_test 259 "crash at delayed truncate"
21852
21853 test_260() {
21854 #define OBD_FAIL_MDC_CLOSE               0x806
21855         $LCTL set_param fail_loc=0x80000806
21856         touch $DIR/$tfile
21857
21858 }
21859 run_test 260 "Check mdc_close fail"
21860
21861 ### Data-on-MDT sanity tests ###
21862 test_270a() {
21863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21864                 skip "Need MDS version at least 2.10.55 for DoM"
21865
21866         # create DoM file
21867         local dom=$DIR/$tdir/dom_file
21868         local tmp=$DIR/$tdir/tmp_file
21869
21870         mkdir_on_mdt0 $DIR/$tdir
21871
21872         # basic checks for DoM component creation
21873         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21874                 error "Can set MDT layout to non-first entry"
21875
21876         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21877                 error "Can define multiple entries as MDT layout"
21878
21879         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21880
21881         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21882         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21883         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21884
21885         local mdtidx=$($LFS getstripe -m $dom)
21886         local mdtname=MDT$(printf %04x $mdtidx)
21887         local facet=mds$((mdtidx + 1))
21888         local space_check=1
21889
21890         # Skip free space checks with ZFS
21891         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21892
21893         # write
21894         sync
21895         local size_tmp=$((65536 * 3))
21896         local mdtfree1=$(do_facet $facet \
21897                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21898
21899         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21900         # check also direct IO along write
21901         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21902         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21903         sync
21904         cmp $tmp $dom || error "file data is different"
21905         [ $(stat -c%s $dom) == $size_tmp ] ||
21906                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21907         if [ $space_check == 1 ]; then
21908                 local mdtfree2=$(do_facet $facet \
21909                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21910
21911                 # increase in usage from by $size_tmp
21912                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21913                         error "MDT free space wrong after write: " \
21914                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21915         fi
21916
21917         # truncate
21918         local size_dom=10000
21919
21920         $TRUNCATE $dom $size_dom
21921         [ $(stat -c%s $dom) == $size_dom ] ||
21922                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21923         if [ $space_check == 1 ]; then
21924                 mdtfree1=$(do_facet $facet \
21925                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21926                 # decrease in usage from $size_tmp to new $size_dom
21927                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21928                   $(((size_tmp - size_dom) / 1024)) ] ||
21929                         error "MDT free space is wrong after truncate: " \
21930                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21931         fi
21932
21933         # append
21934         cat $tmp >> $dom
21935         sync
21936         size_dom=$((size_dom + size_tmp))
21937         [ $(stat -c%s $dom) == $size_dom ] ||
21938                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21939         if [ $space_check == 1 ]; then
21940                 mdtfree2=$(do_facet $facet \
21941                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21942                 # increase in usage by $size_tmp from previous
21943                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21944                         error "MDT free space is wrong after append: " \
21945                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21946         fi
21947
21948         # delete
21949         rm $dom
21950         if [ $space_check == 1 ]; then
21951                 mdtfree1=$(do_facet $facet \
21952                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21953                 # decrease in usage by $size_dom from previous
21954                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21955                         error "MDT free space is wrong after removal: " \
21956                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21957         fi
21958
21959         # combined striping
21960         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21961                 error "Can't create DoM + OST striping"
21962
21963         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21964         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21965         # check also direct IO along write
21966         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21967         sync
21968         cmp $tmp $dom || error "file data is different"
21969         [ $(stat -c%s $dom) == $size_tmp ] ||
21970                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21971         rm $dom $tmp
21972
21973         return 0
21974 }
21975 run_test 270a "DoM: basic functionality tests"
21976
21977 test_270b() {
21978         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21979                 skip "Need MDS version at least 2.10.55"
21980
21981         local dom=$DIR/$tdir/dom_file
21982         local max_size=1048576
21983
21984         mkdir -p $DIR/$tdir
21985         $LFS setstripe -E $max_size -L mdt $dom
21986
21987         # truncate over the limit
21988         $TRUNCATE $dom $(($max_size + 1)) &&
21989                 error "successful truncate over the maximum size"
21990         # write over the limit
21991         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21992                 error "successful write over the maximum size"
21993         # append over the limit
21994         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21995         echo "12345" >> $dom && error "successful append over the maximum size"
21996         rm $dom
21997
21998         return 0
21999 }
22000 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22001
22002 test_270c() {
22003         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22004                 skip "Need MDS version at least 2.10.55"
22005
22006         mkdir -p $DIR/$tdir
22007         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22008
22009         # check files inherit DoM EA
22010         touch $DIR/$tdir/first
22011         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22012                 error "bad pattern"
22013         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22014                 error "bad stripe count"
22015         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22016                 error "bad stripe size"
22017
22018         # check directory inherits DoM EA and uses it as default
22019         mkdir $DIR/$tdir/subdir
22020         touch $DIR/$tdir/subdir/second
22021         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22022                 error "bad pattern in sub-directory"
22023         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22024                 error "bad stripe count in sub-directory"
22025         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22026                 error "bad stripe size in sub-directory"
22027         return 0
22028 }
22029 run_test 270c "DoM: DoM EA inheritance tests"
22030
22031 test_270d() {
22032         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22033                 skip "Need MDS version at least 2.10.55"
22034
22035         mkdir -p $DIR/$tdir
22036         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22037
22038         # inherit default DoM striping
22039         mkdir $DIR/$tdir/subdir
22040         touch $DIR/$tdir/subdir/f1
22041
22042         # change default directory striping
22043         $LFS setstripe -c 1 $DIR/$tdir/subdir
22044         touch $DIR/$tdir/subdir/f2
22045         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22046                 error "wrong default striping in file 2"
22047         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22048                 error "bad pattern in file 2"
22049         return 0
22050 }
22051 run_test 270d "DoM: change striping from DoM to RAID0"
22052
22053 test_270e() {
22054         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22055                 skip "Need MDS version at least 2.10.55"
22056
22057         mkdir -p $DIR/$tdir/dom
22058         mkdir -p $DIR/$tdir/norm
22059         DOMFILES=20
22060         NORMFILES=10
22061         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22062         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22063
22064         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22065         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22066
22067         # find DoM files by layout
22068         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22069         [ $NUM -eq  $DOMFILES ] ||
22070                 error "lfs find -L: found $NUM, expected $DOMFILES"
22071         echo "Test 1: lfs find 20 DOM files by layout: OK"
22072
22073         # there should be 1 dir with default DOM striping
22074         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22075         [ $NUM -eq  1 ] ||
22076                 error "lfs find -L: found $NUM, expected 1 dir"
22077         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22078
22079         # find DoM files by stripe size
22080         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22081         [ $NUM -eq  $DOMFILES ] ||
22082                 error "lfs find -S: found $NUM, expected $DOMFILES"
22083         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22084
22085         # find files by stripe offset except DoM files
22086         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22087         [ $NUM -eq  $NORMFILES ] ||
22088                 error "lfs find -i: found $NUM, expected $NORMFILES"
22089         echo "Test 5: lfs find no DOM files by stripe index: OK"
22090         return 0
22091 }
22092 run_test 270e "DoM: lfs find with DoM files test"
22093
22094 test_270f() {
22095         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22096                 skip "Need MDS version at least 2.10.55"
22097
22098         local mdtname=${FSNAME}-MDT0000-mdtlov
22099         local dom=$DIR/$tdir/dom_file
22100         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22101                                                 lod.$mdtname.dom_stripesize)
22102         local dom_limit=131072
22103
22104         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22105         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22106                                                 lod.$mdtname.dom_stripesize)
22107         [ ${dom_limit} -eq ${dom_current} ] ||
22108                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22109
22110         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22111         $LFS setstripe -d $DIR/$tdir
22112         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22113                 error "Can't set directory default striping"
22114
22115         # exceed maximum stripe size
22116         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22117                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22118         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22119                 error "Able to create DoM component size more than LOD limit"
22120
22121         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22122         dom_current=$(do_facet mds1 $LCTL get_param -n \
22123                                                 lod.$mdtname.dom_stripesize)
22124         [ 0 -eq ${dom_current} ] ||
22125                 error "Can't set zero DoM stripe limit"
22126         rm $dom
22127
22128         # attempt to create DoM file on server with disabled DoM should
22129         # remove DoM entry from layout and be succeed
22130         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22131                 error "Can't create DoM file (DoM is disabled)"
22132         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22133                 error "File has DoM component while DoM is disabled"
22134         rm $dom
22135
22136         # attempt to create DoM file with only DoM stripe should return error
22137         $LFS setstripe -E $dom_limit -L mdt $dom &&
22138                 error "Able to create DoM-only file while DoM is disabled"
22139
22140         # too low values to be aligned with smallest stripe size 64K
22141         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22142         dom_current=$(do_facet mds1 $LCTL get_param -n \
22143                                                 lod.$mdtname.dom_stripesize)
22144         [ 30000 -eq ${dom_current} ] &&
22145                 error "Can set too small DoM stripe limit"
22146
22147         # 64K is a minimal stripe size in Lustre, expect limit of that size
22148         [ 65536 -eq ${dom_current} ] ||
22149                 error "Limit is not set to 64K but ${dom_current}"
22150
22151         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22152         dom_current=$(do_facet mds1 $LCTL get_param -n \
22153                                                 lod.$mdtname.dom_stripesize)
22154         echo $dom_current
22155         [ 2147483648 -eq ${dom_current} ] &&
22156                 error "Can set too large DoM stripe limit"
22157
22158         do_facet mds1 $LCTL set_param -n \
22159                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22160         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22161                 error "Can't create DoM component size after limit change"
22162         do_facet mds1 $LCTL set_param -n \
22163                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22164         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22165                 error "Can't create DoM file after limit decrease"
22166         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22167                 error "Can create big DoM component after limit decrease"
22168         touch ${dom}_def ||
22169                 error "Can't create file with old default layout"
22170
22171         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22172         return 0
22173 }
22174 run_test 270f "DoM: maximum DoM stripe size checks"
22175
22176 test_270g() {
22177         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22178                 skip "Need MDS version at least 2.13.52"
22179         local dom=$DIR/$tdir/$tfile
22180
22181         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22182         local lodname=${FSNAME}-MDT0000-mdtlov
22183
22184         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22185         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22186         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22187         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22188
22189         local dom_limit=1024
22190         local dom_threshold="50%"
22191
22192         $LFS setstripe -d $DIR/$tdir
22193         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22194                 error "Can't set directory default striping"
22195
22196         do_facet mds1 $LCTL set_param -n \
22197                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22198         # set 0 threshold and create DOM file to change tunable stripesize
22199         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22200         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22201                 error "Failed to create $dom file"
22202         # now tunable dom_cur_stripesize should reach maximum
22203         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22204                                         lod.${lodname}.dom_stripesize_cur_kb)
22205         [[ $dom_current == $dom_limit ]] ||
22206                 error "Current DOM stripesize is not maximum"
22207         rm $dom
22208
22209         # set threshold for further tests
22210         do_facet mds1 $LCTL set_param -n \
22211                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22212         echo "DOM threshold is $dom_threshold free space"
22213         local dom_def
22214         local dom_set
22215         # Spoof bfree to exceed threshold
22216         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22217         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22218         for spfree in 40 20 0 15 30 55; do
22219                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22220                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22221                         error "Failed to create $dom file"
22222                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22223                                         lod.${lodname}.dom_stripesize_cur_kb)
22224                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22225                 [[ $dom_def != $dom_current ]] ||
22226                         error "Default stripe size was not changed"
22227                 if [[ $spfree > 0 ]] ; then
22228                         dom_set=$($LFS getstripe -S $dom)
22229                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22230                                 error "DOM component size is still old"
22231                 else
22232                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22233                                 error "DoM component is set with no free space"
22234                 fi
22235                 rm $dom
22236                 dom_current=$dom_def
22237         done
22238 }
22239 run_test 270g "DoM: default DoM stripe size depends on free space"
22240
22241 test_270h() {
22242         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22243                 skip "Need MDS version at least 2.13.53"
22244
22245         local mdtname=${FSNAME}-MDT0000-mdtlov
22246         local dom=$DIR/$tdir/$tfile
22247         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22248
22249         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22250         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22251
22252         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22253         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22254                 error "can't create OST file"
22255         # mirrored file with DOM entry in the second mirror
22256         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22257                 error "can't create mirror with DoM component"
22258
22259         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22260
22261         # DOM component in the middle and has other enries in the same mirror,
22262         # should succeed but lost DoM component
22263         $LFS setstripe --copy=${dom}_1 $dom ||
22264                 error "Can't create file from OST|DOM mirror layout"
22265         # check new file has no DoM layout after all
22266         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22267                 error "File has DoM component while DoM is disabled"
22268 }
22269 run_test 270h "DoM: DoM stripe removal when disabled on server"
22270
22271 test_270i() {
22272         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22273                 skip "Need MDS version at least 2.14.54"
22274
22275         mkdir $DIR/$tdir
22276         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22277                 error "setstripe should fail" || true
22278 }
22279 run_test 270i "DoM: setting invalid DoM striping should fail"
22280
22281 test_271a() {
22282         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22283                 skip "Need MDS version at least 2.10.55"
22284
22285         local dom=$DIR/$tdir/dom
22286
22287         mkdir -p $DIR/$tdir
22288
22289         $LFS setstripe -E 1024K -L mdt $dom
22290
22291         lctl set_param -n mdc.*.stats=clear
22292         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22293         cat $dom > /dev/null
22294         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22295         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22296         ls $dom
22297         rm -f $dom
22298 }
22299 run_test 271a "DoM: data is cached for read after write"
22300
22301 test_271b() {
22302         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22303                 skip "Need MDS version at least 2.10.55"
22304
22305         local dom=$DIR/$tdir/dom
22306
22307         mkdir -p $DIR/$tdir
22308
22309         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22310
22311         lctl set_param -n mdc.*.stats=clear
22312         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22313         cancel_lru_locks mdc
22314         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22315         # second stat to check size is cached on client
22316         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22317         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22318         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22319         rm -f $dom
22320 }
22321 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22322
22323 test_271ba() {
22324         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22325                 skip "Need MDS version at least 2.10.55"
22326
22327         local dom=$DIR/$tdir/dom
22328
22329         mkdir -p $DIR/$tdir
22330
22331         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22332
22333         lctl set_param -n mdc.*.stats=clear
22334         lctl set_param -n osc.*.stats=clear
22335         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22336         cancel_lru_locks mdc
22337         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22338         # second stat to check size is cached on client
22339         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22340         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22341         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22342         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22343         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22344         rm -f $dom
22345 }
22346 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22347
22348
22349 get_mdc_stats() {
22350         local mdtidx=$1
22351         local param=$2
22352         local mdt=MDT$(printf %04x $mdtidx)
22353
22354         if [ -z $param ]; then
22355                 lctl get_param -n mdc.*$mdt*.stats
22356         else
22357                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22358         fi
22359 }
22360
22361 test_271c() {
22362         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22363                 skip "Need MDS version at least 2.10.55"
22364
22365         local dom=$DIR/$tdir/dom
22366
22367         mkdir -p $DIR/$tdir
22368
22369         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22370
22371         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22372         local facet=mds$((mdtidx + 1))
22373
22374         cancel_lru_locks mdc
22375         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22376         createmany -o $dom 1000
22377         lctl set_param -n mdc.*.stats=clear
22378         smalliomany -w $dom 1000 200
22379         get_mdc_stats $mdtidx
22380         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22381         # Each file has 1 open, 1 IO enqueues, total 2000
22382         # but now we have also +1 getxattr for security.capability, total 3000
22383         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22384         unlinkmany $dom 1000
22385
22386         cancel_lru_locks mdc
22387         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22388         createmany -o $dom 1000
22389         lctl set_param -n mdc.*.stats=clear
22390         smalliomany -w $dom 1000 200
22391         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22392         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22393         # for OPEN and IO lock.
22394         [ $((enq - enq_2)) -ge 1000 ] ||
22395                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22396         unlinkmany $dom 1000
22397         return 0
22398 }
22399 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22400
22401 cleanup_271def_tests() {
22402         trap 0
22403         rm -f $1
22404 }
22405
22406 test_271d() {
22407         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22408                 skip "Need MDS version at least 2.10.57"
22409
22410         local dom=$DIR/$tdir/dom
22411         local tmp=$TMP/$tfile
22412         trap "cleanup_271def_tests $tmp" EXIT
22413
22414         mkdir -p $DIR/$tdir
22415
22416         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22417
22418         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22419
22420         cancel_lru_locks mdc
22421         dd if=/dev/urandom of=$tmp bs=1000 count=1
22422         dd if=$tmp of=$dom bs=1000 count=1
22423         cancel_lru_locks mdc
22424
22425         cat /etc/hosts >> $tmp
22426         lctl set_param -n mdc.*.stats=clear
22427
22428         # append data to the same file it should update local page
22429         echo "Append to the same page"
22430         cat /etc/hosts >> $dom
22431         local num=$(get_mdc_stats $mdtidx ost_read)
22432         local ra=$(get_mdc_stats $mdtidx req_active)
22433         local rw=$(get_mdc_stats $mdtidx req_waittime)
22434
22435         [ -z $num ] || error "$num READ RPC occured"
22436         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22437         echo "... DONE"
22438
22439         # compare content
22440         cmp $tmp $dom || error "file miscompare"
22441
22442         cancel_lru_locks mdc
22443         lctl set_param -n mdc.*.stats=clear
22444
22445         echo "Open and read file"
22446         cat $dom > /dev/null
22447         local num=$(get_mdc_stats $mdtidx ost_read)
22448         local ra=$(get_mdc_stats $mdtidx req_active)
22449         local rw=$(get_mdc_stats $mdtidx req_waittime)
22450
22451         [ -z $num ] || error "$num READ RPC occured"
22452         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22453         echo "... DONE"
22454
22455         # compare content
22456         cmp $tmp $dom || error "file miscompare"
22457
22458         return 0
22459 }
22460 run_test 271d "DoM: read on open (1K file in reply buffer)"
22461
22462 test_271f() {
22463         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22464                 skip "Need MDS version at least 2.10.57"
22465
22466         local dom=$DIR/$tdir/dom
22467         local tmp=$TMP/$tfile
22468         trap "cleanup_271def_tests $tmp" EXIT
22469
22470         mkdir -p $DIR/$tdir
22471
22472         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22473
22474         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22475
22476         cancel_lru_locks mdc
22477         dd if=/dev/urandom of=$tmp bs=265000 count=1
22478         dd if=$tmp of=$dom bs=265000 count=1
22479         cancel_lru_locks mdc
22480         cat /etc/hosts >> $tmp
22481         lctl set_param -n mdc.*.stats=clear
22482
22483         echo "Append to the same page"
22484         cat /etc/hosts >> $dom
22485         local num=$(get_mdc_stats $mdtidx ost_read)
22486         local ra=$(get_mdc_stats $mdtidx req_active)
22487         local rw=$(get_mdc_stats $mdtidx req_waittime)
22488
22489         [ -z $num ] || error "$num READ RPC occured"
22490         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22491         echo "... DONE"
22492
22493         # compare content
22494         cmp $tmp $dom || error "file miscompare"
22495
22496         cancel_lru_locks mdc
22497         lctl set_param -n mdc.*.stats=clear
22498
22499         echo "Open and read file"
22500         cat $dom > /dev/null
22501         local num=$(get_mdc_stats $mdtidx ost_read)
22502         local ra=$(get_mdc_stats $mdtidx req_active)
22503         local rw=$(get_mdc_stats $mdtidx req_waittime)
22504
22505         [ -z $num ] && num=0
22506         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22507         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22508         echo "... DONE"
22509
22510         # compare content
22511         cmp $tmp $dom || error "file miscompare"
22512
22513         return 0
22514 }
22515 run_test 271f "DoM: read on open (200K file and read tail)"
22516
22517 test_271g() {
22518         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22519                 skip "Skipping due to old client or server version"
22520
22521         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22522         # to get layout
22523         $CHECKSTAT -t file $DIR1/$tfile
22524
22525         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22526         MULTIOP_PID=$!
22527         sleep 1
22528         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22529         $LCTL set_param fail_loc=0x80000314
22530         rm $DIR1/$tfile || error "Unlink fails"
22531         RC=$?
22532         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22533         [ $RC -eq 0 ] || error "Failed write to stale object"
22534 }
22535 run_test 271g "Discard DoM data vs client flush race"
22536
22537 test_272a() {
22538         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22539                 skip "Need MDS version at least 2.11.50"
22540
22541         local dom=$DIR/$tdir/dom
22542         mkdir -p $DIR/$tdir
22543
22544         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22545         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22546                 error "failed to write data into $dom"
22547         local old_md5=$(md5sum $dom)
22548
22549         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22550                 error "failed to migrate to the same DoM component"
22551
22552         local new_md5=$(md5sum $dom)
22553
22554         [ "$old_md5" == "$new_md5" ] ||
22555                 error "md5sum differ: $old_md5, $new_md5"
22556
22557         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22558                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22559 }
22560 run_test 272a "DoM migration: new layout with the same DOM component"
22561
22562 test_272b() {
22563         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22564                 skip "Need MDS version at least 2.11.50"
22565
22566         local dom=$DIR/$tdir/dom
22567         mkdir -p $DIR/$tdir
22568         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22569
22570         local mdtidx=$($LFS getstripe -m $dom)
22571         local mdtname=MDT$(printf %04x $mdtidx)
22572         local facet=mds$((mdtidx + 1))
22573
22574         local mdtfree1=$(do_facet $facet \
22575                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22576         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22577                 error "failed to write data into $dom"
22578         local old_md5=$(md5sum $dom)
22579         cancel_lru_locks mdc
22580         local mdtfree1=$(do_facet $facet \
22581                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22582
22583         $LFS migrate -c2 $dom ||
22584                 error "failed to migrate to the new composite layout"
22585         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22586                 error "MDT stripe was not removed"
22587
22588         cancel_lru_locks mdc
22589         local new_md5=$(md5sum $dom)
22590         [ "$old_md5" == "$new_md5" ] ||
22591                 error "$old_md5 != $new_md5"
22592
22593         # Skip free space checks with ZFS
22594         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22595                 local mdtfree2=$(do_facet $facet \
22596                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22597                 [ $mdtfree2 -gt $mdtfree1 ] ||
22598                         error "MDT space is not freed after migration"
22599         fi
22600         return 0
22601 }
22602 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22603
22604 test_272c() {
22605         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22606                 skip "Need MDS version at least 2.11.50"
22607
22608         local dom=$DIR/$tdir/$tfile
22609         mkdir -p $DIR/$tdir
22610         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22611
22612         local mdtidx=$($LFS getstripe -m $dom)
22613         local mdtname=MDT$(printf %04x $mdtidx)
22614         local facet=mds$((mdtidx + 1))
22615
22616         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22617                 error "failed to write data into $dom"
22618         local old_md5=$(md5sum $dom)
22619         cancel_lru_locks mdc
22620         local mdtfree1=$(do_facet $facet \
22621                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22622
22623         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22624                 error "failed to migrate to the new composite layout"
22625         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22626                 error "MDT stripe was not removed"
22627
22628         cancel_lru_locks mdc
22629         local new_md5=$(md5sum $dom)
22630         [ "$old_md5" == "$new_md5" ] ||
22631                 error "$old_md5 != $new_md5"
22632
22633         # Skip free space checks with ZFS
22634         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22635                 local mdtfree2=$(do_facet $facet \
22636                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22637                 [ $mdtfree2 -gt $mdtfree1 ] ||
22638                         error "MDS space is not freed after migration"
22639         fi
22640         return 0
22641 }
22642 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22643
22644 test_272d() {
22645         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22646                 skip "Need MDS version at least 2.12.55"
22647
22648         local dom=$DIR/$tdir/$tfile
22649         mkdir -p $DIR/$tdir
22650         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22651
22652         local mdtidx=$($LFS getstripe -m $dom)
22653         local mdtname=MDT$(printf %04x $mdtidx)
22654         local facet=mds$((mdtidx + 1))
22655
22656         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22657                 error "failed to write data into $dom"
22658         local old_md5=$(md5sum $dom)
22659         cancel_lru_locks mdc
22660         local mdtfree1=$(do_facet $facet \
22661                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22662
22663         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22664                 error "failed mirroring to the new composite layout"
22665         $LFS mirror resync $dom ||
22666                 error "failed mirror resync"
22667         $LFS mirror split --mirror-id 1 -d $dom ||
22668                 error "failed mirror split"
22669
22670         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22671                 error "MDT stripe was not removed"
22672
22673         cancel_lru_locks mdc
22674         local new_md5=$(md5sum $dom)
22675         [ "$old_md5" == "$new_md5" ] ||
22676                 error "$old_md5 != $new_md5"
22677
22678         # Skip free space checks with ZFS
22679         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22680                 local mdtfree2=$(do_facet $facet \
22681                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22682                 [ $mdtfree2 -gt $mdtfree1 ] ||
22683                         error "MDS space is not freed after DOM mirror deletion"
22684         fi
22685         return 0
22686 }
22687 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22688
22689 test_272e() {
22690         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22691                 skip "Need MDS version at least 2.12.55"
22692
22693         local dom=$DIR/$tdir/$tfile
22694         mkdir -p $DIR/$tdir
22695         $LFS setstripe -c 2 $dom
22696
22697         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22698                 error "failed to write data into $dom"
22699         local old_md5=$(md5sum $dom)
22700         cancel_lru_locks mdc
22701
22702         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22703                 error "failed mirroring to the DOM layout"
22704         $LFS mirror resync $dom ||
22705                 error "failed mirror resync"
22706         $LFS mirror split --mirror-id 1 -d $dom ||
22707                 error "failed mirror split"
22708
22709         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22710                 error "MDT stripe was not removed"
22711
22712         cancel_lru_locks mdc
22713         local new_md5=$(md5sum $dom)
22714         [ "$old_md5" == "$new_md5" ] ||
22715                 error "$old_md5 != $new_md5"
22716
22717         return 0
22718 }
22719 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22720
22721 test_272f() {
22722         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22723                 skip "Need MDS version at least 2.12.55"
22724
22725         local dom=$DIR/$tdir/$tfile
22726         mkdir -p $DIR/$tdir
22727         $LFS setstripe -c 2 $dom
22728
22729         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22730                 error "failed to write data into $dom"
22731         local old_md5=$(md5sum $dom)
22732         cancel_lru_locks mdc
22733
22734         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22735                 error "failed migrating to the DOM file"
22736
22737         cancel_lru_locks mdc
22738         local new_md5=$(md5sum $dom)
22739         [ "$old_md5" != "$new_md5" ] &&
22740                 error "$old_md5 != $new_md5"
22741
22742         return 0
22743 }
22744 run_test 272f "DoM migration: OST-striped file to DOM file"
22745
22746 test_273a() {
22747         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22748                 skip "Need MDS version at least 2.11.50"
22749
22750         # Layout swap cannot be done if either file has DOM component,
22751         # this will never be supported, migration should be used instead
22752
22753         local dom=$DIR/$tdir/$tfile
22754         mkdir -p $DIR/$tdir
22755
22756         $LFS setstripe -c2 ${dom}_plain
22757         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22758         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22759                 error "can swap layout with DoM component"
22760         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22761                 error "can swap layout with DoM component"
22762
22763         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22764         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22765                 error "can swap layout with DoM component"
22766         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22767                 error "can swap layout with DoM component"
22768         return 0
22769 }
22770 run_test 273a "DoM: layout swapping should fail with DOM"
22771
22772 test_273b() {
22773         mkdir -p $DIR/$tdir
22774         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22775
22776 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22777         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22778
22779         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22780 }
22781 run_test 273b "DoM: race writeback and object destroy"
22782
22783 test_275() {
22784         remote_ost_nodsh && skip "remote OST with nodsh"
22785         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22786                 skip "Need OST version >= 2.10.57"
22787
22788         local file=$DIR/$tfile
22789         local oss
22790
22791         oss=$(comma_list $(osts_nodes))
22792
22793         dd if=/dev/urandom of=$file bs=1M count=2 ||
22794                 error "failed to create a file"
22795         cancel_lru_locks osc
22796
22797         #lock 1
22798         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22799                 error "failed to read a file"
22800
22801 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22802         $LCTL set_param fail_loc=0x8000031f
22803
22804         cancel_lru_locks osc &
22805         sleep 1
22806
22807 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22808         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22809         #IO takes another lock, but matches the PENDING one
22810         #and places it to the IO RPC
22811         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22812                 error "failed to read a file with PENDING lock"
22813 }
22814 run_test 275 "Read on a canceled duplicate lock"
22815
22816 test_276() {
22817         remote_ost_nodsh && skip "remote OST with nodsh"
22818         local pid
22819
22820         do_facet ost1 "(while true; do \
22821                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22822                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22823         pid=$!
22824
22825         for LOOP in $(seq 20); do
22826                 stop ost1
22827                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22828         done
22829         kill -9 $pid
22830         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22831                 rm $TMP/sanity_276_pid"
22832 }
22833 run_test 276 "Race between mount and obd_statfs"
22834
22835 test_277() {
22836         $LCTL set_param ldlm.namespaces.*.lru_size=0
22837         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22838         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22839                         grep ^used_mb | awk '{print $2}')
22840         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22841         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22842                 oflag=direct conv=notrunc
22843         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22844                         grep ^used_mb | awk '{print $2}')
22845         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22846 }
22847 run_test 277 "Direct IO shall drop page cache"
22848
22849 test_278() {
22850         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22851         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22852         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22853                 skip "needs the same host for mdt1 mdt2" && return
22854
22855         local pid1
22856         local pid2
22857
22858 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22859         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22860         stop mds2 &
22861         pid2=$!
22862
22863         stop mds1
22864
22865         echo "Starting MDTs"
22866         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22867         wait $pid2
22868 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22869 #will return NULL
22870         do_facet mds2 $LCTL set_param fail_loc=0
22871
22872         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22873         wait_recovery_complete mds2
22874 }
22875 run_test 278 "Race starting MDS between MDTs stop/start"
22876
22877 test_280() {
22878         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22879                 skip "Need MGS version at least 2.13.52"
22880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22881         combined_mgs_mds || skip "needs combined MGS/MDT"
22882
22883         umount_client $MOUNT
22884 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22885         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22886
22887         mount_client $MOUNT &
22888         sleep 1
22889         stop mgs || error "stop mgs failed"
22890         #for a race mgs would crash
22891         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22892         # make sure we unmount client before remounting
22893         wait
22894         umount_client $MOUNT
22895         mount_client $MOUNT || error "mount client failed"
22896 }
22897 run_test 280 "Race between MGS umount and client llog processing"
22898
22899 cleanup_test_300() {
22900         trap 0
22901         umask $SAVE_UMASK
22902 }
22903 test_striped_dir() {
22904         local mdt_index=$1
22905         local stripe_count
22906         local stripe_index
22907
22908         mkdir -p $DIR/$tdir
22909
22910         SAVE_UMASK=$(umask)
22911         trap cleanup_test_300 RETURN EXIT
22912
22913         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22914                                                 $DIR/$tdir/striped_dir ||
22915                 error "set striped dir error"
22916
22917         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22918         [ "$mode" = "755" ] || error "expect 755 got $mode"
22919
22920         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22921                 error "getdirstripe failed"
22922         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22923         if [ "$stripe_count" != "2" ]; then
22924                 error "1:stripe_count is $stripe_count, expect 2"
22925         fi
22926         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22927         if [ "$stripe_count" != "2" ]; then
22928                 error "2:stripe_count is $stripe_count, expect 2"
22929         fi
22930
22931         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22932         if [ "$stripe_index" != "$mdt_index" ]; then
22933                 error "stripe_index is $stripe_index, expect $mdt_index"
22934         fi
22935
22936         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22937                 error "nlink error after create striped dir"
22938
22939         mkdir $DIR/$tdir/striped_dir/a
22940         mkdir $DIR/$tdir/striped_dir/b
22941
22942         stat $DIR/$tdir/striped_dir/a ||
22943                 error "create dir under striped dir failed"
22944         stat $DIR/$tdir/striped_dir/b ||
22945                 error "create dir under striped dir failed"
22946
22947         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22948                 error "nlink error after mkdir"
22949
22950         rmdir $DIR/$tdir/striped_dir/a
22951         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22952                 error "nlink error after rmdir"
22953
22954         rmdir $DIR/$tdir/striped_dir/b
22955         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22956                 error "nlink error after rmdir"
22957
22958         chattr +i $DIR/$tdir/striped_dir
22959         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22960                 error "immutable flags not working under striped dir!"
22961         chattr -i $DIR/$tdir/striped_dir
22962
22963         rmdir $DIR/$tdir/striped_dir ||
22964                 error "rmdir striped dir error"
22965
22966         cleanup_test_300
22967
22968         true
22969 }
22970
22971 test_300a() {
22972         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22973                 skip "skipped for lustre < 2.7.0"
22974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22975         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22976
22977         test_striped_dir 0 || error "failed on striped dir on MDT0"
22978         test_striped_dir 1 || error "failed on striped dir on MDT0"
22979 }
22980 run_test 300a "basic striped dir sanity test"
22981
22982 test_300b() {
22983         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22984                 skip "skipped for lustre < 2.7.0"
22985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22987
22988         local i
22989         local mtime1
22990         local mtime2
22991         local mtime3
22992
22993         test_mkdir $DIR/$tdir || error "mkdir fail"
22994         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22995                 error "set striped dir error"
22996         for i in {0..9}; do
22997                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22998                 sleep 1
22999                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23000                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23001                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23002                 sleep 1
23003                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23004                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23005                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23006         done
23007         true
23008 }
23009 run_test 300b "check ctime/mtime for striped dir"
23010
23011 test_300c() {
23012         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23013                 skip "skipped for lustre < 2.7.0"
23014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23015         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23016
23017         local file_count
23018
23019         mkdir_on_mdt0 $DIR/$tdir
23020         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23021                 error "set striped dir error"
23022
23023         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23024                 error "chown striped dir failed"
23025
23026         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23027                 error "create 5k files failed"
23028
23029         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23030
23031         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23032
23033         rm -rf $DIR/$tdir
23034 }
23035 run_test 300c "chown && check ls under striped directory"
23036
23037 test_300d() {
23038         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23039                 skip "skipped for lustre < 2.7.0"
23040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23041         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23042
23043         local stripe_count
23044         local file
23045
23046         mkdir -p $DIR/$tdir
23047         $LFS setstripe -c 2 $DIR/$tdir
23048
23049         #local striped directory
23050         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23051                 error "set striped dir error"
23052         #look at the directories for debug purposes
23053         ls -l $DIR/$tdir
23054         $LFS getdirstripe $DIR/$tdir
23055         ls -l $DIR/$tdir/striped_dir
23056         $LFS getdirstripe $DIR/$tdir/striped_dir
23057         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23058                 error "create 10 files failed"
23059
23060         #remote striped directory
23061         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23062                 error "set striped dir error"
23063         #look at the directories for debug purposes
23064         ls -l $DIR/$tdir
23065         $LFS getdirstripe $DIR/$tdir
23066         ls -l $DIR/$tdir/remote_striped_dir
23067         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23068         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23069                 error "create 10 files failed"
23070
23071         for file in $(find $DIR/$tdir); do
23072                 stripe_count=$($LFS getstripe -c $file)
23073                 [ $stripe_count -eq 2 ] ||
23074                         error "wrong stripe $stripe_count for $file"
23075         done
23076
23077         rm -rf $DIR/$tdir
23078 }
23079 run_test 300d "check default stripe under striped directory"
23080
23081 test_300e() {
23082         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23083                 skip "Need MDS version at least 2.7.55"
23084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23085         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23086
23087         local stripe_count
23088         local file
23089
23090         mkdir -p $DIR/$tdir
23091
23092         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23093                 error "set striped dir error"
23094
23095         touch $DIR/$tdir/striped_dir/a
23096         touch $DIR/$tdir/striped_dir/b
23097         touch $DIR/$tdir/striped_dir/c
23098
23099         mkdir $DIR/$tdir/striped_dir/dir_a
23100         mkdir $DIR/$tdir/striped_dir/dir_b
23101         mkdir $DIR/$tdir/striped_dir/dir_c
23102
23103         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23104                 error "set striped adir under striped dir error"
23105
23106         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23107                 error "set striped bdir under striped dir error"
23108
23109         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23110                 error "set striped cdir under striped dir error"
23111
23112         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23113                 error "rename dir under striped dir fails"
23114
23115         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23116                 error "rename dir under different stripes fails"
23117
23118         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23119                 error "rename file under striped dir should succeed"
23120
23121         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23122                 error "rename dir under striped dir should succeed"
23123
23124         rm -rf $DIR/$tdir
23125 }
23126 run_test 300e "check rename under striped directory"
23127
23128 test_300f() {
23129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23130         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23131         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23132                 skip "Need MDS version at least 2.7.55"
23133
23134         local stripe_count
23135         local file
23136
23137         rm -rf $DIR/$tdir
23138         mkdir -p $DIR/$tdir
23139
23140         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23141                 error "set striped dir error"
23142
23143         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23144                 error "set striped dir error"
23145
23146         touch $DIR/$tdir/striped_dir/a
23147         mkdir $DIR/$tdir/striped_dir/dir_a
23148         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23149                 error "create striped dir under striped dir fails"
23150
23151         touch $DIR/$tdir/striped_dir1/b
23152         mkdir $DIR/$tdir/striped_dir1/dir_b
23153         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23154                 error "create striped dir under striped dir fails"
23155
23156         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23157                 error "rename dir under different striped dir should fail"
23158
23159         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23160                 error "rename striped dir under diff striped dir should fail"
23161
23162         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23163                 error "rename file under diff striped dirs fails"
23164
23165         rm -rf $DIR/$tdir
23166 }
23167 run_test 300f "check rename cross striped directory"
23168
23169 test_300_check_default_striped_dir()
23170 {
23171         local dirname=$1
23172         local default_count=$2
23173         local default_index=$3
23174         local stripe_count
23175         local stripe_index
23176         local dir_stripe_index
23177         local dir
23178
23179         echo "checking $dirname $default_count $default_index"
23180         $LFS setdirstripe -D -c $default_count -i $default_index \
23181                                 -H all_char $DIR/$tdir/$dirname ||
23182                 error "set default stripe on striped dir error"
23183         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23184         [ $stripe_count -eq $default_count ] ||
23185                 error "expect $default_count get $stripe_count for $dirname"
23186
23187         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23188         [ $stripe_index -eq $default_index ] ||
23189                 error "expect $default_index get $stripe_index for $dirname"
23190
23191         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23192                                                 error "create dirs failed"
23193
23194         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23195         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23196         for dir in $(find $DIR/$tdir/$dirname/*); do
23197                 stripe_count=$($LFS getdirstripe -c $dir)
23198                 (( $stripe_count == $default_count )) ||
23199                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23200                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23201                 error "stripe count $default_count != $stripe_count for $dir"
23202
23203                 stripe_index=$($LFS getdirstripe -i $dir)
23204                 [ $default_index -eq -1 ] ||
23205                         [ $stripe_index -eq $default_index ] ||
23206                         error "$stripe_index != $default_index for $dir"
23207
23208                 #check default stripe
23209                 stripe_count=$($LFS getdirstripe -D -c $dir)
23210                 [ $stripe_count -eq $default_count ] ||
23211                 error "default count $default_count != $stripe_count for $dir"
23212
23213                 stripe_index=$($LFS getdirstripe -D -i $dir)
23214                 [ $stripe_index -eq $default_index ] ||
23215                 error "default index $default_index != $stripe_index for $dir"
23216         done
23217         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23218 }
23219
23220 test_300g() {
23221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23222         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23223                 skip "Need MDS version at least 2.7.55"
23224
23225         local dir
23226         local stripe_count
23227         local stripe_index
23228
23229         mkdir_on_mdt0 $DIR/$tdir
23230         mkdir $DIR/$tdir/normal_dir
23231
23232         #Checking when client cache stripe index
23233         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23234         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23235                 error "create striped_dir failed"
23236
23237         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23238                 error "create dir0 fails"
23239         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23240         [ $stripe_index -eq 0 ] ||
23241                 error "dir0 expect index 0 got $stripe_index"
23242
23243         mkdir $DIR/$tdir/striped_dir/dir1 ||
23244                 error "create dir1 fails"
23245         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23246         [ $stripe_index -eq 1 ] ||
23247                 error "dir1 expect index 1 got $stripe_index"
23248
23249         #check default stripe count/stripe index
23250         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23251         test_300_check_default_striped_dir normal_dir 1 0
23252         test_300_check_default_striped_dir normal_dir -1 1
23253         test_300_check_default_striped_dir normal_dir 2 -1
23254
23255         #delete default stripe information
23256         echo "delete default stripeEA"
23257         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23258                 error "set default stripe on striped dir error"
23259
23260         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23261         for dir in $(find $DIR/$tdir/normal_dir/*); do
23262                 stripe_count=$($LFS getdirstripe -c $dir)
23263                 [ $stripe_count -eq 0 ] ||
23264                         error "expect 1 get $stripe_count for $dir"
23265         done
23266 }
23267 run_test 300g "check default striped directory for normal directory"
23268
23269 test_300h() {
23270         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23271         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23272                 skip "Need MDS version at least 2.7.55"
23273
23274         local dir
23275         local stripe_count
23276
23277         mkdir $DIR/$tdir
23278         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23279                 error "set striped dir error"
23280
23281         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23282         test_300_check_default_striped_dir striped_dir 1 0
23283         test_300_check_default_striped_dir striped_dir -1 1
23284         test_300_check_default_striped_dir striped_dir 2 -1
23285
23286         #delete default stripe information
23287         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23288                 error "set default stripe on striped dir error"
23289
23290         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23291         for dir in $(find $DIR/$tdir/striped_dir/*); do
23292                 stripe_count=$($LFS getdirstripe -c $dir)
23293                 [ $stripe_count -eq 0 ] ||
23294                         error "expect 1 get $stripe_count for $dir"
23295         done
23296 }
23297 run_test 300h "check default striped directory for striped directory"
23298
23299 test_300i() {
23300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23302         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23303                 skip "Need MDS version at least 2.7.55"
23304
23305         local stripe_count
23306         local file
23307
23308         mkdir $DIR/$tdir
23309
23310         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23311                 error "set striped dir error"
23312
23313         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23314                 error "create files under striped dir failed"
23315
23316         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23317                 error "set striped hashdir error"
23318
23319         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23320                 error "create dir0 under hash dir failed"
23321         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23322                 error "create dir1 under hash dir failed"
23323         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23324                 error "create dir2 under hash dir failed"
23325
23326         # unfortunately, we need to umount to clear dir layout cache for now
23327         # once we fully implement dir layout, we can drop this
23328         umount_client $MOUNT || error "umount failed"
23329         mount_client $MOUNT || error "mount failed"
23330
23331         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23332         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23333         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23334
23335         #set the stripe to be unknown hash type
23336         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23337         $LCTL set_param fail_loc=0x1901
23338         for ((i = 0; i < 10; i++)); do
23339                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23340                         error "stat f-$i failed"
23341                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23342         done
23343
23344         touch $DIR/$tdir/striped_dir/f0 &&
23345                 error "create under striped dir with unknown hash should fail"
23346
23347         $LCTL set_param fail_loc=0
23348
23349         umount_client $MOUNT || error "umount failed"
23350         mount_client $MOUNT || error "mount failed"
23351
23352         return 0
23353 }
23354 run_test 300i "client handle unknown hash type striped directory"
23355
23356 test_300j() {
23357         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23359         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23360                 skip "Need MDS version at least 2.7.55"
23361
23362         local stripe_count
23363         local file
23364
23365         mkdir $DIR/$tdir
23366
23367         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23368         $LCTL set_param fail_loc=0x1702
23369         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23370                 error "set striped dir error"
23371
23372         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23373                 error "create files under striped dir failed"
23374
23375         $LCTL set_param fail_loc=0
23376
23377         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23378
23379         return 0
23380 }
23381 run_test 300j "test large update record"
23382
23383 test_300k() {
23384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23386         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23387                 skip "Need MDS version at least 2.7.55"
23388
23389         # this test needs a huge transaction
23390         local kb
23391         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23392              osd*.$FSNAME-MDT0000.kbytestotal")
23393         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23394
23395         local stripe_count
23396         local file
23397
23398         mkdir $DIR/$tdir
23399
23400         #define OBD_FAIL_LARGE_STRIPE   0x1703
23401         $LCTL set_param fail_loc=0x1703
23402         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23403                 error "set striped dir error"
23404         $LCTL set_param fail_loc=0
23405
23406         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23407                 error "getstripeddir fails"
23408         rm -rf $DIR/$tdir/striped_dir ||
23409                 error "unlink striped dir fails"
23410
23411         return 0
23412 }
23413 run_test 300k "test large striped directory"
23414
23415 test_300l() {
23416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23417         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23418         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23419                 skip "Need MDS version at least 2.7.55"
23420
23421         local stripe_index
23422
23423         test_mkdir -p $DIR/$tdir/striped_dir
23424         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23425                         error "chown $RUNAS_ID failed"
23426         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23427                 error "set default striped dir failed"
23428
23429         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23430         $LCTL set_param fail_loc=0x80000158
23431         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23432
23433         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23434         [ $stripe_index -eq 1 ] ||
23435                 error "expect 1 get $stripe_index for $dir"
23436 }
23437 run_test 300l "non-root user to create dir under striped dir with stale layout"
23438
23439 test_300m() {
23440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23441         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23442         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23443                 skip "Need MDS version at least 2.7.55"
23444
23445         mkdir -p $DIR/$tdir/striped_dir
23446         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23447                 error "set default stripes dir error"
23448
23449         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23450
23451         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23452         [ $stripe_count -eq 0 ] ||
23453                         error "expect 0 get $stripe_count for a"
23454
23455         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23456                 error "set default stripes dir error"
23457
23458         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23459
23460         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23461         [ $stripe_count -eq 0 ] ||
23462                         error "expect 0 get $stripe_count for b"
23463
23464         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23465                 error "set default stripes dir error"
23466
23467         mkdir $DIR/$tdir/striped_dir/c &&
23468                 error "default stripe_index is invalid, mkdir c should fails"
23469
23470         rm -rf $DIR/$tdir || error "rmdir fails"
23471 }
23472 run_test 300m "setstriped directory on single MDT FS"
23473
23474 cleanup_300n() {
23475         local list=$(comma_list $(mdts_nodes))
23476
23477         trap 0
23478         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23479 }
23480
23481 test_300n() {
23482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23483         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23484         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23485                 skip "Need MDS version at least 2.7.55"
23486         remote_mds_nodsh && skip "remote MDS with nodsh"
23487
23488         local stripe_index
23489         local list=$(comma_list $(mdts_nodes))
23490
23491         trap cleanup_300n RETURN EXIT
23492         mkdir -p $DIR/$tdir
23493         chmod 777 $DIR/$tdir
23494         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23495                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23496                 error "create striped dir succeeds with gid=0"
23497
23498         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23499         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23500                 error "create striped dir fails with gid=-1"
23501
23502         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23503         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23504                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23505                 error "set default striped dir succeeds with gid=0"
23506
23507
23508         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23509         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23510                 error "set default striped dir fails with gid=-1"
23511
23512
23513         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23514         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23515                                         error "create test_dir fails"
23516         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23517                                         error "create test_dir1 fails"
23518         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23519                                         error "create test_dir2 fails"
23520         cleanup_300n
23521 }
23522 run_test 300n "non-root user to create dir under striped dir with default EA"
23523
23524 test_300o() {
23525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23526         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23527         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23528                 skip "Need MDS version at least 2.7.55"
23529
23530         local numfree1
23531         local numfree2
23532
23533         mkdir -p $DIR/$tdir
23534
23535         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23536         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23537         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23538                 skip "not enough free inodes $numfree1 $numfree2"
23539         fi
23540
23541         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23542         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23543         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23544                 skip "not enough free space $numfree1 $numfree2"
23545         fi
23546
23547         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23548                 error "setdirstripe fails"
23549
23550         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23551                 error "create dirs fails"
23552
23553         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23554         ls $DIR/$tdir/striped_dir > /dev/null ||
23555                 error "ls striped dir fails"
23556         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23557                 error "unlink big striped dir fails"
23558 }
23559 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23560
23561 test_300p() {
23562         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23563         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23564         remote_mds_nodsh && skip "remote MDS with nodsh"
23565
23566         mkdir_on_mdt0 $DIR/$tdir
23567
23568         #define OBD_FAIL_OUT_ENOSPC     0x1704
23569         do_facet mds2 lctl set_param fail_loc=0x80001704
23570         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23571                  && error "create striped directory should fail"
23572
23573         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23574
23575         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23576         true
23577 }
23578 run_test 300p "create striped directory without space"
23579
23580 test_300q() {
23581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23582         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23583
23584         local fd=$(free_fd)
23585         local cmd="exec $fd<$tdir"
23586         cd $DIR
23587         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23588         eval $cmd
23589         cmd="exec $fd<&-"
23590         trap "eval $cmd" EXIT
23591         cd $tdir || error "cd $tdir fails"
23592         rmdir  ../$tdir || error "rmdir $tdir fails"
23593         mkdir local_dir && error "create dir succeeds"
23594         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23595         eval $cmd
23596         return 0
23597 }
23598 run_test 300q "create remote directory under orphan directory"
23599
23600 test_300r() {
23601         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23602                 skip "Need MDS version at least 2.7.55" && return
23603         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23604
23605         mkdir $DIR/$tdir
23606
23607         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23608                 error "set striped dir error"
23609
23610         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23611                 error "getstripeddir fails"
23612
23613         local stripe_count
23614         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23615                       awk '/lmv_stripe_count:/ { print $2 }')
23616
23617         [ $MDSCOUNT -ne $stripe_count ] &&
23618                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23619
23620         rm -rf $DIR/$tdir/striped_dir ||
23621                 error "unlink striped dir fails"
23622 }
23623 run_test 300r "test -1 striped directory"
23624
23625 test_300s_helper() {
23626         local count=$1
23627
23628         local stripe_dir=$DIR/$tdir/striped_dir.$count
23629
23630         $LFS mkdir -c $count $stripe_dir ||
23631                 error "lfs mkdir -c error"
23632
23633         $LFS getdirstripe $stripe_dir ||
23634                 error "lfs getdirstripe fails"
23635
23636         local stripe_count
23637         stripe_count=$($LFS getdirstripe $stripe_dir |
23638                       awk '/lmv_stripe_count:/ { print $2 }')
23639
23640         [ $count -ne $stripe_count ] &&
23641                 error_noexit "bad stripe count $stripe_count expected $count"
23642
23643         local dupe_stripes
23644         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23645                 awk '/0x/ {count[$1] += 1}; END {
23646                         for (idx in count) {
23647                                 if (count[idx]>1) {
23648                                         print "index " idx " count " count[idx]
23649                                 }
23650                         }
23651                 }')
23652
23653         if [[ -n "$dupe_stripes" ]] ; then
23654                 lfs getdirstripe $stripe_dir
23655                 error_noexit "Dupe MDT above: $dupe_stripes "
23656         fi
23657
23658         rm -rf $stripe_dir ||
23659                 error_noexit "unlink $stripe_dir fails"
23660 }
23661
23662 test_300s() {
23663         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23664                 skip "Need MDS version at least 2.7.55" && return
23665         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23666
23667         mkdir $DIR/$tdir
23668         for count in $(seq 2 $MDSCOUNT); do
23669                 test_300s_helper $count
23670         done
23671 }
23672 run_test 300s "test lfs mkdir -c without -i"
23673
23674
23675 prepare_remote_file() {
23676         mkdir $DIR/$tdir/src_dir ||
23677                 error "create remote source failed"
23678
23679         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23680                  error "cp to remote source failed"
23681         touch $DIR/$tdir/src_dir/a
23682
23683         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23684                 error "create remote target dir failed"
23685
23686         touch $DIR/$tdir/tgt_dir/b
23687
23688         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23689                 error "rename dir cross MDT failed!"
23690
23691         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23692                 error "src_child still exists after rename"
23693
23694         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23695                 error "missing file(a) after rename"
23696
23697         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23698                 error "diff after rename"
23699 }
23700
23701 test_310a() {
23702         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23704
23705         local remote_file=$DIR/$tdir/tgt_dir/b
23706
23707         mkdir -p $DIR/$tdir
23708
23709         prepare_remote_file || error "prepare remote file failed"
23710
23711         #open-unlink file
23712         $OPENUNLINK $remote_file $remote_file ||
23713                 error "openunlink $remote_file failed"
23714         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23715 }
23716 run_test 310a "open unlink remote file"
23717
23718 test_310b() {
23719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23721
23722         local remote_file=$DIR/$tdir/tgt_dir/b
23723
23724         mkdir -p $DIR/$tdir
23725
23726         prepare_remote_file || error "prepare remote file failed"
23727
23728         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23729         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23730         $CHECKSTAT -t file $remote_file || error "check file failed"
23731 }
23732 run_test 310b "unlink remote file with multiple links while open"
23733
23734 test_310c() {
23735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23736         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23737
23738         local remote_file=$DIR/$tdir/tgt_dir/b
23739
23740         mkdir -p $DIR/$tdir
23741
23742         prepare_remote_file || error "prepare remote file failed"
23743
23744         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23745         multiop_bg_pause $remote_file O_uc ||
23746                         error "mulitop failed for remote file"
23747         MULTIPID=$!
23748         $MULTIOP $DIR/$tfile Ouc
23749         kill -USR1 $MULTIPID
23750         wait $MULTIPID
23751 }
23752 run_test 310c "open-unlink remote file with multiple links"
23753
23754 #LU-4825
23755 test_311() {
23756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23757         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23758         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23759                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23760         remote_mds_nodsh && skip "remote MDS with nodsh"
23761
23762         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23763         local mdts=$(comma_list $(mdts_nodes))
23764
23765         mkdir -p $DIR/$tdir
23766         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23767         createmany -o $DIR/$tdir/$tfile. 1000
23768
23769         # statfs data is not real time, let's just calculate it
23770         old_iused=$((old_iused + 1000))
23771
23772         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23773                         osp.*OST0000*MDT0000.create_count")
23774         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23775                                 osp.*OST0000*MDT0000.max_create_count")
23776         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23777
23778         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23779         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23780         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23781
23782         unlinkmany $DIR/$tdir/$tfile. 1000
23783
23784         do_nodes $mdts "$LCTL set_param -n \
23785                         osp.*OST0000*.max_create_count=$max_count"
23786         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23787                 do_nodes $mdts "$LCTL set_param -n \
23788                                 osp.*OST0000*.create_count=$count"
23789         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23790                         grep "=0" && error "create_count is zero"
23791
23792         local new_iused
23793         for i in $(seq 120); do
23794                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23795                 # system may be too busy to destroy all objs in time, use
23796                 # a somewhat small value to not fail autotest
23797                 [ $((old_iused - new_iused)) -gt 400 ] && break
23798                 sleep 1
23799         done
23800
23801         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23802         [ $((old_iused - new_iused)) -gt 400 ] ||
23803                 error "objs not destroyed after unlink"
23804 }
23805 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23806
23807 zfs_oid_to_objid()
23808 {
23809         local ost=$1
23810         local objid=$2
23811
23812         local vdevdir=$(dirname $(facet_vdevice $ost))
23813         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23814         local zfs_zapid=$(do_facet $ost $cmd |
23815                           grep -w "/O/0/d$((objid%32))" -C 5 |
23816                           awk '/Object/{getline; print $1}')
23817         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23818                           awk "/$objid = /"'{printf $3}')
23819
23820         echo $zfs_objid
23821 }
23822
23823 zfs_object_blksz() {
23824         local ost=$1
23825         local objid=$2
23826
23827         local vdevdir=$(dirname $(facet_vdevice $ost))
23828         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23829         local blksz=$(do_facet $ost $cmd $objid |
23830                       awk '/dblk/{getline; printf $4}')
23831
23832         case "${blksz: -1}" in
23833                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23834                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23835                 *) ;;
23836         esac
23837
23838         echo $blksz
23839 }
23840
23841 test_312() { # LU-4856
23842         remote_ost_nodsh && skip "remote OST with nodsh"
23843         [ "$ost1_FSTYPE" = "zfs" ] ||
23844                 skip_env "the test only applies to zfs"
23845
23846         local max_blksz=$(do_facet ost1 \
23847                           $ZFS get -p recordsize $(facet_device ost1) |
23848                           awk '!/VALUE/{print $3}')
23849
23850         # to make life a little bit easier
23851         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23852         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23853
23854         local tf=$DIR/$tdir/$tfile
23855         touch $tf
23856         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23857
23858         # Get ZFS object id
23859         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23860         # block size change by sequential overwrite
23861         local bs
23862
23863         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23864                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23865
23866                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23867                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23868         done
23869         rm -f $tf
23870
23871         # block size change by sequential append write
23872         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23873         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23874         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23875         local count
23876
23877         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23878                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23879                         oflag=sync conv=notrunc
23880
23881                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23882                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23883                         error "blksz error, actual $blksz, " \
23884                                 "expected: 2 * $count * $PAGE_SIZE"
23885         done
23886         rm -f $tf
23887
23888         # random write
23889         touch $tf
23890         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23891         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23892
23893         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23894         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23895         [ $blksz -eq $PAGE_SIZE ] ||
23896                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23897
23898         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23899         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23900         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23901
23902         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23903         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23904         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23905 }
23906 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23907
23908 test_313() {
23909         remote_ost_nodsh && skip "remote OST with nodsh"
23910
23911         local file=$DIR/$tfile
23912
23913         rm -f $file
23914         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23915
23916         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23917         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23918         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23919                 error "write should failed"
23920         do_facet ost1 "$LCTL set_param fail_loc=0"
23921         rm -f $file
23922 }
23923 run_test 313 "io should fail after last_rcvd update fail"
23924
23925 test_314() {
23926         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23927
23928         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23929         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23930         rm -f $DIR/$tfile
23931         wait_delete_completed
23932         do_facet ost1 "$LCTL set_param fail_loc=0"
23933 }
23934 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23935
23936 test_315() { # LU-618
23937         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23938
23939         local file=$DIR/$tfile
23940         rm -f $file
23941
23942         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23943                 error "multiop file write failed"
23944         $MULTIOP $file oO_RDONLY:r4063232_c &
23945         PID=$!
23946
23947         sleep 2
23948
23949         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23950         kill -USR1 $PID
23951
23952         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23953         rm -f $file
23954 }
23955 run_test 315 "read should be accounted"
23956
23957 test_316() {
23958         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23959         large_xattr_enabled || skip_env "ea_inode feature disabled"
23960
23961         rm -rf $DIR/$tdir/d
23962         mkdir -p $DIR/$tdir/d
23963         chown nobody $DIR/$tdir/d
23964         touch $DIR/$tdir/d/file
23965
23966         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23967 }
23968 run_test 316 "lfs mv"
23969
23970 test_317() {
23971         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23972                 skip "Need MDS version at least 2.11.53"
23973         if [ "$ost1_FSTYPE" == "zfs" ]; then
23974                 skip "LU-10370: no implementation for ZFS"
23975         fi
23976
23977         local trunc_sz
23978         local grant_blk_size
23979
23980         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23981                         awk '/grant_block_size:/ { print $2; exit; }')
23982         #
23983         # Create File of size 5M. Truncate it to below size's and verify
23984         # blocks count.
23985         #
23986         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23987                 error "Create file $DIR/$tfile failed"
23988         stack_trap "rm -f $DIR/$tfile" EXIT
23989
23990         for trunc_sz in 2097152 4097 4000 509 0; do
23991                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23992                         error "truncate $tfile to $trunc_sz failed"
23993                 local sz=$(stat --format=%s $DIR/$tfile)
23994                 local blk=$(stat --format=%b $DIR/$tfile)
23995                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23996                                      grant_blk_size) * 8))
23997
23998                 if [[ $blk -ne $trunc_blk ]]; then
23999                         $(which stat) $DIR/$tfile
24000                         error "Expected Block $trunc_blk got $blk for $tfile"
24001                 fi
24002
24003                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24004                         error "Expected Size $trunc_sz got $sz for $tfile"
24005         done
24006
24007         #
24008         # sparse file test
24009         # Create file with a hole and write actual 65536 bytes which aligned
24010         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24011         #
24012         local bs=65536
24013         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24014                 error "Create file : $DIR/$tfile"
24015
24016         #
24017         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24018         # blocks. The block count must drop to 8.
24019         #
24020         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24021                 ((bs - grant_blk_size) + 1)))
24022         $TRUNCATE $DIR/$tfile $trunc_sz ||
24023                 error "truncate $tfile to $trunc_sz failed"
24024
24025         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24026         sz=$(stat --format=%s $DIR/$tfile)
24027         blk=$(stat --format=%b $DIR/$tfile)
24028
24029         if [[ $blk -ne $trunc_bsz ]]; then
24030                 $(which stat) $DIR/$tfile
24031                 error "Expected Block $trunc_bsz got $blk for $tfile"
24032         fi
24033
24034         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24035                 error "Expected Size $trunc_sz got $sz for $tfile"
24036 }
24037 run_test 317 "Verify blocks get correctly update after truncate"
24038
24039 test_318() {
24040         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24041         local old_max_active=$($LCTL get_param -n \
24042                             ${llite_name}.max_read_ahead_async_active \
24043                             2>/dev/null)
24044
24045         $LCTL set_param llite.*.max_read_ahead_async_active=256
24046         local max_active=$($LCTL get_param -n \
24047                            ${llite_name}.max_read_ahead_async_active \
24048                            2>/dev/null)
24049         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24050
24051         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24052                 error "set max_read_ahead_async_active should succeed"
24053
24054         $LCTL set_param llite.*.max_read_ahead_async_active=512
24055         max_active=$($LCTL get_param -n \
24056                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24057         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24058
24059         # restore @max_active
24060         [ $old_max_active -ne 0 ] && $LCTL set_param \
24061                 llite.*.max_read_ahead_async_active=$old_max_active
24062
24063         local old_threshold=$($LCTL get_param -n \
24064                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24065         local max_per_file_mb=$($LCTL get_param -n \
24066                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24067
24068         local invalid=$(($max_per_file_mb + 1))
24069         $LCTL set_param \
24070                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24071                         && error "set $invalid should fail"
24072
24073         local valid=$(($invalid - 1))
24074         $LCTL set_param \
24075                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24076                         error "set $valid should succeed"
24077         local threshold=$($LCTL get_param -n \
24078                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24079         [ $threshold -eq $valid ] || error \
24080                 "expect threshold $valid got $threshold"
24081         $LCTL set_param \
24082                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24083 }
24084 run_test 318 "Verify async readahead tunables"
24085
24086 test_319() {
24087         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24088
24089         local before=$(date +%s)
24090         local evict
24091         local mdir=$DIR/$tdir
24092         local file=$mdir/xxx
24093
24094         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24095         touch $file
24096
24097 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24098         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24099         $LFS mv -m1 $file &
24100
24101         sleep 1
24102         dd if=$file of=/dev/null
24103         wait
24104         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24105           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24106
24107         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24108 }
24109 run_test 319 "lost lease lock on migrate error"
24110
24111 test_398a() { # LU-4198
24112         local ost1_imp=$(get_osc_import_name client ost1)
24113         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24114                          cut -d'.' -f2)
24115
24116         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24117         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24118
24119         # request a new lock on client
24120         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24121
24122         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24123         local lock_count=$($LCTL get_param -n \
24124                            ldlm.namespaces.$imp_name.lru_size)
24125         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24126
24127         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24128
24129         # no lock cached, should use lockless IO and not enqueue new lock
24130         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24131         lock_count=$($LCTL get_param -n \
24132                      ldlm.namespaces.$imp_name.lru_size)
24133         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24134 }
24135 run_test 398a "direct IO should cancel lock otherwise lockless"
24136
24137 test_398b() { # LU-4198
24138         which fio || skip_env "no fio installed"
24139         $LFS setstripe -c -1 $DIR/$tfile
24140
24141         local size=12
24142         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24143
24144         local njobs=4
24145         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24146         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24147                 --numjobs=$njobs --fallocate=none \
24148                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24149                 --filename=$DIR/$tfile &
24150         bg_pid=$!
24151
24152         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24153         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24154                 --numjobs=$njobs --fallocate=none \
24155                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24156                 --filename=$DIR/$tfile || true
24157         wait $bg_pid
24158
24159         rm -f $DIR/$tfile
24160 }
24161 run_test 398b "DIO and buffer IO race"
24162
24163 test_398c() { # LU-4198
24164         local ost1_imp=$(get_osc_import_name client ost1)
24165         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24166                          cut -d'.' -f2)
24167
24168         which fio || skip_env "no fio installed"
24169
24170         saved_debug=$($LCTL get_param -n debug)
24171         $LCTL set_param debug=0
24172
24173         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24174         ((size /= 1024)) # by megabytes
24175         ((size /= 2)) # write half of the OST at most
24176         [ $size -gt 40 ] && size=40 #reduce test time anyway
24177
24178         $LFS setstripe -c 1 $DIR/$tfile
24179
24180         # it seems like ldiskfs reserves more space than necessary if the
24181         # writing blocks are not mapped, so it extends the file firstly
24182         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24183         cancel_lru_locks osc
24184
24185         # clear and verify rpc_stats later
24186         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24187
24188         local njobs=4
24189         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24190         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24191                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24192                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24193                 --filename=$DIR/$tfile
24194         [ $? -eq 0 ] || error "fio write error"
24195
24196         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24197                 error "Locks were requested while doing AIO"
24198
24199         # get the percentage of 1-page I/O
24200         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24201                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24202                 awk '{print $7}')
24203         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24204
24205         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24206         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24207                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24208                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24209                 --filename=$DIR/$tfile
24210         [ $? -eq 0 ] || error "fio mixed read write error"
24211
24212         echo "AIO with large block size ${size}M"
24213         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24214                 --numjobs=1 --fallocate=none --ioengine=libaio \
24215                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24216                 --filename=$DIR/$tfile
24217         [ $? -eq 0 ] || error "fio large block size failed"
24218
24219         rm -f $DIR/$tfile
24220         $LCTL set_param debug="$saved_debug"
24221 }
24222 run_test 398c "run fio to test AIO"
24223
24224 test_398d() { #  LU-13846
24225         which aiocp || skip_env "no aiocp installed"
24226         local aio_file=$DIR/$tfile.aio
24227
24228         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24229
24230         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24231         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24232         stack_trap "rm -f $DIR/$tfile $aio_file"
24233
24234         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24235
24236         # make sure we don't crash and fail properly
24237         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24238                 error "aio not aligned with PAGE SIZE should fail"
24239
24240         rm -f $DIR/$tfile $aio_file
24241 }
24242 run_test 398d "run aiocp to verify block size > stripe size"
24243
24244 test_398e() {
24245         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24246         touch $DIR/$tfile.new
24247         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24248 }
24249 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24250
24251 test_398f() { #  LU-14687
24252         which aiocp || skip_env "no aiocp installed"
24253         local aio_file=$DIR/$tfile.aio
24254
24255         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24256
24257         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24258         stack_trap "rm -f $DIR/$tfile $aio_file"
24259
24260         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24261         $LCTL set_param fail_loc=0x1418
24262         # make sure we don't crash and fail properly
24263         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24264                 error "aio with page allocation failure succeeded"
24265         $LCTL set_param fail_loc=0
24266         diff $DIR/$tfile $aio_file
24267         [[ $? != 0 ]] || error "no diff after failed aiocp"
24268 }
24269 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24270
24271 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24272 # stripe and i/o size must be > stripe size
24273 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24274 # single RPC in flight.  This test shows async DIO submission is working by
24275 # showing multiple RPCs in flight.
24276 test_398g() { #  LU-13798
24277         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24278
24279         # We need to do some i/o first to acquire enough grant to put our RPCs
24280         # in flight; otherwise a new connection may not have enough grant
24281         # available
24282         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24283                 error "parallel dio failed"
24284         stack_trap "rm -f $DIR/$tfile"
24285
24286         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24287         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24288         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24289         stack_trap "$LCTL set_param -n $pages_per_rpc"
24290
24291         # Recreate file so it's empty
24292         rm -f $DIR/$tfile
24293         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24294         #Pause rpc completion to guarantee we see multiple rpcs in flight
24295         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24296         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24297         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24298
24299         # Clear rpc stats
24300         $LCTL set_param osc.*.rpc_stats=c
24301
24302         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24303                 error "parallel dio failed"
24304         stack_trap "rm -f $DIR/$tfile"
24305
24306         $LCTL get_param osc.*-OST0000-*.rpc_stats
24307         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24308                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24309                 grep "8:" | awk '{print $8}')
24310         # We look at the "8 rpcs in flight" field, and verify A) it is present
24311         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24312         # as expected for an 8M DIO to a file with 1M stripes.
24313         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24314
24315         # Verify turning off parallel dio works as expected
24316         # Clear rpc stats
24317         $LCTL set_param osc.*.rpc_stats=c
24318         $LCTL set_param llite.*.parallel_dio=0
24319         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24320
24321         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24322                 error "dio with parallel dio disabled failed"
24323
24324         # Ideally, we would see only one RPC in flight here, but there is an
24325         # unavoidable race between i/o completion and RPC in flight counting,
24326         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24327         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24328         # So instead we just verify it's always < 8.
24329         $LCTL get_param osc.*-OST0000-*.rpc_stats
24330         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24331                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24332                 grep '^$' -B1 | grep . | awk '{print $1}')
24333         [ $ret != "8:" ] ||
24334                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24335 }
24336 run_test 398g "verify parallel dio async RPC submission"
24337
24338 test_398h() { #  LU-13798
24339         local dio_file=$DIR/$tfile.dio
24340
24341         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24342
24343         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24344         stack_trap "rm -f $DIR/$tfile $dio_file"
24345
24346         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24347                 error "parallel dio failed"
24348         diff $DIR/$tfile $dio_file
24349         [[ $? == 0 ]] || error "file diff after aiocp"
24350 }
24351 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24352
24353 test_398i() { #  LU-13798
24354         local dio_file=$DIR/$tfile.dio
24355
24356         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24357
24358         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24359         stack_trap "rm -f $DIR/$tfile $dio_file"
24360
24361         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24362         $LCTL set_param fail_loc=0x1418
24363         # make sure we don't crash and fail properly
24364         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24365                 error "parallel dio page allocation failure succeeded"
24366         diff $DIR/$tfile $dio_file
24367         [[ $? != 0 ]] || error "no diff after failed aiocp"
24368 }
24369 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24370
24371 test_398j() { #  LU-13798
24372         # Stripe size > RPC size but less than i/o size tests split across
24373         # stripes and RPCs for individual i/o op
24374         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24375
24376         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24377         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24378         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24379         stack_trap "$LCTL set_param -n $pages_per_rpc"
24380
24381         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24382                 error "parallel dio write failed"
24383         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24384
24385         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24386                 error "parallel dio read failed"
24387         diff $DIR/$tfile $DIR/$tfile.2
24388         [[ $? == 0 ]] || error "file diff after parallel dio read"
24389 }
24390 run_test 398j "test parallel dio where stripe size > rpc_size"
24391
24392 test_398k() { #  LU-13798
24393         wait_delete_completed
24394         wait_mds_ost_sync
24395
24396         # 4 stripe file; we will cause out of space on OST0
24397         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24398
24399         # Fill OST0 (if it's not too large)
24400         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24401                    head -n1)
24402         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24403                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24404         fi
24405         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24406         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24407                 error "dd should fill OST0"
24408         stack_trap "rm -f $DIR/$tfile.1"
24409
24410         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24411         err=$?
24412
24413         ls -la $DIR/$tfile
24414         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24415                 error "file is not 0 bytes in size"
24416
24417         # dd above should not succeed, but don't error until here so we can
24418         # get debug info above
24419         [[ $err != 0 ]] ||
24420                 error "parallel dio write with enospc succeeded"
24421         stack_trap "rm -f $DIR/$tfile"
24422 }
24423 run_test 398k "test enospc on first stripe"
24424
24425 test_398l() { #  LU-13798
24426         wait_delete_completed
24427         wait_mds_ost_sync
24428
24429         # 4 stripe file; we will cause out of space on OST0
24430         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24431         # happens on the second i/o chunk we issue
24432         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24433
24434         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24435         stack_trap "rm -f $DIR/$tfile"
24436
24437         # Fill OST0 (if it's not too large)
24438         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24439                    head -n1)
24440         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24441                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24442         fi
24443         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24444         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24445                 error "dd should fill OST0"
24446         stack_trap "rm -f $DIR/$tfile.1"
24447
24448         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24449         err=$?
24450         stack_trap "rm -f $DIR/$tfile.2"
24451
24452         # Check that short write completed as expected
24453         ls -la $DIR/$tfile.2
24454         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24455                 error "file is not 1M in size"
24456
24457         # dd above should not succeed, but don't error until here so we can
24458         # get debug info above
24459         [[ $err != 0 ]] ||
24460                 error "parallel dio write with enospc succeeded"
24461
24462         # Truncate source file to same length as output file and diff them
24463         $TRUNCATE $DIR/$tfile 1048576
24464         diff $DIR/$tfile $DIR/$tfile.2
24465         [[ $? == 0 ]] || error "data incorrect after short write"
24466 }
24467 run_test 398l "test enospc on intermediate stripe/RPC"
24468
24469 test_398m() { #  LU-13798
24470         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24471
24472         # Set up failure on OST0, the first stripe:
24473         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24474         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24475         # So this fail_val specifies OST0
24476         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24477         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24478
24479         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24480                 error "parallel dio write with failure on first stripe succeeded"
24481         stack_trap "rm -f $DIR/$tfile"
24482         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24483
24484         # Place data in file for read
24485         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24486                 error "parallel dio write failed"
24487
24488         # Fail read on OST0, first stripe
24489         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24490         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24491         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24492                 error "parallel dio read with error on first stripe succeeded"
24493         rm -f $DIR/$tfile.2
24494         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24495
24496         # Switch to testing on OST1, second stripe
24497         # Clear file contents, maintain striping
24498         echo > $DIR/$tfile
24499         # Set up failure on OST1, second stripe:
24500         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24501         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24502
24503         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24504                 error "parallel dio write with failure on first stripe succeeded"
24505         stack_trap "rm -f $DIR/$tfile"
24506         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24507
24508         # Place data in file for read
24509         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24510                 error "parallel dio write failed"
24511
24512         # Fail read on OST1, second stripe
24513         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24514         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24515         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24516                 error "parallel dio read with error on first stripe succeeded"
24517         rm -f $DIR/$tfile.2
24518         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24519 }
24520 run_test 398m "test RPC failures with parallel dio"
24521
24522 # Parallel submission of DIO should not cause problems for append, but it's
24523 # important to verify.
24524 test_398n() { #  LU-13798
24525         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24526
24527         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24528                 error "dd to create source file failed"
24529         stack_trap "rm -f $DIR/$tfile"
24530
24531         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24532                 error "parallel dio write with failure on second stripe succeeded"
24533         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24534         diff $DIR/$tfile $DIR/$tfile.1
24535         [[ $? == 0 ]] || error "data incorrect after append"
24536
24537 }
24538 run_test 398n "test append with parallel DIO"
24539
24540 test_fake_rw() {
24541         local read_write=$1
24542         if [ "$read_write" = "write" ]; then
24543                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24544         elif [ "$read_write" = "read" ]; then
24545                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24546         else
24547                 error "argument error"
24548         fi
24549
24550         # turn off debug for performance testing
24551         local saved_debug=$($LCTL get_param -n debug)
24552         $LCTL set_param debug=0
24553
24554         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24555
24556         # get ost1 size - $FSNAME-OST0000
24557         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24558         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24559         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24560
24561         if [ "$read_write" = "read" ]; then
24562                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24563         fi
24564
24565         local start_time=$(date +%s.%N)
24566         $dd_cmd bs=1M count=$blocks oflag=sync ||
24567                 error "real dd $read_write error"
24568         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24569
24570         if [ "$read_write" = "write" ]; then
24571                 rm -f $DIR/$tfile
24572         fi
24573
24574         # define OBD_FAIL_OST_FAKE_RW           0x238
24575         do_facet ost1 $LCTL set_param fail_loc=0x238
24576
24577         local start_time=$(date +%s.%N)
24578         $dd_cmd bs=1M count=$blocks oflag=sync ||
24579                 error "fake dd $read_write error"
24580         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24581
24582         if [ "$read_write" = "write" ]; then
24583                 # verify file size
24584                 cancel_lru_locks osc
24585                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24586                         error "$tfile size not $blocks MB"
24587         fi
24588         do_facet ost1 $LCTL set_param fail_loc=0
24589
24590         echo "fake $read_write $duration_fake vs. normal $read_write" \
24591                 "$duration in seconds"
24592         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24593                 error_not_in_vm "fake write is slower"
24594
24595         $LCTL set_param -n debug="$saved_debug"
24596         rm -f $DIR/$tfile
24597 }
24598 test_399a() { # LU-7655 for OST fake write
24599         remote_ost_nodsh && skip "remote OST with nodsh"
24600
24601         test_fake_rw write
24602 }
24603 run_test 399a "fake write should not be slower than normal write"
24604
24605 test_399b() { # LU-8726 for OST fake read
24606         remote_ost_nodsh && skip "remote OST with nodsh"
24607         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24608                 skip_env "ldiskfs only test"
24609         fi
24610
24611         test_fake_rw read
24612 }
24613 run_test 399b "fake read should not be slower than normal read"
24614
24615 test_400a() { # LU-1606, was conf-sanity test_74
24616         if ! which $CC > /dev/null 2>&1; then
24617                 skip_env "$CC is not installed"
24618         fi
24619
24620         local extra_flags=''
24621         local out=$TMP/$tfile
24622         local prefix=/usr/include/lustre
24623         local prog
24624
24625         # Oleg removes c files in his test rig so test if any c files exist
24626         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24627                 skip_env "Needed c test files are missing"
24628
24629         if ! [[ -d $prefix ]]; then
24630                 # Assume we're running in tree and fixup the include path.
24631                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24632                 extra_flags+=" -L$LUSTRE/utils/.lib"
24633         fi
24634
24635         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24636                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24637                         error "client api broken"
24638         done
24639         rm -f $out
24640 }
24641 run_test 400a "Lustre client api program can compile and link"
24642
24643 test_400b() { # LU-1606, LU-5011
24644         local header
24645         local out=$TMP/$tfile
24646         local prefix=/usr/include/linux/lustre
24647
24648         # We use a hard coded prefix so that this test will not fail
24649         # when run in tree. There are headers in lustre/include/lustre/
24650         # that are not packaged (like lustre_idl.h) and have more
24651         # complicated include dependencies (like config.h and lnet/types.h).
24652         # Since this test about correct packaging we just skip them when
24653         # they don't exist (see below) rather than try to fixup cppflags.
24654
24655         if ! which $CC > /dev/null 2>&1; then
24656                 skip_env "$CC is not installed"
24657         fi
24658
24659         for header in $prefix/*.h; do
24660                 if ! [[ -f "$header" ]]; then
24661                         continue
24662                 fi
24663
24664                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24665                         continue # lustre_ioctl.h is internal header
24666                 fi
24667
24668                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24669                         error "cannot compile '$header'"
24670         done
24671         rm -f $out
24672 }
24673 run_test 400b "packaged headers can be compiled"
24674
24675 test_401a() { #LU-7437
24676         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24677         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24678
24679         #count the number of parameters by "list_param -R"
24680         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24681         #count the number of parameters by listing proc files
24682         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24683         echo "proc_dirs='$proc_dirs'"
24684         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24685         local procs=$(find -L $proc_dirs -mindepth 1 -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         # test the list_param -D option only returns directories
24692         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24693         #count the number of parameters by listing proc directories
24694         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24695                 sort -u | wc -l)
24696
24697         [ $params -eq $procs ] ||
24698                 error "found $params parameters vs. $procs proc files"
24699 }
24700 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24701
24702 test_401b() {
24703         # jobid_var may not allow arbitrary values, so use jobid_name
24704         # if available
24705         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24706                 local testname=jobid_name tmp='testing%p'
24707         else
24708                 local testname=jobid_var tmp=testing
24709         fi
24710
24711         local save=$($LCTL get_param -n $testname)
24712
24713         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24714                 error "no error returned when setting bad parameters"
24715
24716         local jobid_new=$($LCTL get_param -n foe $testname baz)
24717         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24718
24719         $LCTL set_param -n fog=bam $testname=$save bat=fog
24720         local jobid_old=$($LCTL get_param -n foe $testname bag)
24721         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24722 }
24723 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24724
24725 test_401c() {
24726         # jobid_var may not allow arbitrary values, so use jobid_name
24727         # if available
24728         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24729                 local testname=jobid_name
24730         else
24731                 local testname=jobid_var
24732         fi
24733
24734         local jobid_var_old=$($LCTL get_param -n $testname)
24735         local jobid_var_new
24736
24737         $LCTL set_param $testname= &&
24738                 error "no error returned for 'set_param a='"
24739
24740         jobid_var_new=$($LCTL get_param -n $testname)
24741         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24742                 error "$testname was changed by setting without value"
24743
24744         $LCTL set_param $testname &&
24745                 error "no error returned for 'set_param a'"
24746
24747         jobid_var_new=$($LCTL get_param -n $testname)
24748         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24749                 error "$testname was changed by setting without value"
24750 }
24751 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24752
24753 test_401d() {
24754         # jobid_var may not allow arbitrary values, so use jobid_name
24755         # if available
24756         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24757                 local testname=jobid_name new_value='foo=bar%p'
24758         else
24759                 local testname=jobid_var new_valuie=foo=bar
24760         fi
24761
24762         local jobid_var_old=$($LCTL get_param -n $testname)
24763         local jobid_var_new
24764
24765         $LCTL set_param $testname=$new_value ||
24766                 error "'set_param a=b' did not accept a value containing '='"
24767
24768         jobid_var_new=$($LCTL get_param -n $testname)
24769         [[ "$jobid_var_new" == "$new_value" ]] ||
24770                 error "'set_param a=b' failed on a value containing '='"
24771
24772         # Reset the $testname to test the other format
24773         $LCTL set_param $testname=$jobid_var_old
24774         jobid_var_new=$($LCTL get_param -n $testname)
24775         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24776                 error "failed to reset $testname"
24777
24778         $LCTL set_param $testname $new_value ||
24779                 error "'set_param a b' did not accept a value containing '='"
24780
24781         jobid_var_new=$($LCTL get_param -n $testname)
24782         [[ "$jobid_var_new" == "$new_value" ]] ||
24783                 error "'set_param a b' failed on a value containing '='"
24784
24785         $LCTL set_param $testname $jobid_var_old
24786         jobid_var_new=$($LCTL get_param -n $testname)
24787         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24788                 error "failed to reset $testname"
24789 }
24790 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24791
24792 test_401e() { # LU-14779
24793         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24794                 error "lctl list_param MGC* failed"
24795         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24796         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24797                 error "lctl get_param lru_size failed"
24798 }
24799 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24800
24801 test_402() {
24802         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24803         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24804                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24805         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24806                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24807                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24808         remote_mds_nodsh && skip "remote MDS with nodsh"
24809
24810         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24811 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24812         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24813         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24814                 echo "Touch failed - OK"
24815 }
24816 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24817
24818 test_403() {
24819         local file1=$DIR/$tfile.1
24820         local file2=$DIR/$tfile.2
24821         local tfile=$TMP/$tfile
24822
24823         rm -f $file1 $file2 $tfile
24824
24825         touch $file1
24826         ln $file1 $file2
24827
24828         # 30 sec OBD_TIMEOUT in ll_getattr()
24829         # right before populating st_nlink
24830         $LCTL set_param fail_loc=0x80001409
24831         stat -c %h $file1 > $tfile &
24832
24833         # create an alias, drop all locks and reclaim the dentry
24834         < $file2
24835         cancel_lru_locks mdc
24836         cancel_lru_locks osc
24837         sysctl -w vm.drop_caches=2
24838
24839         wait
24840
24841         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24842
24843         rm -f $tfile $file1 $file2
24844 }
24845 run_test 403 "i_nlink should not drop to zero due to aliasing"
24846
24847 test_404() { # LU-6601
24848         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24849                 skip "Need server version newer than 2.8.52"
24850         remote_mds_nodsh && skip "remote MDS with nodsh"
24851
24852         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24853                 awk '/osp .*-osc-MDT/ { print $4}')
24854
24855         local osp
24856         for osp in $mosps; do
24857                 echo "Deactivate: " $osp
24858                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24859                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24860                         awk -vp=$osp '$4 == p { print $2 }')
24861                 [ $stat = IN ] || {
24862                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24863                         error "deactivate error"
24864                 }
24865                 echo "Activate: " $osp
24866                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24867                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24868                         awk -vp=$osp '$4 == p { print $2 }')
24869                 [ $stat = UP ] || {
24870                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24871                         error "activate error"
24872                 }
24873         done
24874 }
24875 run_test 404 "validate manual {de}activated works properly for OSPs"
24876
24877 test_405() {
24878         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24879         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24880                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24881                         skip "Layout swap lock is not supported"
24882
24883         check_swap_layouts_support
24884         check_swap_layout_no_dom $DIR
24885
24886         test_mkdir $DIR/$tdir
24887         swap_lock_test -d $DIR/$tdir ||
24888                 error "One layout swap locked test failed"
24889 }
24890 run_test 405 "Various layout swap lock tests"
24891
24892 test_406() {
24893         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24894         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24895         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24897         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24898                 skip "Need MDS version at least 2.8.50"
24899
24900         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24901         local test_pool=$TESTNAME
24902
24903         pool_add $test_pool || error "pool_add failed"
24904         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24905                 error "pool_add_targets failed"
24906
24907         save_layout_restore_at_exit $MOUNT
24908
24909         # parent set default stripe count only, child will stripe from both
24910         # parent and fs default
24911         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24912                 error "setstripe $MOUNT failed"
24913         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24914         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24915         for i in $(seq 10); do
24916                 local f=$DIR/$tdir/$tfile.$i
24917                 touch $f || error "touch failed"
24918                 local count=$($LFS getstripe -c $f)
24919                 [ $count -eq $OSTCOUNT ] ||
24920                         error "$f stripe count $count != $OSTCOUNT"
24921                 local offset=$($LFS getstripe -i $f)
24922                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24923                 local size=$($LFS getstripe -S $f)
24924                 [ $size -eq $((def_stripe_size * 2)) ] ||
24925                         error "$f stripe size $size != $((def_stripe_size * 2))"
24926                 local pool=$($LFS getstripe -p $f)
24927                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24928         done
24929
24930         # change fs default striping, delete parent default striping, now child
24931         # will stripe from new fs default striping only
24932         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24933                 error "change $MOUNT default stripe failed"
24934         $LFS setstripe -c 0 $DIR/$tdir ||
24935                 error "delete $tdir default stripe failed"
24936         for i in $(seq 11 20); do
24937                 local f=$DIR/$tdir/$tfile.$i
24938                 touch $f || error "touch $f failed"
24939                 local count=$($LFS getstripe -c $f)
24940                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24941                 local offset=$($LFS getstripe -i $f)
24942                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24943                 local size=$($LFS getstripe -S $f)
24944                 [ $size -eq $def_stripe_size ] ||
24945                         error "$f stripe size $size != $def_stripe_size"
24946                 local pool=$($LFS getstripe -p $f)
24947                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24948         done
24949
24950         unlinkmany $DIR/$tdir/$tfile. 1 20
24951
24952         local f=$DIR/$tdir/$tfile
24953         pool_remove_all_targets $test_pool $f
24954         pool_remove $test_pool $f
24955 }
24956 run_test 406 "DNE support fs default striping"
24957
24958 test_407() {
24959         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24960         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24961                 skip "Need MDS version at least 2.8.55"
24962         remote_mds_nodsh && skip "remote MDS with nodsh"
24963
24964         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24965                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24966         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24967                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24968         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24969
24970         #define OBD_FAIL_DT_TXN_STOP    0x2019
24971         for idx in $(seq $MDSCOUNT); do
24972                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24973         done
24974         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24975         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24976                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24977         true
24978 }
24979 run_test 407 "transaction fail should cause operation fail"
24980
24981 test_408() {
24982         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24983
24984         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24985         lctl set_param fail_loc=0x8000040a
24986         # let ll_prepare_partial_page() fail
24987         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24988
24989         rm -f $DIR/$tfile
24990
24991         # create at least 100 unused inodes so that
24992         # shrink_icache_memory(0) should not return 0
24993         touch $DIR/$tfile-{0..100}
24994         rm -f $DIR/$tfile-{0..100}
24995         sync
24996
24997         echo 2 > /proc/sys/vm/drop_caches
24998 }
24999 run_test 408 "drop_caches should not hang due to page leaks"
25000
25001 test_409()
25002 {
25003         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25004
25005         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25006         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25007         touch $DIR/$tdir/guard || error "(2) Fail to create"
25008
25009         local PREFIX=$(str_repeat 'A' 128)
25010         echo "Create 1K hard links start at $(date)"
25011         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25012                 error "(3) Fail to hard link"
25013
25014         echo "Links count should be right although linkEA overflow"
25015         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25016         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25017         [ $linkcount -eq 1001 ] ||
25018                 error "(5) Unexpected hard links count: $linkcount"
25019
25020         echo "List all links start at $(date)"
25021         ls -l $DIR/$tdir/foo > /dev/null ||
25022                 error "(6) Fail to list $DIR/$tdir/foo"
25023
25024         echo "Unlink hard links start at $(date)"
25025         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25026                 error "(7) Fail to unlink"
25027         echo "Unlink hard links finished at $(date)"
25028 }
25029 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25030
25031 test_410()
25032 {
25033         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25034                 skip "Need client version at least 2.9.59"
25035         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25036                 skip "Need MODULES build"
25037
25038         # Create a file, and stat it from the kernel
25039         local testfile=$DIR/$tfile
25040         touch $testfile
25041
25042         local run_id=$RANDOM
25043         local my_ino=$(stat --format "%i" $testfile)
25044
25045         # Try to insert the module. This will always fail as the
25046         # module is designed to not be inserted.
25047         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25048             &> /dev/null
25049
25050         # Anything but success is a test failure
25051         dmesg | grep -q \
25052             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25053             error "no inode match"
25054 }
25055 run_test 410 "Test inode number returned from kernel thread"
25056
25057 cleanup_test411_cgroup() {
25058         trap 0
25059         rmdir "$1"
25060 }
25061
25062 test_411() {
25063         local cg_basedir=/sys/fs/cgroup/memory
25064         # LU-9966
25065         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25066                 skip "no setup for cgroup"
25067
25068         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25069                 error "test file creation failed"
25070         cancel_lru_locks osc
25071
25072         # Create a very small memory cgroup to force a slab allocation error
25073         local cgdir=$cg_basedir/osc_slab_alloc
25074         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25075         trap "cleanup_test411_cgroup $cgdir" EXIT
25076         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25077         echo 1M > $cgdir/memory.limit_in_bytes
25078
25079         # Should not LBUG, just be killed by oom-killer
25080         # dd will return 0 even allocation failure in some environment.
25081         # So don't check return value
25082         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25083         cleanup_test411_cgroup $cgdir
25084
25085         return 0
25086 }
25087 run_test 411 "Slab allocation error with cgroup does not LBUG"
25088
25089 test_412() {
25090         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25091         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
25092                 skip "Need server version at least 2.10.55"
25093         fi
25094
25095         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25096                 error "mkdir failed"
25097         $LFS getdirstripe $DIR/$tdir
25098         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25099         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25100                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25101         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25102         [ $stripe_count -eq 2 ] ||
25103                 error "expect 2 get $stripe_count"
25104 }
25105 run_test 412 "mkdir on specific MDTs"
25106
25107 generate_uneven_mdts() {
25108         local threshold=$1
25109         local lmv_qos_maxage
25110         local lod_qos_maxage
25111         local ffree
25112         local bavail
25113         local max
25114         local min
25115         local max_index
25116         local min_index
25117         local tmp
25118         local i
25119
25120         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25121         $LCTL set_param lmv.*.qos_maxage=1
25122         stack_trap "$LCTL set_param \
25123                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25124         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25125                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25126         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25127                 lod.*.mdt_qos_maxage=1
25128         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25129                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25130
25131         echo
25132         echo "Check for uneven MDTs: "
25133
25134         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25135         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25136         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25137
25138         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25139         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25140         max_index=0
25141         min_index=0
25142         for ((i = 1; i < ${#ffree[@]}; i++)); do
25143                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25144                 if [ $tmp -gt $max ]; then
25145                         max=$tmp
25146                         max_index=$i
25147                 fi
25148                 if [ $tmp -lt $min ]; then
25149                         min=$tmp
25150                         min_index=$i
25151                 fi
25152         done
25153
25154         (( ${ffree[min_index]} > 0 )) ||
25155                 skip "no free files in MDT$min_index"
25156         (( ${ffree[min_index]} < 10000000 )) ||
25157                 skip "too many free files in MDT$min_index"
25158
25159         # Check if we need to generate uneven MDTs
25160         local diff=$(((max - min) * 100 / min))
25161         local testdir=$DIR/$tdir-fillmdt
25162         local start
25163
25164         mkdir -p $testdir
25165
25166         i=0
25167         while (( diff < threshold )); do
25168                 # generate uneven MDTs, create till $threshold% diff
25169                 echo -n "weight diff=$diff% must be > $threshold% ..."
25170                 echo "Fill MDT$min_index with 1000 files: loop $i"
25171                 testdir=$DIR/$tdir-fillmdt/$i
25172                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25173                         error "mkdir $testdir failed"
25174                 $LFS setstripe -E 1M -L mdt $testdir ||
25175                         error "setstripe $testdir failed"
25176                 start=$SECONDS
25177                 for F in f.{0..999}; do
25178                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25179                                 /dev/null 2>&1 || error "dd $F failed"
25180                 done
25181
25182                 # wait for QOS to update
25183                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25184
25185                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25186                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25187                 max=$(((${ffree[max_index]} >> 8) * \
25188                         (${bavail[max_index]} * bsize >> 16)))
25189                 min=$(((${ffree[min_index]} >> 8) * \
25190                         (${bavail[min_index]} * bsize >> 16)))
25191                 diff=$(((max - min) * 100 / min))
25192                 i=$((i + 1))
25193         done
25194
25195         echo "MDT filesfree available: ${ffree[@]}"
25196         echo "MDT blocks available: ${bavail[@]}"
25197         echo "weight diff=$diff%"
25198 }
25199
25200 test_qos_mkdir() {
25201         local mkdir_cmd=$1
25202         local stripe_count=$2
25203         local mdts=$(comma_list $(mdts_nodes))
25204
25205         local testdir
25206         local lmv_qos_prio_free
25207         local lmv_qos_threshold_rr
25208         local lmv_qos_maxage
25209         local lod_qos_prio_free
25210         local lod_qos_threshold_rr
25211         local lod_qos_maxage
25212         local count
25213         local i
25214
25215         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25216         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25217         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25218                 head -n1)
25219         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25220         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25221         stack_trap "$LCTL set_param \
25222                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25223         stack_trap "$LCTL set_param \
25224                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25225         stack_trap "$LCTL set_param \
25226                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25227
25228         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25229                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25230         lod_qos_prio_free=${lod_qos_prio_free%%%}
25231         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25232                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25233         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25234         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25235                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25236         stack_trap "do_nodes $mdts $LCTL set_param \
25237                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25238         stack_trap "do_nodes $mdts $LCTL set_param \
25239                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25240         stack_trap "do_nodes $mdts $LCTL set_param \
25241                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25242
25243         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25244         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25245
25246         testdir=$DIR/$tdir-s$stripe_count/rr
25247
25248         local stripe_index=$($LFS getstripe -m $testdir)
25249         local test_mkdir_rr=true
25250
25251         getfattr -d -m dmv -e hex $testdir | grep dmv
25252         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25253                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25254                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25255                         test_mkdir_rr=false
25256         fi
25257
25258         echo
25259         $test_mkdir_rr &&
25260                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25261                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25262
25263         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25264         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25265                 eval $mkdir_cmd $testdir/subdir$i ||
25266                         error "$mkdir_cmd subdir$i failed"
25267         done
25268
25269         for (( i = 0; i < $MDSCOUNT; i++ )); do
25270                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25271                 echo "$count directories created on MDT$i"
25272                 if $test_mkdir_rr; then
25273                         (( $count == 100 )) ||
25274                                 error "subdirs are not evenly distributed"
25275                 elif (( $i == $stripe_index )); then
25276                         (( $count == 100 * MDSCOUNT )) ||
25277                                 error "$count subdirs created on MDT$i"
25278                 else
25279                         (( $count == 0 )) ||
25280                                 error "$count subdirs created on MDT$i"
25281                 fi
25282
25283                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25284                         count=$($LFS getdirstripe $testdir/* |
25285                                 grep -c -P "^\s+$i\t")
25286                         echo "$count stripes created on MDT$i"
25287                         # deviation should < 5% of average
25288                         (( $count >= 95 * stripe_count &&
25289                            $count <= 105 * stripe_count)) ||
25290                                 error "stripes are not evenly distributed"
25291                 fi
25292         done
25293
25294         echo
25295         echo "Check for uneven MDTs: "
25296
25297         local ffree
25298         local bavail
25299         local max
25300         local min
25301         local max_index
25302         local min_index
25303         local tmp
25304
25305         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25306         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25307         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25308
25309         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25310         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25311         max_index=0
25312         min_index=0
25313         for ((i = 1; i < ${#ffree[@]}; i++)); do
25314                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25315                 if [ $tmp -gt $max ]; then
25316                         max=$tmp
25317                         max_index=$i
25318                 fi
25319                 if [ $tmp -lt $min ]; then
25320                         min=$tmp
25321                         min_index=$i
25322                 fi
25323         done
25324
25325         (( ${ffree[min_index]} > 0 )) ||
25326                 skip "no free files in MDT$min_index"
25327         (( ${ffree[min_index]} < 10000000 )) ||
25328                 skip "too many free files in MDT$min_index"
25329
25330         echo "MDT filesfree available: ${ffree[@]}"
25331         echo "MDT blocks available: ${bavail[@]}"
25332         echo "weight diff=$(((max - min) * 100 / min))%"
25333         echo
25334         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25335
25336         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25337         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25338         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25339         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25340         # decrease statfs age, so that it can be updated in time
25341         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25342         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25343
25344         sleep 1
25345
25346         testdir=$DIR/$tdir-s$stripe_count/qos
25347         local num=200
25348
25349         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25350         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25351                 eval $mkdir_cmd $testdir/subdir$i ||
25352                         error "$mkdir_cmd subdir$i failed"
25353         done
25354
25355         max=0
25356         for (( i = 0; i < $MDSCOUNT; i++ )); do
25357                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25358                 (( count > max )) && max=$count
25359                 echo "$count directories created on MDT$i"
25360         done
25361
25362         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25363
25364         # D-value should > 10% of averge
25365         (( max - min > num / 10 )) ||
25366                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25367
25368         # ditto for stripes
25369         if (( stripe_count > 1 )); then
25370                 max=0
25371                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25372                         count=$($LFS getdirstripe $testdir/* |
25373                                 grep -c -P "^\s+$i\t")
25374                         (( count > max )) && max=$count
25375                         echo "$count stripes created on MDT$i"
25376                 done
25377
25378                 min=$($LFS getdirstripe $testdir/* |
25379                         grep -c -P "^\s+$min_index\t")
25380                 (( max - min > num * stripe_count / 10 )) ||
25381                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25382         fi
25383 }
25384
25385 most_full_mdt() {
25386         local ffree
25387         local bavail
25388         local bsize
25389         local min
25390         local min_index
25391         local tmp
25392
25393         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25394         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25395         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25396
25397         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25398         min_index=0
25399         for ((i = 1; i < ${#ffree[@]}; i++)); do
25400                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25401                 (( tmp < min )) && min=$tmp && min_index=$i
25402         done
25403
25404         echo -n $min_index
25405 }
25406
25407 test_413a() {
25408         [ $MDSCOUNT -lt 2 ] &&
25409                 skip "We need at least 2 MDTs for this test"
25410
25411         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25412                 skip "Need server version at least 2.12.52"
25413
25414         local stripe_count
25415
25416         generate_uneven_mdts 100
25417         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25418                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25419                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25420                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25421                         error "mkdir failed"
25422                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25423         done
25424 }
25425 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25426
25427 test_413b() {
25428         [ $MDSCOUNT -lt 2 ] &&
25429                 skip "We need at least 2 MDTs for this test"
25430
25431         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25432                 skip "Need server version at least 2.12.52"
25433
25434         local testdir
25435         local stripe_count
25436
25437         generate_uneven_mdts 100
25438         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25439                 testdir=$DIR/$tdir-s$stripe_count
25440                 mkdir $testdir || error "mkdir $testdir failed"
25441                 mkdir $testdir/rr || error "mkdir rr failed"
25442                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25443                         error "mkdir qos failed"
25444                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25445                         $testdir/rr || error "setdirstripe rr failed"
25446                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25447                         error "setdirstripe failed"
25448                 test_qos_mkdir "mkdir" $stripe_count
25449         done
25450 }
25451 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25452
25453 test_413c() {
25454         (( $MDSCOUNT >= 2 )) ||
25455                 skip "We need at least 2 MDTs for this test"
25456
25457         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25458                 skip "Need server version at least 2.14.51"
25459
25460         local testdir
25461         local inherit
25462         local inherit_rr
25463
25464         testdir=$DIR/${tdir}-s1
25465         mkdir $testdir || error "mkdir $testdir failed"
25466         mkdir $testdir/rr || error "mkdir rr failed"
25467         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25468         # default max_inherit is -1, default max_inherit_rr is 0
25469         $LFS setdirstripe -D -c 1 $testdir/rr ||
25470                 error "setdirstripe rr failed"
25471         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25472                 error "setdirstripe qos failed"
25473         test_qos_mkdir "mkdir" 1
25474
25475         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25476         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25477         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25478         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25479         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25480
25481         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25482         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25483         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25484         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25485         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25486         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25487         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25488                 error "level2 shouldn't have default LMV" || true
25489 }
25490 run_test 413c "mkdir with default LMV max inherit rr"
25491
25492 test_413d() {
25493         (( MDSCOUNT >= 2 )) ||
25494                 skip "We need at least 2 MDTs for this test"
25495
25496         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25497                 skip "Need server version at least 2.14.51"
25498
25499         local lmv_qos_threshold_rr
25500
25501         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25502                 head -n1)
25503         stack_trap "$LCTL set_param \
25504                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25505
25506         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25507         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25508         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25509                 error "$tdir shouldn't have default LMV"
25510         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25511                 error "mkdir sub failed"
25512
25513         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25514
25515         (( count == 100 )) || error "$count subdirs on MDT0"
25516 }
25517 run_test 413d "inherit ROOT default LMV"
25518
25519 test_413z() {
25520         local pids=""
25521         local subdir
25522         local pid
25523
25524         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25525                 unlinkmany $subdir/f. 1000 &
25526                 pids="$pids $!"
25527         done
25528
25529         for pid in $pids; do
25530                 wait $pid
25531         done
25532 }
25533 run_test 413z "413 test cleanup"
25534
25535 test_414() {
25536 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25537         $LCTL set_param fail_loc=0x80000521
25538         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25539         rm -f $DIR/$tfile
25540 }
25541 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25542
25543 test_415() {
25544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25545         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25546                 skip "Need server version at least 2.11.52"
25547
25548         # LU-11102
25549         local total
25550         local setattr_pid
25551         local start_time
25552         local end_time
25553         local duration
25554
25555         total=500
25556         # this test may be slow on ZFS
25557         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25558
25559         # though this test is designed for striped directory, let's test normal
25560         # directory too since lock is always saved as CoS lock.
25561         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25562         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25563
25564         (
25565                 while true; do
25566                         touch $DIR/$tdir
25567                 done
25568         ) &
25569         setattr_pid=$!
25570
25571         start_time=$(date +%s)
25572         for i in $(seq $total); do
25573                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25574                         > /dev/null
25575         done
25576         end_time=$(date +%s)
25577         duration=$((end_time - start_time))
25578
25579         kill -9 $setattr_pid
25580
25581         echo "rename $total files took $duration sec"
25582         [ $duration -lt 100 ] || error "rename took $duration sec"
25583 }
25584 run_test 415 "lock revoke is not missing"
25585
25586 test_416() {
25587         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25588                 skip "Need server version at least 2.11.55"
25589
25590         # define OBD_FAIL_OSD_TXN_START    0x19a
25591         do_facet mds1 lctl set_param fail_loc=0x19a
25592
25593         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25594
25595         true
25596 }
25597 run_test 416 "transaction start failure won't cause system hung"
25598
25599 cleanup_417() {
25600         trap 0
25601         do_nodes $(comma_list $(mdts_nodes)) \
25602                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25603         do_nodes $(comma_list $(mdts_nodes)) \
25604                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25605         do_nodes $(comma_list $(mdts_nodes)) \
25606                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25607 }
25608
25609 test_417() {
25610         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25611         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25612                 skip "Need MDS version at least 2.11.56"
25613
25614         trap cleanup_417 RETURN EXIT
25615
25616         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25617         do_nodes $(comma_list $(mdts_nodes)) \
25618                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25619         $LFS migrate -m 0 $DIR/$tdir.1 &&
25620                 error "migrate dir $tdir.1 should fail"
25621
25622         do_nodes $(comma_list $(mdts_nodes)) \
25623                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25624         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25625                 error "create remote dir $tdir.2 should fail"
25626
25627         do_nodes $(comma_list $(mdts_nodes)) \
25628                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25629         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25630                 error "create striped dir $tdir.3 should fail"
25631         true
25632 }
25633 run_test 417 "disable remote dir, striped dir and dir migration"
25634
25635 # Checks that the outputs of df [-i] and lfs df [-i] match
25636 #
25637 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25638 check_lfs_df() {
25639         local dir=$2
25640         local inodes
25641         local df_out
25642         local lfs_df_out
25643         local count
25644         local passed=false
25645
25646         # blocks or inodes
25647         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25648
25649         for count in {1..100}; do
25650                 do_nodes "$CLIENTS" \
25651                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25652                 sync; sleep 0.2
25653
25654                 # read the lines of interest
25655                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25656                         error "df $inodes $dir | tail -n +2 failed"
25657                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25658                         error "lfs df $inodes $dir | grep summary: failed"
25659
25660                 # skip first substrings of each output as they are different
25661                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25662                 # compare the two outputs
25663                 passed=true
25664                 #  skip "available" on MDT until LU-13997 is fixed.
25665                 #for i in {1..5}; do
25666                 for i in 1 2 4 5; do
25667                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25668                 done
25669                 $passed && break
25670         done
25671
25672         if ! $passed; then
25673                 df -P $inodes $dir
25674                 echo
25675                 lfs df $inodes $dir
25676                 error "df and lfs df $1 output mismatch: "      \
25677                       "df ${inodes}: ${df_out[*]}, "            \
25678                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25679         fi
25680 }
25681
25682 test_418() {
25683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25684
25685         local dir=$DIR/$tdir
25686         local numfiles=$((RANDOM % 4096 + 2))
25687         local numblocks=$((RANDOM % 256 + 1))
25688
25689         wait_delete_completed
25690         test_mkdir $dir
25691
25692         # check block output
25693         check_lfs_df blocks $dir
25694         # check inode output
25695         check_lfs_df inodes $dir
25696
25697         # create a single file and retest
25698         echo "Creating a single file and testing"
25699         createmany -o $dir/$tfile- 1 &>/dev/null ||
25700                 error "creating 1 file in $dir failed"
25701         check_lfs_df blocks $dir
25702         check_lfs_df inodes $dir
25703
25704         # create a random number of files
25705         echo "Creating $((numfiles - 1)) files and testing"
25706         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25707                 error "creating $((numfiles - 1)) files in $dir failed"
25708
25709         # write a random number of blocks to the first test file
25710         echo "Writing $numblocks 4K blocks and testing"
25711         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25712                 count=$numblocks &>/dev/null ||
25713                 error "dd to $dir/${tfile}-0 failed"
25714
25715         # retest
25716         check_lfs_df blocks $dir
25717         check_lfs_df inodes $dir
25718
25719         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25720                 error "unlinking $numfiles files in $dir failed"
25721 }
25722 run_test 418 "df and lfs df outputs match"
25723
25724 test_419()
25725 {
25726         local dir=$DIR/$tdir
25727
25728         mkdir -p $dir
25729         touch $dir/file
25730
25731         cancel_lru_locks mdc
25732
25733         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25734         $LCTL set_param fail_loc=0x1410
25735         cat $dir/file
25736         $LCTL set_param fail_loc=0
25737         rm -rf $dir
25738 }
25739 run_test 419 "Verify open file by name doesn't crash kernel"
25740
25741 test_420()
25742 {
25743         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25744                 skip "Need MDS version at least 2.12.53"
25745
25746         local SAVE_UMASK=$(umask)
25747         local dir=$DIR/$tdir
25748         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25749
25750         mkdir -p $dir
25751         umask 0000
25752         mkdir -m03777 $dir/testdir
25753         ls -dn $dir/testdir
25754         # Need to remove trailing '.' when SELinux is enabled
25755         local dirperms=$(ls -dn $dir/testdir |
25756                          awk '{ sub(/\.$/, "", $1); print $1}')
25757         [ $dirperms == "drwxrwsrwt" ] ||
25758                 error "incorrect perms on $dir/testdir"
25759
25760         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25761                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25762         ls -n $dir/testdir/testfile
25763         local fileperms=$(ls -n $dir/testdir/testfile |
25764                           awk '{ sub(/\.$/, "", $1); print $1}')
25765         [ $fileperms == "-rwxr-xr-x" ] ||
25766                 error "incorrect perms on $dir/testdir/testfile"
25767
25768         umask $SAVE_UMASK
25769 }
25770 run_test 420 "clear SGID bit on non-directories for non-members"
25771
25772 test_421a() {
25773         local cnt
25774         local fid1
25775         local fid2
25776
25777         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25778                 skip "Need MDS version at least 2.12.54"
25779
25780         test_mkdir $DIR/$tdir
25781         createmany -o $DIR/$tdir/f 3
25782         cnt=$(ls -1 $DIR/$tdir | wc -l)
25783         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25784
25785         fid1=$(lfs path2fid $DIR/$tdir/f1)
25786         fid2=$(lfs path2fid $DIR/$tdir/f2)
25787         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25788
25789         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25790         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25791
25792         cnt=$(ls -1 $DIR/$tdir | wc -l)
25793         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25794
25795         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25796         createmany -o $DIR/$tdir/f 3
25797         cnt=$(ls -1 $DIR/$tdir | wc -l)
25798         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25799
25800         fid1=$(lfs path2fid $DIR/$tdir/f1)
25801         fid2=$(lfs path2fid $DIR/$tdir/f2)
25802         echo "remove using fsname $FSNAME"
25803         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25804
25805         cnt=$(ls -1 $DIR/$tdir | wc -l)
25806         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25807 }
25808 run_test 421a "simple rm by fid"
25809
25810 test_421b() {
25811         local cnt
25812         local FID1
25813         local FID2
25814
25815         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25816                 skip "Need MDS version at least 2.12.54"
25817
25818         test_mkdir $DIR/$tdir
25819         createmany -o $DIR/$tdir/f 3
25820         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25821         MULTIPID=$!
25822
25823         FID1=$(lfs path2fid $DIR/$tdir/f1)
25824         FID2=$(lfs path2fid $DIR/$tdir/f2)
25825         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25826
25827         kill -USR1 $MULTIPID
25828         wait
25829
25830         cnt=$(ls $DIR/$tdir | wc -l)
25831         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25832 }
25833 run_test 421b "rm by fid on open file"
25834
25835 test_421c() {
25836         local cnt
25837         local FIDS
25838
25839         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25840                 skip "Need MDS version at least 2.12.54"
25841
25842         test_mkdir $DIR/$tdir
25843         createmany -o $DIR/$tdir/f 3
25844         touch $DIR/$tdir/$tfile
25845         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25846         cnt=$(ls -1 $DIR/$tdir | wc -l)
25847         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25848
25849         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25850         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25851
25852         cnt=$(ls $DIR/$tdir | wc -l)
25853         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25854 }
25855 run_test 421c "rm by fid against hardlinked files"
25856
25857 test_421d() {
25858         local cnt
25859         local FIDS
25860
25861         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25862                 skip "Need MDS version at least 2.12.54"
25863
25864         test_mkdir $DIR/$tdir
25865         createmany -o $DIR/$tdir/f 4097
25866         cnt=$(ls -1 $DIR/$tdir | wc -l)
25867         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25868
25869         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25870         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25871
25872         cnt=$(ls $DIR/$tdir | wc -l)
25873         rm -rf $DIR/$tdir
25874         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25875 }
25876 run_test 421d "rmfid en masse"
25877
25878 test_421e() {
25879         local cnt
25880         local FID
25881
25882         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25883         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25884                 skip "Need MDS version at least 2.12.54"
25885
25886         mkdir -p $DIR/$tdir
25887         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25888         createmany -o $DIR/$tdir/striped_dir/f 512
25889         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25890         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25891
25892         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25893                 sed "s/[/][^:]*://g")
25894         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25895
25896         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25897         rm -rf $DIR/$tdir
25898         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25899 }
25900 run_test 421e "rmfid in DNE"
25901
25902 test_421f() {
25903         local cnt
25904         local FID
25905
25906         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25907                 skip "Need MDS version at least 2.12.54"
25908
25909         test_mkdir $DIR/$tdir
25910         touch $DIR/$tdir/f
25911         cnt=$(ls -1 $DIR/$tdir | wc -l)
25912         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25913
25914         FID=$(lfs path2fid $DIR/$tdir/f)
25915         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25916         # rmfid should fail
25917         cnt=$(ls -1 $DIR/$tdir | wc -l)
25918         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25919
25920         chmod a+rw $DIR/$tdir
25921         ls -la $DIR/$tdir
25922         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25923         # rmfid should fail
25924         cnt=$(ls -1 $DIR/$tdir | wc -l)
25925         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25926
25927         rm -f $DIR/$tdir/f
25928         $RUNAS touch $DIR/$tdir/f
25929         FID=$(lfs path2fid $DIR/$tdir/f)
25930         echo "rmfid as root"
25931         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25932         cnt=$(ls -1 $DIR/$tdir | wc -l)
25933         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25934
25935         rm -f $DIR/$tdir/f
25936         $RUNAS touch $DIR/$tdir/f
25937         cnt=$(ls -1 $DIR/$tdir | wc -l)
25938         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25939         FID=$(lfs path2fid $DIR/$tdir/f)
25940         # rmfid w/o user_fid2path mount option should fail
25941         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25942         cnt=$(ls -1 $DIR/$tdir | wc -l)
25943         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25944
25945         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25946         stack_trap "rmdir $tmpdir"
25947         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25948                 error "failed to mount client'"
25949         stack_trap "umount_client $tmpdir"
25950
25951         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25952         # rmfid should succeed
25953         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25954         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25955
25956         # rmfid shouldn't allow to remove files due to dir's permission
25957         chmod a+rwx $tmpdir/$tdir
25958         touch $tmpdir/$tdir/f
25959         ls -la $tmpdir/$tdir
25960         FID=$(lfs path2fid $tmpdir/$tdir/f)
25961         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25962         return 0
25963 }
25964 run_test 421f "rmfid checks permissions"
25965
25966 test_421g() {
25967         local cnt
25968         local FIDS
25969
25970         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25971         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25972                 skip "Need MDS version at least 2.12.54"
25973
25974         mkdir -p $DIR/$tdir
25975         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25976         createmany -o $DIR/$tdir/striped_dir/f 512
25977         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25978         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25979
25980         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25981                 sed "s/[/][^:]*://g")
25982
25983         rm -f $DIR/$tdir/striped_dir/f1*
25984         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25985         removed=$((512 - cnt))
25986
25987         # few files have been just removed, so we expect
25988         # rmfid to fail on their fids
25989         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25990         [ $removed != $errors ] && error "$errors != $removed"
25991
25992         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25993         rm -rf $DIR/$tdir
25994         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25995 }
25996 run_test 421g "rmfid to return errors properly"
25997
25998 test_422() {
25999         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26000         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26001         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26002         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26003         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26004
26005         local amc=$(at_max_get client)
26006         local amo=$(at_max_get mds1)
26007         local timeout=`lctl get_param -n timeout`
26008
26009         at_max_set 0 client
26010         at_max_set 0 mds1
26011
26012 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26013         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26014                         fail_val=$(((2*timeout + 10)*1000))
26015         touch $DIR/$tdir/d3/file &
26016         sleep 2
26017 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26018         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26019                         fail_val=$((2*timeout + 5))
26020         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26021         local pid=$!
26022         sleep 1
26023         kill -9 $pid
26024         sleep $((2 * timeout))
26025         echo kill $pid
26026         kill -9 $pid
26027         lctl mark touch
26028         touch $DIR/$tdir/d2/file3
26029         touch $DIR/$tdir/d2/file4
26030         touch $DIR/$tdir/d2/file5
26031
26032         wait
26033         at_max_set $amc client
26034         at_max_set $amo mds1
26035
26036         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26037         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26038                 error "Watchdog is always throttled"
26039 }
26040 run_test 422 "kill a process with RPC in progress"
26041
26042 stat_test() {
26043     df -h $MOUNT &
26044     df -h $MOUNT &
26045     df -h $MOUNT &
26046     df -h $MOUNT &
26047     df -h $MOUNT &
26048     df -h $MOUNT &
26049 }
26050
26051 test_423() {
26052     local _stats
26053     # ensure statfs cache is expired
26054     sleep 2;
26055
26056     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26057     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26058
26059     return 0
26060 }
26061 run_test 423 "statfs should return a right data"
26062
26063 test_424() {
26064 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26065         $LCTL set_param fail_loc=0x80000522
26066         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26067         rm -f $DIR/$tfile
26068 }
26069 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26070
26071 test_425() {
26072         test_mkdir -c -1 $DIR/$tdir
26073         $LFS setstripe -c -1 $DIR/$tdir
26074
26075         lru_resize_disable "" 100
26076         stack_trap "lru_resize_enable" EXIT
26077
26078         sleep 5
26079
26080         for i in $(seq $((MDSCOUNT * 125))); do
26081                 local t=$DIR/$tdir/$tfile_$i
26082
26083                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26084                         error_noexit "Create file $t"
26085         done
26086         stack_trap "rm -rf $DIR/$tdir" EXIT
26087
26088         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26089                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26090                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26091
26092                 [ $lock_count -le $lru_size ] ||
26093                         error "osc lock count $lock_count > lru size $lru_size"
26094         done
26095
26096         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26097                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26098                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26099
26100                 [ $lock_count -le $lru_size ] ||
26101                         error "mdc lock count $lock_count > lru size $lru_size"
26102         done
26103 }
26104 run_test 425 "lock count should not exceed lru size"
26105
26106 test_426() {
26107         splice-test -r $DIR/$tfile
26108         splice-test -rd $DIR/$tfile
26109         splice-test $DIR/$tfile
26110         splice-test -d $DIR/$tfile
26111 }
26112 run_test 426 "splice test on Lustre"
26113
26114 test_427() {
26115         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26116         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26117                 skip "Need MDS version at least 2.12.4"
26118         local log
26119
26120         mkdir $DIR/$tdir
26121         mkdir $DIR/$tdir/1
26122         mkdir $DIR/$tdir/2
26123         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26124         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26125
26126         $LFS getdirstripe $DIR/$tdir/1/dir
26127
26128         #first setfattr for creating updatelog
26129         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26130
26131 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26132         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26133         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26134         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26135
26136         sleep 2
26137         fail mds2
26138         wait_recovery_complete mds2 $((2*TIMEOUT))
26139
26140         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26141         echo $log | grep "get update log failed" &&
26142                 error "update log corruption is detected" || true
26143 }
26144 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26145
26146 test_428() {
26147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26148         local cache_limit=$CACHE_MAX
26149
26150         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26151         $LCTL set_param -n llite.*.max_cached_mb=64
26152
26153         mkdir $DIR/$tdir
26154         $LFS setstripe -c 1 $DIR/$tdir
26155         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26156         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26157         #test write
26158         for f in $(seq 4); do
26159                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26160         done
26161         wait
26162
26163         cancel_lru_locks osc
26164         # Test read
26165         for f in $(seq 4); do
26166                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26167         done
26168         wait
26169 }
26170 run_test 428 "large block size IO should not hang"
26171
26172 test_429() { # LU-7915 / LU-10948
26173         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26174         local testfile=$DIR/$tfile
26175         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26176         local new_flag=1
26177         local first_rpc
26178         local second_rpc
26179         local third_rpc
26180
26181         $LCTL get_param $ll_opencache_threshold_count ||
26182                 skip "client does not have opencache parameter"
26183
26184         set_opencache $new_flag
26185         stack_trap "restore_opencache"
26186         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26187                 error "enable opencache failed"
26188         touch $testfile
26189         # drop MDC DLM locks
26190         cancel_lru_locks mdc
26191         # clear MDC RPC stats counters
26192         $LCTL set_param $mdc_rpcstats=clear
26193
26194         # According to the current implementation, we need to run 3 times
26195         # open & close file to verify if opencache is enabled correctly.
26196         # 1st, RPCs are sent for lookup/open and open handle is released on
26197         #      close finally.
26198         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26199         #      so open handle won't be released thereafter.
26200         # 3rd, No RPC is sent out.
26201         $MULTIOP $testfile oc || error "multiop failed"
26202         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26203         echo "1st: $first_rpc RPCs in flight"
26204
26205         $MULTIOP $testfile oc || error "multiop failed"
26206         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26207         echo "2nd: $second_rpc RPCs in flight"
26208
26209         $MULTIOP $testfile oc || error "multiop failed"
26210         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26211         echo "3rd: $third_rpc RPCs in flight"
26212
26213         #verify no MDC RPC is sent
26214         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26215 }
26216 run_test 429 "verify if opencache flag on client side does work"
26217
26218 lseek_test_430() {
26219         local offset
26220         local file=$1
26221
26222         # data at [200K, 400K)
26223         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26224                 error "256K->512K dd fails"
26225         # data at [2M, 3M)
26226         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26227                 error "2M->3M dd fails"
26228         # data at [4M, 5M)
26229         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26230                 error "4M->5M dd fails"
26231         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26232         # start at first component hole #1
26233         printf "Seeking hole from 1000 ... "
26234         offset=$(lseek_test -l 1000 $file)
26235         echo $offset
26236         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26237         printf "Seeking data from 1000 ... "
26238         offset=$(lseek_test -d 1000 $file)
26239         echo $offset
26240         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26241
26242         # start at first component data block
26243         printf "Seeking hole from 300000 ... "
26244         offset=$(lseek_test -l 300000 $file)
26245         echo $offset
26246         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26247         printf "Seeking data from 300000 ... "
26248         offset=$(lseek_test -d 300000 $file)
26249         echo $offset
26250         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26251
26252         # start at the first component but beyond end of object size
26253         printf "Seeking hole from 1000000 ... "
26254         offset=$(lseek_test -l 1000000 $file)
26255         echo $offset
26256         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26257         printf "Seeking data from 1000000 ... "
26258         offset=$(lseek_test -d 1000000 $file)
26259         echo $offset
26260         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26261
26262         # start at second component stripe 2 (empty file)
26263         printf "Seeking hole from 1500000 ... "
26264         offset=$(lseek_test -l 1500000 $file)
26265         echo $offset
26266         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26267         printf "Seeking data from 1500000 ... "
26268         offset=$(lseek_test -d 1500000 $file)
26269         echo $offset
26270         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26271
26272         # start at second component stripe 1 (all data)
26273         printf "Seeking hole from 3000000 ... "
26274         offset=$(lseek_test -l 3000000 $file)
26275         echo $offset
26276         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26277         printf "Seeking data from 3000000 ... "
26278         offset=$(lseek_test -d 3000000 $file)
26279         echo $offset
26280         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26281
26282         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26283                 error "2nd dd fails"
26284         echo "Add data block at 640K...1280K"
26285
26286         # start at before new data block, in hole
26287         printf "Seeking hole from 600000 ... "
26288         offset=$(lseek_test -l 600000 $file)
26289         echo $offset
26290         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26291         printf "Seeking data from 600000 ... "
26292         offset=$(lseek_test -d 600000 $file)
26293         echo $offset
26294         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26295
26296         # start at the first component new data block
26297         printf "Seeking hole from 1000000 ... "
26298         offset=$(lseek_test -l 1000000 $file)
26299         echo $offset
26300         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26301         printf "Seeking data from 1000000 ... "
26302         offset=$(lseek_test -d 1000000 $file)
26303         echo $offset
26304         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26305
26306         # start at second component stripe 2, new data
26307         printf "Seeking hole from 1200000 ... "
26308         offset=$(lseek_test -l 1200000 $file)
26309         echo $offset
26310         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26311         printf "Seeking data from 1200000 ... "
26312         offset=$(lseek_test -d 1200000 $file)
26313         echo $offset
26314         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26315
26316         # start beyond file end
26317         printf "Using offset > filesize ... "
26318         lseek_test -l 4000000 $file && error "lseek should fail"
26319         printf "Using offset > filesize ... "
26320         lseek_test -d 4000000 $file && error "lseek should fail"
26321
26322         printf "Done\n\n"
26323 }
26324
26325 test_430a() {
26326         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26327                 skip "MDT does not support SEEK_HOLE"
26328
26329         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26330                 skip "OST does not support SEEK_HOLE"
26331
26332         local file=$DIR/$tdir/$tfile
26333
26334         mkdir -p $DIR/$tdir
26335
26336         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26337         # OST stripe #1 will have continuous data at [1M, 3M)
26338         # OST stripe #2 is empty
26339         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26340         lseek_test_430 $file
26341         rm $file
26342         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26343         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26344         lseek_test_430 $file
26345         rm $file
26346         $LFS setstripe -c2 -S 512K $file
26347         echo "Two stripes, stripe size 512K"
26348         lseek_test_430 $file
26349         rm $file
26350         # FLR with stale mirror
26351         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26352                        -N -c2 -S 1M $file
26353         echo "Mirrored file:"
26354         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26355         echo "Plain 2 stripes 1M"
26356         lseek_test_430 $file
26357         rm $file
26358 }
26359 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26360
26361 test_430b() {
26362         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26363                 skip "OST does not support SEEK_HOLE"
26364
26365         local offset
26366         local file=$DIR/$tdir/$tfile
26367
26368         mkdir -p $DIR/$tdir
26369         # Empty layout lseek should fail
26370         $MCREATE $file
26371         # seek from 0
26372         printf "Seeking hole from 0 ... "
26373         lseek_test -l 0 $file && error "lseek should fail"
26374         printf "Seeking data from 0 ... "
26375         lseek_test -d 0 $file && error "lseek should fail"
26376         rm $file
26377
26378         # 1M-hole file
26379         $LFS setstripe -E 1M -c2 -E eof $file
26380         $TRUNCATE $file 1048576
26381         printf "Seeking hole from 1000000 ... "
26382         offset=$(lseek_test -l 1000000 $file)
26383         echo $offset
26384         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26385         printf "Seeking data from 1000000 ... "
26386         lseek_test -d 1000000 $file && error "lseek should fail"
26387         rm $file
26388
26389         # full component followed by non-inited one
26390         $LFS setstripe -E 1M -c2 -E eof $file
26391         dd if=/dev/urandom of=$file bs=1M count=1
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         # init second component and truncate back
26399         echo "123" >> $file
26400         $TRUNCATE $file 1048576
26401         printf "Seeking hole from 1000000 ... "
26402         offset=$(lseek_test -l 1000000 $file)
26403         echo $offset
26404         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26405         printf "Seeking hole from 1048576 ... "
26406         lseek_test -l 1048576 $file && error "lseek should fail"
26407         # boundary checks for big values
26408         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26409         offset=$(lseek_test -d 0 $file.10g)
26410         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26411         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26412         offset=$(lseek_test -d 0 $file.100g)
26413         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26414         return 0
26415 }
26416 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26417
26418 test_430c() {
26419         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26420                 skip "OST does not support SEEK_HOLE"
26421
26422         local file=$DIR/$tdir/$tfile
26423         local start
26424
26425         mkdir -p $DIR/$tdir
26426         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26427
26428         # cp version 8.33+ prefers lseek over fiemap
26429         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26430                 start=$SECONDS
26431                 time cp $file /dev/null
26432                 (( SECONDS - start < 5 )) ||
26433                         error "cp: too long runtime $((SECONDS - start))"
26434
26435         fi
26436         # tar version 1.29+ supports SEEK_HOLE/DATA
26437         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26438                 start=$SECONDS
26439                 time tar cS $file - | cat > /dev/null
26440                 (( SECONDS - start < 5 )) ||
26441                         error "tar: too long runtime $((SECONDS - start))"
26442         fi
26443 }
26444 run_test 430c "lseek: external tools check"
26445
26446 test_431() { # LU-14187
26447         local file=$DIR/$tdir/$tfile
26448
26449         mkdir -p $DIR/$tdir
26450         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26451         dd if=/dev/urandom of=$file bs=4k count=1
26452         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26453         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26454         #define OBD_FAIL_OST_RESTART_IO 0x251
26455         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26456         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26457         cp $file $file.0
26458         cancel_lru_locks
26459         sync_all_data
26460         echo 3 > /proc/sys/vm/drop_caches
26461         diff  $file $file.0 || error "data diff"
26462 }
26463 run_test 431 "Restart transaction for IO"
26464
26465 cleanup_test_432() {
26466         do_facet mgs $LCTL nodemap_activate 0
26467         wait_nm_sync active
26468 }
26469
26470 test_432() {
26471         local tmpdir=$TMP/dir432
26472
26473         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26474                 skip "Need MDS version at least 2.14.52"
26475
26476         stack_trap cleanup_test_432 EXIT
26477         mkdir $DIR/$tdir
26478         mkdir $tmpdir
26479
26480         do_facet mgs $LCTL nodemap_activate 1
26481         wait_nm_sync active
26482         do_facet mgs $LCTL nodemap_modify --name default \
26483                 --property admin --value 1
26484         do_facet mgs $LCTL nodemap_modify --name default \
26485                 --property trusted --value 1
26486         cancel_lru_locks mdc
26487         wait_nm_sync default admin_nodemap
26488         wait_nm_sync default trusted_nodemap
26489
26490         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26491                grep -ci "Operation not permitted") -ne 0 ]; then
26492                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26493         fi
26494 }
26495 run_test 432 "mv dir from outside Lustre"
26496
26497 prep_801() {
26498         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26499         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26500                 skip "Need server version at least 2.9.55"
26501
26502         start_full_debug_logging
26503 }
26504
26505 post_801() {
26506         stop_full_debug_logging
26507 }
26508
26509 barrier_stat() {
26510         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26511                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26512                            awk '/The barrier for/ { print $7 }')
26513                 echo $st
26514         else
26515                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26516                 echo \'$st\'
26517         fi
26518 }
26519
26520 barrier_expired() {
26521         local expired
26522
26523         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26524                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26525                           awk '/will be expired/ { print $7 }')
26526         else
26527                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26528         fi
26529
26530         echo $expired
26531 }
26532
26533 test_801a() {
26534         prep_801
26535
26536         echo "Start barrier_freeze at: $(date)"
26537         #define OBD_FAIL_BARRIER_DELAY          0x2202
26538         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26539         # Do not reduce barrier time - See LU-11873
26540         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26541
26542         sleep 2
26543         local b_status=$(barrier_stat)
26544         echo "Got barrier status at: $(date)"
26545         [ "$b_status" = "'freezing_p1'" ] ||
26546                 error "(1) unexpected barrier status $b_status"
26547
26548         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26549         wait
26550         b_status=$(barrier_stat)
26551         [ "$b_status" = "'frozen'" ] ||
26552                 error "(2) unexpected barrier status $b_status"
26553
26554         local expired=$(barrier_expired)
26555         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26556         sleep $((expired + 3))
26557
26558         b_status=$(barrier_stat)
26559         [ "$b_status" = "'expired'" ] ||
26560                 error "(3) unexpected barrier status $b_status"
26561
26562         # Do not reduce barrier time - See LU-11873
26563         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26564                 error "(4) fail to freeze barrier"
26565
26566         b_status=$(barrier_stat)
26567         [ "$b_status" = "'frozen'" ] ||
26568                 error "(5) unexpected barrier status $b_status"
26569
26570         echo "Start barrier_thaw at: $(date)"
26571         #define OBD_FAIL_BARRIER_DELAY          0x2202
26572         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26573         do_facet mgs $LCTL barrier_thaw $FSNAME &
26574
26575         sleep 2
26576         b_status=$(barrier_stat)
26577         echo "Got barrier status at: $(date)"
26578         [ "$b_status" = "'thawing'" ] ||
26579                 error "(6) unexpected barrier status $b_status"
26580
26581         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26582         wait
26583         b_status=$(barrier_stat)
26584         [ "$b_status" = "'thawed'" ] ||
26585                 error "(7) unexpected barrier status $b_status"
26586
26587         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26588         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26589         do_facet mgs $LCTL barrier_freeze $FSNAME
26590
26591         b_status=$(barrier_stat)
26592         [ "$b_status" = "'failed'" ] ||
26593                 error "(8) unexpected barrier status $b_status"
26594
26595         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26596         do_facet mgs $LCTL barrier_thaw $FSNAME
26597
26598         post_801
26599 }
26600 run_test 801a "write barrier user interfaces and stat machine"
26601
26602 test_801b() {
26603         prep_801
26604
26605         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26606         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26607         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26608         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26609         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26610
26611         cancel_lru_locks mdc
26612
26613         # 180 seconds should be long enough
26614         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26615
26616         local b_status=$(barrier_stat)
26617         [ "$b_status" = "'frozen'" ] ||
26618                 error "(6) unexpected barrier status $b_status"
26619
26620         mkdir $DIR/$tdir/d0/d10 &
26621         mkdir_pid=$!
26622
26623         touch $DIR/$tdir/d1/f13 &
26624         touch_pid=$!
26625
26626         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26627         ln_pid=$!
26628
26629         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26630         mv_pid=$!
26631
26632         rm -f $DIR/$tdir/d4/f12 &
26633         rm_pid=$!
26634
26635         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26636
26637         # To guarantee taht the 'stat' is not blocked
26638         b_status=$(barrier_stat)
26639         [ "$b_status" = "'frozen'" ] ||
26640                 error "(8) unexpected barrier status $b_status"
26641
26642         # let above commands to run at background
26643         sleep 5
26644
26645         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26646         ps -p $touch_pid || error "(10) touch should be blocked"
26647         ps -p $ln_pid || error "(11) link should be blocked"
26648         ps -p $mv_pid || error "(12) rename should be blocked"
26649         ps -p $rm_pid || error "(13) unlink should be blocked"
26650
26651         b_status=$(barrier_stat)
26652         [ "$b_status" = "'frozen'" ] ||
26653                 error "(14) unexpected barrier status $b_status"
26654
26655         do_facet mgs $LCTL barrier_thaw $FSNAME
26656         b_status=$(barrier_stat)
26657         [ "$b_status" = "'thawed'" ] ||
26658                 error "(15) unexpected barrier status $b_status"
26659
26660         wait $mkdir_pid || error "(16) mkdir should succeed"
26661         wait $touch_pid || error "(17) touch should succeed"
26662         wait $ln_pid || error "(18) link should succeed"
26663         wait $mv_pid || error "(19) rename should succeed"
26664         wait $rm_pid || error "(20) unlink should succeed"
26665
26666         post_801
26667 }
26668 run_test 801b "modification will be blocked by write barrier"
26669
26670 test_801c() {
26671         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26672
26673         prep_801
26674
26675         stop mds2 || error "(1) Fail to stop mds2"
26676
26677         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26678
26679         local b_status=$(barrier_stat)
26680         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26681                 do_facet mgs $LCTL barrier_thaw $FSNAME
26682                 error "(2) unexpected barrier status $b_status"
26683         }
26684
26685         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26686                 error "(3) Fail to rescan barrier bitmap"
26687
26688         # Do not reduce barrier time - See LU-11873
26689         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26690
26691         b_status=$(barrier_stat)
26692         [ "$b_status" = "'frozen'" ] ||
26693                 error "(4) unexpected barrier status $b_status"
26694
26695         do_facet mgs $LCTL barrier_thaw $FSNAME
26696         b_status=$(barrier_stat)
26697         [ "$b_status" = "'thawed'" ] ||
26698                 error "(5) unexpected barrier status $b_status"
26699
26700         local devname=$(mdsdevname 2)
26701
26702         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26703
26704         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26705                 error "(7) Fail to rescan barrier bitmap"
26706
26707         post_801
26708 }
26709 run_test 801c "rescan barrier bitmap"
26710
26711 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26712 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26713 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26714 saved_MOUNT_OPTS=$MOUNT_OPTS
26715
26716 cleanup_802a() {
26717         trap 0
26718
26719         stopall
26720         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26721         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26722         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26723         MOUNT_OPTS=$saved_MOUNT_OPTS
26724         setupall
26725 }
26726
26727 test_802a() {
26728         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26729         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26730         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26731                 skip "Need server version at least 2.9.55"
26732
26733         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26734
26735         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26736
26737         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26738                 error "(2) Fail to copy"
26739
26740         trap cleanup_802a EXIT
26741
26742         # sync by force before remount as readonly
26743         sync; sync_all_data; sleep 3; sync_all_data
26744
26745         stopall
26746
26747         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26748         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26749         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26750
26751         echo "Mount the server as read only"
26752         setupall server_only || error "(3) Fail to start servers"
26753
26754         echo "Mount client without ro should fail"
26755         mount_client $MOUNT &&
26756                 error "(4) Mount client without 'ro' should fail"
26757
26758         echo "Mount client with ro should succeed"
26759         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26760         mount_client $MOUNT ||
26761                 error "(5) Mount client with 'ro' should succeed"
26762
26763         echo "Modify should be refused"
26764         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26765
26766         echo "Read should be allowed"
26767         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26768                 error "(7) Read should succeed under ro mode"
26769
26770         cleanup_802a
26771 }
26772 run_test 802a "simulate readonly device"
26773
26774 test_802b() {
26775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26776         remote_mds_nodsh && skip "remote MDS with nodsh"
26777
26778         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26779                 skip "readonly option not available"
26780
26781         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26782
26783         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26784                 error "(2) Fail to copy"
26785
26786         # write back all cached data before setting MDT to readonly
26787         cancel_lru_locks
26788         sync_all_data
26789
26790         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26791         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26792
26793         echo "Modify should be refused"
26794         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26795
26796         echo "Read should be allowed"
26797         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26798                 error "(7) Read should succeed under ro mode"
26799
26800         # disable readonly
26801         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26802 }
26803 run_test 802b "be able to set MDTs to readonly"
26804
26805 test_803a() {
26806         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26807         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26808                 skip "MDS needs to be newer than 2.10.54"
26809
26810         mkdir_on_mdt0 $DIR/$tdir
26811         # Create some objects on all MDTs to trigger related logs objects
26812         for idx in $(seq $MDSCOUNT); do
26813                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26814                         $DIR/$tdir/dir${idx} ||
26815                         error "Fail to create $DIR/$tdir/dir${idx}"
26816         done
26817
26818         sync; sleep 3
26819         wait_delete_completed # ensure old test cleanups are finished
26820         echo "before create:"
26821         $LFS df -i $MOUNT
26822         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26823
26824         for i in {1..10}; do
26825                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26826                         error "Fail to create $DIR/$tdir/foo$i"
26827         done
26828
26829         sync; sleep 3
26830         echo "after create:"
26831         $LFS df -i $MOUNT
26832         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26833
26834         # allow for an llog to be cleaned up during the test
26835         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26836                 error "before ($before_used) + 10 > after ($after_used)"
26837
26838         for i in {1..10}; do
26839                 rm -rf $DIR/$tdir/foo$i ||
26840                         error "Fail to remove $DIR/$tdir/foo$i"
26841         done
26842
26843         sleep 3 # avoid MDT return cached statfs
26844         wait_delete_completed
26845         echo "after unlink:"
26846         $LFS df -i $MOUNT
26847         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26848
26849         # allow for an llog to be created during the test
26850         [ $after_used -le $((before_used + 1)) ] ||
26851                 error "after ($after_used) > before ($before_used) + 1"
26852 }
26853 run_test 803a "verify agent object for remote object"
26854
26855 test_803b() {
26856         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26857         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26858                 skip "MDS needs to be newer than 2.13.56"
26859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26860
26861         for i in $(seq 0 $((MDSCOUNT - 1))); do
26862                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26863         done
26864
26865         local before=0
26866         local after=0
26867
26868         local tmp
26869
26870         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26871         for i in $(seq 0 $((MDSCOUNT - 1))); do
26872                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26873                         awk '/getattr/ { print $2 }')
26874                 before=$((before + tmp))
26875         done
26876         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26877         for i in $(seq 0 $((MDSCOUNT - 1))); do
26878                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26879                         awk '/getattr/ { print $2 }')
26880                 after=$((after + tmp))
26881         done
26882
26883         [ $before -eq $after ] || error "getattr count $before != $after"
26884 }
26885 run_test 803b "remote object can getattr from cache"
26886
26887 test_804() {
26888         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26889         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26890                 skip "MDS needs to be newer than 2.10.54"
26891         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26892
26893         mkdir -p $DIR/$tdir
26894         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26895                 error "Fail to create $DIR/$tdir/dir0"
26896
26897         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26898         local dev=$(mdsdevname 2)
26899
26900         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26901                 grep ${fid} || error "NOT found agent entry for dir0"
26902
26903         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26904                 error "Fail to create $DIR/$tdir/dir1"
26905
26906         touch $DIR/$tdir/dir1/foo0 ||
26907                 error "Fail to create $DIR/$tdir/dir1/foo0"
26908         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26909         local rc=0
26910
26911         for idx in $(seq $MDSCOUNT); do
26912                 dev=$(mdsdevname $idx)
26913                 do_facet mds${idx} \
26914                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26915                         grep ${fid} && rc=$idx
26916         done
26917
26918         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26919                 error "Fail to rename foo0 to foo1"
26920         if [ $rc -eq 0 ]; then
26921                 for idx in $(seq $MDSCOUNT); do
26922                         dev=$(mdsdevname $idx)
26923                         do_facet mds${idx} \
26924                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26925                         grep ${fid} && rc=$idx
26926                 done
26927         fi
26928
26929         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26930                 error "Fail to rename foo1 to foo2"
26931         if [ $rc -eq 0 ]; then
26932                 for idx in $(seq $MDSCOUNT); do
26933                         dev=$(mdsdevname $idx)
26934                         do_facet mds${idx} \
26935                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26936                         grep ${fid} && rc=$idx
26937                 done
26938         fi
26939
26940         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26941
26942         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26943                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26944         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26945                 error "Fail to rename foo2 to foo0"
26946         unlink $DIR/$tdir/dir1/foo0 ||
26947                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26948         rm -rf $DIR/$tdir/dir0 ||
26949                 error "Fail to rm $DIR/$tdir/dir0"
26950
26951         for idx in $(seq $MDSCOUNT); do
26952                 dev=$(mdsdevname $idx)
26953                 rc=0
26954
26955                 stop mds${idx}
26956                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26957                         rc=$?
26958                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26959                         error "mount mds$idx failed"
26960                 df $MOUNT > /dev/null 2>&1
26961
26962                 # e2fsck should not return error
26963                 [ $rc -eq 0 ] ||
26964                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26965         done
26966 }
26967 run_test 804 "verify agent entry for remote entry"
26968
26969 cleanup_805() {
26970         do_facet $SINGLEMDS zfs set quota=$old $fsset
26971         unlinkmany $DIR/$tdir/f- 1000000
26972         trap 0
26973 }
26974
26975 test_805() {
26976         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26977         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26978         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26979                 skip "netfree not implemented before 0.7"
26980         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26981                 skip "Need MDS version at least 2.10.57"
26982
26983         local fsset
26984         local freekb
26985         local usedkb
26986         local old
26987         local quota
26988         local pref="osd-zfs.$FSNAME-MDT0000."
26989
26990         # limit available space on MDS dataset to meet nospace issue
26991         # quickly. then ZFS 0.7.2 can use reserved space if asked
26992         # properly (using netfree flag in osd_declare_destroy()
26993         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26994         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26995                 gawk '{print $3}')
26996         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26997         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26998         let "usedkb=usedkb-freekb"
26999         let "freekb=freekb/2"
27000         if let "freekb > 5000"; then
27001                 let "freekb=5000"
27002         fi
27003         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27004         trap cleanup_805 EXIT
27005         mkdir_on_mdt0 $DIR/$tdir
27006         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27007                 error "Can't set PFL layout"
27008         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27009         rm -rf $DIR/$tdir || error "not able to remove"
27010         do_facet $SINGLEMDS zfs set quota=$old $fsset
27011         trap 0
27012 }
27013 run_test 805 "ZFS can remove from full fs"
27014
27015 # Size-on-MDS test
27016 check_lsom_data()
27017 {
27018         local file=$1
27019         local expect=$(stat -c %s $file)
27020
27021         check_lsom_size $1 $expect
27022
27023         local blocks=$($LFS getsom -b $file)
27024         expect=$(stat -c %b $file)
27025         [[ $blocks == $expect ]] ||
27026                 error "$file expected blocks: $expect, got: $blocks"
27027 }
27028
27029 check_lsom_size()
27030 {
27031         local size
27032         local expect=$2
27033
27034         cancel_lru_locks mdc
27035
27036         size=$($LFS getsom -s $1)
27037         [[ $size == $expect ]] ||
27038                 error "$file expected size: $expect, got: $size"
27039 }
27040
27041 test_806() {
27042         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27043                 skip "Need MDS version at least 2.11.52"
27044
27045         local bs=1048576
27046
27047         touch $DIR/$tfile || error "touch $tfile failed"
27048
27049         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27050         save_lustre_params client "llite.*.xattr_cache" > $save
27051         lctl set_param llite.*.xattr_cache=0
27052         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27053
27054         # single-threaded write
27055         echo "Test SOM for single-threaded write"
27056         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27057                 error "write $tfile failed"
27058         check_lsom_size $DIR/$tfile $bs
27059
27060         local num=32
27061         local size=$(($num * $bs))
27062         local offset=0
27063         local i
27064
27065         echo "Test SOM for single client multi-threaded($num) write"
27066         $TRUNCATE $DIR/$tfile 0
27067         for ((i = 0; i < $num; i++)); do
27068                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27069                 local pids[$i]=$!
27070                 offset=$((offset + $bs))
27071         done
27072         for (( i=0; i < $num; i++ )); do
27073                 wait ${pids[$i]}
27074         done
27075         check_lsom_size $DIR/$tfile $size
27076
27077         $TRUNCATE $DIR/$tfile 0
27078         for ((i = 0; i < $num; i++)); do
27079                 offset=$((offset - $bs))
27080                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27081                 local pids[$i]=$!
27082         done
27083         for (( i=0; i < $num; i++ )); do
27084                 wait ${pids[$i]}
27085         done
27086         check_lsom_size $DIR/$tfile $size
27087
27088         # multi-client writes
27089         num=$(get_node_count ${CLIENTS//,/ })
27090         size=$(($num * $bs))
27091         offset=0
27092         i=0
27093
27094         echo "Test SOM for multi-client ($num) writes"
27095         $TRUNCATE $DIR/$tfile 0
27096         for client in ${CLIENTS//,/ }; do
27097                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27098                 local pids[$i]=$!
27099                 i=$((i + 1))
27100                 offset=$((offset + $bs))
27101         done
27102         for (( i=0; i < $num; i++ )); do
27103                 wait ${pids[$i]}
27104         done
27105         check_lsom_size $DIR/$tfile $offset
27106
27107         i=0
27108         $TRUNCATE $DIR/$tfile 0
27109         for client in ${CLIENTS//,/ }; do
27110                 offset=$((offset - $bs))
27111                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27112                 local pids[$i]=$!
27113                 i=$((i + 1))
27114         done
27115         for (( i=0; i < $num; i++ )); do
27116                 wait ${pids[$i]}
27117         done
27118         check_lsom_size $DIR/$tfile $size
27119
27120         # verify truncate
27121         echo "Test SOM for truncate"
27122         $TRUNCATE $DIR/$tfile 1048576
27123         check_lsom_size $DIR/$tfile 1048576
27124         $TRUNCATE $DIR/$tfile 1234
27125         check_lsom_size $DIR/$tfile 1234
27126
27127         # verify SOM blocks count
27128         echo "Verify SOM block count"
27129         $TRUNCATE $DIR/$tfile 0
27130         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27131                 error "failed to write file $tfile"
27132         check_lsom_data $DIR/$tfile
27133 }
27134 run_test 806 "Verify Lazy Size on MDS"
27135
27136 test_807() {
27137         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27138         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27139                 skip "Need MDS version at least 2.11.52"
27140
27141         # Registration step
27142         changelog_register || error "changelog_register failed"
27143         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27144         changelog_users $SINGLEMDS | grep -q $cl_user ||
27145                 error "User $cl_user not found in changelog_users"
27146
27147         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27148         save_lustre_params client "llite.*.xattr_cache" > $save
27149         lctl set_param llite.*.xattr_cache=0
27150         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27151
27152         rm -rf $DIR/$tdir || error "rm $tdir failed"
27153         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27154         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27155         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27156         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27157                 error "truncate $tdir/trunc failed"
27158
27159         local bs=1048576
27160         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27161                 error "write $tfile failed"
27162
27163         # multi-client wirtes
27164         local num=$(get_node_count ${CLIENTS//,/ })
27165         local offset=0
27166         local i=0
27167
27168         echo "Test SOM for multi-client ($num) writes"
27169         touch $DIR/$tfile || error "touch $tfile failed"
27170         $TRUNCATE $DIR/$tfile 0
27171         for client in ${CLIENTS//,/ }; do
27172                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27173                 local pids[$i]=$!
27174                 i=$((i + 1))
27175                 offset=$((offset + $bs))
27176         done
27177         for (( i=0; i < $num; i++ )); do
27178                 wait ${pids[$i]}
27179         done
27180
27181         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27182         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27183         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27184         check_lsom_data $DIR/$tdir/trunc
27185         check_lsom_data $DIR/$tdir/single_dd
27186         check_lsom_data $DIR/$tfile
27187
27188         rm -rf $DIR/$tdir
27189         # Deregistration step
27190         changelog_deregister || error "changelog_deregister failed"
27191 }
27192 run_test 807 "verify LSOM syncing tool"
27193
27194 check_som_nologged()
27195 {
27196         local lines=$($LFS changelog $FSNAME-MDT0000 |
27197                 grep 'x=trusted.som' | wc -l)
27198         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27199 }
27200
27201 test_808() {
27202         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27203                 skip "Need MDS version at least 2.11.55"
27204
27205         # Registration step
27206         changelog_register || error "changelog_register failed"
27207
27208         touch $DIR/$tfile || error "touch $tfile failed"
27209         check_som_nologged
27210
27211         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27212                 error "write $tfile failed"
27213         check_som_nologged
27214
27215         $TRUNCATE $DIR/$tfile 1234
27216         check_som_nologged
27217
27218         $TRUNCATE $DIR/$tfile 1048576
27219         check_som_nologged
27220
27221         # Deregistration step
27222         changelog_deregister || error "changelog_deregister failed"
27223 }
27224 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27225
27226 check_som_nodata()
27227 {
27228         $LFS getsom $1
27229         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27230 }
27231
27232 test_809() {
27233         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27234                 skip "Need MDS version at least 2.11.56"
27235
27236         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27237                 error "failed to create DoM-only file $DIR/$tfile"
27238         touch $DIR/$tfile || error "touch $tfile failed"
27239         check_som_nodata $DIR/$tfile
27240
27241         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27242                 error "write $tfile failed"
27243         check_som_nodata $DIR/$tfile
27244
27245         $TRUNCATE $DIR/$tfile 1234
27246         check_som_nodata $DIR/$tfile
27247
27248         $TRUNCATE $DIR/$tfile 4097
27249         check_som_nodata $DIR/$file
27250 }
27251 run_test 809 "Verify no SOM xattr store for DoM-only files"
27252
27253 test_810() {
27254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27255         $GSS && skip_env "could not run with gss"
27256         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27257                 skip "OST < 2.12.58 doesn't align checksum"
27258
27259         set_checksums 1
27260         stack_trap "set_checksums $ORIG_CSUM" EXIT
27261         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27262
27263         local csum
27264         local before
27265         local after
27266         for csum in $CKSUM_TYPES; do
27267                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27268                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27269                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27270                         eval set -- $i
27271                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27272                         before=$(md5sum $DIR/$tfile)
27273                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27274                         after=$(md5sum $DIR/$tfile)
27275                         [ "$before" == "$after" ] ||
27276                                 error "$csum: $before != $after bs=$1 seek=$2"
27277                 done
27278         done
27279 }
27280 run_test 810 "partial page writes on ZFS (LU-11663)"
27281
27282 test_812a() {
27283         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27284                 skip "OST < 2.12.51 doesn't support this fail_loc"
27285
27286         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27287         # ensure ost1 is connected
27288         stat $DIR/$tfile >/dev/null || error "can't stat"
27289         wait_osc_import_state client ost1 FULL
27290         # no locks, no reqs to let the connection idle
27291         cancel_lru_locks osc
27292
27293         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27294 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27295         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27296         wait_osc_import_state client ost1 CONNECTING
27297         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27298
27299         stat $DIR/$tfile >/dev/null || error "can't stat file"
27300 }
27301 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27302
27303 test_812b() { # LU-12378
27304         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27305                 skip "OST < 2.12.51 doesn't support this fail_loc"
27306
27307         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27308         # ensure ost1 is connected
27309         stat $DIR/$tfile >/dev/null || error "can't stat"
27310         wait_osc_import_state client ost1 FULL
27311         # no locks, no reqs to let the connection idle
27312         cancel_lru_locks osc
27313
27314         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27315 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27316         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27317         wait_osc_import_state client ost1 CONNECTING
27318         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27319
27320         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27321         wait_osc_import_state client ost1 IDLE
27322 }
27323 run_test 812b "do not drop no resend request for idle connect"
27324
27325 test_812c() {
27326         local old
27327
27328         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27329
27330         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27331         $LFS getstripe $DIR/$tfile
27332         $LCTL set_param osc.*.idle_timeout=10
27333         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27334         # ensure ost1 is connected
27335         stat $DIR/$tfile >/dev/null || error "can't stat"
27336         wait_osc_import_state client ost1 FULL
27337         # no locks, no reqs to let the connection idle
27338         cancel_lru_locks osc
27339
27340 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27341         $LCTL set_param fail_loc=0x80000533
27342         sleep 15
27343         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27344 }
27345 run_test 812c "idle import vs lock enqueue race"
27346
27347 test_813() {
27348         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27349         [ -z "$file_heat_sav" ] && skip "no file heat support"
27350
27351         local readsample
27352         local writesample
27353         local readbyte
27354         local writebyte
27355         local readsample1
27356         local writesample1
27357         local readbyte1
27358         local writebyte1
27359
27360         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27361         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27362
27363         $LCTL set_param -n llite.*.file_heat=1
27364         echo "Turn on file heat"
27365         echo "Period second: $period_second, Decay percentage: $decay_pct"
27366
27367         echo "QQQQ" > $DIR/$tfile
27368         echo "QQQQ" > $DIR/$tfile
27369         echo "QQQQ" > $DIR/$tfile
27370         cat $DIR/$tfile > /dev/null
27371         cat $DIR/$tfile > /dev/null
27372         cat $DIR/$tfile > /dev/null
27373         cat $DIR/$tfile > /dev/null
27374
27375         local out=$($LFS heat_get $DIR/$tfile)
27376
27377         $LFS heat_get $DIR/$tfile
27378         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27379         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27380         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27381         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27382
27383         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27384         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27385         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27386         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27387
27388         sleep $((period_second + 3))
27389         echo "Sleep $((period_second + 3)) seconds..."
27390         # The recursion formula to calculate the heat of the file f is as
27391         # follow:
27392         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27393         # Where Hi is the heat value in the period between time points i*I and
27394         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27395         # to the weight of Ci.
27396         out=$($LFS heat_get $DIR/$tfile)
27397         $LFS heat_get $DIR/$tfile
27398         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27399         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27400         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27401         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27402
27403         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27404                 error "read sample ($readsample) is wrong"
27405         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27406                 error "write sample ($writesample) is wrong"
27407         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27408                 error "read bytes ($readbyte) is wrong"
27409         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27410                 error "write bytes ($writebyte) is wrong"
27411
27412         echo "QQQQ" > $DIR/$tfile
27413         echo "QQQQ" > $DIR/$tfile
27414         echo "QQQQ" > $DIR/$tfile
27415         cat $DIR/$tfile > /dev/null
27416         cat $DIR/$tfile > /dev/null
27417         cat $DIR/$tfile > /dev/null
27418         cat $DIR/$tfile > /dev/null
27419
27420         sleep $((period_second + 3))
27421         echo "Sleep $((period_second + 3)) seconds..."
27422
27423         out=$($LFS heat_get $DIR/$tfile)
27424         $LFS heat_get $DIR/$tfile
27425         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27426         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27427         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27428         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27429
27430         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27431                 4 * $decay_pct) / 100") -eq 1 ] ||
27432                 error "read sample ($readsample1) is wrong"
27433         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27434                 3 * $decay_pct) / 100") -eq 1 ] ||
27435                 error "write sample ($writesample1) is wrong"
27436         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27437                 20 * $decay_pct) / 100") -eq 1 ] ||
27438                 error "read bytes ($readbyte1) is wrong"
27439         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27440                 15 * $decay_pct) / 100") -eq 1 ] ||
27441                 error "write bytes ($writebyte1) is wrong"
27442
27443         echo "Turn off file heat for the file $DIR/$tfile"
27444         $LFS heat_set -o $DIR/$tfile
27445
27446         echo "QQQQ" > $DIR/$tfile
27447         echo "QQQQ" > $DIR/$tfile
27448         echo "QQQQ" > $DIR/$tfile
27449         cat $DIR/$tfile > /dev/null
27450         cat $DIR/$tfile > /dev/null
27451         cat $DIR/$tfile > /dev/null
27452         cat $DIR/$tfile > /dev/null
27453
27454         out=$($LFS heat_get $DIR/$tfile)
27455         $LFS heat_get $DIR/$tfile
27456         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27457         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27458         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27459         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27460
27461         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27462         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27463         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27464         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27465
27466         echo "Trun on file heat for the file $DIR/$tfile"
27467         $LFS heat_set -O $DIR/$tfile
27468
27469         echo "QQQQ" > $DIR/$tfile
27470         echo "QQQQ" > $DIR/$tfile
27471         echo "QQQQ" > $DIR/$tfile
27472         cat $DIR/$tfile > /dev/null
27473         cat $DIR/$tfile > /dev/null
27474         cat $DIR/$tfile > /dev/null
27475         cat $DIR/$tfile > /dev/null
27476
27477         out=$($LFS heat_get $DIR/$tfile)
27478         $LFS heat_get $DIR/$tfile
27479         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27480         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27481         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27482         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27483
27484         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27485         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27486         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27487         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27488
27489         $LFS heat_set -c $DIR/$tfile
27490         $LCTL set_param -n llite.*.file_heat=0
27491         echo "Turn off file heat support for the Lustre filesystem"
27492
27493         echo "QQQQ" > $DIR/$tfile
27494         echo "QQQQ" > $DIR/$tfile
27495         echo "QQQQ" > $DIR/$tfile
27496         cat $DIR/$tfile > /dev/null
27497         cat $DIR/$tfile > /dev/null
27498         cat $DIR/$tfile > /dev/null
27499         cat $DIR/$tfile > /dev/null
27500
27501         out=$($LFS heat_get $DIR/$tfile)
27502         $LFS heat_get $DIR/$tfile
27503         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27504         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27505         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27506         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27507
27508         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27509         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27510         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27511         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27512
27513         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27514         rm -f $DIR/$tfile
27515 }
27516 run_test 813 "File heat verfication"
27517
27518 test_814()
27519 {
27520         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27521         echo -n y >> $DIR/$tfile
27522         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27523         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27524 }
27525 run_test 814 "sparse cp works as expected (LU-12361)"
27526
27527 test_815()
27528 {
27529         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27530         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27531 }
27532 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27533
27534 test_816() {
27535         local ost1_imp=$(get_osc_import_name client ost1)
27536         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27537                          cut -d'.' -f2)
27538
27539         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27540         # ensure ost1 is connected
27541
27542         stat $DIR/$tfile >/dev/null || error "can't stat"
27543         wait_osc_import_state client ost1 FULL
27544         # no locks, no reqs to let the connection idle
27545         cancel_lru_locks osc
27546         lru_resize_disable osc
27547         local before
27548         local now
27549         before=$($LCTL get_param -n \
27550                  ldlm.namespaces.$imp_name.lru_size)
27551
27552         wait_osc_import_state client ost1 IDLE
27553         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27554         now=$($LCTL get_param -n \
27555               ldlm.namespaces.$imp_name.lru_size)
27556         [ $before == $now ] || error "lru_size changed $before != $now"
27557 }
27558 run_test 816 "do not reset lru_resize on idle reconnect"
27559
27560 cleanup_817() {
27561         umount $tmpdir
27562         exportfs -u localhost:$DIR/nfsexp
27563         rm -rf $DIR/nfsexp
27564 }
27565
27566 test_817() {
27567         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27568
27569         mkdir -p $DIR/nfsexp
27570         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27571                 error "failed to export nfs"
27572
27573         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27574         stack_trap cleanup_817 EXIT
27575
27576         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27577                 error "failed to mount nfs to $tmpdir"
27578
27579         cp /bin/true $tmpdir
27580         $DIR/nfsexp/true || error "failed to execute 'true' command"
27581 }
27582 run_test 817 "nfsd won't cache write lock for exec file"
27583
27584 test_818() {
27585         test_mkdir -i0 -c1 $DIR/$tdir
27586         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27587         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27588         stop $SINGLEMDS
27589
27590         # restore osp-syn threads
27591         stack_trap "fail $SINGLEMDS"
27592
27593         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27594         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27595         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27596                 error "start $SINGLEMDS failed"
27597         rm -rf $DIR/$tdir
27598
27599         local testid=$(echo $TESTNAME | tr '_' ' ')
27600
27601         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27602                 grep "run LFSCK" || error "run LFSCK is not suggested"
27603 }
27604 run_test 818 "unlink with failed llog"
27605
27606 test_819a() {
27607         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27608         cancel_lru_locks osc
27609         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27610         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27611         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27612         rm -f $TDIR/$tfile
27613 }
27614 run_test 819a "too big niobuf in read"
27615
27616 test_819b() {
27617         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27618         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27619         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27620         cancel_lru_locks osc
27621         sleep 1
27622         rm -f $TDIR/$tfile
27623 }
27624 run_test 819b "too big niobuf in write"
27625
27626
27627 function test_820_start_ost() {
27628         sleep 5
27629
27630         for num in $(seq $OSTCOUNT); do
27631                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27632         done
27633 }
27634
27635 test_820() {
27636         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27637
27638         mkdir $DIR/$tdir
27639         umount_client $MOUNT || error "umount failed"
27640         for num in $(seq $OSTCOUNT); do
27641                 stop ost$num
27642         done
27643
27644         # mount client with no active OSTs
27645         # so that the client can't initialize max LOV EA size
27646         # from OSC notifications
27647         mount_client $MOUNT || error "mount failed"
27648         # delay OST starting to keep this 0 max EA size for a while
27649         test_820_start_ost &
27650
27651         # create a directory on MDS2
27652         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27653                 error "Failed to create directory"
27654         # open intent should update default EA size
27655         # see mdc_update_max_ea_from_body()
27656         # notice this is the very first RPC to MDS2
27657         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27658         ret=$?
27659         echo $out
27660         # With SSK, this situation can lead to -EPERM being returned.
27661         # In that case, simply retry.
27662         if [ $ret -ne 0 ] && $SHARED_KEY; then
27663                 if echo "$out" | grep -q "not permitted"; then
27664                         cp /etc/services $DIR/$tdir/mds2
27665                         ret=$?
27666                 fi
27667         fi
27668         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27669 }
27670 run_test 820 "update max EA from open intent"
27671
27672 test_822() {
27673         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27674
27675         save_lustre_params mds1 \
27676                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27677         do_facet $SINGLEMDS "$LCTL set_param -n \
27678                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27679         do_facet $SINGLEMDS "$LCTL set_param -n \
27680                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27681
27682         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27683         local maxage=$(do_facet mds1 $LCTL get_param -n \
27684                        osp.$FSNAME-OST0000*MDT0000.maxage)
27685         sleep $((maxage + 1))
27686
27687         #define OBD_FAIL_NET_ERROR_RPC          0x532
27688         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27689
27690         stack_trap "restore_lustre_params < $p; rm $p"
27691
27692         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27693                       osp.$FSNAME-OST0000*MDT0000.create_count")
27694         for i in $(seq 1 $count); do
27695                 touch $DIR/$tfile.${i} || error "touch failed"
27696         done
27697 }
27698 run_test 822 "test precreate failure"
27699
27700 test_823() {
27701         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27702         local OST_MAX_PRECREATE=20000
27703
27704         save_lustre_params mds1 \
27705                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27706         do_facet $SINGLEMDS "$LCTL set_param -n \
27707                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27708         do_facet $SINGLEMDS "$LCTL set_param -n \
27709                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27710
27711         stack_trap "restore_lustre_params < $p; rm $p"
27712
27713         do_facet $SINGLEMDS "$LCTL set_param -n \
27714                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27715
27716         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27717                       osp.$FSNAME-OST0000*MDT0000.create_count")
27718         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27719                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27720         local expect_count=$(((($max/2)/256) * 256))
27721
27722         log "setting create_count to 100200:"
27723         log " -result- count: $count with max: $max, expecting: $expect_count"
27724
27725         [[ $count -eq expect_count ]] ||
27726                 error "Create count not set to max precreate."
27727 }
27728 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27729
27730 test_831() {
27731         local sync_changes=$(do_facet $SINGLEMDS \
27732                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27733
27734         [ "$sync_changes" -gt 100 ] &&
27735                 skip "Sync changes $sync_changes > 100 already"
27736
27737         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27738
27739         $LFS mkdir -i 0 $DIR/$tdir
27740         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27741
27742         save_lustre_params mds1 \
27743                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27744         save_lustre_params mds1 \
27745                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27746
27747         do_facet mds1 "$LCTL set_param -n \
27748                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27749                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27750         stack_trap "restore_lustre_params < $p" EXIT
27751
27752         createmany -o $DIR/$tdir/f- 1000
27753         unlinkmany $DIR/$tdir/f- 1000 &
27754         local UNLINK_PID=$!
27755
27756         while sleep 1; do
27757                 sync_changes=$(do_facet mds1 \
27758                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27759                 # the check in the code is racy, fail the test
27760                 # if the value above the limit by 10.
27761                 [ $sync_changes -gt 110 ] && {
27762                         kill -2 $UNLINK_PID
27763                         wait
27764                         error "osp changes throttling failed, $sync_changes>110"
27765                 }
27766                 kill -0 $UNLINK_PID 2> /dev/null || break
27767         done
27768         wait
27769 }
27770 run_test 831 "throttling unlink/setattr queuing on OSP"
27771
27772 #
27773 # tests that do cleanup/setup should be run at the end
27774 #
27775
27776 test_900() {
27777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27778         local ls
27779
27780         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27781         $LCTL set_param fail_loc=0x903
27782
27783         cancel_lru_locks MGC
27784
27785         FAIL_ON_ERROR=true cleanup
27786         FAIL_ON_ERROR=true setup
27787 }
27788 run_test 900 "umount should not race with any mgc requeue thread"
27789
27790 # LUS-6253/LU-11185
27791 test_901() {
27792         local oldc
27793         local newc
27794         local olds
27795         local news
27796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27797
27798         # some get_param have a bug to handle dot in param name
27799         cancel_lru_locks MGC
27800         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27801         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27802         umount_client $MOUNT || error "umount failed"
27803         mount_client $MOUNT || error "mount failed"
27804         cancel_lru_locks MGC
27805         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27806         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27807
27808         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27809         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27810
27811         return 0
27812 }
27813 run_test 901 "don't leak a mgc lock on client umount"
27814
27815 # LU-13377
27816 test_902() {
27817         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27818                 skip "client does not have LU-13377 fix"
27819         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27820         $LCTL set_param fail_loc=0x1415
27821         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27822         cancel_lru_locks osc
27823         rm -f $DIR/$tfile
27824 }
27825 run_test 902 "test short write doesn't hang lustre"
27826
27827 # LU-14711
27828 test_903() {
27829         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27830         echo "blah" > $DIR/${tfile}-2
27831         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27832         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27833         $LCTL set_param fail_loc=0x417 fail_val=20
27834
27835         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27836         sleep 1 # To start the destroy
27837         wait_destroy_complete 150 || error "Destroy taking too long"
27838         cat $DIR/$tfile > /dev/null || error "Evicted"
27839 }
27840 run_test 903 "Test long page discard does not cause evictions"
27841
27842 complete $SECONDS
27843 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27844 check_and_cleanup_lustre
27845 if [ "$I_MOUNTED" != "yes" ]; then
27846         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27847 fi
27848 exit_status